From bfb5a39301be322943ab2cd1347121194e871dc2 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Thu, 5 Apr 2018 12:51:26 -0500 Subject: [PATCH 001/197] Improvements for blind vote publishing - Move code for broadcasting blind vote to p2p network and applying data to success handler of tx broadcast - Add popups when publishing blind vote --- .../proposal/active/ActiveProposalsView.java | 35 +++++++++---------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index 268c08d4fe8..cf30c1c16e1 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -39,6 +39,7 @@ import bisq.core.dao.vote.result.BooleanVoteResult; import bisq.core.locale.Res; +import bisq.common.UserThread; import bisq.common.crypto.CryptoException; import bisq.common.util.Tuple2; import bisq.common.util.Tuple3; @@ -47,12 +48,9 @@ import org.bitcoinj.core.Coin; import org.bitcoinj.core.InsufficientMoneyException; -import org.bitcoinj.core.Transaction; import javax.inject.Inject; -import com.google.common.util.concurrent.FutureCallback; - import javafx.scene.Node; import javafx.scene.control.Button; import javafx.scene.control.Label; @@ -69,10 +67,7 @@ import java.util.ArrayList; import java.util.Comparator; import java.util.List; - -import org.jetbrains.annotations.NotNull; - -import javax.annotation.Nullable; +import java.util.concurrent.TimeUnit; import static bisq.desktop.util.FormBuilder.add3ButtonsAfterGroup; import static bisq.desktop.util.FormBuilder.addButtonAfterGroup; @@ -130,19 +125,21 @@ protected void activate() { voteButton.setOnAction(e -> { Coin stake = bsqFormatter.parseToCoin(stakeInputTextField.getText()); // TODO verify stake - //TODO show popup + Popup startPublishingPopup = new Popup<>(); + startPublishingPopup.information(Res.get("dao.proposal.blindVote.startPublishing")) + .hideCloseButton() + .show(); try { - blindVoteService.publishBlindVote(stake, new FutureCallback() { - @Override - public void onSuccess(@Nullable Transaction result) { - //TODO - } - - @Override - public void onFailure(@NotNull Throwable t) { - //TODO - } - }); + blindVoteService.publishBlindVote(stake, + () -> { + startPublishingPopup.hide(); + UserThread.runAfter(() -> { + new Popup<>().feedback(Res.get("dao.proposal.blindVote.success")) + .show(); + }, 100, TimeUnit.MILLISECONDS); + }, errorMessage -> { + new Popup<>().error(errorMessage).show(); + }); } catch (CryptoException e1) { //TODO show error popup e1.printStackTrace(); From 2848e7527e92d0eb797c89d6905b8b8ab581bfac Mon Sep 17 00:00:00 2001 From: sqrrm Date: Thu, 5 Apr 2018 21:03:05 +0200 Subject: [PATCH 002/197] Refactor move Phase to Cycles --- .../components/SeparatedPhaseBars.java | 6 +++--- .../main/dao/proposal/BaseProposalView.java | 7 ++++--- .../main/dao/proposal/ProposalListItem.java | 5 +++-- .../proposal/active/ActiveProposalsView.java | 5 +++-- .../dashboard/ProposalDashboardView.java | 19 ++++++++++--------- 5 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java b/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java index e68b155d851..7e3c2cfa8d5 100644 --- a/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java +++ b/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java @@ -17,7 +17,7 @@ package bisq.desktop.components; -import bisq.core.dao.vote.PeriodService; +import bisq.core.dao.vote.Cycles; import bisq.core.locale.Res; import bisq.common.UserThread; @@ -139,7 +139,7 @@ private void adjustWidth(double availableWidth) { @Getter public static class SeparatedPhaseBarsItem { - private final PeriodService.Phase phase; + private final Cycles.Phase phase; private final boolean showBlocks; private final IntegerProperty startValueProperty = new SimpleIntegerProperty(); private final IntegerProperty endValueProperty = new SimpleIntegerProperty(); @@ -150,7 +150,7 @@ public static class SeparatedPhaseBarsItem { @Setter private Label titleLabel; - public SeparatedPhaseBarsItem(PeriodService.Phase phase, boolean showBlocks) { + public SeparatedPhaseBarsItem(Cycles.Phase phase, boolean showBlocks) { this.phase = phase; this.showBlocks = showBlocks; } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java index 371fe77ba31..4a9a628553d 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java @@ -29,6 +29,7 @@ import bisq.core.dao.blockchain.BsqBlockChain; import bisq.core.dao.blockchain.ReadableBsqBlockChain; import bisq.core.dao.blockchain.vo.BsqBlock; +import bisq.core.dao.vote.Cycles; import bisq.core.dao.vote.PeriodService; import bisq.core.dao.vote.proposal.Proposal; import bisq.core.dao.vote.proposal.ProposalPayload; @@ -86,9 +87,9 @@ public abstract class BaseProposalView extends ActivatableView i protected GridPane detailsGridPane, gridPane; protected ProposalListItem selectedProposalListItem; protected ListChangeListener proposalListChangeListener; - protected ChangeListener phaseChangeListener; + protected ChangeListener phaseChangeListener; protected final PeriodService periodService; - protected PeriodService.Phase currentPhase; + protected Cycles.Phase currentPhase; protected Subscription phaseSubscription; private ScrollPane proposalDisplayView; @@ -236,7 +237,7 @@ protected void onSelectProposal(ProposalListItem item) { hideProposalDisplay(); } - protected void onPhaseChanged(PeriodService.Phase phase) { + protected void onPhaseChanged(Cycles.Phase phase) { if (!phase.equals(this.currentPhase)) { this.currentPhase = phase; onSelectProposal(selectedProposalListItem); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index 99903701125..dcf156b8147 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -27,6 +27,7 @@ import bisq.core.dao.blockchain.ReadableBsqBlockChain; import bisq.core.dao.blockchain.vo.BsqBlock; import bisq.core.dao.blockchain.vo.Tx; +import bisq.core.dao.vote.Cycles; import bisq.core.dao.vote.PeriodService; import bisq.core.dao.vote.proposal.Proposal; import bisq.core.dao.vote.proposal.ProposalService; @@ -72,7 +73,7 @@ public class ProposalListItem implements BsqBlockChain.Listener { private TxConfidenceListener txConfidenceListener; private Tooltip tooltip = new Tooltip(Res.get("confidence.unknown")); private Transaction walletTransaction; - private ChangeListener phaseChangeListener; + private ChangeListener phaseChangeListener; private AutoTooltipButton actionButton; private ImageView actionButtonIconView; @Setter @@ -122,7 +123,7 @@ public class ProposalListItem implements BsqBlockChain.Listener { proposal.getVoteResultProperty().addListener(voteResultChangeListener); } - public void applyState(PeriodService.Phase newValue, VoteResult voteResult) { + public void applyState(Cycles.Phase newValue, VoteResult voteResult) { actionButton.setText(""); actionButton.setVisible(false); actionButton.setOnAction(null); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index 268c08d4fe8..f0d8b6df22a 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -32,6 +32,7 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.InsufficientBsqException; import bisq.core.dao.blockchain.ReadableBsqBlockChain; +import bisq.core.dao.vote.Cycles; import bisq.core.dao.vote.PeriodService; import bisq.core.dao.vote.blindvote.BlindVoteService; import bisq.core.dao.vote.proposal.Proposal; @@ -251,10 +252,10 @@ private void onCancelVote() { } @Override - protected void onPhaseChanged(PeriodService.Phase phase) { + protected void onPhaseChanged(Cycles.Phase phase) { super.onPhaseChanged(phase); - changeVoteViewItemsVisibility(phase == PeriodService.Phase.BLIND_VOTE); + changeVoteViewItemsVisibility(phase == Cycles.Phase.BLIND_VOTE); if (removeButton != null) { removeButton.setManaged(false); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java index 197be5c2535..3b2facb11df 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java @@ -23,6 +23,7 @@ import bisq.desktop.util.Layout; import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.dao.vote.Cycles; import bisq.core.dao.vote.PeriodService; import bisq.core.locale.Res; @@ -49,7 +50,7 @@ public class ProposalDashboardView extends ActivatableView { private List phaseBarsItems; private final BsqWalletService bsqWalletService; private final PeriodService periodService; - private PeriodService.Phase currentPhase; + private Cycles.Phase currentPhase; private Subscription phaseSubscription; private GridPane gridPane; private int gridRow = 0; @@ -97,14 +98,14 @@ public void initialize() { private SeparatedPhaseBars createSeparatedPhaseBars() { phaseBarsItems = Arrays.asList( - new SeparatedPhaseBars.SeparatedPhaseBarsItem(PeriodService.Phase.PROPOSAL, true), - new SeparatedPhaseBars.SeparatedPhaseBarsItem(PeriodService.Phase.BREAK1, false), - new SeparatedPhaseBars.SeparatedPhaseBarsItem(PeriodService.Phase.BLIND_VOTE, true), - new SeparatedPhaseBars.SeparatedPhaseBarsItem(PeriodService.Phase.BREAK2, false), - new SeparatedPhaseBars.SeparatedPhaseBarsItem(PeriodService.Phase.VOTE_REVEAL, true), - new SeparatedPhaseBars.SeparatedPhaseBarsItem(PeriodService.Phase.BREAK3, false), - new SeparatedPhaseBars.SeparatedPhaseBarsItem(PeriodService.Phase.ISSUANCE, false), - new SeparatedPhaseBars.SeparatedPhaseBarsItem(PeriodService.Phase.BREAK4, false)); + new SeparatedPhaseBars.SeparatedPhaseBarsItem(Cycles.Phase.PROPOSAL, true), + new SeparatedPhaseBars.SeparatedPhaseBarsItem(Cycles.Phase.BREAK1, false), + new SeparatedPhaseBars.SeparatedPhaseBarsItem(Cycles.Phase.BLIND_VOTE, true), + new SeparatedPhaseBars.SeparatedPhaseBarsItem(Cycles.Phase.BREAK2, false), + new SeparatedPhaseBars.SeparatedPhaseBarsItem(Cycles.Phase.VOTE_REVEAL, true), + new SeparatedPhaseBars.SeparatedPhaseBarsItem(Cycles.Phase.BREAK3, false), + new SeparatedPhaseBars.SeparatedPhaseBarsItem(Cycles.Phase.ISSUANCE, false), + new SeparatedPhaseBars.SeparatedPhaseBarsItem(Cycles.Phase.BREAK4, false)); return new SeparatedPhaseBars(phaseBarsItems); } From 2fa19b0685982d7f5d0c2eefa0c35c5d8abd179c Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Thu, 5 Apr 2018 17:16:48 -0500 Subject: [PATCH 003/197] Use new TxBroadcaster class for better error handling --- .../main/dao/wallet/send/BsqSendView.java | 33 +++++++++++-------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java b/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java index 21b2d9d7d84..ac1da147c65 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java @@ -34,9 +34,13 @@ import bisq.desktop.util.validation.BsqValidator; import bisq.core.btc.Restrictions; +import bisq.core.btc.wallet.BroadcastException; +import bisq.core.btc.wallet.BroadcastTimeoutException; import bisq.core.btc.wallet.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; +import bisq.core.btc.wallet.MalleabilityException; +import bisq.core.btc.wallet.TxBroadcaster; import bisq.core.btc.wallet.WalletsManager; import bisq.core.btc.wallet.WalletsSetup; import bisq.core.locale.Res; @@ -50,17 +54,11 @@ import javax.inject.Inject; -import com.google.common.util.concurrent.FutureCallback; - import javafx.scene.control.Button; import javafx.scene.layout.GridPane; import javafx.beans.value.ChangeListener; -import org.jetbrains.annotations.NotNull; - -import javax.annotation.Nullable; - import static bisq.desktop.util.FormBuilder.addButtonAfterGroup; import static bisq.desktop.util.FormBuilder.addLabelInputTextField; import static bisq.desktop.util.FormBuilder.addTitledGroupBg; @@ -159,18 +157,25 @@ public void initialize() { bsqFormatter.formatCoinWithCode(receiverAmount))) .actionButtonText(Res.get("shared.yes")) .onAction(() -> { - walletsManager.publishAndCommitBsqTx(txWithBtcFee, new FutureCallback() { + walletsManager.publishAndCommitBsqTx(txWithBtcFee, new TxBroadcaster.Callback() { + @Override + public void onSuccess() { + log.debug("Successfully sent tx with id " + txWithBtcFee.getHashAsString()); + } + + @Override + public void onTimeout(BroadcastTimeoutException exception) { + new Popup<>().warning(exception.toString()); + } + @Override - public void onSuccess(@Nullable Transaction transaction) { - if (transaction != null) { - log.debug("Successfully sent tx with id " + transaction.getHashAsString()); - } + public void onTxMalleability(MalleabilityException exception) { + new Popup<>().warning(exception.toString()); } @Override - public void onFailure(@NotNull Throwable t) { - log.error(t.toString()); - new Popup<>().warning(t.toString()); + public void onFailure(BroadcastException exception) { + new Popup<>().warning(exception.toString()); } }); From 4d217e682ad63291579d4430944191b480d764da Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Thu, 5 Apr 2018 17:49:40 -0500 Subject: [PATCH 004/197] Replace Broadcaster with TxBroadcaster - Add transaction as param to onSuccess handler - Remove Broadcaster - Use onTimeout and onTxMalleability default implementation if not dedicated handling code was there --- .../main/dao/wallet/send/BsqSendView.java | 17 ++++++++++------- .../overlays/windows/ManualPayoutTxWindow.java | 15 ++++++--------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java b/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java index ac1da147c65..b7087db1e9e 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java @@ -34,13 +34,13 @@ import bisq.desktop.util.validation.BsqValidator; import bisq.core.btc.Restrictions; -import bisq.core.btc.wallet.BroadcastException; -import bisq.core.btc.wallet.BroadcastTimeoutException; import bisq.core.btc.wallet.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; -import bisq.core.btc.wallet.MalleabilityException; +import bisq.core.btc.wallet.TxBroadcastException; +import bisq.core.btc.wallet.TxBroadcastTimeoutException; import bisq.core.btc.wallet.TxBroadcaster; +import bisq.core.btc.wallet.TxMalleabilityException; import bisq.core.btc.wallet.WalletsManager; import bisq.core.btc.wallet.WalletsSetup; import bisq.core.locale.Res; @@ -159,22 +159,25 @@ public void initialize() { .onAction(() -> { walletsManager.publishAndCommitBsqTx(txWithBtcFee, new TxBroadcaster.Callback() { @Override - public void onSuccess() { + public void onSuccess(Transaction transaction) { log.debug("Successfully sent tx with id " + txWithBtcFee.getHashAsString()); } @Override - public void onTimeout(BroadcastTimeoutException exception) { + public void onTimeout(TxBroadcastTimeoutException exception) { + //TODO handle new Popup<>().warning(exception.toString()); } @Override - public void onTxMalleability(MalleabilityException exception) { + public void onTxMalleability(TxMalleabilityException exception) { + //TODO handle new Popup<>().warning(exception.toString()); } @Override - public void onFailure(BroadcastException exception) { + public void onFailure(TxBroadcastException exception) { + //TODO handle new Popup<>().warning(exception.toString()); } }); diff --git a/src/main/java/bisq/desktop/main/overlays/windows/ManualPayoutTxWindow.java b/src/main/java/bisq/desktop/main/overlays/windows/ManualPayoutTxWindow.java index 96f9163f555..5b45e9e2e51 100644 --- a/src/main/java/bisq/desktop/main/overlays/windows/ManualPayoutTxWindow.java +++ b/src/main/java/bisq/desktop/main/overlays/windows/ManualPayoutTxWindow.java @@ -25,6 +25,8 @@ import bisq.core.btc.exceptions.TransactionVerificationException; import bisq.core.btc.exceptions.WalletException; import bisq.core.btc.wallet.TradeWalletService; +import bisq.core.btc.wallet.TxBroadcastException; +import bisq.core.btc.wallet.TxBroadcaster; import bisq.core.btc.wallet.WalletsSetup; import bisq.network.p2p.P2PService; @@ -37,16 +39,12 @@ import javax.inject.Inject; -import com.google.common.util.concurrent.FutureCallback; - import javafx.scene.Scene; import javafx.scene.input.KeyCode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.jetbrains.annotations.NotNull; - import javax.annotation.Nullable; import static bisq.desktop.util.FormBuilder.addLabelInputTextField; @@ -154,7 +152,7 @@ private void addContent() { actionButtonText("Sign and publish transaction"); - FutureCallback callback = new FutureCallback() { + TxBroadcaster.Callback callback = new TxBroadcaster.Callback() { @Override public void onSuccess(@Nullable Transaction result) { log.error("onSuccess"); @@ -167,10 +165,9 @@ public void onSuccess(@Nullable Transaction result) { } @Override - public void onFailure(@NotNull Throwable t) { - log.error(t.toString()); - log.error("onFailure"); - UserThread.execute(() -> new Popup<>().warning(t.toString()).show()); + public void onFailure(TxBroadcastException exception) { + log.error(exception.toString()); + UserThread.execute(() -> new Popup<>().warning(exception.toString()).show()); } }; onAction(() -> { From 3a553b1d1103ca3275c20b437ac185e7889500c9 Mon Sep 17 00:00:00 2001 From: sqrrm Date: Fri, 6 Apr 2018 01:06:38 +0200 Subject: [PATCH 005/197] Fix phase calculation --- .../main/dao/proposal/dashboard/ProposalDashboardView.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java index 3b2facb11df..98ba599034c 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java @@ -147,7 +147,7 @@ private void onChainHeightChanged(int height) { item.setStartAndEnd(startBlock, endBlock); double progress = 0; if (height >= startBlock && height <= endBlock) { - progress = (double) (height - startBlock + 1) / (double) item.getPhase().getDurationInBlocks(); + progress = (double) (height - startBlock + 1) / (double) periodService.getCycle(height).getPhaseDuration(item.getPhase()); } else if (height < startBlock) { progress = 0; } else if (height > endBlock) { From 316a305f5335573fc2ff7eb133fa1c5a35454abb Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Fri, 6 Apr 2018 17:01:08 -0500 Subject: [PATCH 006/197] Improve UI, logging and error handling - Use ExceptionHandler at publishBlindVote - Add hasEnoughBsqFunds method to BlindVoteService - Show fee and confirmation popup at publish blind vote - Add GUIUtils.showBsqFeeInfoPopup to avoid code duplication - Add busyAnimation to publish blind vote button - Improve logs --- .../main/dao/proposal/BaseProposalView.java | 10 +- .../main/dao/proposal/ProposalListItem.java | 1 - .../proposal/active/ActiveProposalsView.java | 94 ++++++++++--------- .../proposal/closed/ClosedProposalsView.java | 9 +- .../dao/proposal/make/MakeProposalView.java | 35 +++---- .../dao/proposal/myvotes/MyVotesView.java | 10 +- src/main/java/bisq/desktop/util/GUIUtil.java | 18 ++++ 7 files changed, 104 insertions(+), 73 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java index 371fe77ba31..3658f3e8e7f 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java @@ -23,12 +23,14 @@ import bisq.desktop.components.AutoTooltipTableColumn; import bisq.desktop.components.HyperlinkWithIcon; import bisq.desktop.components.TableGroupHeadline; +import bisq.desktop.util.BSFormatter; import bisq.desktop.util.BsqFormatter; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.blockchain.BsqBlockChain; import bisq.core.dao.blockchain.ReadableBsqBlockChain; import bisq.core.dao.blockchain.vo.BsqBlock; +import bisq.core.dao.param.DaoParamService; import bisq.core.dao.vote.PeriodService; import bisq.core.dao.vote.proposal.Proposal; import bisq.core.dao.vote.proposal.ProposalPayload; @@ -73,8 +75,10 @@ public abstract class BaseProposalView extends ActivatableView i protected final ProposalService proposalService; protected final ReadableBsqBlockChain readableBsqBlockChain; + protected final DaoParamService daoParamService; protected final BsqWalletService bsqWalletService; protected final BsqFormatter bsqFormatter; + protected final BSFormatter btcFormatter; protected final ObservableList proposalListItems = FXCollections.observableArrayList(); protected final SortedList sortedList = new SortedList<>(proposalListItems); @@ -101,13 +105,17 @@ public abstract class BaseProposalView extends ActivatableView i protected BaseProposalView(ProposalService proposalService, BsqWalletService bsqWalletService, ReadableBsqBlockChain readableBsqBlockChain, + DaoParamService daoParamService, PeriodService periodService, - BsqFormatter bsqFormatter) { + BsqFormatter bsqFormatter, + BSFormatter btcFormatter) { this.proposalService = proposalService; this.bsqWalletService = bsqWalletService; this.readableBsqBlockChain = readableBsqBlockChain; + this.daoParamService = daoParamService; this.periodService = periodService; this.bsqFormatter = bsqFormatter; + this.btcFormatter = btcFormatter; } @Override diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index 99903701125..8d8bedcf220 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -162,7 +162,6 @@ public void applyState(PeriodService.Phase newValue, VoteResult voteResult) { //TODO } } else { - log.error("actionButtonIconView.setVisible(false);"); actionButtonIconView.setVisible(false); } } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index cf30c1c16e1..49b0a0c1cb1 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -18,36 +18,37 @@ package bisq.desktop.main.dao.proposal.active; import bisq.desktop.common.view.FxmlView; +import bisq.desktop.components.BusyAnimation; import bisq.desktop.components.InputTextField; import bisq.desktop.components.TitledGroupBg; import bisq.desktop.main.dao.proposal.BaseProposalView; import bisq.desktop.main.dao.proposal.ProposalListItem; import bisq.desktop.main.overlays.popups.Popup; +import bisq.desktop.util.BSFormatter; import bisq.desktop.util.BsqFormatter; +import bisq.desktop.util.GUIUtil; import bisq.desktop.util.Layout; import bisq.core.btc.exceptions.TransactionVerificationException; import bisq.core.btc.exceptions.WalletException; import bisq.core.btc.wallet.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.btc.wallet.InsufficientBsqException; import bisq.core.dao.blockchain.ReadableBsqBlockChain; +import bisq.core.dao.param.DaoParamService; import bisq.core.dao.vote.PeriodService; +import bisq.core.dao.vote.blindvote.BlindVoteConsensus; import bisq.core.dao.vote.blindvote.BlindVoteService; import bisq.core.dao.vote.proposal.Proposal; import bisq.core.dao.vote.proposal.ProposalService; import bisq.core.dao.vote.result.BooleanVoteResult; import bisq.core.locale.Res; -import bisq.common.UserThread; -import bisq.common.crypto.CryptoException; import bisq.common.util.Tuple2; import bisq.common.util.Tuple3; -import com.google.protobuf.InvalidProtocolBufferException; - import org.bitcoinj.core.Coin; import org.bitcoinj.core.InsufficientMoneyException; +import org.bitcoinj.core.Transaction; import javax.inject.Inject; @@ -62,17 +63,11 @@ import javafx.util.Callback; -import java.io.IOException; - import java.util.ArrayList; import java.util.Comparator; import java.util.List; -import java.util.concurrent.TimeUnit; -import static bisq.desktop.util.FormBuilder.add3ButtonsAfterGroup; -import static bisq.desktop.util.FormBuilder.addButtonAfterGroup; -import static bisq.desktop.util.FormBuilder.addLabelInputTextField; -import static bisq.desktop.util.FormBuilder.addTitledGroupBg; +import static bisq.desktop.util.FormBuilder.*; @FxmlView public class ActiveProposalsView extends BaseProposalView implements BsqBalanceListener { @@ -82,6 +77,8 @@ public class ActiveProposalsView extends BaseProposalView implements BsqBalanceL private Button removeButton, acceptButton, rejectButton, cancelVoteButton, voteButton; private InputTextField stakeInputTextField; private List voteViewItems = new ArrayList<>(); + private BusyAnimation voteButtonBusyAnimation; + private Label voteButtonInfoLabel; /////////////////////////////////////////////////////////////////////////////////////////// @@ -94,9 +91,11 @@ private ActiveProposalsView(ProposalService voteRequestManger, BlindVoteService blindVoteService, BsqWalletService bsqWalletService, ReadableBsqBlockChain readableBsqBlockChain, - BsqFormatter bsqFormatter) { - super(voteRequestManger, bsqWalletService, readableBsqBlockChain, periodService, - bsqFormatter); + DaoParamService daoParamService, + BsqFormatter bsqFormatter, + BSFormatter btcFormatter) { + super(voteRequestManger, bsqWalletService, readableBsqBlockChain, daoParamService, periodService, bsqFormatter, + btcFormatter); this.blindVoteService = blindVoteService; } @@ -123,43 +122,43 @@ protected void activate() { if (voteButton != null) { voteButton.setOnAction(e -> { - Coin stake = bsqFormatter.parseToCoin(stakeInputTextField.getText()); // TODO verify stake - Popup startPublishingPopup = new Popup<>(); - startPublishingPopup.information(Res.get("dao.proposal.blindVote.startPublishing")) - .hideCloseButton() - .show(); + Coin stake = bsqFormatter.parseToCoin(stakeInputTextField.getText()); + final Coin fee = BlindVoteConsensus.getFee(daoParamService, readableBsqBlockChain.getChainHeadHeight()); + Transaction dummyTx = null; try { - blindVoteService.publishBlindVote(stake, - () -> { - startPublishingPopup.hide(); - UserThread.runAfter(() -> { - new Popup<>().feedback(Res.get("dao.proposal.blindVote.success")) - .show(); - }, 100, TimeUnit.MILLISECONDS); - }, errorMessage -> { - new Popup<>().error(errorMessage).show(); - }); - } catch (CryptoException e1) { - //TODO show error popup - e1.printStackTrace(); - } catch (InsufficientBsqException e1) { - e1.printStackTrace(); - } catch (WalletException e1) { - e1.printStackTrace(); - } catch (TransactionVerificationException e1) { - e1.printStackTrace(); - } catch (InsufficientMoneyException e1) { - e1.printStackTrace(); - } catch (InvalidProtocolBufferException e1) { - e1.printStackTrace(); - } catch (IOException e1) { - e1.printStackTrace(); + // We create a tx with dummy opreturn data to get the mining fee for confirmation popup + dummyTx = blindVoteService.getBlindVoteTx(stake, fee, new byte[22]); + } catch (InsufficientMoneyException | WalletException | TransactionVerificationException exception) { + new Popup<>().warning(exception.toString()).show(); + } + + if (dummyTx != null) { + Coin miningFee = dummyTx.getFee(); + int txSize = dummyTx.bitcoinSerialize().length; + GUIUtil.showBsqFeeInfoPopup(fee, miningFee, txSize, bsqFormatter, btcFormatter, + Res.get("dao.blindVote"), () -> publishBlindVote(stake)); } }); } } + private void publishBlindVote(Coin stake) { + voteButtonBusyAnimation.play(); + voteButtonInfoLabel.setText(Res.get("dao.blindVote.startPublishing")); + blindVoteService.publishBlindVote(stake, + () -> { + voteButtonBusyAnimation.stop(); + voteButtonInfoLabel.setText(""); + new Popup().feedback(Res.get("dao.blindVote.success")) + .show(); + }, exception -> { + voteButtonBusyAnimation.stop(); + voteButtonInfoLabel.setText(""); + new Popup<>().warning(exception.toString()).show(); + }); + } + @Override protected void deactivate() { super.deactivate(); @@ -180,7 +179,10 @@ private void createVoteView() { Res.getWithCol("dao.proposal.myVote.stake"), Layout .FIRST_ROW_AND_GROUP_DISTANCE - 20); stakeInputTextField = tuple2.second; - voteButton = addButtonAfterGroup(root, ++gridRow, Res.get("dao.proposal.myVote.button")); + Tuple3 tuple = addButtonBusyAnimationLabelAfterGroup(root, ++gridRow, Res.get("dao.proposal.myVote.button")); + voteButton = tuple.first; + voteButtonBusyAnimation = tuple.second; + voteButtonInfoLabel = tuple.third; voteViewItems.add(titledGroupBg); voteViewItems.add(tuple2.first); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java index 66ed8481b4f..8acd1359f61 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java @@ -19,10 +19,12 @@ import bisq.desktop.common.view.FxmlView; import bisq.desktop.main.dao.proposal.BaseProposalView; +import bisq.desktop.util.BSFormatter; import bisq.desktop.util.BsqFormatter; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.blockchain.ReadableBsqBlockChain; +import bisq.core.dao.param.DaoParamService; import bisq.core.dao.vote.PeriodService; import bisq.core.dao.vote.proposal.ProposalService; @@ -40,8 +42,11 @@ private ClosedProposalsView(ProposalService proposalService, PeriodService periodService, BsqWalletService bsqWalletService, ReadableBsqBlockChain readableBsqBlockChain, - BsqFormatter bsqFormatter) { - super(proposalService, bsqWalletService, readableBsqBlockChain, periodService, bsqFormatter); + DaoParamService daoParamService, + BsqFormatter bsqFormatter, + BSFormatter bsFormatter) { + super(proposalService, bsqWalletService, readableBsqBlockChain, daoParamService, periodService, + bsqFormatter, bsFormatter); } @Override diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index 6185f7dcdb6..57ae79d3b63 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -44,7 +44,6 @@ import bisq.core.dao.vote.proposal.generic.GenericProposalService; import bisq.core.locale.Res; import bisq.core.provider.fee.FeeService; -import bisq.core.util.CoinUtil; import bisq.network.p2p.P2PService; @@ -175,25 +174,11 @@ private void publishProposal(ProposalType type) { Coin miningFee = Objects.requireNonNull(tx).getFee(); int txSize = tx.bitcoinSerialize().length; - final Coin fee = ProposalConsensus.getFee(daoParamService, readableBsqBlockChain); - new Popup<>().headLine(Res.get("dao.proposal.create.confirm")) - .confirmation(Res.get("dao.proposal.create.confirm.info", - bsqFormatter.formatCoinWithCode(fee), - btcFormatter.formatCoinWithCode(miningFee), - CoinUtil.getFeePerByte(miningFee, txSize), - txSize / 1000d)) - .actionButtonText(Res.get("shared.yes")) - .onAction(() -> { - proposalService.publishProposal(proposal, - () -> { - proposalDisplay.clearForm(); - proposalTypeComboBox.getSelectionModel().clearSelection(); - new Popup<>().confirmation(Res.get("dao.tx.published.success")).show(); - }, - errorMessage -> new Popup<>().warning(errorMessage).show()); - }) - .closeButtonText(Res.get("shared.cancel")) - .show(); + final Coin fee = ProposalConsensus.getFee(daoParamService, readableBsqBlockChain.getChainHeadHeight()); + + GUIUtil.showBsqFeeInfoPopup(fee, miningFee, txSize, bsqFormatter, btcFormatter, + Res.get("dao.proposal"), () -> publishProposal(proposal)); + } catch (InsufficientMoneyException e) { BSFormatter formatter = e instanceof InsufficientBsqException ? bsqFormatter : btcFormatter; new Popup<>().warning(Res.get("dao.proposal.create.missingFunds", @@ -214,6 +199,16 @@ private void publishProposal(ProposalType type) { } } + private void publishProposal(Proposal proposal) { + proposalService.publishProposal(proposal, + () -> { + proposalDisplay.clearForm(); + proposalTypeComboBox.getSelectionModel().clearSelection(); + new Popup<>().confirmation(Res.get("dao.tx.published.success")).show(); + }, + errorMessage -> new Popup<>().warning(errorMessage).show()); + } + private Proposal createProposal(ProposalType type) throws InsufficientMoneyException, TransactionVerificationException, ValidationException, WalletException, IOException { diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java index d319b68dd52..d744bbdb815 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java @@ -24,12 +24,14 @@ import bisq.desktop.components.TableGroupHeadline; import bisq.desktop.main.dao.proposal.BaseProposalView; import bisq.desktop.main.dao.proposal.ProposalListItem; +import bisq.desktop.util.BSFormatter; import bisq.desktop.util.BsqFormatter; import bisq.desktop.util.GUIUtil; import bisq.desktop.util.Layout; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.blockchain.ReadableBsqBlockChain; +import bisq.core.dao.param.DaoParamService; import bisq.core.dao.vote.PeriodService; import bisq.core.dao.vote.myvote.MyVoteService; import bisq.core.dao.vote.proposal.ProposalList; @@ -92,10 +94,12 @@ private MyVotesView(ProposalService voteRequestManger, MyVoteService myVoteService, BsqWalletService bsqWalletService, ReadableBsqBlockChain readableBsqBlockChain, + DaoParamService daoParamService, Preferences preferences, - BsqFormatter bsqFormatter) { - super(voteRequestManger, bsqWalletService, readableBsqBlockChain, periodService, - bsqFormatter); + BsqFormatter bsqFormatter, + BSFormatter btcFormatter) { + super(voteRequestManger, bsqWalletService, readableBsqBlockChain, daoParamService, periodService, bsqFormatter, + btcFormatter); this.myVoteService = myVoteService; this.readableBsqBlockChain = readableBsqBlockChain; this.preferences = preferences; diff --git a/src/main/java/bisq/desktop/util/GUIUtil.java b/src/main/java/bisq/desktop/util/GUIUtil.java index 0c8271c01fc..1824148c1a4 100644 --- a/src/main/java/bisq/desktop/util/GUIUtil.java +++ b/src/main/java/bisq/desktop/util/GUIUtil.java @@ -33,6 +33,7 @@ import bisq.core.user.DontShowAgainLookup; import bisq.core.user.Preferences; import bisq.core.user.User; +import bisq.core.util.CoinUtil; import bisq.network.p2p.P2PService; @@ -543,4 +544,21 @@ public static void removeChildrenFromGridPaneRows(GridPane gridPane, int start, childByRowMap.get(i).forEach(child -> gridPane.getChildren().remove(child)); } } + + public static void showBsqFeeInfoPopup(Coin fee, Coin miningFee, int txSize, BsqFormatter bsqFormatter, + BSFormatter btcFormatter, String type, + Runnable actionHandler) { + new Popup<>().headLine(Res.get("dao.feeTx.confirm", type)) + .confirmation(Res.get("dao.feeTx.confirm.details", + type, + bsqFormatter.formatCoinWithCode(fee), + btcFormatter.formatCoinWithCode(miningFee), + CoinUtil.getFeePerByte(miningFee, txSize), + txSize / 1000d, + type)) + .actionButtonText(Res.get("shared.yes")) + .onAction(actionHandler::run) + .closeButtonText(Res.get("shared.cancel")) + .show(); + } } From 405a07447afe03bcf38f5cc394df9d8ee5fb8dfd Mon Sep 17 00:00:00 2001 From: sqrrm Date: Sat, 7 Apr 2018 15:12:46 +0200 Subject: [PATCH 007/197] Refactor Phase back to PeriodService --- .../components/SeparatedPhaseBars.java | 6 +++--- .../main/dao/proposal/BaseProposalView.java | 7 +++---- .../main/dao/proposal/ProposalListItem.java | 5 ++--- .../proposal/active/ActiveProposalsView.java | 5 ++--- .../dashboard/ProposalDashboardView.java | 19 +++++++++---------- 5 files changed, 19 insertions(+), 23 deletions(-) diff --git a/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java b/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java index 7e3c2cfa8d5..e68b155d851 100644 --- a/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java +++ b/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java @@ -17,7 +17,7 @@ package bisq.desktop.components; -import bisq.core.dao.vote.Cycles; +import bisq.core.dao.vote.PeriodService; import bisq.core.locale.Res; import bisq.common.UserThread; @@ -139,7 +139,7 @@ private void adjustWidth(double availableWidth) { @Getter public static class SeparatedPhaseBarsItem { - private final Cycles.Phase phase; + private final PeriodService.Phase phase; private final boolean showBlocks; private final IntegerProperty startValueProperty = new SimpleIntegerProperty(); private final IntegerProperty endValueProperty = new SimpleIntegerProperty(); @@ -150,7 +150,7 @@ public static class SeparatedPhaseBarsItem { @Setter private Label titleLabel; - public SeparatedPhaseBarsItem(Cycles.Phase phase, boolean showBlocks) { + public SeparatedPhaseBarsItem(PeriodService.Phase phase, boolean showBlocks) { this.phase = phase; this.showBlocks = showBlocks; } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java index 4a9a628553d..371fe77ba31 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java @@ -29,7 +29,6 @@ import bisq.core.dao.blockchain.BsqBlockChain; import bisq.core.dao.blockchain.ReadableBsqBlockChain; import bisq.core.dao.blockchain.vo.BsqBlock; -import bisq.core.dao.vote.Cycles; import bisq.core.dao.vote.PeriodService; import bisq.core.dao.vote.proposal.Proposal; import bisq.core.dao.vote.proposal.ProposalPayload; @@ -87,9 +86,9 @@ public abstract class BaseProposalView extends ActivatableView i protected GridPane detailsGridPane, gridPane; protected ProposalListItem selectedProposalListItem; protected ListChangeListener proposalListChangeListener; - protected ChangeListener phaseChangeListener; + protected ChangeListener phaseChangeListener; protected final PeriodService periodService; - protected Cycles.Phase currentPhase; + protected PeriodService.Phase currentPhase; protected Subscription phaseSubscription; private ScrollPane proposalDisplayView; @@ -237,7 +236,7 @@ protected void onSelectProposal(ProposalListItem item) { hideProposalDisplay(); } - protected void onPhaseChanged(Cycles.Phase phase) { + protected void onPhaseChanged(PeriodService.Phase phase) { if (!phase.equals(this.currentPhase)) { this.currentPhase = phase; onSelectProposal(selectedProposalListItem); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index dcf156b8147..99903701125 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -27,7 +27,6 @@ import bisq.core.dao.blockchain.ReadableBsqBlockChain; import bisq.core.dao.blockchain.vo.BsqBlock; import bisq.core.dao.blockchain.vo.Tx; -import bisq.core.dao.vote.Cycles; import bisq.core.dao.vote.PeriodService; import bisq.core.dao.vote.proposal.Proposal; import bisq.core.dao.vote.proposal.ProposalService; @@ -73,7 +72,7 @@ public class ProposalListItem implements BsqBlockChain.Listener { private TxConfidenceListener txConfidenceListener; private Tooltip tooltip = new Tooltip(Res.get("confidence.unknown")); private Transaction walletTransaction; - private ChangeListener phaseChangeListener; + private ChangeListener phaseChangeListener; private AutoTooltipButton actionButton; private ImageView actionButtonIconView; @Setter @@ -123,7 +122,7 @@ public class ProposalListItem implements BsqBlockChain.Listener { proposal.getVoteResultProperty().addListener(voteResultChangeListener); } - public void applyState(Cycles.Phase newValue, VoteResult voteResult) { + public void applyState(PeriodService.Phase newValue, VoteResult voteResult) { actionButton.setText(""); actionButton.setVisible(false); actionButton.setOnAction(null); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index f0d8b6df22a..268c08d4fe8 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -32,7 +32,6 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.InsufficientBsqException; import bisq.core.dao.blockchain.ReadableBsqBlockChain; -import bisq.core.dao.vote.Cycles; import bisq.core.dao.vote.PeriodService; import bisq.core.dao.vote.blindvote.BlindVoteService; import bisq.core.dao.vote.proposal.Proposal; @@ -252,10 +251,10 @@ private void onCancelVote() { } @Override - protected void onPhaseChanged(Cycles.Phase phase) { + protected void onPhaseChanged(PeriodService.Phase phase) { super.onPhaseChanged(phase); - changeVoteViewItemsVisibility(phase == Cycles.Phase.BLIND_VOTE); + changeVoteViewItemsVisibility(phase == PeriodService.Phase.BLIND_VOTE); if (removeButton != null) { removeButton.setManaged(false); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java index 98ba599034c..4b06d9bc1ec 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java @@ -23,7 +23,6 @@ import bisq.desktop.util.Layout; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.vote.Cycles; import bisq.core.dao.vote.PeriodService; import bisq.core.locale.Res; @@ -50,7 +49,7 @@ public class ProposalDashboardView extends ActivatableView { private List phaseBarsItems; private final BsqWalletService bsqWalletService; private final PeriodService periodService; - private Cycles.Phase currentPhase; + private PeriodService.Phase currentPhase; private Subscription phaseSubscription; private GridPane gridPane; private int gridRow = 0; @@ -98,14 +97,14 @@ public void initialize() { private SeparatedPhaseBars createSeparatedPhaseBars() { phaseBarsItems = Arrays.asList( - new SeparatedPhaseBars.SeparatedPhaseBarsItem(Cycles.Phase.PROPOSAL, true), - new SeparatedPhaseBars.SeparatedPhaseBarsItem(Cycles.Phase.BREAK1, false), - new SeparatedPhaseBars.SeparatedPhaseBarsItem(Cycles.Phase.BLIND_VOTE, true), - new SeparatedPhaseBars.SeparatedPhaseBarsItem(Cycles.Phase.BREAK2, false), - new SeparatedPhaseBars.SeparatedPhaseBarsItem(Cycles.Phase.VOTE_REVEAL, true), - new SeparatedPhaseBars.SeparatedPhaseBarsItem(Cycles.Phase.BREAK3, false), - new SeparatedPhaseBars.SeparatedPhaseBarsItem(Cycles.Phase.ISSUANCE, false), - new SeparatedPhaseBars.SeparatedPhaseBarsItem(Cycles.Phase.BREAK4, false)); + new SeparatedPhaseBars.SeparatedPhaseBarsItem(PeriodService.Phase.PROPOSAL, true), + new SeparatedPhaseBars.SeparatedPhaseBarsItem(PeriodService.Phase.BREAK1, false), + new SeparatedPhaseBars.SeparatedPhaseBarsItem(PeriodService.Phase.BLIND_VOTE, true), + new SeparatedPhaseBars.SeparatedPhaseBarsItem(PeriodService.Phase.BREAK2, false), + new SeparatedPhaseBars.SeparatedPhaseBarsItem(PeriodService.Phase.VOTE_REVEAL, true), + new SeparatedPhaseBars.SeparatedPhaseBarsItem(PeriodService.Phase.BREAK3, false), + new SeparatedPhaseBars.SeparatedPhaseBarsItem(PeriodService.Phase.ISSUANCE, false), + new SeparatedPhaseBars.SeparatedPhaseBarsItem(PeriodService.Phase.BREAK4, false)); return new SeparatedPhaseBars(phaseBarsItems); } From c5b01a0ed455d9a56c2253a222fecf261ca1bece Mon Sep 17 00:00:00 2001 From: sqrrm Date: Sat, 7 Apr 2018 15:42:16 +0200 Subject: [PATCH 008/197] Rename StartBlock to FirstBlock, EndBlock to LastBlock --- .../main/dao/proposal/dashboard/ProposalDashboardView.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java index 4b06d9bc1ec..2bc5eb0e01a 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java @@ -141,12 +141,13 @@ protected void deactivate() { private void onChainHeightChanged(int height) { phaseBarsItems.forEach(item -> { - int startBlock = periodService.getAbsoluteStartBlockOfPhase(height, item.getPhase()); - int endBlock = periodService.getAbsoluteEndBlockOfPhase(height, item.getPhase()); + int startBlock = periodService.getFirstBlockOfPhase(periodService.getCycle(height), item.getPhase()); + int endBlock = periodService.getLastBlockOfPhase(periodService.getCycle(height), item.getPhase()); item.setStartAndEnd(startBlock, endBlock); double progress = 0; if (height >= startBlock && height <= endBlock) { - progress = (double) (height - startBlock + 1) / (double) periodService.getCycle(height).getPhaseDuration(item.getPhase()); + progress = (double) (height - startBlock + 1) / + (double) periodService.getCycle(height).getPhaseDuration(item.getPhase()); } else if (height < startBlock) { progress = 0; } else if (height > endBlock) { From 3003964bf3e94aa08ba2e81a003dccf87012b566 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sat, 7 Apr 2018 12:08:33 -0500 Subject: [PATCH 009/197] Extract reusable code to baseService. Add more validation --- .../java/bisq/desktop/main/dao/proposal/ProposalListItem.java | 2 +- .../desktop/main/dao/proposal/active/ActiveProposalsView.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index 8d8bedcf220..3d038016c1c 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -131,7 +131,7 @@ public void applyState(PeriodService.Phase newValue, VoteResult voteResult) { case UNDEFINED: break; case PROPOSAL: - if (proposalService.isMine(proposal)) { + if (proposalService.isMine(proposal.getProposalPayload())) { actionButton.setVisible(!isTxInPastCycle); actionButtonIconView.setVisible(actionButton.isVisible()); actionButton.setText(Res.get("shared.remove")); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index 49b0a0c1cb1..01406800042 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -266,7 +266,7 @@ protected void onPhaseChanged(PeriodService.Phase phase) { final Proposal proposal = selectedProposalListItem.getProposal(); switch (phase) { case PROPOSAL: - if (proposalService.isMine(proposal)) { + if (proposalService.isMine(proposal.getProposalPayload())) { if (removeButton == null) { removeButton = addButtonAfterGroup(detailsGridPane, proposalDisplay.incrementAndGetGridRow(), Res.get("dao.proposal.active.remove")); removeButton.setOnAction(event -> onRemove()); From 7c03980bc22c9dc09662e31cfda3f1167d9c6bdd Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sat, 7 Apr 2018 15:12:55 -0500 Subject: [PATCH 010/197] Use BaseService for BlindVoteService. Fix checks with current cycle --- .../desktop/main/dao/proposal/active/ActiveProposalsView.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index 01406800042..cf8b3e3fd66 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -325,7 +325,7 @@ protected void onPhaseChanged(PeriodService.Phase phase) { @Override protected void updateProposalList() { - doUpdateProposalList(proposalService.getActiveProposals()); + doUpdateProposalList(proposalService.getValidOrMyUnconfirmedProposals()); } private void updateStateAfterVote() { From 2e5d5d2191c049df5eccec5560ba8d5eba3b4eaf Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sat, 7 Apr 2018 19:29:09 -0500 Subject: [PATCH 011/197] Pass chainHeight to period service. --- .../java/bisq/desktop/main/dao/proposal/ProposalListItem.java | 3 ++- .../desktop/main/dao/proposal/active/ActiveProposalsView.java | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index 3d038016c1c..ac65e11efec 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -126,7 +126,8 @@ public void applyState(PeriodService.Phase newValue, VoteResult voteResult) { actionButton.setText(""); actionButton.setVisible(false); actionButton.setOnAction(null); - final boolean isTxInPastCycle = periodService.isTxInPastCycle(proposal.getTxId()); + final boolean isTxInPastCycle = periodService.isTxInPastCycle(proposal.getTxId(), + readableBsqBlockChain.getChainHeadHeight()); switch (newValue) { case UNDEFINED: break; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index cf8b3e3fd66..c12ad4bba9e 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -262,7 +262,8 @@ protected void onPhaseChanged(PeriodService.Phase phase) { } if (selectedProposalListItem != null && proposalDisplay != null && - !periodService.isTxInPastCycle(selectedProposalListItem.getProposal().getTxId())) { + !periodService.isTxInPastCycle(selectedProposalListItem.getProposal().getTxId(), + readableBsqBlockChain.getChainHeadHeight())) { final Proposal proposal = selectedProposalListItem.getProposal(); switch (phase) { case PROPOSAL: From 819f8e472f610426ca84237e2587a322bea328f8 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sat, 7 Apr 2018 20:13:47 -0500 Subject: [PATCH 012/197] Add isTxInCorrectCycle checks with correct chainHeight --- .../desktop/main/dao/proposal/active/ActiveProposalsView.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index c12ad4bba9e..e17f03c5d2e 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -326,7 +326,7 @@ protected void onPhaseChanged(PeriodService.Phase phase) { @Override protected void updateProposalList() { - doUpdateProposalList(proposalService.getValidOrMyUnconfirmedProposals()); + doUpdateProposalList(proposalService.getActiveOrMyUnconfirmedProposals()); } private void updateStateAfterVote() { From 585478fef9cd945ea912777c143a438491a0240f Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sat, 7 Apr 2018 21:11:07 -0500 Subject: [PATCH 013/197] Rename package result to voteresult --- .../java/bisq/desktop/main/dao/proposal/ProposalListItem.java | 4 ++-- .../desktop/main/dao/proposal/active/ActiveProposalsView.java | 2 +- .../bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index ac65e11efec..b4ded74d6de 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -30,8 +30,8 @@ import bisq.core.dao.vote.PeriodService; import bisq.core.dao.vote.proposal.Proposal; import bisq.core.dao.vote.proposal.ProposalService; -import bisq.core.dao.vote.result.BooleanVoteResult; -import bisq.core.dao.vote.result.VoteResult; +import bisq.core.dao.vote.voteresult.BooleanVoteResult; +import bisq.core.dao.vote.voteresult.VoteResult; import bisq.core.locale.Res; import org.bitcoinj.core.Transaction; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index e17f03c5d2e..4527e4ad5d6 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -40,7 +40,7 @@ import bisq.core.dao.vote.blindvote.BlindVoteService; import bisq.core.dao.vote.proposal.Proposal; import bisq.core.dao.vote.proposal.ProposalService; -import bisq.core.dao.vote.result.BooleanVoteResult; +import bisq.core.dao.vote.voteresult.BooleanVoteResult; import bisq.core.locale.Res; import bisq.common.util.Tuple2; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java index d744bbdb815..46b9a5ad78a 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java @@ -36,8 +36,8 @@ import bisq.core.dao.vote.myvote.MyVoteService; import bisq.core.dao.vote.proposal.ProposalList; import bisq.core.dao.vote.proposal.ProposalService; -import bisq.core.dao.vote.result.BooleanVoteResult; -import bisq.core.dao.vote.result.VoteResult; +import bisq.core.dao.vote.voteresult.BooleanVoteResult; +import bisq.core.dao.vote.voteresult.VoteResult; import bisq.core.locale.Res; import bisq.core.user.Preferences; From d06b067aa5c214e043d7c17c75456fc3fcfd1d90 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sat, 7 Apr 2018 21:22:47 -0500 Subject: [PATCH 014/197] Renaming - VoteResult to Vote - LongVoteResult to LongVote - BooleanVoteResult to BooleanVote --- .../main/dao/proposal/ProposalListItem.java | 16 ++++++++-------- .../dao/proposal/active/ActiveProposalsView.java | 8 ++++---- .../main/dao/proposal/myvotes/MyVotesView.java | 10 +++++----- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index b4ded74d6de..9daffa03fcd 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -30,8 +30,8 @@ import bisq.core.dao.vote.PeriodService; import bisq.core.dao.vote.proposal.Proposal; import bisq.core.dao.vote.proposal.ProposalService; -import bisq.core.dao.vote.voteresult.BooleanVoteResult; -import bisq.core.dao.vote.voteresult.VoteResult; +import bisq.core.dao.vote.voteresult.BooleanVote; +import bisq.core.dao.vote.voteresult.Vote; import bisq.core.locale.Res; import org.bitcoinj.core.Transaction; @@ -63,7 +63,7 @@ public class ProposalListItem implements BsqBlockChain.Listener { private final ReadableBsqBlockChain readableBsqBlockChain; private final BsqFormatter bsqFormatter; private final ChangeListener chainHeightListener; - private final ChangeListener voteResultChangeListener; + private final ChangeListener voteResultChangeListener; @Getter private TxConfidenceIndicator txConfidenceIndicator; @Getter @@ -111,7 +111,7 @@ public class ProposalListItem implements BsqBlockChain.Listener { readableBsqBlockChain.addListener(this); phaseChangeListener = (observable, oldValue, newValue) -> { - applyState(newValue, proposal.getVoteResult()); + applyState(newValue, proposal.getVote()); }; voteResultChangeListener = (observable, oldValue, newValue) -> { @@ -122,7 +122,7 @@ public class ProposalListItem implements BsqBlockChain.Listener { proposal.getVoteResultProperty().addListener(voteResultChangeListener); } - public void applyState(PeriodService.Phase newValue, VoteResult voteResult) { + public void applyState(PeriodService.Phase newValue, Vote vote) { actionButton.setText(""); actionButton.setVisible(false); actionButton.setOnAction(null); @@ -151,10 +151,10 @@ public void applyState(PeriodService.Phase newValue, VoteResult voteResult) { if (!isTxInPastCycle) { actionNode = actionButtonIconView; actionButton.setVisible(false); - if (proposal.getVoteResult() != null) { + if (proposal.getVote() != null) { actionButtonIconView.setVisible(true); - if (voteResult instanceof BooleanVoteResult) { - if (((BooleanVoteResult) voteResult).isAccepted()) { + if (vote instanceof BooleanVote) { + if (((BooleanVote) vote).isAccepted()) { actionButtonIconView.setId("accepted"); } else { actionButtonIconView.setId("rejected"); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index 4527e4ad5d6..22f7e6f5a50 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -40,7 +40,7 @@ import bisq.core.dao.vote.blindvote.BlindVoteService; import bisq.core.dao.vote.proposal.Proposal; import bisq.core.dao.vote.proposal.ProposalService; -import bisq.core.dao.vote.voteresult.BooleanVoteResult; +import bisq.core.dao.vote.voteresult.BooleanVote; import bisq.core.locale.Res; import bisq.common.util.Tuple2; @@ -235,17 +235,17 @@ protected void onSelectProposal(ProposalListItem item) { } private void onAccept() { - selectedProposalListItem.getProposal().setVoteResult(new BooleanVoteResult(true)); + selectedProposalListItem.getProposal().setVote(new BooleanVote(true)); updateStateAfterVote(); } private void onReject() { - selectedProposalListItem.getProposal().setVoteResult(new BooleanVoteResult(false)); + selectedProposalListItem.getProposal().setVote(new BooleanVote(false)); updateStateAfterVote(); } private void onCancelVote() { - selectedProposalListItem.getProposal().setVoteResult(null); + selectedProposalListItem.getProposal().setVote(null); updateStateAfterVote(); } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java index 46b9a5ad78a..d43bfac60d6 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java @@ -36,8 +36,8 @@ import bisq.core.dao.vote.myvote.MyVoteService; import bisq.core.dao.vote.proposal.ProposalList; import bisq.core.dao.vote.proposal.ProposalService; -import bisq.core.dao.vote.voteresult.BooleanVoteResult; -import bisq.core.dao.vote.voteresult.VoteResult; +import bisq.core.dao.vote.voteresult.BooleanVote; +import bisq.core.dao.vote.voteresult.Vote; import bisq.core.locale.Res; import bisq.core.user.Preferences; @@ -375,9 +375,9 @@ public void updateItem(final ProposalListItem item, boolean empty) { if (item != null && !empty) { actionButtonIconView = new ImageView(); - VoteResult voteResult = item.getProposal().getVoteResult(); - if (voteResult instanceof BooleanVoteResult) { - if (((BooleanVoteResult) voteResult).isAccepted()) { + Vote vote = item.getProposal().getVote(); + if (vote instanceof BooleanVote) { + if (((BooleanVote) vote).isAccepted()) { actionButtonIconView.setId("accepted"); } else { actionButtonIconView.setId("rejected"); From 1a08030ba3f188990d540348c891c50144e88628 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sat, 7 Apr 2018 21:23:43 -0500 Subject: [PATCH 015/197] Move vote classes one level down --- .../java/bisq/desktop/main/dao/proposal/ProposalListItem.java | 4 ++-- .../desktop/main/dao/proposal/active/ActiveProposalsView.java | 2 +- .../bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index 9daffa03fcd..330dbd98407 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -27,11 +27,11 @@ import bisq.core.dao.blockchain.ReadableBsqBlockChain; import bisq.core.dao.blockchain.vo.BsqBlock; import bisq.core.dao.blockchain.vo.Tx; +import bisq.core.dao.vote.BooleanVote; import bisq.core.dao.vote.PeriodService; +import bisq.core.dao.vote.Vote; import bisq.core.dao.vote.proposal.Proposal; import bisq.core.dao.vote.proposal.ProposalService; -import bisq.core.dao.vote.voteresult.BooleanVote; -import bisq.core.dao.vote.voteresult.Vote; import bisq.core.locale.Res; import org.bitcoinj.core.Transaction; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index 22f7e6f5a50..5b8f40d5052 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -35,12 +35,12 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.blockchain.ReadableBsqBlockChain; import bisq.core.dao.param.DaoParamService; +import bisq.core.dao.vote.BooleanVote; import bisq.core.dao.vote.PeriodService; import bisq.core.dao.vote.blindvote.BlindVoteConsensus; import bisq.core.dao.vote.blindvote.BlindVoteService; import bisq.core.dao.vote.proposal.Proposal; import bisq.core.dao.vote.proposal.ProposalService; -import bisq.core.dao.vote.voteresult.BooleanVote; import bisq.core.locale.Res; import bisq.common.util.Tuple2; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java index d43bfac60d6..02bb9b869e3 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java @@ -32,12 +32,12 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.blockchain.ReadableBsqBlockChain; import bisq.core.dao.param.DaoParamService; +import bisq.core.dao.vote.BooleanVote; import bisq.core.dao.vote.PeriodService; +import bisq.core.dao.vote.Vote; import bisq.core.dao.vote.myvote.MyVoteService; import bisq.core.dao.vote.proposal.ProposalList; import bisq.core.dao.vote.proposal.ProposalService; -import bisq.core.dao.vote.voteresult.BooleanVote; -import bisq.core.dao.vote.voteresult.Vote; import bisq.core.locale.Res; import bisq.core.user.Preferences; From 80221720cb88a8c7c0d5e049beb5bb0d3dae8dc7 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sat, 7 Apr 2018 23:38:46 -0500 Subject: [PATCH 016/197] Refactor and improve Issuance domain. Add issued amount to UI - Add VoteResultService for all proposals - Use stake instead of nr. of votes for majority data view calculation - Use IssuanceService fro compensation requests - Add more checks at issuance - Use secondary sort by hex of hash for getMajorityHash - Add issued amount to dashboard view --- .../dao/proposal/myvotes/VoteListItem.java | 2 +- .../wallet/dashboard/BsqDashboardView.java | 23 ++++++++++++------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java index 62e441cda2d..6ddcfbf5e08 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java @@ -149,7 +149,7 @@ public void onTransactionConfidenceChanged(TransactionConfidence confidence) { private void calculateStake() { if (stake == 0) { String txId = myVote.getTxId(); - stake = readableBsqBlockChain.getBlindVoteStakeTxOutputs().stream() + stake = readableBsqBlockChain.getUnspentBlindVoteStakeTxOutputs().stream() .filter(txOutput -> txOutput.getTxId().equals(txId)) .filter(txOutput -> txOutput.getIndex() == 0) .mapToLong(TxOutput::getValue) diff --git a/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java b/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java index a1dac3b057e..3d78201af99 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java @@ -66,8 +66,8 @@ public class BsqDashboardView extends ActivatableView implements private final BsqFormatter bsqFormatter; private int gridRow = 0; - private TextField issuedAmountTextField, availableAmountTextField, burntAmountTextField, allTxTextField, - burntTxTextField, spentTxTextField, + private TextField genesisIssueAmountTextField, compRequestIssueAmountTextField, availableAmountTextField, burntAmountTextField, allTxTextField, + burntTxTextField/*, spentTxTextField*/, utxoTextField, priceTextField, marketCapTextField; private ChangeListener priceChangeListener; private HyperlinkWithIcon hyperlinkWithIcon; @@ -94,7 +94,7 @@ private BsqDashboardView(BsqBalanceUtil bsqBalanceUtil, public void initialize() { gridRow = bsqBalanceUtil.addGroup(root, gridRow); - addTitledGroupBg(root, ++gridRow, 12, Res.get("dao.wallet.dashboard.statistics"), Layout.GROUP_DISTANCE); + addTitledGroupBg(root, ++gridRow, 11, Res.get("dao.wallet.dashboard.statistics"), Layout.GROUP_DISTANCE); addLabelTextField(root, gridRow, Res.get("dao.wallet.dashboard.genesisBlockHeight"), String.valueOf(readableBsqBlockChain.getGenesisBlockHeight()), Layout.FIRST_ROW_AND_GROUP_DISTANCE); @@ -109,13 +109,14 @@ public void initialize() { GridPane.setMargin(hyperlinkWithIcon, new Insets(0, 0, 0, -4)); root.getChildren().add(hyperlinkWithIcon); - issuedAmountTextField = addLabelTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.issuedAmount")).second; + genesisIssueAmountTextField = addLabelTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.genesisIssueAmount")).second; + compRequestIssueAmountTextField = addLabelTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.compRequestIssueAmount")).second; availableAmountTextField = addLabelTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.availableAmount")).second; burntAmountTextField = addLabelTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.burntAmount")).second; allTxTextField = addLabelTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.allTx")).second; utxoTextField = addLabelTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.utxo")).second; - spentTxTextField = addLabelTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.spentTxo")).second; + // spentTxTextField = addLabelTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.spentTxo")).second; burntTxTextField = addLabelTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.burntTx")).second; priceTextField = addLabelTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.price")).second; @@ -157,14 +158,20 @@ public void onBlockAdded(BsqBlock bsqBlock) { private void updateWithBsqBlockChainData() { - issuedAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(readableBsqBlockChain.getIssuedAmountAtGenesis())); + final Coin issuedAmountFromGenesis = readableBsqBlockChain.getIssuedAmountAtGenesis(); + genesisIssueAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(issuedAmountFromGenesis)); + + final Coin issuedAmountFromCompRequests = readableBsqBlockChain.getIssuedAmountFromCompRequests(); + compRequestIssueAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(issuedAmountFromCompRequests)); + final Coin burntFee = readableBsqBlockChain.getTotalBurntFee(); - final Coin availableAmount = readableBsqBlockChain.getIssuedAmountAtGenesis().subtract(burntFee); + final Coin availableAmount = issuedAmountFromGenesis.add(issuedAmountFromCompRequests).subtract(burntFee); + availableAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(availableAmount)); burntAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(burntFee)); allTxTextField.setText(String.valueOf(readableBsqBlockChain.getTransactions().size())); utxoTextField.setText(String.valueOf(readableBsqBlockChain.getUnspentTxOutputs().size())); - spentTxTextField.setText(String.valueOf(readableBsqBlockChain.getSpentTxOutputs().size())); + //spentTxTextField.setText(String.valueOf(readableBsqBlockChain.getSpentTxOutputs().size())); burntTxTextField.setText(String.valueOf(readableBsqBlockChain.getFeeTransactions().size())); } From 89f3841cb262d4639ad31c63b25f786a1746f9b5 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Mon, 9 Apr 2018 12:59:51 -0500 Subject: [PATCH 017/197] Revert "Periodservice cycles" --- .travis.yml | 7 +++++++ .../main/dao/proposal/dashboard/ProposalDashboardView.java | 7 +++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index ed2abf26c06..1c83f08631f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,12 @@ language: java jdk: oraclejdk8 +before_cache: + - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock + - rm -fr $HOME/.gradle/caches/*/plugin-resolution/ +cache: + directories: + - $HOME/.gradle/caches/ + - $HOME/.gradle/wrapper/ notifications: slack: on_success: change diff --git a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java index 2bc5eb0e01a..197be5c2535 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java @@ -141,13 +141,12 @@ protected void deactivate() { private void onChainHeightChanged(int height) { phaseBarsItems.forEach(item -> { - int startBlock = periodService.getFirstBlockOfPhase(periodService.getCycle(height), item.getPhase()); - int endBlock = periodService.getLastBlockOfPhase(periodService.getCycle(height), item.getPhase()); + int startBlock = periodService.getAbsoluteStartBlockOfPhase(height, item.getPhase()); + int endBlock = periodService.getAbsoluteEndBlockOfPhase(height, item.getPhase()); item.setStartAndEnd(startBlock, endBlock); double progress = 0; if (height >= startBlock && height <= endBlock) { - progress = (double) (height - startBlock + 1) / - (double) periodService.getCycle(height).getPhaseDuration(item.getPhase()); + progress = (double) (height - startBlock + 1) / (double) item.getPhase().getDurationInBlocks(); } else if (height < startBlock) { progress = 0; } else if (height > endBlock) { From c07822da376f1cba9f24c6a4cfc80ffd84ea456e Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Wed, 11 Apr 2018 13:51:19 -0500 Subject: [PATCH 018/197] Refactor proposal domain and make it more thread safe - Add MyProposalService and ProposalListService to split up responsibility and threading boundaries - Make ProposalService running in parser thread. Refactor resonsibilities. - Add thread context aware listeners - Use injectable NodeExecutor to make parsre thread accessible for thread context aware listeners - Add stream() method and Iterable interface to PersistableList - Add ProposalFactory to create proposals from its payload - Add ProposalPayload and BlindVoteList to Tx - Add getLastOutput method to Tx --- src/main/java/bisq/desktop/app/BisqApp.java | 2 ++ .../main/dao/proposal/BaseProposalView.java | 33 +++++++------------ .../proposal/active/ActiveProposalsView.java | 17 +++++++--- .../proposal/closed/ClosedProposalsView.java | 17 +++++++--- .../dao/proposal/make/MakeProposalView.java | 10 +++--- .../dao/proposal/myvotes/MyVotesView.java | 19 ++++++----- 6 files changed, 53 insertions(+), 45 deletions(-) diff --git a/src/main/java/bisq/desktop/app/BisqApp.java b/src/main/java/bisq/desktop/app/BisqApp.java index 36a6b2a38bd..80e4477a262 100644 --- a/src/main/java/bisq/desktop/app/BisqApp.java +++ b/src/main/java/bisq/desktop/app/BisqApp.java @@ -51,6 +51,7 @@ import bisq.core.dao.param.DaoParamService; import bisq.core.dao.vote.blindvote.BlindVoteService; import bisq.core.dao.vote.myvote.MyVoteService; +import bisq.core.dao.vote.proposal.MyProposalService; import bisq.core.dao.vote.proposal.ProposalService; import bisq.core.filter.FilterManager; import bisq.core.locale.CurrencyUtil; @@ -231,6 +232,7 @@ public void start(Stage stage) throws IOException { persistedDataHosts.add(injector.getInstance(FailedTradesManager.class)); persistedDataHosts.add(injector.getInstance(DisputeManager.class)); persistedDataHosts.add(injector.getInstance(P2PService.class)); + persistedDataHosts.add(injector.getInstance(MyProposalService.class)); persistedDataHosts.add(injector.getInstance(ProposalService.class)); persistedDataHosts.add(injector.getInstance(BlindVoteService.class)); persistedDataHosts.add(injector.getInstance(MyVoteService.class)); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java index 3658f3e8e7f..41b73e52a36 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java @@ -27,18 +27,16 @@ import bisq.desktop.util.BsqFormatter; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.blockchain.BsqBlockChain; import bisq.core.dao.blockchain.ReadableBsqBlockChain; -import bisq.core.dao.blockchain.vo.BsqBlock; import bisq.core.dao.param.DaoParamService; import bisq.core.dao.vote.PeriodService; +import bisq.core.dao.vote.proposal.MyProposalService; import bisq.core.dao.vote.proposal.Proposal; +import bisq.core.dao.vote.proposal.ProposalListService; import bisq.core.dao.vote.proposal.ProposalPayload; import bisq.core.dao.vote.proposal.ProposalService; import bisq.core.locale.Res; -import bisq.common.UserThread; - import javax.inject.Inject; import javafx.scene.Node; @@ -71,11 +69,13 @@ import java.util.stream.Collectors; @FxmlView -public abstract class BaseProposalView extends ActivatableView implements BsqBlockChain.Listener { +public abstract class BaseProposalView extends ActivatableView { - protected final ProposalService proposalService; + protected final MyProposalService myProposalService; protected final ReadableBsqBlockChain readableBsqBlockChain; protected final DaoParamService daoParamService; + protected final ProposalListService proposalListService; + protected final ProposalService proposalService; protected final BsqWalletService bsqWalletService; protected final BsqFormatter bsqFormatter; protected final BSFormatter btcFormatter; @@ -102,13 +102,17 @@ public abstract class BaseProposalView extends ActivatableView i /////////////////////////////////////////////////////////////////////////////////////////// @Inject - protected BaseProposalView(ProposalService proposalService, + protected BaseProposalView(MyProposalService myProposalService, + ProposalListService proposalListService, + ProposalService proposalService, BsqWalletService bsqWalletService, ReadableBsqBlockChain readableBsqBlockChain, DaoParamService daoParamService, PeriodService periodService, BsqFormatter bsqFormatter, BSFormatter btcFormatter) { + this.myProposalService = myProposalService; + this.proposalListService = proposalListService; this.proposalService = proposalService; this.bsqWalletService = bsqWalletService; this.readableBsqBlockChain = readableBsqBlockChain; @@ -135,8 +139,6 @@ protected void activate() { selectedProposalSubscription = EasyBind.subscribe(proposalTableView.getSelectionModel().selectedItemProperty(), this::onSelectProposal); periodService.getPhaseProperty().addListener(phaseChangeListener); - readableBsqBlockChain.addListener(this); - proposalService.getObservableList().addListener(proposalListChangeListener); onPhaseChanged(periodService.getPhaseProperty().get()); @@ -151,8 +153,6 @@ protected void deactivate() { selectedProposalSubscription.unsubscribe(); periodService.getPhaseProperty().removeListener(phaseChangeListener); - readableBsqBlockChain.removeListener(this); - proposalService.getObservableList().removeListener(proposalListChangeListener); sortedList.comparatorProperty().unbind(); @@ -162,17 +162,6 @@ protected void deactivate() { } - /////////////////////////////////////////////////////////////////////////////////////////// - // BsqBlockChain.Listener - /////////////////////////////////////////////////////////////////////////////////////////// - - @Override - public void onBlockAdded(BsqBlock bsqBlock) { - // Need delay otherwise we modify list while dispatching and cause a ConcurrentModificationException - UserThread.execute(this::updateProposalList); - } - - /////////////////////////////////////////////////////////////////////////////////////////// // Create views /////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index 5b8f40d5052..a49491e3f5e 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -39,7 +39,9 @@ import bisq.core.dao.vote.PeriodService; import bisq.core.dao.vote.blindvote.BlindVoteConsensus; import bisq.core.dao.vote.blindvote.BlindVoteService; +import bisq.core.dao.vote.proposal.MyProposalService; import bisq.core.dao.vote.proposal.Proposal; +import bisq.core.dao.vote.proposal.ProposalListService; import bisq.core.dao.vote.proposal.ProposalService; import bisq.core.locale.Res; @@ -86,7 +88,9 @@ public class ActiveProposalsView extends BaseProposalView implements BsqBalanceL /////////////////////////////////////////////////////////////////////////////////////////// @Inject - private ActiveProposalsView(ProposalService voteRequestManger, + private ActiveProposalsView(MyProposalService myProposalService, + ProposalListService proposalListService, + ProposalService proposalService, PeriodService periodService, BlindVoteService blindVoteService, BsqWalletService bsqWalletService, @@ -94,8 +98,9 @@ private ActiveProposalsView(ProposalService voteRequestManger, DaoParamService daoParamService, BsqFormatter bsqFormatter, BSFormatter btcFormatter) { - super(voteRequestManger, bsqWalletService, readableBsqBlockChain, daoParamService, periodService, bsqFormatter, - btcFormatter); + + super(myProposalService, proposalListService, proposalService, bsqWalletService, readableBsqBlockChain, + daoParamService, periodService, bsqFormatter, btcFormatter); this.blindVoteService = blindVoteService; } @@ -113,6 +118,7 @@ public void initialize() { protected void activate() { super.activate(); + proposalListService.getActiveOrMyUnconfirmedProposals().addListener(proposalListChangeListener); bsqWalletService.addBsqBalanceListener(this); onUpdateBalances(bsqWalletService.getAvailableBalance(), @@ -163,6 +169,7 @@ private void publishBlindVote(Coin stake) { protected void deactivate() { super.deactivate(); + proposalListService.getActiveOrMyUnconfirmedProposals().removeListener(proposalListChangeListener); bsqWalletService.removeBsqBalanceListener(this); } @@ -326,7 +333,7 @@ protected void onPhaseChanged(PeriodService.Phase phase) { @Override protected void updateProposalList() { - doUpdateProposalList(proposalService.getActiveOrMyUnconfirmedProposals()); + doUpdateProposalList(proposalListService.getActiveOrMyUnconfirmedProposals()); } private void updateStateAfterVote() { @@ -343,7 +350,7 @@ private void changeVoteViewItemsVisibility(boolean value) { } private void onRemove() { - if (proposalService.removeProposal(selectedProposalListItem.getProposal())) + if (myProposalService.removeProposal(selectedProposalListItem.getProposal())) hideProposalDisplay(); else new Popup<>().warning(Res.get("dao.proposal.active.remove.failed")).show(); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java index 8acd1359f61..25f7eb178fb 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java @@ -26,6 +26,8 @@ import bisq.core.dao.blockchain.ReadableBsqBlockChain; import bisq.core.dao.param.DaoParamService; import bisq.core.dao.vote.PeriodService; +import bisq.core.dao.vote.proposal.MyProposalService; +import bisq.core.dao.vote.proposal.ProposalListService; import bisq.core.dao.vote.proposal.ProposalService; import javax.inject.Inject; @@ -38,15 +40,18 @@ public class ClosedProposalsView extends BaseProposalView { /////////////////////////////////////////////////////////////////////////////////////////// @Inject - private ClosedProposalsView(ProposalService proposalService, + private ClosedProposalsView(MyProposalService myProposalService, + ProposalListService proposalListService, + ProposalService proposalService, PeriodService periodService, BsqWalletService bsqWalletService, ReadableBsqBlockChain readableBsqBlockChain, DaoParamService daoParamService, BsqFormatter bsqFormatter, - BSFormatter bsFormatter) { - super(proposalService, bsqWalletService, readableBsqBlockChain, daoParamService, periodService, - bsqFormatter, bsFormatter); + BSFormatter btcFormatter) { + + super(myProposalService, proposalListService, proposalService, bsqWalletService, readableBsqBlockChain, + daoParamService, periodService, bsqFormatter, btcFormatter); } @Override @@ -60,16 +65,18 @@ public void initialize() { @Override protected void activate() { super.activate(); + proposalListService.getClosedProposals().addListener(proposalListChangeListener); } @Override protected void deactivate() { super.deactivate(); + proposalListService.getClosedProposals().removeListener(proposalListChangeListener); } @Override protected void updateProposalList() { - doUpdateProposalList(proposalService.getClosedProposals()); + doUpdateProposalList(proposalListService.getClosedProposals()); } } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index 57ae79d3b63..41013fc1434 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -33,9 +33,9 @@ import bisq.core.btc.wallet.WalletsSetup; import bisq.core.dao.blockchain.ReadableBsqBlockChain; import bisq.core.dao.param.DaoParamService; +import bisq.core.dao.vote.proposal.MyProposalService; import bisq.core.dao.vote.proposal.Proposal; import bisq.core.dao.vote.proposal.ProposalConsensus; -import bisq.core.dao.vote.proposal.ProposalService; import bisq.core.dao.vote.proposal.ProposalType; import bisq.core.dao.vote.proposal.ValidationException; import bisq.core.dao.vote.proposal.compensation.CompensationRequestPayload; @@ -85,7 +85,7 @@ public class MakeProposalView extends ActivatableView { private final WalletsSetup walletsSetup; private final P2PService p2PService; private final FeeService feeService; - private final ProposalService proposalService; + private final MyProposalService myProposalService; private final CompensationRequestService compensationRequestService; private final GenericProposalService genericProposalService; private final ReadableBsqBlockChain readableBsqBlockChain; @@ -106,7 +106,7 @@ private MakeProposalView(BsqWalletService bsqWalletService, WalletsSetup walletsSetup, P2PService p2PService, FeeService feeService, - ProposalService proposalService, + MyProposalService myProposalService, CompensationRequestService compensationRequestService, GenericProposalService genericProposalService, ReadableBsqBlockChain readableBsqBlockChain, @@ -117,7 +117,7 @@ private MakeProposalView(BsqWalletService bsqWalletService, this.walletsSetup = walletsSetup; this.p2PService = p2PService; this.feeService = feeService; - this.proposalService = proposalService; + this.myProposalService = myProposalService; this.compensationRequestService = compensationRequestService; this.genericProposalService = genericProposalService; this.readableBsqBlockChain = readableBsqBlockChain; @@ -200,7 +200,7 @@ private void publishProposal(ProposalType type) { } private void publishProposal(Proposal proposal) { - proposalService.publishProposal(proposal, + myProposalService.publishProposal(proposal, () -> { proposalDisplay.clearForm(); proposalTypeComboBox.getSelectionModel().clearSelection(); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java index 02bb9b869e3..a44342ba846 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java @@ -36,7 +36,9 @@ import bisq.core.dao.vote.PeriodService; import bisq.core.dao.vote.Vote; import bisq.core.dao.vote.myvote.MyVoteService; +import bisq.core.dao.vote.proposal.MyProposalService; import bisq.core.dao.vote.proposal.ProposalList; +import bisq.core.dao.vote.proposal.ProposalListService; import bisq.core.dao.vote.proposal.ProposalService; import bisq.core.locale.Res; import bisq.core.user.Preferences; @@ -74,7 +76,6 @@ @FxmlView public class MyVotesView extends BaseProposalView { private final MyVoteService myVoteService; - private final ReadableBsqBlockChain readableBsqBlockChain; private final Preferences preferences; private final ObservableList voteListItems = FXCollections.observableArrayList(); @@ -89,19 +90,21 @@ public class MyVotesView extends BaseProposalView { /////////////////////////////////////////////////////////////////////////////////////////// @Inject - private MyVotesView(ProposalService voteRequestManger, + private MyVotesView(MyProposalService myProposalService, + ProposalListService proposalListService, + ProposalService proposalService, PeriodService periodService, - MyVoteService myVoteService, BsqWalletService bsqWalletService, ReadableBsqBlockChain readableBsqBlockChain, DaoParamService daoParamService, - Preferences preferences, BsqFormatter bsqFormatter, - BSFormatter btcFormatter) { - super(voteRequestManger, bsqWalletService, readableBsqBlockChain, daoParamService, periodService, bsqFormatter, - btcFormatter); + BSFormatter btcFormatter, + MyVoteService myVoteService, + Preferences preferences) { + + super(myProposalService, proposalListService, proposalService, bsqWalletService, readableBsqBlockChain, + daoParamService, periodService, bsqFormatter, btcFormatter); this.myVoteService = myVoteService; - this.readableBsqBlockChain = readableBsqBlockChain; this.preferences = preferences; } From de3e1615d94b3bc441739f39efb803df5318d634 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Wed, 11 Apr 2018 14:33:05 -0500 Subject: [PATCH 019/197] Merge branch 'master_origin' into voting # Conflicts: # src/main/java/bisq/desktop/app/BisqApp.java --- src/main/java/bisq/desktop/app/BisqApp.java | 5 -- .../fiataccounts/FiatAccountsView.java | 49 ++++++++++--------- .../setup/DesktopPersistedDataHost.java | 2 +- 3 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/main/java/bisq/desktop/app/BisqApp.java b/src/main/java/bisq/desktop/app/BisqApp.java index fe35f844bd2..14943009123 100644 --- a/src/main/java/bisq/desktop/app/BisqApp.java +++ b/src/main/java/bisq/desktop/app/BisqApp.java @@ -45,11 +45,6 @@ import bisq.core.btc.wallet.WalletsManager; import bisq.core.btc.wallet.WalletsSetup; import bisq.core.dao.DaoSetup; -import bisq.core.dao.param.DaoParamService; -import bisq.core.dao.vote.blindvote.BlindVoteService; -import bisq.core.dao.vote.myvote.MyVoteService; -import bisq.core.dao.vote.proposal.MyProposalService; -import bisq.core.dao.vote.proposal.ProposalService; import bisq.core.filter.FilterManager; import bisq.core.locale.Res; import bisq.core.offer.OpenOfferManager; diff --git a/src/main/java/bisq/desktop/main/account/content/fiataccounts/FiatAccountsView.java b/src/main/java/bisq/desktop/main/account/content/fiataccounts/FiatAccountsView.java index e6488d948d9..88dbaf9a7d7 100644 --- a/src/main/java/bisq/desktop/main/account/content/fiataccounts/FiatAccountsView.java +++ b/src/main/java/bisq/desktop/main/account/content/fiataccounts/FiatAccountsView.java @@ -17,18 +17,6 @@ package bisq.desktop.main.account.content.fiataccounts; -import bisq.common.UserThread; -import bisq.common.util.Tuple2; -import bisq.common.util.Tuple3; -import bisq.core.app.BisqEnvironment; -import bisq.core.locale.Res; -import bisq.core.payment.AccountAgeWitnessService; -import bisq.core.payment.ClearXchangeAccount; -import bisq.core.payment.PaymentAccount; -import bisq.core.payment.PaymentAccountFactory; -import bisq.core.payment.WesternUnionAccount; -import bisq.core.payment.payload.PaymentMethod; -import bisq.core.util.validation.InputValidator; import bisq.desktop.common.view.ActivatableViewAndModel; import bisq.desktop.common.view.FxmlView; import bisq.desktop.components.AutoTooltipButton; @@ -80,9 +68,25 @@ import bisq.desktop.util.validation.UpholdValidator; import bisq.desktop.util.validation.VenmoValidator; import bisq.desktop.util.validation.WeChatPayValidator; -import javafx.beans.value.ChangeListener; -import javafx.collections.FXCollections; -import javafx.geometry.VPos; + +import bisq.core.app.BisqEnvironment; +import bisq.core.locale.Res; +import bisq.core.payment.AccountAgeWitnessService; +import bisq.core.payment.ClearXchangeAccount; +import bisq.core.payment.PaymentAccount; +import bisq.core.payment.PaymentAccountFactory; +import bisq.core.payment.WesternUnionAccount; +import bisq.core.payment.payload.PaymentMethod; +import bisq.core.util.validation.InputValidator; + +import bisq.common.UserThread; +import bisq.common.util.Tuple2; +import bisq.common.util.Tuple3; + +import org.bitcoinj.core.Coin; + +import javax.inject.Inject; + import javafx.scene.control.Button; import javafx.scene.control.ComboBox; import javafx.scene.control.Label; @@ -92,20 +96,21 @@ import javafx.scene.layout.AnchorPane; import javafx.scene.layout.GridPane; import javafx.scene.text.TextAlignment; + +import javafx.geometry.VPos; + +import javafx.beans.value.ChangeListener; + +import javafx.collections.FXCollections; + import javafx.util.Callback; import javafx.util.StringConverter; -import org.bitcoinj.core.Coin; -import javax.inject.Inject; import java.util.List; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; -import static bisq.desktop.util.FormBuilder.add2ButtonsAfterGroup; -import static bisq.desktop.util.FormBuilder.add3ButtonsAfterGroup; -import static bisq.desktop.util.FormBuilder.addLabelComboBox; -import static bisq.desktop.util.FormBuilder.addLabelListView; -import static bisq.desktop.util.FormBuilder.addTitledGroupBg; +import static bisq.desktop.util.FormBuilder.*; @FxmlView public class FiatAccountsView extends ActivatableViewAndModel { diff --git a/src/main/java/bisq/desktop/setup/DesktopPersistedDataHost.java b/src/main/java/bisq/desktop/setup/DesktopPersistedDataHost.java index 190faf74038..2e2c0d823f0 100644 --- a/src/main/java/bisq/desktop/setup/DesktopPersistedDataHost.java +++ b/src/main/java/bisq/desktop/setup/DesktopPersistedDataHost.java @@ -30,7 +30,7 @@ @Slf4j public class DesktopPersistedDataHost { - + // All classes which are persisting objects need to be added here public static List getPersistedDataHosts(Injector injector) { List persistedDataHosts = new ArrayList<>(); From 89bee8ad89ff5b932738856e757075691ee767d1 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Wed, 11 Apr 2018 15:31:08 -0500 Subject: [PATCH 020/197] Refactor BsqBlockChain (WIP) - Move BsqBlockchain data to ChainState - Add ChainStateService for accessing ChainState data - Replace ReadableBsqBlockChain and WritableBsqBlockChain with ChainStateService --- .../main/dao/proposal/BaseProposalView.java | 10 ++--- .../main/dao/proposal/ProposalListItem.java | 21 +++++----- .../proposal/active/ActiveProposalsView.java | 10 ++--- .../proposal/closed/ClosedProposalsView.java | 6 +-- .../dao/proposal/make/MakeProposalView.java | 10 ++--- .../dao/proposal/myvotes/MyVotesView.java | 8 ++-- .../dao/proposal/myvotes/VoteListItem.java | 21 +++++----- .../wallet/dashboard/BsqDashboardView.java | 41 +++++++++---------- .../desktop/main/dao/wallet/tx/BsqTxView.java | 25 ++++++----- .../TransactionListItemFactory.java | 10 ++--- .../transactions/TransactionsListItem.java | 6 +-- 11 files changed, 82 insertions(+), 86 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java index 41b73e52a36..7d8472a6401 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java @@ -27,8 +27,8 @@ import bisq.desktop.util.BsqFormatter; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.blockchain.ReadableBsqBlockChain; import bisq.core.dao.param.DaoParamService; +import bisq.core.dao.state.ChainStateService; import bisq.core.dao.vote.PeriodService; import bisq.core.dao.vote.proposal.MyProposalService; import bisq.core.dao.vote.proposal.Proposal; @@ -72,7 +72,7 @@ public abstract class BaseProposalView extends ActivatableView { protected final MyProposalService myProposalService; - protected final ReadableBsqBlockChain readableBsqBlockChain; + protected final ChainStateService chainStateService; protected final DaoParamService daoParamService; protected final ProposalListService proposalListService; protected final ProposalService proposalService; @@ -106,7 +106,7 @@ protected BaseProposalView(MyProposalService myProposalService, ProposalListService proposalListService, ProposalService proposalService, BsqWalletService bsqWalletService, - ReadableBsqBlockChain readableBsqBlockChain, + ChainStateService chainStateService, DaoParamService daoParamService, PeriodService periodService, BsqFormatter bsqFormatter, @@ -115,7 +115,7 @@ protected BaseProposalView(MyProposalService myProposalService, this.proposalListService = proposalListService; this.proposalService = proposalService; this.bsqWalletService = bsqWalletService; - this.readableBsqBlockChain = readableBsqBlockChain; + this.chainStateService = chainStateService; this.daoParamService = daoParamService; this.periodService = periodService; this.bsqFormatter = bsqFormatter; @@ -255,7 +255,7 @@ protected void doUpdateProposalList(List list) { proposalService, periodService, bsqWalletService, - readableBsqBlockChain, + chainStateService, bsqFormatter)) .collect(Collectors.toSet())); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index 330dbd98407..d9b57f33060 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -23,10 +23,9 @@ import bisq.core.btc.listeners.TxConfidenceListener; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.blockchain.BsqBlockChain; -import bisq.core.dao.blockchain.ReadableBsqBlockChain; import bisq.core.dao.blockchain.vo.BsqBlock; import bisq.core.dao.blockchain.vo.Tx; +import bisq.core.dao.state.ChainStateService; import bisq.core.dao.vote.BooleanVote; import bisq.core.dao.vote.PeriodService; import bisq.core.dao.vote.Vote; @@ -54,13 +53,13 @@ @ToString @Slf4j @EqualsAndHashCode -public class ProposalListItem implements BsqBlockChain.Listener { +public class ProposalListItem implements ChainStateService.Listener { @Getter private final Proposal proposal; private final ProposalService proposalService; private final PeriodService periodService; private final BsqWalletService bsqWalletService; - private final ReadableBsqBlockChain readableBsqBlockChain; + private final ChainStateService chainStateService; private final BsqFormatter bsqFormatter; private final ChangeListener chainHeightListener; private final ChangeListener voteResultChangeListener; @@ -83,13 +82,13 @@ public class ProposalListItem implements BsqBlockChain.Listener { ProposalService proposalService, PeriodService periodService, BsqWalletService bsqWalletService, - ReadableBsqBlockChain readableBsqBlockChain, + ChainStateService chainStateService, BsqFormatter bsqFormatter) { this.proposal = proposal; this.proposalService = proposalService; this.periodService = periodService; this.bsqWalletService = bsqWalletService; - this.readableBsqBlockChain = readableBsqBlockChain; + this.chainStateService = chainStateService; this.bsqFormatter = bsqFormatter; @@ -108,7 +107,7 @@ public class ProposalListItem implements BsqBlockChain.Listener { bsqWalletService.getChainHeightProperty().addListener(chainHeightListener); setupConfidence(); - readableBsqBlockChain.addListener(this); + chainStateService.addListener(this); phaseChangeListener = (observable, oldValue, newValue) -> { applyState(newValue, proposal.getVote()); @@ -127,7 +126,7 @@ public void applyState(PeriodService.Phase newValue, Vote vote) { actionButton.setVisible(false); actionButton.setOnAction(null); final boolean isTxInPastCycle = periodService.isTxInPastCycle(proposal.getTxId(), - readableBsqBlockChain.getChainHeadHeight()); + chainStateService.getChainHeadHeight()); switch (newValue) { case UNDEFINED: break; @@ -187,7 +186,7 @@ public void applyState(PeriodService.Phase newValue, Vote vote) { /////////////////////////////////////////////////////////////////////////////////////////// - // BsqBlockChain.Listener + // ChainStateService.Listener /////////////////////////////////////////////////////////////////////////////////////////// @Override @@ -198,7 +197,7 @@ public void onBlockAdded(BsqBlock bsqBlock) { private void setupConfidence() { - final Tx tx = readableBsqBlockChain.getTxMap().get(proposal.getProposalPayload().getTxId()); + final Tx tx = chainStateService.getTxMap().get(proposal.getProposalPayload().getTxId()); if (tx != null) { final String txId = tx.getId(); @@ -242,7 +241,7 @@ private void updateConfidence(TransactionConfidence confidence, int depthInBlock } public void cleanup() { - readableBsqBlockChain.removeListener(this); + chainStateService.removeListener(this); bsqWalletService.getChainHeightProperty().removeListener(chainHeightListener); if (txConfidenceListener != null) bsqWalletService.removeTxConfidenceListener(txConfidenceListener); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index a49491e3f5e..1e13c2f1fbf 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -33,8 +33,8 @@ import bisq.core.btc.exceptions.WalletException; import bisq.core.btc.wallet.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.blockchain.ReadableBsqBlockChain; import bisq.core.dao.param.DaoParamService; +import bisq.core.dao.state.ChainStateService; import bisq.core.dao.vote.BooleanVote; import bisq.core.dao.vote.PeriodService; import bisq.core.dao.vote.blindvote.BlindVoteConsensus; @@ -94,12 +94,12 @@ private ActiveProposalsView(MyProposalService myProposalService, PeriodService periodService, BlindVoteService blindVoteService, BsqWalletService bsqWalletService, - ReadableBsqBlockChain readableBsqBlockChain, + ChainStateService chainStateService, DaoParamService daoParamService, BsqFormatter bsqFormatter, BSFormatter btcFormatter) { - super(myProposalService, proposalListService, proposalService, bsqWalletService, readableBsqBlockChain, + super(myProposalService, proposalListService, proposalService, bsqWalletService, chainStateService, daoParamService, periodService, bsqFormatter, btcFormatter); this.blindVoteService = blindVoteService; } @@ -130,7 +130,7 @@ protected void activate() { voteButton.setOnAction(e -> { // TODO verify stake Coin stake = bsqFormatter.parseToCoin(stakeInputTextField.getText()); - final Coin fee = BlindVoteConsensus.getFee(daoParamService, readableBsqBlockChain.getChainHeadHeight()); + final Coin fee = BlindVoteConsensus.getFee(daoParamService, chainStateService.getChainHeadHeight()); Transaction dummyTx = null; try { // We create a tx with dummy opreturn data to get the mining fee for confirmation popup @@ -270,7 +270,7 @@ protected void onPhaseChanged(PeriodService.Phase phase) { if (selectedProposalListItem != null && proposalDisplay != null && !periodService.isTxInPastCycle(selectedProposalListItem.getProposal().getTxId(), - readableBsqBlockChain.getChainHeadHeight())) { + chainStateService.getChainHeadHeight())) { final Proposal proposal = selectedProposalListItem.getProposal(); switch (phase) { case PROPOSAL: diff --git a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java index 25f7eb178fb..ec29a0660bf 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java @@ -23,8 +23,8 @@ import bisq.desktop.util.BsqFormatter; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.blockchain.ReadableBsqBlockChain; import bisq.core.dao.param.DaoParamService; +import bisq.core.dao.state.ChainStateService; import bisq.core.dao.vote.PeriodService; import bisq.core.dao.vote.proposal.MyProposalService; import bisq.core.dao.vote.proposal.ProposalListService; @@ -45,12 +45,12 @@ private ClosedProposalsView(MyProposalService myProposalService, ProposalService proposalService, PeriodService periodService, BsqWalletService bsqWalletService, - ReadableBsqBlockChain readableBsqBlockChain, + ChainStateService chainStateService, DaoParamService daoParamService, BsqFormatter bsqFormatter, BSFormatter btcFormatter) { - super(myProposalService, proposalListService, proposalService, bsqWalletService, readableBsqBlockChain, + super(myProposalService, proposalListService, proposalService, bsqWalletService, chainStateService, daoParamService, periodService, bsqFormatter, btcFormatter); } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index 41013fc1434..8ae4994c12d 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -31,8 +31,8 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.InsufficientBsqException; import bisq.core.btc.wallet.WalletsSetup; -import bisq.core.dao.blockchain.ReadableBsqBlockChain; import bisq.core.dao.param.DaoParamService; +import bisq.core.dao.state.ChainStateService; import bisq.core.dao.vote.proposal.MyProposalService; import bisq.core.dao.vote.proposal.Proposal; import bisq.core.dao.vote.proposal.ProposalConsensus; @@ -88,7 +88,7 @@ public class MakeProposalView extends ActivatableView { private final MyProposalService myProposalService; private final CompensationRequestService compensationRequestService; private final GenericProposalService genericProposalService; - private final ReadableBsqBlockChain readableBsqBlockChain; + private final ChainStateService chainStateService; private final DaoParamService daoParamService; private final BSFormatter btcFormatter; private final BsqFormatter bsqFormatter; @@ -109,7 +109,7 @@ private MakeProposalView(BsqWalletService bsqWalletService, MyProposalService myProposalService, CompensationRequestService compensationRequestService, GenericProposalService genericProposalService, - ReadableBsqBlockChain readableBsqBlockChain, + ChainStateService chainStateService, DaoParamService daoParamService, BSFormatter btcFormatter, BsqFormatter bsqFormatter) { @@ -120,7 +120,7 @@ private MakeProposalView(BsqWalletService bsqWalletService, this.myProposalService = myProposalService; this.compensationRequestService = compensationRequestService; this.genericProposalService = genericProposalService; - this.readableBsqBlockChain = readableBsqBlockChain; + this.chainStateService = chainStateService; this.daoParamService = daoParamService; this.btcFormatter = btcFormatter; this.bsqFormatter = bsqFormatter; @@ -174,7 +174,7 @@ private void publishProposal(ProposalType type) { Coin miningFee = Objects.requireNonNull(tx).getFee(); int txSize = tx.bitcoinSerialize().length; - final Coin fee = ProposalConsensus.getFee(daoParamService, readableBsqBlockChain.getChainHeadHeight()); + final Coin fee = ProposalConsensus.getFee(daoParamService, chainStateService.getChainHeadHeight()); GUIUtil.showBsqFeeInfoPopup(fee, miningFee, txSize, bsqFormatter, btcFormatter, Res.get("dao.proposal"), () -> publishProposal(proposal)); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java index a44342ba846..5952db65bd8 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java @@ -30,8 +30,8 @@ import bisq.desktop.util.Layout; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.blockchain.ReadableBsqBlockChain; import bisq.core.dao.param.DaoParamService; +import bisq.core.dao.state.ChainStateService; import bisq.core.dao.vote.BooleanVote; import bisq.core.dao.vote.PeriodService; import bisq.core.dao.vote.Vote; @@ -95,14 +95,14 @@ private MyVotesView(MyProposalService myProposalService, ProposalService proposalService, PeriodService periodService, BsqWalletService bsqWalletService, - ReadableBsqBlockChain readableBsqBlockChain, + ChainStateService chainStateService, DaoParamService daoParamService, BsqFormatter bsqFormatter, BSFormatter btcFormatter, MyVoteService myVoteService, Preferences preferences) { - super(myProposalService, proposalListService, proposalService, bsqWalletService, readableBsqBlockChain, + super(myProposalService, proposalListService, proposalService, bsqWalletService, chainStateService, daoParamService, periodService, bsqFormatter, btcFormatter); this.myVoteService = myVoteService; this.preferences = preferences; @@ -130,7 +130,7 @@ protected void activate() { voteListItems.clear(); List items = myVoteService.getMyVoteList().stream() - .map(vote -> new VoteListItem(vote, bsqWalletService, readableBsqBlockChain, bsqFormatter)) + .map(vote -> new VoteListItem(vote, bsqWalletService, chainStateService, bsqFormatter)) .collect(Collectors.toList()); voteListItems.addAll(items); } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java index 6ddcfbf5e08..558dc4bdc5d 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java @@ -22,11 +22,10 @@ import bisq.core.btc.listeners.TxConfidenceListener; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.blockchain.BsqBlockChain; -import bisq.core.dao.blockchain.ReadableBsqBlockChain; import bisq.core.dao.blockchain.vo.BsqBlock; import bisq.core.dao.blockchain.vo.Tx; import bisq.core.dao.blockchain.vo.TxOutput; +import bisq.core.dao.state.ChainStateService; import bisq.core.dao.vote.myvote.MyVote; import bisq.core.locale.Res; @@ -51,11 +50,11 @@ @ToString @Slf4j @EqualsAndHashCode -public class VoteListItem implements BsqBlockChain.Listener { +public class VoteListItem implements ChainStateService.Listener { @Getter private final MyVote myVote; private final BsqWalletService bsqWalletService; - private final ReadableBsqBlockChain readableBsqBlockChain; + private final ChainStateService chainStateService; private final BsqFormatter bsqFormatter; private final ChangeListener chainHeightListener; @Getter @@ -75,11 +74,11 @@ public class VoteListItem implements BsqBlockChain.Listener { VoteListItem(MyVote myVote, BsqWalletService bsqWalletService, - ReadableBsqBlockChain readableBsqBlockChain, + ChainStateService chainStateService, BsqFormatter bsqFormatter) { this.myVote = myVote; this.bsqWalletService = bsqWalletService; - this.readableBsqBlockChain = readableBsqBlockChain; + this.chainStateService = chainStateService; this.bsqFormatter = bsqFormatter; txConfidenceIndicator = new TxConfidenceIndicator(); @@ -88,7 +87,7 @@ public class VoteListItem implements BsqBlockChain.Listener { txConfidenceIndicator.setProgress(-1); txConfidenceIndicator.setPrefSize(24, 24); txConfidenceIndicator.setTooltip(tooltip); - readableBsqBlockChain.addListener(this); + chainStateService.addListener(this); chainHeightListener = (observable, oldValue, newValue) -> setupConfidence(); bsqWalletService.getChainHeightProperty().addListener(chainHeightListener); @@ -98,7 +97,7 @@ public class VoteListItem implements BsqBlockChain.Listener { /////////////////////////////////////////////////////////////////////////////////////////// - // BsqBlockChain.Listener + // ChainStateService.Listener /////////////////////////////////////////////////////////////////////////////////////////// @Override @@ -110,7 +109,7 @@ public void onBlockAdded(BsqBlock bsqBlock) { private void setupConfidence() { calculateStake(); - final Tx tx = readableBsqBlockChain.getTxMap().get(myVote.getBlindVote().getTxId()); + final Tx tx = chainStateService.getTxMap().get(myVote.getBlindVote().getTxId()); if (tx != null) { final String txId = tx.getId(); @@ -149,7 +148,7 @@ public void onTransactionConfidenceChanged(TransactionConfidence confidence) { private void calculateStake() { if (stake == 0) { String txId = myVote.getTxId(); - stake = readableBsqBlockChain.getUnspentBlindVoteStakeTxOutputs().stream() + stake = chainStateService.getUnspentBlindVoteStakeTxOutputs().stream() .filter(txOutput -> txOutput.getTxId().equals(txId)) .filter(txOutput -> txOutput.getIndex() == 0) .mapToLong(TxOutput::getValue) @@ -167,7 +166,7 @@ private void updateConfidence(TransactionConfidence confidence, int depthInBlock public void cleanup() { bsqWalletService.getChainHeightProperty().removeListener(chainHeightListener); - readableBsqBlockChain.removeListener(this); + chainStateService.removeListener(this); if (txConfidenceListener != null) bsqWalletService.removeTxConfidenceListener(txConfidenceListener); } diff --git a/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java b/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java index 3d78201af99..69dad7a781e 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java @@ -26,9 +26,8 @@ import bisq.desktop.util.GUIUtil; import bisq.desktop.util.Layout; -import bisq.core.dao.blockchain.BsqBlockChain; -import bisq.core.dao.blockchain.ReadableBsqBlockChain; import bisq.core.dao.blockchain.vo.BsqBlock; +import bisq.core.dao.state.ChainStateService; import bisq.core.locale.Res; import bisq.core.monetary.Altcoin; import bisq.core.monetary.Price; @@ -57,10 +56,10 @@ import static bisq.desktop.util.FormBuilder.addTitledGroupBg; @FxmlView -public class BsqDashboardView extends ActivatableView implements BsqBlockChain.Listener { +public class BsqDashboardView extends ActivatableView implements bisq.core.dao.state.ChainStateService.Listener { private final BsqBalanceUtil bsqBalanceUtil; - private final ReadableBsqBlockChain readableBsqBlockChain; + private final ChainStateService chainStateService; private final PriceFeedService priceFeedService; private final Preferences preferences; private final BsqFormatter bsqFormatter; @@ -79,12 +78,12 @@ public class BsqDashboardView extends ActivatableView implements @Inject private BsqDashboardView(BsqBalanceUtil bsqBalanceUtil, - ReadableBsqBlockChain readableBsqBlockChain, + ChainStateService chainStateService, PriceFeedService priceFeedService, Preferences preferences, BsqFormatter bsqFormatter) { this.bsqBalanceUtil = bsqBalanceUtil; - this.readableBsqBlockChain = readableBsqBlockChain; + this.chainStateService = chainStateService; this.priceFeedService = priceFeedService; this.preferences = preferences; this.bsqFormatter = bsqFormatter; @@ -97,13 +96,13 @@ public void initialize() { addTitledGroupBg(root, ++gridRow, 11, Res.get("dao.wallet.dashboard.statistics"), Layout.GROUP_DISTANCE); addLabelTextField(root, gridRow, Res.get("dao.wallet.dashboard.genesisBlockHeight"), - String.valueOf(readableBsqBlockChain.getGenesisBlockHeight()), Layout.FIRST_ROW_AND_GROUP_DISTANCE); + String.valueOf(chainStateService.getGenesisBlockHeight()), Layout.FIRST_ROW_AND_GROUP_DISTANCE); Label label = new AutoTooltipLabel(Res.get("dao.wallet.dashboard.genesisTxId")); GridPane.setRowIndex(label, ++gridRow); root.getChildren().add(label); - hyperlinkWithIcon = new HyperlinkWithIcon(readableBsqBlockChain.getGenesisTxId(), AwesomeIcon.EXTERNAL_LINK); - hyperlinkWithIcon.setTooltip(new Tooltip(Res.get("tooltip.openBlockchainForTx", readableBsqBlockChain.getGenesisTxId()))); + hyperlinkWithIcon = new HyperlinkWithIcon(chainStateService.getGenesisTxId(), AwesomeIcon.EXTERNAL_LINK); + hyperlinkWithIcon.setTooltip(new Tooltip(Res.get("tooltip.openBlockchainForTx", chainStateService.getGenesisTxId()))); GridPane.setRowIndex(hyperlinkWithIcon, gridRow); GridPane.setColumnIndex(hyperlinkWithIcon, 1); GridPane.setMargin(hyperlinkWithIcon, new Insets(0, 0, 0, -4)); @@ -129,10 +128,10 @@ public void initialize() { protected void activate() { bsqBalanceUtil.activate(); - readableBsqBlockChain.addListener(this); + chainStateService.addListener(this); priceFeedService.updateCounterProperty().addListener(priceChangeListener); - hyperlinkWithIcon.setOnAction(event -> GUIUtil.openWebPage(preferences.getBsqBlockChainExplorer().txUrl + readableBsqBlockChain.getGenesisTxId())); + hyperlinkWithIcon.setOnAction(event -> GUIUtil.openWebPage(preferences.getBsqBlockChainExplorer().txUrl + chainStateService.getGenesisTxId())); updateWithBsqBlockChainData(); updatePrice(); @@ -141,14 +140,14 @@ protected void activate() { @Override protected void deactivate() { bsqBalanceUtil.deactivate(); - readableBsqBlockChain.removeListener(this); + chainStateService.removeListener(this); priceFeedService.updateCounterProperty().removeListener(priceChangeListener); hyperlinkWithIcon.setOnAction(null); } /////////////////////////////////////////////////////////////////////////////////////////// - // BsqBlockChain.Listener + // ChainStateService.Listener /////////////////////////////////////////////////////////////////////////////////////////// @Override @@ -158,25 +157,25 @@ public void onBlockAdded(BsqBlock bsqBlock) { private void updateWithBsqBlockChainData() { - final Coin issuedAmountFromGenesis = readableBsqBlockChain.getIssuedAmountAtGenesis(); + final Coin issuedAmountFromGenesis = chainStateService.getIssuedAmountAtGenesis(); genesisIssueAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(issuedAmountFromGenesis)); - final Coin issuedAmountFromCompRequests = readableBsqBlockChain.getIssuedAmountFromCompRequests(); + final Coin issuedAmountFromCompRequests = chainStateService.getIssuedAmountFromCompRequests(); compRequestIssueAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(issuedAmountFromCompRequests)); - final Coin burntFee = readableBsqBlockChain.getTotalBurntFee(); + final Coin burntFee = chainStateService.getTotalBurntFee(); final Coin availableAmount = issuedAmountFromGenesis.add(issuedAmountFromCompRequests).subtract(burntFee); availableAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(availableAmount)); burntAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(burntFee)); - allTxTextField.setText(String.valueOf(readableBsqBlockChain.getTransactions().size())); - utxoTextField.setText(String.valueOf(readableBsqBlockChain.getUnspentTxOutputs().size())); - //spentTxTextField.setText(String.valueOf(readableBsqBlockChain.getSpentTxOutputs().size())); - burntTxTextField.setText(String.valueOf(readableBsqBlockChain.getFeeTransactions().size())); + allTxTextField.setText(String.valueOf(chainStateService.getTransactions().size())); + utxoTextField.setText(String.valueOf(chainStateService.getUnspentTxOutputs().size())); + //spentTxTextField.setText(String.valueOf(chainStateService.getSpentTxOutputs().size())); + burntTxTextField.setText(String.valueOf(chainStateService.getFeeTransactions().size())); } private void updatePrice() { - final Coin issuedAmount = readableBsqBlockChain.getIssuedAmountAtGenesis(); + final Coin issuedAmount = chainStateService.getIssuedAmountAtGenesis(); final MarketPrice bsqMarketPrice = priceFeedService.getMarketPrice("BSQ"); if (bsqMarketPrice != null) { long bsqPrice = MathUtils.roundDoubleToLong(MathUtils.scaleUpByPowerOf10(bsqMarketPrice.getPrice(), Altcoin.SMALLEST_UNIT_EXPONENT)); diff --git a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java index 02f1be8dd45..23f65ff2e2c 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java @@ -32,11 +32,10 @@ import bisq.core.btc.wallet.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; -import bisq.core.dao.blockchain.BsqBlockChain; -import bisq.core.dao.blockchain.ReadableBsqBlockChain; import bisq.core.dao.blockchain.vo.BsqBlock; import bisq.core.dao.blockchain.vo.Tx; import bisq.core.dao.blockchain.vo.TxType; +import bisq.core.dao.state.ChainStateService; import bisq.core.locale.Res; import bisq.core.user.Preferences; @@ -81,14 +80,14 @@ import java.util.stream.Collectors; @FxmlView -public class BsqTxView extends ActivatableView implements BsqBalanceListener, BsqBlockChain.Listener { +public class BsqTxView extends ActivatableView implements BsqBalanceListener, bisq.core.dao.state.ChainStateService.Listener { private TableView tableView; private Pane rootParent; private final BsqFormatter bsqFormatter; private final BsqWalletService bsqWalletService; - private final ReadableBsqBlockChain readableBsqBlockChain; + private final ChainStateService chainStateService; private final BtcWalletService btcWalletService; private final BsqBalanceUtil bsqBalanceUtil; private final Preferences preferences; @@ -112,13 +111,13 @@ public class BsqTxView extends ActivatableView implements BsqBal private BsqTxView(BsqFormatter bsqFormatter, BsqWalletService bsqWalletService, Preferences preferences, - ReadableBsqBlockChain readableBsqBlockChain, + ChainStateService chainStateService, BtcWalletService btcWalletService, BsqBalanceUtil bsqBalanceUtil) { this.bsqFormatter = bsqFormatter; this.bsqWalletService = bsqWalletService; this.preferences = preferences; - this.readableBsqBlockChain = readableBsqBlockChain; + this.chainStateService = chainStateService; this.btcWalletService = btcWalletService; this.bsqBalanceUtil = bsqBalanceUtil; } @@ -176,7 +175,7 @@ protected void activate() { sortedList.comparatorProperty().bind(tableView.comparatorProperty()); tableView.setItems(sortedList); - readableBsqBlockChain.addListener(this); + chainStateService.addListener(this); if (root.getParent() instanceof Pane) { rootParent = (Pane) root.getParent(); @@ -195,7 +194,7 @@ protected void deactivate() { bsqWalletService.getWalletTransactions().removeListener(walletBsqTransactionsListener); bsqWalletService.removeBsqBalanceListener(this); btcWalletService.getChainHeightProperty().removeListener(chainHeightChangedListener); - readableBsqBlockChain.removeListener(this); + chainStateService.removeListener(this); observableList.forEach(BsqTxListItem::cleanup); @@ -214,7 +213,7 @@ public void onUpdateBalances(Coin confirmedBalance, /////////////////////////////////////////////////////////////////////////////////////////// - // BsqBlockChain.Listener + // ChainStateService.Listener /////////////////////////////////////////////////////////////////////////////////////////// @Override @@ -225,7 +224,7 @@ public void onBlockAdded(BsqBlock bsqBlock) { private void onChainHeightChanged() { final int bsqWalletChainHeight = bsqWalletService.getChainHeightProperty().get(); - final int bsqBlockChainHeight = readableBsqBlockChain.getChainHeadHeight(); + final int bsqBlockChainHeight = chainStateService.getChainHeadHeight(); if (bsqWalletChainHeight > 0) { final boolean synced = bsqWalletChainHeight == bsqBlockChainHeight; chainSyncIndicator.setVisible(!synced); @@ -256,12 +255,12 @@ private void updateList() { final List walletTransactions = new ArrayList<>(bsqWalletService.getWalletTransactions()); List items = walletTransactions.stream() .map(transaction -> { - final Optional optionalTx = readableBsqBlockChain.getTx(transaction.getHashAsString()); + final Optional optionalTx = chainStateService.getTx(transaction.getHashAsString()); return new BsqTxListItem(transaction, optionalTx, bsqWalletService, btcWalletService, - readableBsqBlockChain.hasTxBurntFee(transaction.getHashAsString()), + chainStateService.hasTxBurntFee(transaction.getHashAsString()), transaction.getUpdateTime(), bsqFormatter); }) @@ -532,7 +531,7 @@ public void updateItem(final BsqTxListItem item, boolean empty) { if (item.getOptionalTx().isPresent() && item.getOptionalTx().get().isIssuanceTx()) { awesomeIcon = AwesomeIcon.MONEY; style = "dao-tx-type-issuance-icon"; - long blockTimeInSec = readableBsqBlockChain.getBlockTime(item.getOptionalTx().get().getIssuanceBlockHeight()); + long blockTimeInSec = chainStateService.getBlockTime(item.getOptionalTx().get().getIssuanceBlockHeight()); toolTipText = Res.get("dao.tx.issuance.tooltip", bsqFormatter.formatDateTime(new Date(blockTimeInSec * 1000))); } else { awesomeIcon = AwesomeIcon.FILE; diff --git a/src/main/java/bisq/desktop/main/funds/transactions/TransactionListItemFactory.java b/src/main/java/bisq/desktop/main/funds/transactions/TransactionListItemFactory.java index b927b55aef2..e65df06e895 100644 --- a/src/main/java/bisq/desktop/main/funds/transactions/TransactionListItemFactory.java +++ b/src/main/java/bisq/desktop/main/funds/transactions/TransactionListItemFactory.java @@ -21,7 +21,7 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; -import bisq.core.dao.blockchain.ReadableBsqBlockChain; +import bisq.core.dao.state.ChainStateService; import bisq.core.trade.Tradable; import org.bitcoinj.core.Transaction; @@ -35,15 +35,15 @@ public class TransactionListItemFactory { private final BtcWalletService btcWalletService; private final BsqWalletService bsqWalletService; - private final ReadableBsqBlockChain readableBsqBlockChain; + private final ChainStateService chainStateService; private final BSFormatter formatter; @Inject TransactionListItemFactory(BtcWalletService btcWalletService, BsqWalletService bsqWalletService, - ReadableBsqBlockChain readableBsqBlockChain, BSFormatter formatter) { + ChainStateService chainStateService, BSFormatter formatter) { this.btcWalletService = btcWalletService; this.bsqWalletService = bsqWalletService; - this.readableBsqBlockChain = readableBsqBlockChain; + this.chainStateService = chainStateService; this.formatter = formatter; } @@ -51,6 +51,6 @@ TransactionsListItem create(Transaction transaction, @Nullable TransactionAwareT Optional maybeTradable = Optional.ofNullable(tradable) .map(TransactionAwareTradable::asTradable); - return new TransactionsListItem(transaction, btcWalletService, bsqWalletService, maybeTradable, readableBsqBlockChain, formatter); + return new TransactionsListItem(transaction, btcWalletService, bsqWalletService, maybeTradable, chainStateService, formatter); } } diff --git a/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java b/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java index ef7f4623657..9aa2dc04204 100644 --- a/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java +++ b/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java @@ -26,8 +26,8 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; import bisq.core.btc.wallet.WalletService; -import bisq.core.dao.blockchain.ReadableBsqBlockChain; import bisq.core.dao.blockchain.vo.TxType; +import bisq.core.dao.state.ChainStateService; import bisq.core.locale.Res; import bisq.core.offer.Offer; import bisq.core.offer.OpenOffer; @@ -80,7 +80,7 @@ public TransactionsListItem(Transaction transaction, BtcWalletService btcWalletService, BsqWalletService bsqWalletService, Optional tradableOptional, - ReadableBsqBlockChain readableBsqBlockChain, + ChainStateService chainStateService, BSFormatter formatter) { this.formatter = formatter; txId = transaction.getHashAsString(); @@ -130,7 +130,7 @@ public TransactionsListItem(Transaction transaction, txFeeForBsqPayment = true; // - final Optional txTypeOptional = readableBsqBlockChain.getTxType(txId); + final Optional txTypeOptional = chainStateService.getTxType(txId); if (txTypeOptional.isPresent() && txTypeOptional.get().equals(TxType.COMPENSATION_REQUEST)) details = Res.get("funds.tx.proposal"); } else { From 1556e279094367f331ad10c57b3ab7dcbd0bd228 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Wed, 11 Apr 2018 20:37:45 -0500 Subject: [PATCH 021/197] Make blockchain data immutable (WIP) - Remove immutable fields from Tx, TxInput adn TxOutput - Add maps to ChainState for mutable fields - Integrate BaseService in BlindVoteService - Remove ValidationCandidate and BaseService - Remove reset prameter at clone methods - Move validation out of valueObject into Validator classes to keep valueObjects small --- .../main/dao/wallet/tx/BsqTxListItem.java | 21 +++++++++++++------ .../desktop/main/dao/wallet/tx/BsqTxView.java | 15 +++++++++---- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java index 3734b338264..4f0fd78f2d2 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java @@ -27,6 +27,7 @@ import bisq.core.btc.wallet.WalletService; import bisq.core.dao.blockchain.vo.Tx; import bisq.core.dao.blockchain.vo.TxType; +import bisq.core.dao.state.ChainStateService; import bisq.core.locale.Res; import org.bitcoinj.core.Coin; @@ -50,15 +51,18 @@ class BsqTxListItem { private final Optional optionalTx; private final BsqWalletService bsqWalletService; private final BtcWalletService btcWalletService; - private Date date; + private final ChainStateService chainStateService; + private final BsqFormatter bsqFormatter; + private final Date date; private final String txId; + private int confirmations = 0; private final String address; private final String direction; private Coin amount; private boolean received; private boolean isBurnedBsqTx; - private BsqFormatter bsqFormatter; + private TxConfidenceIndicator txConfidenceIndicator; private TxConfidenceListener txConfidenceListener; private boolean issuanceTx; @@ -67,6 +71,7 @@ class BsqTxListItem { Optional optionalTx, BsqWalletService bsqWalletService, BtcWalletService btcWalletService, + ChainStateService chainStateService, boolean isBurnedBsqTx, Date date, BsqFormatter bsqFormatter) { @@ -74,6 +79,7 @@ class BsqTxListItem { this.optionalTx = optionalTx; this.bsqWalletService = bsqWalletService; this.btcWalletService = btcWalletService; + this.chainStateService = chainStateService; this.isBurnedBsqTx = isBurnedBsqTx; this.date = date; this.bsqFormatter = bsqFormatter; @@ -159,10 +165,13 @@ public void cleanup() { } public TxType getTxType() { - if (optionalTx.isPresent()) - return optionalTx.get().getTxType(); - else - return confirmations == 0 ? TxType.UNVERIFIED : TxType.UNDEFINED_TX_TYPE; + if (optionalTx.isPresent()) { + Optional optionalTxType = chainStateService.getTxType(optionalTx.get().getId()); + if (optionalTxType.isPresent()) + return optionalTxType.get(); + } + + return confirmations == 0 ? TxType.UNVERIFIED : TxType.UNDEFINED_TX_TYPE; } public void setAmount(Coin amount) { diff --git a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java index 23f65ff2e2c..a566c49fb9a 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java @@ -260,6 +260,7 @@ private void updateList() { optionalTx, bsqWalletService, btcWalletService, + chainStateService, chainStateService.hasTxBurntFee(transaction.getHashAsString()), transaction.getUpdateTime(), bsqFormatter); @@ -367,7 +368,10 @@ public void updateItem(final BsqTxListItem item, boolean empty) { Label label; if (item.getConfirmations() > 0 && txType.ordinal() > TxType.INVALID.ordinal()) { final Optional optionalTx = item.getOptionalTx(); - if (txType == TxType.COMPENSATION_REQUEST && optionalTx.isPresent() && optionalTx.get().isIssuanceTx()) { + + if (txType == TxType.COMPENSATION_REQUEST && + optionalTx.isPresent() && + chainStateService.isIssuanceTx(optionalTx.get().getId())) { if (field != null) field.setOnAction(null); @@ -528,11 +532,14 @@ public void updateItem(final BsqTxListItem item, boolean empty) { break; case PROPOSAL: case COMPENSATION_REQUEST: - if (item.getOptionalTx().isPresent() && item.getOptionalTx().get().isIssuanceTx()) { + final String txId = item.getOptionalTx().get().getId(); + if (item.getOptionalTx().isPresent() && chainStateService.isIssuanceTx(txId)) { awesomeIcon = AwesomeIcon.MONEY; style = "dao-tx-type-issuance-icon"; - long blockTimeInSec = chainStateService.getBlockTime(item.getOptionalTx().get().getIssuanceBlockHeight()); - toolTipText = Res.get("dao.tx.issuance.tooltip", bsqFormatter.formatDateTime(new Date(blockTimeInSec * 1000))); + final int issuanceBlockHeight = chainStateService.getIssuanceBlockHeight(txId); + long blockTimeInSec = chainStateService.getBlockTime(issuanceBlockHeight); + final String formattedDate = bsqFormatter.formatDateTime(new Date(blockTimeInSec * 1000)); + toolTipText = Res.get("dao.tx.issuance.tooltip", formattedDate); } else { awesomeIcon = AwesomeIcon.FILE; style = "dao-tx-type-fee-icon"; From b6d3b9b0d8507aae1e783a25065bd1ab4e587ba2 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Wed, 11 Apr 2018 22:41:03 -0500 Subject: [PATCH 022/197] Rename ChainState to State --- .../main/dao/proposal/BaseProposalView.java | 10 ++--- .../main/dao/proposal/ProposalListItem.java | 20 +++++----- .../proposal/active/ActiveProposalsView.java | 10 ++--- .../proposal/closed/ClosedProposalsView.java | 6 +-- .../dao/proposal/make/MakeProposalView.java | 10 ++--- .../dao/proposal/myvotes/MyVotesView.java | 8 ++-- .../dao/proposal/myvotes/VoteListItem.java | 20 +++++----- .../wallet/dashboard/BsqDashboardView.java | 40 +++++++++---------- .../main/dao/wallet/tx/BsqTxListItem.java | 10 ++--- .../desktop/main/dao/wallet/tx/BsqTxView.java | 32 +++++++-------- .../TransactionListItemFactory.java | 10 ++--- .../transactions/TransactionsListItem.java | 6 +-- 12 files changed, 91 insertions(+), 91 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java index 7d8472a6401..87dd0012881 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java @@ -28,7 +28,7 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.param.DaoParamService; -import bisq.core.dao.state.ChainStateService; +import bisq.core.dao.state.StateService; import bisq.core.dao.vote.PeriodService; import bisq.core.dao.vote.proposal.MyProposalService; import bisq.core.dao.vote.proposal.Proposal; @@ -72,7 +72,7 @@ public abstract class BaseProposalView extends ActivatableView { protected final MyProposalService myProposalService; - protected final ChainStateService chainStateService; + protected final StateService stateService; protected final DaoParamService daoParamService; protected final ProposalListService proposalListService; protected final ProposalService proposalService; @@ -106,7 +106,7 @@ protected BaseProposalView(MyProposalService myProposalService, ProposalListService proposalListService, ProposalService proposalService, BsqWalletService bsqWalletService, - ChainStateService chainStateService, + StateService stateService, DaoParamService daoParamService, PeriodService periodService, BsqFormatter bsqFormatter, @@ -115,7 +115,7 @@ protected BaseProposalView(MyProposalService myProposalService, this.proposalListService = proposalListService; this.proposalService = proposalService; this.bsqWalletService = bsqWalletService; - this.chainStateService = chainStateService; + this.stateService = stateService; this.daoParamService = daoParamService; this.periodService = periodService; this.bsqFormatter = bsqFormatter; @@ -255,7 +255,7 @@ protected void doUpdateProposalList(List list) { proposalService, periodService, bsqWalletService, - chainStateService, + stateService, bsqFormatter)) .collect(Collectors.toSet())); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index d9b57f33060..fee36c6e29f 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -25,7 +25,7 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.blockchain.vo.BsqBlock; import bisq.core.dao.blockchain.vo.Tx; -import bisq.core.dao.state.ChainStateService; +import bisq.core.dao.state.StateService; import bisq.core.dao.vote.BooleanVote; import bisq.core.dao.vote.PeriodService; import bisq.core.dao.vote.Vote; @@ -53,13 +53,13 @@ @ToString @Slf4j @EqualsAndHashCode -public class ProposalListItem implements ChainStateService.Listener { +public class ProposalListItem implements StateService.Listener { @Getter private final Proposal proposal; private final ProposalService proposalService; private final PeriodService periodService; private final BsqWalletService bsqWalletService; - private final ChainStateService chainStateService; + private final StateService stateService; private final BsqFormatter bsqFormatter; private final ChangeListener chainHeightListener; private final ChangeListener voteResultChangeListener; @@ -82,13 +82,13 @@ public class ProposalListItem implements ChainStateService.Listener { ProposalService proposalService, PeriodService periodService, BsqWalletService bsqWalletService, - ChainStateService chainStateService, + StateService stateService, BsqFormatter bsqFormatter) { this.proposal = proposal; this.proposalService = proposalService; this.periodService = periodService; this.bsqWalletService = bsqWalletService; - this.chainStateService = chainStateService; + this.stateService = stateService; this.bsqFormatter = bsqFormatter; @@ -107,7 +107,7 @@ public class ProposalListItem implements ChainStateService.Listener { bsqWalletService.getChainHeightProperty().addListener(chainHeightListener); setupConfidence(); - chainStateService.addListener(this); + stateService.addListener(this); phaseChangeListener = (observable, oldValue, newValue) -> { applyState(newValue, proposal.getVote()); @@ -126,7 +126,7 @@ public void applyState(PeriodService.Phase newValue, Vote vote) { actionButton.setVisible(false); actionButton.setOnAction(null); final boolean isTxInPastCycle = periodService.isTxInPastCycle(proposal.getTxId(), - chainStateService.getChainHeadHeight()); + stateService.getChainHeadHeight()); switch (newValue) { case UNDEFINED: break; @@ -186,7 +186,7 @@ public void applyState(PeriodService.Phase newValue, Vote vote) { /////////////////////////////////////////////////////////////////////////////////////////// - // ChainStateService.Listener + // StateService.Listener /////////////////////////////////////////////////////////////////////////////////////////// @Override @@ -197,7 +197,7 @@ public void onBlockAdded(BsqBlock bsqBlock) { private void setupConfidence() { - final Tx tx = chainStateService.getTxMap().get(proposal.getProposalPayload().getTxId()); + final Tx tx = stateService.getTxMap().get(proposal.getProposalPayload().getTxId()); if (tx != null) { final String txId = tx.getId(); @@ -241,7 +241,7 @@ private void updateConfidence(TransactionConfidence confidence, int depthInBlock } public void cleanup() { - chainStateService.removeListener(this); + stateService.removeListener(this); bsqWalletService.getChainHeightProperty().removeListener(chainHeightListener); if (txConfidenceListener != null) bsqWalletService.removeTxConfidenceListener(txConfidenceListener); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index 1e13c2f1fbf..19e33e2720f 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -34,7 +34,7 @@ import bisq.core.btc.wallet.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.param.DaoParamService; -import bisq.core.dao.state.ChainStateService; +import bisq.core.dao.state.StateService; import bisq.core.dao.vote.BooleanVote; import bisq.core.dao.vote.PeriodService; import bisq.core.dao.vote.blindvote.BlindVoteConsensus; @@ -94,12 +94,12 @@ private ActiveProposalsView(MyProposalService myProposalService, PeriodService periodService, BlindVoteService blindVoteService, BsqWalletService bsqWalletService, - ChainStateService chainStateService, + StateService stateService, DaoParamService daoParamService, BsqFormatter bsqFormatter, BSFormatter btcFormatter) { - super(myProposalService, proposalListService, proposalService, bsqWalletService, chainStateService, + super(myProposalService, proposalListService, proposalService, bsqWalletService, stateService, daoParamService, periodService, bsqFormatter, btcFormatter); this.blindVoteService = blindVoteService; } @@ -130,7 +130,7 @@ protected void activate() { voteButton.setOnAction(e -> { // TODO verify stake Coin stake = bsqFormatter.parseToCoin(stakeInputTextField.getText()); - final Coin fee = BlindVoteConsensus.getFee(daoParamService, chainStateService.getChainHeadHeight()); + final Coin fee = BlindVoteConsensus.getFee(daoParamService, stateService.getChainHeadHeight()); Transaction dummyTx = null; try { // We create a tx with dummy opreturn data to get the mining fee for confirmation popup @@ -270,7 +270,7 @@ protected void onPhaseChanged(PeriodService.Phase phase) { if (selectedProposalListItem != null && proposalDisplay != null && !periodService.isTxInPastCycle(selectedProposalListItem.getProposal().getTxId(), - chainStateService.getChainHeadHeight())) { + stateService.getChainHeadHeight())) { final Proposal proposal = selectedProposalListItem.getProposal(); switch (phase) { case PROPOSAL: diff --git a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java index ec29a0660bf..68c644a0a89 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java @@ -24,7 +24,7 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.param.DaoParamService; -import bisq.core.dao.state.ChainStateService; +import bisq.core.dao.state.StateService; import bisq.core.dao.vote.PeriodService; import bisq.core.dao.vote.proposal.MyProposalService; import bisq.core.dao.vote.proposal.ProposalListService; @@ -45,12 +45,12 @@ private ClosedProposalsView(MyProposalService myProposalService, ProposalService proposalService, PeriodService periodService, BsqWalletService bsqWalletService, - ChainStateService chainStateService, + StateService stateService, DaoParamService daoParamService, BsqFormatter bsqFormatter, BSFormatter btcFormatter) { - super(myProposalService, proposalListService, proposalService, bsqWalletService, chainStateService, + super(myProposalService, proposalListService, proposalService, bsqWalletService, stateService, daoParamService, periodService, bsqFormatter, btcFormatter); } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index 8ae4994c12d..04d9d3e49ec 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -32,7 +32,7 @@ import bisq.core.btc.wallet.InsufficientBsqException; import bisq.core.btc.wallet.WalletsSetup; import bisq.core.dao.param.DaoParamService; -import bisq.core.dao.state.ChainStateService; +import bisq.core.dao.state.StateService; import bisq.core.dao.vote.proposal.MyProposalService; import bisq.core.dao.vote.proposal.Proposal; import bisq.core.dao.vote.proposal.ProposalConsensus; @@ -88,7 +88,7 @@ public class MakeProposalView extends ActivatableView { private final MyProposalService myProposalService; private final CompensationRequestService compensationRequestService; private final GenericProposalService genericProposalService; - private final ChainStateService chainStateService; + private final StateService stateService; private final DaoParamService daoParamService; private final BSFormatter btcFormatter; private final BsqFormatter bsqFormatter; @@ -109,7 +109,7 @@ private MakeProposalView(BsqWalletService bsqWalletService, MyProposalService myProposalService, CompensationRequestService compensationRequestService, GenericProposalService genericProposalService, - ChainStateService chainStateService, + StateService stateService, DaoParamService daoParamService, BSFormatter btcFormatter, BsqFormatter bsqFormatter) { @@ -120,7 +120,7 @@ private MakeProposalView(BsqWalletService bsqWalletService, this.myProposalService = myProposalService; this.compensationRequestService = compensationRequestService; this.genericProposalService = genericProposalService; - this.chainStateService = chainStateService; + this.stateService = stateService; this.daoParamService = daoParamService; this.btcFormatter = btcFormatter; this.bsqFormatter = bsqFormatter; @@ -174,7 +174,7 @@ private void publishProposal(ProposalType type) { Coin miningFee = Objects.requireNonNull(tx).getFee(); int txSize = tx.bitcoinSerialize().length; - final Coin fee = ProposalConsensus.getFee(daoParamService, chainStateService.getChainHeadHeight()); + final Coin fee = ProposalConsensus.getFee(daoParamService, stateService.getChainHeadHeight()); GUIUtil.showBsqFeeInfoPopup(fee, miningFee, txSize, bsqFormatter, btcFormatter, Res.get("dao.proposal"), () -> publishProposal(proposal)); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java index 5952db65bd8..627c6b9b12e 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java @@ -31,7 +31,7 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.param.DaoParamService; -import bisq.core.dao.state.ChainStateService; +import bisq.core.dao.state.StateService; import bisq.core.dao.vote.BooleanVote; import bisq.core.dao.vote.PeriodService; import bisq.core.dao.vote.Vote; @@ -95,14 +95,14 @@ private MyVotesView(MyProposalService myProposalService, ProposalService proposalService, PeriodService periodService, BsqWalletService bsqWalletService, - ChainStateService chainStateService, + StateService stateService, DaoParamService daoParamService, BsqFormatter bsqFormatter, BSFormatter btcFormatter, MyVoteService myVoteService, Preferences preferences) { - super(myProposalService, proposalListService, proposalService, bsqWalletService, chainStateService, + super(myProposalService, proposalListService, proposalService, bsqWalletService, stateService, daoParamService, periodService, bsqFormatter, btcFormatter); this.myVoteService = myVoteService; this.preferences = preferences; @@ -130,7 +130,7 @@ protected void activate() { voteListItems.clear(); List items = myVoteService.getMyVoteList().stream() - .map(vote -> new VoteListItem(vote, bsqWalletService, chainStateService, bsqFormatter)) + .map(vote -> new VoteListItem(vote, bsqWalletService, stateService, bsqFormatter)) .collect(Collectors.toList()); voteListItems.addAll(items); } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java index 558dc4bdc5d..8b52f7be9cf 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java @@ -25,7 +25,7 @@ import bisq.core.dao.blockchain.vo.BsqBlock; import bisq.core.dao.blockchain.vo.Tx; import bisq.core.dao.blockchain.vo.TxOutput; -import bisq.core.dao.state.ChainStateService; +import bisq.core.dao.state.StateService; import bisq.core.dao.vote.myvote.MyVote; import bisq.core.locale.Res; @@ -50,11 +50,11 @@ @ToString @Slf4j @EqualsAndHashCode -public class VoteListItem implements ChainStateService.Listener { +public class VoteListItem implements StateService.Listener { @Getter private final MyVote myVote; private final BsqWalletService bsqWalletService; - private final ChainStateService chainStateService; + private final StateService stateService; private final BsqFormatter bsqFormatter; private final ChangeListener chainHeightListener; @Getter @@ -74,11 +74,11 @@ public class VoteListItem implements ChainStateService.Listener { VoteListItem(MyVote myVote, BsqWalletService bsqWalletService, - ChainStateService chainStateService, + StateService stateService, BsqFormatter bsqFormatter) { this.myVote = myVote; this.bsqWalletService = bsqWalletService; - this.chainStateService = chainStateService; + this.stateService = stateService; this.bsqFormatter = bsqFormatter; txConfidenceIndicator = new TxConfidenceIndicator(); @@ -87,7 +87,7 @@ public class VoteListItem implements ChainStateService.Listener { txConfidenceIndicator.setProgress(-1); txConfidenceIndicator.setPrefSize(24, 24); txConfidenceIndicator.setTooltip(tooltip); - chainStateService.addListener(this); + stateService.addListener(this); chainHeightListener = (observable, oldValue, newValue) -> setupConfidence(); bsqWalletService.getChainHeightProperty().addListener(chainHeightListener); @@ -97,7 +97,7 @@ public class VoteListItem implements ChainStateService.Listener { /////////////////////////////////////////////////////////////////////////////////////////// - // ChainStateService.Listener + // StateService.Listener /////////////////////////////////////////////////////////////////////////////////////////// @Override @@ -109,7 +109,7 @@ public void onBlockAdded(BsqBlock bsqBlock) { private void setupConfidence() { calculateStake(); - final Tx tx = chainStateService.getTxMap().get(myVote.getBlindVote().getTxId()); + final Tx tx = stateService.getTxMap().get(myVote.getBlindVote().getTxId()); if (tx != null) { final String txId = tx.getId(); @@ -148,7 +148,7 @@ public void onTransactionConfidenceChanged(TransactionConfidence confidence) { private void calculateStake() { if (stake == 0) { String txId = myVote.getTxId(); - stake = chainStateService.getUnspentBlindVoteStakeTxOutputs().stream() + stake = stateService.getUnspentBlindVoteStakeTxOutputs().stream() .filter(txOutput -> txOutput.getTxId().equals(txId)) .filter(txOutput -> txOutput.getIndex() == 0) .mapToLong(TxOutput::getValue) @@ -166,7 +166,7 @@ private void updateConfidence(TransactionConfidence confidence, int depthInBlock public void cleanup() { bsqWalletService.getChainHeightProperty().removeListener(chainHeightListener); - chainStateService.removeListener(this); + stateService.removeListener(this); if (txConfidenceListener != null) bsqWalletService.removeTxConfidenceListener(txConfidenceListener); } diff --git a/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java b/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java index 69dad7a781e..042edacfd18 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java @@ -27,7 +27,7 @@ import bisq.desktop.util.Layout; import bisq.core.dao.blockchain.vo.BsqBlock; -import bisq.core.dao.state.ChainStateService; +import bisq.core.dao.state.StateService; import bisq.core.locale.Res; import bisq.core.monetary.Altcoin; import bisq.core.monetary.Price; @@ -56,10 +56,10 @@ import static bisq.desktop.util.FormBuilder.addTitledGroupBg; @FxmlView -public class BsqDashboardView extends ActivatableView implements bisq.core.dao.state.ChainStateService.Listener { +public class BsqDashboardView extends ActivatableView implements StateService.Listener { private final BsqBalanceUtil bsqBalanceUtil; - private final ChainStateService chainStateService; + private final StateService stateService; private final PriceFeedService priceFeedService; private final Preferences preferences; private final BsqFormatter bsqFormatter; @@ -78,12 +78,12 @@ public class BsqDashboardView extends ActivatableView implements @Inject private BsqDashboardView(BsqBalanceUtil bsqBalanceUtil, - ChainStateService chainStateService, + StateService stateService, PriceFeedService priceFeedService, Preferences preferences, BsqFormatter bsqFormatter) { this.bsqBalanceUtil = bsqBalanceUtil; - this.chainStateService = chainStateService; + this.stateService = stateService; this.priceFeedService = priceFeedService; this.preferences = preferences; this.bsqFormatter = bsqFormatter; @@ -96,13 +96,13 @@ public void initialize() { addTitledGroupBg(root, ++gridRow, 11, Res.get("dao.wallet.dashboard.statistics"), Layout.GROUP_DISTANCE); addLabelTextField(root, gridRow, Res.get("dao.wallet.dashboard.genesisBlockHeight"), - String.valueOf(chainStateService.getGenesisBlockHeight()), Layout.FIRST_ROW_AND_GROUP_DISTANCE); + String.valueOf(stateService.getGenesisBlockHeight()), Layout.FIRST_ROW_AND_GROUP_DISTANCE); Label label = new AutoTooltipLabel(Res.get("dao.wallet.dashboard.genesisTxId")); GridPane.setRowIndex(label, ++gridRow); root.getChildren().add(label); - hyperlinkWithIcon = new HyperlinkWithIcon(chainStateService.getGenesisTxId(), AwesomeIcon.EXTERNAL_LINK); - hyperlinkWithIcon.setTooltip(new Tooltip(Res.get("tooltip.openBlockchainForTx", chainStateService.getGenesisTxId()))); + hyperlinkWithIcon = new HyperlinkWithIcon(stateService.getGenesisTxId(), AwesomeIcon.EXTERNAL_LINK); + hyperlinkWithIcon.setTooltip(new Tooltip(Res.get("tooltip.openBlockchainForTx", stateService.getGenesisTxId()))); GridPane.setRowIndex(hyperlinkWithIcon, gridRow); GridPane.setColumnIndex(hyperlinkWithIcon, 1); GridPane.setMargin(hyperlinkWithIcon, new Insets(0, 0, 0, -4)); @@ -128,10 +128,10 @@ public void initialize() { protected void activate() { bsqBalanceUtil.activate(); - chainStateService.addListener(this); + stateService.addListener(this); priceFeedService.updateCounterProperty().addListener(priceChangeListener); - hyperlinkWithIcon.setOnAction(event -> GUIUtil.openWebPage(preferences.getBsqBlockChainExplorer().txUrl + chainStateService.getGenesisTxId())); + hyperlinkWithIcon.setOnAction(event -> GUIUtil.openWebPage(preferences.getBsqBlockChainExplorer().txUrl + stateService.getGenesisTxId())); updateWithBsqBlockChainData(); updatePrice(); @@ -140,14 +140,14 @@ protected void activate() { @Override protected void deactivate() { bsqBalanceUtil.deactivate(); - chainStateService.removeListener(this); + stateService.removeListener(this); priceFeedService.updateCounterProperty().removeListener(priceChangeListener); hyperlinkWithIcon.setOnAction(null); } /////////////////////////////////////////////////////////////////////////////////////////// - // ChainStateService.Listener + // StateService.Listener /////////////////////////////////////////////////////////////////////////////////////////// @Override @@ -157,25 +157,25 @@ public void onBlockAdded(BsqBlock bsqBlock) { private void updateWithBsqBlockChainData() { - final Coin issuedAmountFromGenesis = chainStateService.getIssuedAmountAtGenesis(); + final Coin issuedAmountFromGenesis = stateService.getIssuedAmountAtGenesis(); genesisIssueAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(issuedAmountFromGenesis)); - final Coin issuedAmountFromCompRequests = chainStateService.getIssuedAmountFromCompRequests(); + final Coin issuedAmountFromCompRequests = stateService.getIssuedAmountFromCompRequests(); compRequestIssueAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(issuedAmountFromCompRequests)); - final Coin burntFee = chainStateService.getTotalBurntFee(); + final Coin burntFee = stateService.getTotalBurntFee(); final Coin availableAmount = issuedAmountFromGenesis.add(issuedAmountFromCompRequests).subtract(burntFee); availableAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(availableAmount)); burntAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(burntFee)); - allTxTextField.setText(String.valueOf(chainStateService.getTransactions().size())); - utxoTextField.setText(String.valueOf(chainStateService.getUnspentTxOutputs().size())); - //spentTxTextField.setText(String.valueOf(chainStateService.getSpentTxOutputs().size())); - burntTxTextField.setText(String.valueOf(chainStateService.getFeeTransactions().size())); + allTxTextField.setText(String.valueOf(stateService.getTransactions().size())); + utxoTextField.setText(String.valueOf(stateService.getUnspentTxOutputs().size())); + //spentTxTextField.setText(String.valueOf(stateService.getSpentTxOutputs().size())); + burntTxTextField.setText(String.valueOf(stateService.getFeeTransactions().size())); } private void updatePrice() { - final Coin issuedAmount = chainStateService.getIssuedAmountAtGenesis(); + final Coin issuedAmount = stateService.getIssuedAmountAtGenesis(); final MarketPrice bsqMarketPrice = priceFeedService.getMarketPrice("BSQ"); if (bsqMarketPrice != null) { long bsqPrice = MathUtils.roundDoubleToLong(MathUtils.scaleUpByPowerOf10(bsqMarketPrice.getPrice(), Altcoin.SMALLEST_UNIT_EXPONENT)); diff --git a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java index 4f0fd78f2d2..e063dda46b5 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java @@ -27,7 +27,7 @@ import bisq.core.btc.wallet.WalletService; import bisq.core.dao.blockchain.vo.Tx; import bisq.core.dao.blockchain.vo.TxType; -import bisq.core.dao.state.ChainStateService; +import bisq.core.dao.state.StateService; import bisq.core.locale.Res; import org.bitcoinj.core.Coin; @@ -51,7 +51,7 @@ class BsqTxListItem { private final Optional optionalTx; private final BsqWalletService bsqWalletService; private final BtcWalletService btcWalletService; - private final ChainStateService chainStateService; + private final StateService stateService; private final BsqFormatter bsqFormatter; private final Date date; private final String txId; @@ -71,7 +71,7 @@ class BsqTxListItem { Optional optionalTx, BsqWalletService bsqWalletService, BtcWalletService btcWalletService, - ChainStateService chainStateService, + StateService stateService, boolean isBurnedBsqTx, Date date, BsqFormatter bsqFormatter) { @@ -79,7 +79,7 @@ class BsqTxListItem { this.optionalTx = optionalTx; this.bsqWalletService = bsqWalletService; this.btcWalletService = btcWalletService; - this.chainStateService = chainStateService; + this.stateService = stateService; this.isBurnedBsqTx = isBurnedBsqTx; this.date = date; this.bsqFormatter = bsqFormatter; @@ -166,7 +166,7 @@ public void cleanup() { public TxType getTxType() { if (optionalTx.isPresent()) { - Optional optionalTxType = chainStateService.getTxType(optionalTx.get().getId()); + Optional optionalTxType = stateService.getTxType(optionalTx.get().getId()); if (optionalTxType.isPresent()) return optionalTxType.get(); } diff --git a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java index a566c49fb9a..b3db7b589f7 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java @@ -35,7 +35,7 @@ import bisq.core.dao.blockchain.vo.BsqBlock; import bisq.core.dao.blockchain.vo.Tx; import bisq.core.dao.blockchain.vo.TxType; -import bisq.core.dao.state.ChainStateService; +import bisq.core.dao.state.StateService; import bisq.core.locale.Res; import bisq.core.user.Preferences; @@ -80,14 +80,14 @@ import java.util.stream.Collectors; @FxmlView -public class BsqTxView extends ActivatableView implements BsqBalanceListener, bisq.core.dao.state.ChainStateService.Listener { +public class BsqTxView extends ActivatableView implements BsqBalanceListener, StateService.Listener { private TableView tableView; private Pane rootParent; private final BsqFormatter bsqFormatter; private final BsqWalletService bsqWalletService; - private final ChainStateService chainStateService; + private final StateService stateService; private final BtcWalletService btcWalletService; private final BsqBalanceUtil bsqBalanceUtil; private final Preferences preferences; @@ -111,13 +111,13 @@ public class BsqTxView extends ActivatableView implements BsqBal private BsqTxView(BsqFormatter bsqFormatter, BsqWalletService bsqWalletService, Preferences preferences, - ChainStateService chainStateService, + StateService stateService, BtcWalletService btcWalletService, BsqBalanceUtil bsqBalanceUtil) { this.bsqFormatter = bsqFormatter; this.bsqWalletService = bsqWalletService; this.preferences = preferences; - this.chainStateService = chainStateService; + this.stateService = stateService; this.btcWalletService = btcWalletService; this.bsqBalanceUtil = bsqBalanceUtil; } @@ -175,7 +175,7 @@ protected void activate() { sortedList.comparatorProperty().bind(tableView.comparatorProperty()); tableView.setItems(sortedList); - chainStateService.addListener(this); + stateService.addListener(this); if (root.getParent() instanceof Pane) { rootParent = (Pane) root.getParent(); @@ -194,7 +194,7 @@ protected void deactivate() { bsqWalletService.getWalletTransactions().removeListener(walletBsqTransactionsListener); bsqWalletService.removeBsqBalanceListener(this); btcWalletService.getChainHeightProperty().removeListener(chainHeightChangedListener); - chainStateService.removeListener(this); + stateService.removeListener(this); observableList.forEach(BsqTxListItem::cleanup); @@ -213,7 +213,7 @@ public void onUpdateBalances(Coin confirmedBalance, /////////////////////////////////////////////////////////////////////////////////////////// - // ChainStateService.Listener + // StateService.Listener /////////////////////////////////////////////////////////////////////////////////////////// @Override @@ -224,7 +224,7 @@ public void onBlockAdded(BsqBlock bsqBlock) { private void onChainHeightChanged() { final int bsqWalletChainHeight = bsqWalletService.getChainHeightProperty().get(); - final int bsqBlockChainHeight = chainStateService.getChainHeadHeight(); + final int bsqBlockChainHeight = stateService.getChainHeadHeight(); if (bsqWalletChainHeight > 0) { final boolean synced = bsqWalletChainHeight == bsqBlockChainHeight; chainSyncIndicator.setVisible(!synced); @@ -255,13 +255,13 @@ private void updateList() { final List walletTransactions = new ArrayList<>(bsqWalletService.getWalletTransactions()); List items = walletTransactions.stream() .map(transaction -> { - final Optional optionalTx = chainStateService.getTx(transaction.getHashAsString()); + final Optional optionalTx = stateService.getTx(transaction.getHashAsString()); return new BsqTxListItem(transaction, optionalTx, bsqWalletService, btcWalletService, - chainStateService, - chainStateService.hasTxBurntFee(transaction.getHashAsString()), + stateService, + stateService.hasTxBurntFee(transaction.getHashAsString()), transaction.getUpdateTime(), bsqFormatter); }) @@ -371,7 +371,7 @@ public void updateItem(final BsqTxListItem item, boolean empty) { if (txType == TxType.COMPENSATION_REQUEST && optionalTx.isPresent() && - chainStateService.isIssuanceTx(optionalTx.get().getId())) { + stateService.isIssuanceTx(optionalTx.get().getId())) { if (field != null) field.setOnAction(null); @@ -533,11 +533,11 @@ public void updateItem(final BsqTxListItem item, boolean empty) { case PROPOSAL: case COMPENSATION_REQUEST: final String txId = item.getOptionalTx().get().getId(); - if (item.getOptionalTx().isPresent() && chainStateService.isIssuanceTx(txId)) { + if (item.getOptionalTx().isPresent() && stateService.isIssuanceTx(txId)) { awesomeIcon = AwesomeIcon.MONEY; style = "dao-tx-type-issuance-icon"; - final int issuanceBlockHeight = chainStateService.getIssuanceBlockHeight(txId); - long blockTimeInSec = chainStateService.getBlockTime(issuanceBlockHeight); + final int issuanceBlockHeight = stateService.getIssuanceBlockHeight(txId); + long blockTimeInSec = stateService.getBlockTime(issuanceBlockHeight); final String formattedDate = bsqFormatter.formatDateTime(new Date(blockTimeInSec * 1000)); toolTipText = Res.get("dao.tx.issuance.tooltip", formattedDate); } else { diff --git a/src/main/java/bisq/desktop/main/funds/transactions/TransactionListItemFactory.java b/src/main/java/bisq/desktop/main/funds/transactions/TransactionListItemFactory.java index e65df06e895..7fc5b61ff1a 100644 --- a/src/main/java/bisq/desktop/main/funds/transactions/TransactionListItemFactory.java +++ b/src/main/java/bisq/desktop/main/funds/transactions/TransactionListItemFactory.java @@ -21,7 +21,7 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; -import bisq.core.dao.state.ChainStateService; +import bisq.core.dao.state.StateService; import bisq.core.trade.Tradable; import org.bitcoinj.core.Transaction; @@ -35,15 +35,15 @@ public class TransactionListItemFactory { private final BtcWalletService btcWalletService; private final BsqWalletService bsqWalletService; - private final ChainStateService chainStateService; + private final StateService stateService; private final BSFormatter formatter; @Inject TransactionListItemFactory(BtcWalletService btcWalletService, BsqWalletService bsqWalletService, - ChainStateService chainStateService, BSFormatter formatter) { + StateService stateService, BSFormatter formatter) { this.btcWalletService = btcWalletService; this.bsqWalletService = bsqWalletService; - this.chainStateService = chainStateService; + this.stateService = stateService; this.formatter = formatter; } @@ -51,6 +51,6 @@ TransactionsListItem create(Transaction transaction, @Nullable TransactionAwareT Optional maybeTradable = Optional.ofNullable(tradable) .map(TransactionAwareTradable::asTradable); - return new TransactionsListItem(transaction, btcWalletService, bsqWalletService, maybeTradable, chainStateService, formatter); + return new TransactionsListItem(transaction, btcWalletService, bsqWalletService, maybeTradable, stateService, formatter); } } diff --git a/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java b/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java index 9aa2dc04204..cbbc144d10a 100644 --- a/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java +++ b/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java @@ -27,7 +27,7 @@ import bisq.core.btc.wallet.BtcWalletService; import bisq.core.btc.wallet.WalletService; import bisq.core.dao.blockchain.vo.TxType; -import bisq.core.dao.state.ChainStateService; +import bisq.core.dao.state.StateService; import bisq.core.locale.Res; import bisq.core.offer.Offer; import bisq.core.offer.OpenOffer; @@ -80,7 +80,7 @@ public TransactionsListItem(Transaction transaction, BtcWalletService btcWalletService, BsqWalletService bsqWalletService, Optional tradableOptional, - ChainStateService chainStateService, + StateService stateService, BSFormatter formatter) { this.formatter = formatter; txId = transaction.getHashAsString(); @@ -130,7 +130,7 @@ public TransactionsListItem(Transaction transaction, txFeeForBsqPayment = true; // - final Optional txTypeOptional = chainStateService.getTxType(txId); + final Optional txTypeOptional = stateService.getTxType(txId); if (txTypeOptional.isPresent() && txTypeOptional.get().equals(TxType.COMPENSATION_REQUEST)) details = Res.get("funds.tx.proposal"); } else { From 7f1b0ebe09696f0f3148dc739dbf7ecb2f6b63b7 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Fri, 13 Apr 2018 09:40:56 -0500 Subject: [PATCH 023/197] Refactoring: Move package blockchain to bisq.core.dao.state.blockchain --- .../bisq/desktop/main/dao/proposal/ProposalListItem.java | 4 ++-- .../desktop/main/dao/proposal/myvotes/VoteListItem.java | 6 +++--- .../desktop/main/dao/wallet/dashboard/BsqDashboardView.java | 2 +- .../java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java | 4 ++-- .../java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java | 6 +++--- .../main/funds/transactions/TransactionsListItem.java | 2 +- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index fee36c6e29f..a72c2aa344a 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -23,9 +23,9 @@ import bisq.core.btc.listeners.TxConfidenceListener; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.blockchain.vo.BsqBlock; -import bisq.core.dao.blockchain.vo.Tx; import bisq.core.dao.state.StateService; +import bisq.core.dao.state.blockchain.vo.BsqBlock; +import bisq.core.dao.state.blockchain.vo.Tx; import bisq.core.dao.vote.BooleanVote; import bisq.core.dao.vote.PeriodService; import bisq.core.dao.vote.Vote; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java index 8b52f7be9cf..5f49ed5cde1 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java @@ -22,10 +22,10 @@ import bisq.core.btc.listeners.TxConfidenceListener; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.blockchain.vo.BsqBlock; -import bisq.core.dao.blockchain.vo.Tx; -import bisq.core.dao.blockchain.vo.TxOutput; import bisq.core.dao.state.StateService; +import bisq.core.dao.state.blockchain.vo.BsqBlock; +import bisq.core.dao.state.blockchain.vo.Tx; +import bisq.core.dao.state.blockchain.vo.TxOutput; import bisq.core.dao.vote.myvote.MyVote; import bisq.core.locale.Res; diff --git a/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java b/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java index 042edacfd18..0b0a9159412 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java @@ -26,8 +26,8 @@ import bisq.desktop.util.GUIUtil; import bisq.desktop.util.Layout; -import bisq.core.dao.blockchain.vo.BsqBlock; import bisq.core.dao.state.StateService; +import bisq.core.dao.state.blockchain.vo.BsqBlock; import bisq.core.locale.Res; import bisq.core.monetary.Altcoin; import bisq.core.monetary.Price; diff --git a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java index e063dda46b5..a79bbe101f3 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java @@ -25,9 +25,9 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; import bisq.core.btc.wallet.WalletService; -import bisq.core.dao.blockchain.vo.Tx; -import bisq.core.dao.blockchain.vo.TxType; import bisq.core.dao.state.StateService; +import bisq.core.dao.state.blockchain.vo.Tx; +import bisq.core.dao.state.blockchain.vo.TxType; import bisq.core.locale.Res; import org.bitcoinj.core.Coin; diff --git a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java index b3db7b589f7..b0bd32d6451 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java @@ -32,10 +32,10 @@ import bisq.core.btc.wallet.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; -import bisq.core.dao.blockchain.vo.BsqBlock; -import bisq.core.dao.blockchain.vo.Tx; -import bisq.core.dao.blockchain.vo.TxType; import bisq.core.dao.state.StateService; +import bisq.core.dao.state.blockchain.vo.BsqBlock; +import bisq.core.dao.state.blockchain.vo.Tx; +import bisq.core.dao.state.blockchain.vo.TxType; import bisq.core.locale.Res; import bisq.core.user.Preferences; diff --git a/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java b/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java index cbbc144d10a..e950a13c972 100644 --- a/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java +++ b/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java @@ -26,8 +26,8 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; import bisq.core.btc.wallet.WalletService; -import bisq.core.dao.blockchain.vo.TxType; import bisq.core.dao.state.StateService; +import bisq.core.dao.state.blockchain.vo.TxType; import bisq.core.locale.Res; import bisq.core.offer.Offer; import bisq.core.offer.OpenOffer; From 21fe0a03b5e2d9d7d14105714a8f074e4c9aa171 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Fri, 13 Apr 2018 09:46:11 -0500 Subject: [PATCH 024/197] Refactoring: move vo one level up - move bisq.core.dao.state.blockchain.vo to bisq.core.dao.state.blockchain --- .../bisq/desktop/main/dao/proposal/ProposalListItem.java | 4 ++-- .../desktop/main/dao/proposal/myvotes/VoteListItem.java | 6 +++--- .../desktop/main/dao/wallet/dashboard/BsqDashboardView.java | 2 +- .../java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java | 4 ++-- .../java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java | 6 +++--- .../main/funds/transactions/TransactionsListItem.java | 2 +- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index a72c2aa344a..36a6633c676 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -24,8 +24,8 @@ import bisq.core.btc.listeners.TxConfidenceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.state.StateService; -import bisq.core.dao.state.blockchain.vo.BsqBlock; -import bisq.core.dao.state.blockchain.vo.Tx; +import bisq.core.dao.state.blockchain.BsqBlock; +import bisq.core.dao.state.blockchain.Tx; import bisq.core.dao.vote.BooleanVote; import bisq.core.dao.vote.PeriodService; import bisq.core.dao.vote.Vote; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java index 5f49ed5cde1..56005d28aec 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java @@ -23,9 +23,9 @@ import bisq.core.btc.listeners.TxConfidenceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.state.StateService; -import bisq.core.dao.state.blockchain.vo.BsqBlock; -import bisq.core.dao.state.blockchain.vo.Tx; -import bisq.core.dao.state.blockchain.vo.TxOutput; +import bisq.core.dao.state.blockchain.BsqBlock; +import bisq.core.dao.state.blockchain.Tx; +import bisq.core.dao.state.blockchain.TxOutput; import bisq.core.dao.vote.myvote.MyVote; import bisq.core.locale.Res; diff --git a/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java b/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java index 0b0a9159412..fd06f4db7d4 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java @@ -27,7 +27,7 @@ import bisq.desktop.util.Layout; import bisq.core.dao.state.StateService; -import bisq.core.dao.state.blockchain.vo.BsqBlock; +import bisq.core.dao.state.blockchain.BsqBlock; import bisq.core.locale.Res; import bisq.core.monetary.Altcoin; import bisq.core.monetary.Price; diff --git a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java index a79bbe101f3..ea3079cc0ee 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java @@ -26,8 +26,8 @@ import bisq.core.btc.wallet.BtcWalletService; import bisq.core.btc.wallet.WalletService; import bisq.core.dao.state.StateService; -import bisq.core.dao.state.blockchain.vo.Tx; -import bisq.core.dao.state.blockchain.vo.TxType; +import bisq.core.dao.state.blockchain.Tx; +import bisq.core.dao.state.blockchain.TxType; import bisq.core.locale.Res; import org.bitcoinj.core.Coin; diff --git a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java index b0bd32d6451..74571804d4e 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java @@ -33,9 +33,9 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; import bisq.core.dao.state.StateService; -import bisq.core.dao.state.blockchain.vo.BsqBlock; -import bisq.core.dao.state.blockchain.vo.Tx; -import bisq.core.dao.state.blockchain.vo.TxType; +import bisq.core.dao.state.blockchain.BsqBlock; +import bisq.core.dao.state.blockchain.Tx; +import bisq.core.dao.state.blockchain.TxType; import bisq.core.locale.Res; import bisq.core.user.Preferences; diff --git a/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java b/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java index e950a13c972..f1bdd17577f 100644 --- a/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java +++ b/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java @@ -27,7 +27,7 @@ import bisq.core.btc.wallet.BtcWalletService; import bisq.core.btc.wallet.WalletService; import bisq.core.dao.state.StateService; -import bisq.core.dao.state.blockchain.vo.TxType; +import bisq.core.dao.state.blockchain.TxType; import bisq.core.locale.Res; import bisq.core.offer.Offer; import bisq.core.offer.OpenOffer; From e90bc0b36352a1ad7ed251168604599eed23064c Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Fri, 13 Apr 2018 09:48:12 -0500 Subject: [PATCH 025/197] Rename BsqBlock to TxBlock --- .../java/bisq/desktop/main/dao/proposal/ProposalListItem.java | 4 ++-- .../bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java | 4 ++-- .../desktop/main/dao/wallet/dashboard/BsqDashboardView.java | 4 ++-- src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index 36a6633c676..cdd7a47141a 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -24,7 +24,7 @@ import bisq.core.btc.listeners.TxConfidenceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.state.StateService; -import bisq.core.dao.state.blockchain.BsqBlock; +import bisq.core.dao.state.blockchain.TxBlock; import bisq.core.dao.state.blockchain.Tx; import bisq.core.dao.vote.BooleanVote; import bisq.core.dao.vote.PeriodService; @@ -190,7 +190,7 @@ public void applyState(PeriodService.Phase newValue, Vote vote) { /////////////////////////////////////////////////////////////////////////////////////////// @Override - public void onBlockAdded(BsqBlock bsqBlock) { + public void onBlockAdded(TxBlock txBlock) { //TODO do we want that here??? setupConfidence(); } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java index 56005d28aec..764c851b117 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java @@ -23,7 +23,7 @@ import bisq.core.btc.listeners.TxConfidenceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.state.StateService; -import bisq.core.dao.state.blockchain.BsqBlock; +import bisq.core.dao.state.blockchain.TxBlock; import bisq.core.dao.state.blockchain.Tx; import bisq.core.dao.state.blockchain.TxOutput; import bisq.core.dao.vote.myvote.MyVote; @@ -101,7 +101,7 @@ public class VoteListItem implements StateService.Listener { /////////////////////////////////////////////////////////////////////////////////////////// @Override - public void onBlockAdded(BsqBlock bsqBlock) { + public void onBlockAdded(TxBlock txBlock) { //TODO do we want that here??? setupConfidence(); } diff --git a/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java b/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java index fd06f4db7d4..50aafacc6d4 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java @@ -27,7 +27,7 @@ import bisq.desktop.util.Layout; import bisq.core.dao.state.StateService; -import bisq.core.dao.state.blockchain.BsqBlock; +import bisq.core.dao.state.blockchain.TxBlock; import bisq.core.locale.Res; import bisq.core.monetary.Altcoin; import bisq.core.monetary.Price; @@ -151,7 +151,7 @@ protected void deactivate() { /////////////////////////////////////////////////////////////////////////////////////////// @Override - public void onBlockAdded(BsqBlock bsqBlock) { + public void onBlockAdded(TxBlock txBlock) { updateWithBsqBlockChainData(); } diff --git a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java index 74571804d4e..fc3456c046a 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java @@ -33,7 +33,7 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; import bisq.core.dao.state.StateService; -import bisq.core.dao.state.blockchain.BsqBlock; +import bisq.core.dao.state.blockchain.TxBlock; import bisq.core.dao.state.blockchain.Tx; import bisq.core.dao.state.blockchain.TxType; import bisq.core.locale.Res; @@ -217,7 +217,7 @@ public void onUpdateBalances(Coin confirmedBalance, /////////////////////////////////////////////////////////////////////////////////////////// @Override - public void onBlockAdded(BsqBlock bsqBlock) { + public void onBlockAdded(TxBlock txBlock) { onChainHeightChanged(); } From 29149ebedbaa6d6b2e634b39d41b03759896302c Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Fri, 13 Apr 2018 12:07:04 -0500 Subject: [PATCH 026/197] Refactor handling of blocks in state class. We create a immutable data unit Block which contains an immutable list of blockchain related blocks (TxBlock) and an immutable list of non-blockchain related events. Service classes which produces StateChangeEvents like ProposalService registers as stateChangeEventListProvider and returns a list of StateChangeEvents when a new TxBlock arrives. The stateService collect all those returned lists and put it to the newly created immutable Block. - Rename BsqBlock to TxBlock - Create Block class containing txBlock as delegate and stateChangeEvents - Add registerStateChangeEventListProvider method for clients processing a new TxBlock and producing stateChangeEvents - Rename StateService listeners to blockListeners - Pass Block instead of TxBlock at blockListeners.onBlockAdded - Rename StateService.Listener to StateService.BlockListener - Rename ParamChangeEvent to ChangeParamEvent - Make ChangeParamEvent extending StateChangeEvent - Make ChangeParam implementing ProtectedStoragePayload --- .../desktop/main/dao/proposal/ProposalListItem.java | 12 ++++++------ .../main/dao/proposal/myvotes/VoteListItem.java | 12 ++++++------ .../main/dao/wallet/dashboard/BsqDashboardView.java | 12 ++++++------ .../bisq/desktop/main/dao/wallet/tx/BsqTxView.java | 12 ++++++------ .../bisq/desktop/main/offer/offerbook/OfferBook.java | 2 +- 5 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index cdd7a47141a..c834dcee3af 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -23,8 +23,8 @@ import bisq.core.btc.listeners.TxConfidenceListener; import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.dao.state.Block; import bisq.core.dao.state.StateService; -import bisq.core.dao.state.blockchain.TxBlock; import bisq.core.dao.state.blockchain.Tx; import bisq.core.dao.vote.BooleanVote; import bisq.core.dao.vote.PeriodService; @@ -53,7 +53,7 @@ @ToString @Slf4j @EqualsAndHashCode -public class ProposalListItem implements StateService.Listener { +public class ProposalListItem implements StateService.BlockListener { @Getter private final Proposal proposal; private final ProposalService proposalService; @@ -107,7 +107,7 @@ public class ProposalListItem implements StateService.Listener { bsqWalletService.getChainHeightProperty().addListener(chainHeightListener); setupConfidence(); - stateService.addListener(this); + stateService.addBlockListener(this); phaseChangeListener = (observable, oldValue, newValue) -> { applyState(newValue, proposal.getVote()); @@ -186,11 +186,11 @@ public void applyState(PeriodService.Phase newValue, Vote vote) { /////////////////////////////////////////////////////////////////////////////////////////// - // StateService.Listener + // StateService.BlockListener /////////////////////////////////////////////////////////////////////////////////////////// @Override - public void onBlockAdded(TxBlock txBlock) { + public void onBlockAdded(Block block) { //TODO do we want that here??? setupConfidence(); } @@ -241,7 +241,7 @@ private void updateConfidence(TransactionConfidence confidence, int depthInBlock } public void cleanup() { - stateService.removeListener(this); + stateService.removeBlockListener(this); bsqWalletService.getChainHeightProperty().removeListener(chainHeightListener); if (txConfidenceListener != null) bsqWalletService.removeTxConfidenceListener(txConfidenceListener); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java index 764c851b117..7476ba9c939 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java @@ -22,8 +22,8 @@ import bisq.core.btc.listeners.TxConfidenceListener; import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.dao.state.Block; import bisq.core.dao.state.StateService; -import bisq.core.dao.state.blockchain.TxBlock; import bisq.core.dao.state.blockchain.Tx; import bisq.core.dao.state.blockchain.TxOutput; import bisq.core.dao.vote.myvote.MyVote; @@ -50,7 +50,7 @@ @ToString @Slf4j @EqualsAndHashCode -public class VoteListItem implements StateService.Listener { +public class VoteListItem implements StateService.BlockListener { @Getter private final MyVote myVote; private final BsqWalletService bsqWalletService; @@ -87,7 +87,7 @@ public class VoteListItem implements StateService.Listener { txConfidenceIndicator.setProgress(-1); txConfidenceIndicator.setPrefSize(24, 24); txConfidenceIndicator.setTooltip(tooltip); - stateService.addListener(this); + stateService.addBlockListener(this); chainHeightListener = (observable, oldValue, newValue) -> setupConfidence(); bsqWalletService.getChainHeightProperty().addListener(chainHeightListener); @@ -97,11 +97,11 @@ public class VoteListItem implements StateService.Listener { /////////////////////////////////////////////////////////////////////////////////////////// - // StateService.Listener + // StateService.BlockListener /////////////////////////////////////////////////////////////////////////////////////////// @Override - public void onBlockAdded(TxBlock txBlock) { + public void onBlockAdded(Block block) { //TODO do we want that here??? setupConfidence(); } @@ -166,7 +166,7 @@ private void updateConfidence(TransactionConfidence confidence, int depthInBlock public void cleanup() { bsqWalletService.getChainHeightProperty().removeListener(chainHeightListener); - stateService.removeListener(this); + stateService.removeBlockListener(this); if (txConfidenceListener != null) bsqWalletService.removeTxConfidenceListener(txConfidenceListener); } diff --git a/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java b/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java index 50aafacc6d4..53ea0e81994 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java @@ -26,8 +26,8 @@ import bisq.desktop.util.GUIUtil; import bisq.desktop.util.Layout; +import bisq.core.dao.state.Block; import bisq.core.dao.state.StateService; -import bisq.core.dao.state.blockchain.TxBlock; import bisq.core.locale.Res; import bisq.core.monetary.Altcoin; import bisq.core.monetary.Price; @@ -56,7 +56,7 @@ import static bisq.desktop.util.FormBuilder.addTitledGroupBg; @FxmlView -public class BsqDashboardView extends ActivatableView implements StateService.Listener { +public class BsqDashboardView extends ActivatableView implements StateService.BlockListener { private final BsqBalanceUtil bsqBalanceUtil; private final StateService stateService; @@ -128,7 +128,7 @@ public void initialize() { protected void activate() { bsqBalanceUtil.activate(); - stateService.addListener(this); + stateService.addBlockListener(this); priceFeedService.updateCounterProperty().addListener(priceChangeListener); hyperlinkWithIcon.setOnAction(event -> GUIUtil.openWebPage(preferences.getBsqBlockChainExplorer().txUrl + stateService.getGenesisTxId())); @@ -140,18 +140,18 @@ protected void activate() { @Override protected void deactivate() { bsqBalanceUtil.deactivate(); - stateService.removeListener(this); + stateService.removeBlockListener(this); priceFeedService.updateCounterProperty().removeListener(priceChangeListener); hyperlinkWithIcon.setOnAction(null); } /////////////////////////////////////////////////////////////////////////////////////////// - // StateService.Listener + // StateService.BlockListener /////////////////////////////////////////////////////////////////////////////////////////// @Override - public void onBlockAdded(TxBlock txBlock) { + public void onBlockAdded(Block block) { updateWithBsqBlockChainData(); } diff --git a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java index fc3456c046a..762e2dc4654 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java @@ -32,8 +32,8 @@ import bisq.core.btc.wallet.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; +import bisq.core.dao.state.Block; import bisq.core.dao.state.StateService; -import bisq.core.dao.state.blockchain.TxBlock; import bisq.core.dao.state.blockchain.Tx; import bisq.core.dao.state.blockchain.TxType; import bisq.core.locale.Res; @@ -80,7 +80,7 @@ import java.util.stream.Collectors; @FxmlView -public class BsqTxView extends ActivatableView implements BsqBalanceListener, StateService.Listener { +public class BsqTxView extends ActivatableView implements BsqBalanceListener, StateService.BlockListener { private TableView tableView; private Pane rootParent; @@ -175,7 +175,7 @@ protected void activate() { sortedList.comparatorProperty().bind(tableView.comparatorProperty()); tableView.setItems(sortedList); - stateService.addListener(this); + stateService.addBlockListener(this); if (root.getParent() instanceof Pane) { rootParent = (Pane) root.getParent(); @@ -194,7 +194,7 @@ protected void deactivate() { bsqWalletService.getWalletTransactions().removeListener(walletBsqTransactionsListener); bsqWalletService.removeBsqBalanceListener(this); btcWalletService.getChainHeightProperty().removeListener(chainHeightChangedListener); - stateService.removeListener(this); + stateService.removeBlockListener(this); observableList.forEach(BsqTxListItem::cleanup); @@ -213,11 +213,11 @@ public void onUpdateBalances(Coin confirmedBalance, /////////////////////////////////////////////////////////////////////////////////////////// - // StateService.Listener + // StateService.BlockListener /////////////////////////////////////////////////////////////////////////////////////////// @Override - public void onBlockAdded(TxBlock txBlock) { + public void onBlockAdded(Block block) { onChainHeightChanged(); } diff --git a/src/main/java/bisq/desktop/main/offer/offerbook/OfferBook.java b/src/main/java/bisq/desktop/main/offer/offerbook/OfferBook.java index 1aa16f3f275..05e4df07ec4 100644 --- a/src/main/java/bisq/desktop/main/offer/offerbook/OfferBook.java +++ b/src/main/java/bisq/desktop/main/offer/offerbook/OfferBook.java @@ -41,7 +41,7 @@ * Holds and manages the unsorted and unfiltered offerbook list of both buy and sell offers. * It is handled as singleton by Guice and is used by 2 instances of OfferBookDataModel (one for Buy one for Sell). * As it is used only by the Buy and Sell UIs we treat it as local UI model. - * It also use OfferRepository.Listener as the lists items class and we don't want to get any dependency out of the + * It also use OfferRepository.BlockListener as the lists items class and we don't want to get any dependency out of the * package for that. */ @Slf4j From df259d83e950e6a3f1ffea446d67e3a1ab5a0856 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Fri, 13 Apr 2018 12:09:00 -0500 Subject: [PATCH 027/197] Refactor: move bisq.core.dao.param to bisq.core.dao.vote.param --- .../java/bisq/desktop/main/dao/proposal/BaseProposalView.java | 2 +- .../desktop/main/dao/proposal/active/ActiveProposalsView.java | 2 +- .../desktop/main/dao/proposal/closed/ClosedProposalsView.java | 2 +- .../bisq/desktop/main/dao/proposal/make/MakeProposalView.java | 2 +- .../bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java index 87dd0012881..3359456e8c6 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java @@ -27,7 +27,7 @@ import bisq.desktop.util.BsqFormatter; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.param.DaoParamService; +import bisq.core.dao.vote.param.DaoParamService; import bisq.core.dao.state.StateService; import bisq.core.dao.vote.PeriodService; import bisq.core.dao.vote.proposal.MyProposalService; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index 19e33e2720f..24c964a4249 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -33,7 +33,7 @@ import bisq.core.btc.exceptions.WalletException; import bisq.core.btc.wallet.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.param.DaoParamService; +import bisq.core.dao.vote.param.DaoParamService; import bisq.core.dao.state.StateService; import bisq.core.dao.vote.BooleanVote; import bisq.core.dao.vote.PeriodService; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java index 68c644a0a89..36045352264 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java @@ -23,7 +23,7 @@ import bisq.desktop.util.BsqFormatter; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.param.DaoParamService; +import bisq.core.dao.vote.param.DaoParamService; import bisq.core.dao.state.StateService; import bisq.core.dao.vote.PeriodService; import bisq.core.dao.vote.proposal.MyProposalService; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index 04d9d3e49ec..f989e18d8ea 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -31,7 +31,7 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.InsufficientBsqException; import bisq.core.btc.wallet.WalletsSetup; -import bisq.core.dao.param.DaoParamService; +import bisq.core.dao.vote.param.DaoParamService; import bisq.core.dao.state.StateService; import bisq.core.dao.vote.proposal.MyProposalService; import bisq.core.dao.vote.proposal.Proposal; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java index 627c6b9b12e..6f48c851c2c 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java @@ -30,7 +30,7 @@ import bisq.desktop.util.Layout; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.param.DaoParamService; +import bisq.core.dao.vote.param.DaoParamService; import bisq.core.dao.state.StateService; import bisq.core.dao.vote.BooleanVote; import bisq.core.dao.vote.PeriodService; From 18b05a1e7822885475f1deb4c2acba32b0d30c8b Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Fri, 13 Apr 2018 12:11:35 -0500 Subject: [PATCH 028/197] Refactor: move param lasses to other package. - Move classed of bisq.core.dao.vote.param to bisq.core.dao.vote.proposal.param --- .../java/bisq/desktop/main/dao/proposal/BaseProposalView.java | 2 +- .../desktop/main/dao/proposal/active/ActiveProposalsView.java | 2 +- .../desktop/main/dao/proposal/closed/ClosedProposalsView.java | 2 +- .../bisq/desktop/main/dao/proposal/make/MakeProposalView.java | 2 +- .../bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java index 3359456e8c6..05c0dada681 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java @@ -27,7 +27,7 @@ import bisq.desktop.util.BsqFormatter; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.vote.param.DaoParamService; +import bisq.core.dao.vote.proposal.param.DaoParamService; import bisq.core.dao.state.StateService; import bisq.core.dao.vote.PeriodService; import bisq.core.dao.vote.proposal.MyProposalService; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index 24c964a4249..4263b278567 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -33,7 +33,7 @@ import bisq.core.btc.exceptions.WalletException; import bisq.core.btc.wallet.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.vote.param.DaoParamService; +import bisq.core.dao.vote.proposal.param.DaoParamService; import bisq.core.dao.state.StateService; import bisq.core.dao.vote.BooleanVote; import bisq.core.dao.vote.PeriodService; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java index 36045352264..49839771825 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java @@ -23,7 +23,7 @@ import bisq.desktop.util.BsqFormatter; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.vote.param.DaoParamService; +import bisq.core.dao.vote.proposal.param.DaoParamService; import bisq.core.dao.state.StateService; import bisq.core.dao.vote.PeriodService; import bisq.core.dao.vote.proposal.MyProposalService; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index f989e18d8ea..59a07b0d277 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -31,7 +31,7 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.InsufficientBsqException; import bisq.core.btc.wallet.WalletsSetup; -import bisq.core.dao.vote.param.DaoParamService; +import bisq.core.dao.vote.proposal.param.DaoParamService; import bisq.core.dao.state.StateService; import bisq.core.dao.vote.proposal.MyProposalService; import bisq.core.dao.vote.proposal.Proposal; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java index 6f48c851c2c..902caa032d1 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java @@ -30,7 +30,7 @@ import bisq.desktop.util.Layout; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.vote.param.DaoParamService; +import bisq.core.dao.vote.proposal.param.DaoParamService; import bisq.core.dao.state.StateService; import bisq.core.dao.vote.BooleanVote; import bisq.core.dao.vote.PeriodService; From 9cbdceebc35e641997c3574bd95f93a2cdf59146 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Fri, 13 Apr 2018 12:30:46 -0500 Subject: [PATCH 029/197] Remame DaoParam to Param and DaoParamService to ParamService --- .../desktop/main/dao/proposal/BaseProposalView.java | 8 ++++---- .../main/dao/proposal/active/ActiveProposalsView.java | 8 ++++---- .../main/dao/proposal/closed/ClosedProposalsView.java | 6 +++--- .../main/dao/proposal/make/MakeProposalView.java | 10 +++++----- .../desktop/main/dao/proposal/myvotes/MyVotesView.java | 6 +++--- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java index 05c0dada681..33c97e9d912 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java @@ -27,7 +27,7 @@ import bisq.desktop.util.BsqFormatter; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.vote.proposal.param.DaoParamService; +import bisq.core.dao.vote.proposal.param.ParamService; import bisq.core.dao.state.StateService; import bisq.core.dao.vote.PeriodService; import bisq.core.dao.vote.proposal.MyProposalService; @@ -73,7 +73,7 @@ public abstract class BaseProposalView extends ActivatableView { protected final MyProposalService myProposalService; protected final StateService stateService; - protected final DaoParamService daoParamService; + protected final ParamService paramService; protected final ProposalListService proposalListService; protected final ProposalService proposalService; protected final BsqWalletService bsqWalletService; @@ -107,7 +107,7 @@ protected BaseProposalView(MyProposalService myProposalService, ProposalService proposalService, BsqWalletService bsqWalletService, StateService stateService, - DaoParamService daoParamService, + ParamService paramService, PeriodService periodService, BsqFormatter bsqFormatter, BSFormatter btcFormatter) { @@ -116,7 +116,7 @@ protected BaseProposalView(MyProposalService myProposalService, this.proposalService = proposalService; this.bsqWalletService = bsqWalletService; this.stateService = stateService; - this.daoParamService = daoParamService; + this.paramService = paramService; this.periodService = periodService; this.bsqFormatter = bsqFormatter; this.btcFormatter = btcFormatter; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index 4263b278567..ec505530f72 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -33,7 +33,7 @@ import bisq.core.btc.exceptions.WalletException; import bisq.core.btc.wallet.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.vote.proposal.param.DaoParamService; +import bisq.core.dao.vote.proposal.param.ParamService; import bisq.core.dao.state.StateService; import bisq.core.dao.vote.BooleanVote; import bisq.core.dao.vote.PeriodService; @@ -95,12 +95,12 @@ private ActiveProposalsView(MyProposalService myProposalService, BlindVoteService blindVoteService, BsqWalletService bsqWalletService, StateService stateService, - DaoParamService daoParamService, + ParamService paramService, BsqFormatter bsqFormatter, BSFormatter btcFormatter) { super(myProposalService, proposalListService, proposalService, bsqWalletService, stateService, - daoParamService, periodService, bsqFormatter, btcFormatter); + paramService, periodService, bsqFormatter, btcFormatter); this.blindVoteService = blindVoteService; } @@ -130,7 +130,7 @@ protected void activate() { voteButton.setOnAction(e -> { // TODO verify stake Coin stake = bsqFormatter.parseToCoin(stakeInputTextField.getText()); - final Coin fee = BlindVoteConsensus.getFee(daoParamService, stateService.getChainHeadHeight()); + final Coin fee = BlindVoteConsensus.getFee(paramService, stateService.getChainHeadHeight()); Transaction dummyTx = null; try { // We create a tx with dummy opreturn data to get the mining fee for confirmation popup diff --git a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java index 49839771825..386955241ad 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java @@ -23,7 +23,7 @@ import bisq.desktop.util.BsqFormatter; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.vote.proposal.param.DaoParamService; +import bisq.core.dao.vote.proposal.param.ParamService; import bisq.core.dao.state.StateService; import bisq.core.dao.vote.PeriodService; import bisq.core.dao.vote.proposal.MyProposalService; @@ -46,12 +46,12 @@ private ClosedProposalsView(MyProposalService myProposalService, PeriodService periodService, BsqWalletService bsqWalletService, StateService stateService, - DaoParamService daoParamService, + ParamService paramService, BsqFormatter bsqFormatter, BSFormatter btcFormatter) { super(myProposalService, proposalListService, proposalService, bsqWalletService, stateService, - daoParamService, periodService, bsqFormatter, btcFormatter); + paramService, periodService, bsqFormatter, btcFormatter); } @Override diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index 59a07b0d277..b313cfaeea9 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -31,7 +31,7 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.InsufficientBsqException; import bisq.core.btc.wallet.WalletsSetup; -import bisq.core.dao.vote.proposal.param.DaoParamService; +import bisq.core.dao.vote.proposal.param.ParamService; import bisq.core.dao.state.StateService; import bisq.core.dao.vote.proposal.MyProposalService; import bisq.core.dao.vote.proposal.Proposal; @@ -89,7 +89,7 @@ public class MakeProposalView extends ActivatableView { private final CompensationRequestService compensationRequestService; private final GenericProposalService genericProposalService; private final StateService stateService; - private final DaoParamService daoParamService; + private final ParamService paramService; private final BSFormatter btcFormatter; private final BsqFormatter bsqFormatter; private ComboBox proposalTypeComboBox; @@ -110,7 +110,7 @@ private MakeProposalView(BsqWalletService bsqWalletService, CompensationRequestService compensationRequestService, GenericProposalService genericProposalService, StateService stateService, - DaoParamService daoParamService, + ParamService paramService, BSFormatter btcFormatter, BsqFormatter bsqFormatter) { this.bsqWalletService = bsqWalletService; @@ -121,7 +121,7 @@ private MakeProposalView(BsqWalletService bsqWalletService, this.compensationRequestService = compensationRequestService; this.genericProposalService = genericProposalService; this.stateService = stateService; - this.daoParamService = daoParamService; + this.paramService = paramService; this.btcFormatter = btcFormatter; this.bsqFormatter = bsqFormatter; } @@ -174,7 +174,7 @@ private void publishProposal(ProposalType type) { Coin miningFee = Objects.requireNonNull(tx).getFee(); int txSize = tx.bitcoinSerialize().length; - final Coin fee = ProposalConsensus.getFee(daoParamService, stateService.getChainHeadHeight()); + final Coin fee = ProposalConsensus.getFee(paramService, stateService.getChainHeadHeight()); GUIUtil.showBsqFeeInfoPopup(fee, miningFee, txSize, bsqFormatter, btcFormatter, Res.get("dao.proposal"), () -> publishProposal(proposal)); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java index 902caa032d1..77be838556e 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java @@ -30,7 +30,7 @@ import bisq.desktop.util.Layout; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.vote.proposal.param.DaoParamService; +import bisq.core.dao.vote.proposal.param.ParamService; import bisq.core.dao.state.StateService; import bisq.core.dao.vote.BooleanVote; import bisq.core.dao.vote.PeriodService; @@ -96,14 +96,14 @@ private MyVotesView(MyProposalService myProposalService, PeriodService periodService, BsqWalletService bsqWalletService, StateService stateService, - DaoParamService daoParamService, + ParamService paramService, BsqFormatter bsqFormatter, BSFormatter btcFormatter, MyVoteService myVoteService, Preferences preferences) { super(myProposalService, proposalListService, proposalService, bsqWalletService, stateService, - daoParamService, periodService, bsqFormatter, btcFormatter); + paramService, periodService, bsqFormatter, btcFormatter); this.myVoteService = myVoteService; this.preferences = preferences; } From 3b4b9ebc5444729b2a1672b237376581e195db82 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Fri, 13 Apr 2018 13:48:20 -0500 Subject: [PATCH 030/197] Make ProposalPayload immutable. Remove transaction from Proposal. --- .../main/dao/proposal/make/MakeProposalView.java | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index b313cfaeea9..d161b0af5cb 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -31,17 +31,15 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.InsufficientBsqException; import bisq.core.btc.wallet.WalletsSetup; -import bisq.core.dao.vote.proposal.param.ParamService; import bisq.core.dao.state.StateService; import bisq.core.dao.vote.proposal.MyProposalService; import bisq.core.dao.vote.proposal.Proposal; import bisq.core.dao.vote.proposal.ProposalConsensus; import bisq.core.dao.vote.proposal.ProposalType; import bisq.core.dao.vote.proposal.ValidationException; -import bisq.core.dao.vote.proposal.compensation.CompensationRequestPayload; import bisq.core.dao.vote.proposal.compensation.CompensationRequestService; -import bisq.core.dao.vote.proposal.generic.GenericProposalPayload; import bisq.core.dao.vote.proposal.generic.GenericProposalService; +import bisq.core.dao.vote.proposal.param.ParamService; import bisq.core.locale.Res; import bisq.core.provider.fee.FeeService; @@ -170,7 +168,9 @@ protected void deactivate() { private void publishProposal(ProposalType type) { try { Proposal proposal = createProposal(type); - Transaction tx = Objects.requireNonNull(proposal).getTx(); + final String txId = Objects.requireNonNull(proposal).getTxId(); + Transaction tx = Objects.requireNonNull(bsqWalletService.getTransaction(txId)); + Coin miningFee = Objects.requireNonNull(tx).getFee(); int txSize = tx.bitcoinSerialize().length; @@ -217,21 +217,18 @@ private Proposal createProposal(ProposalType type) switch (type) { case COMPENSATION_REQUEST: - CompensationRequestPayload compensationRequestPayload = compensationRequestService.createCompensationRequestPayload( - proposalDisplay.nameTextField.getText(), + return compensationRequestService.makeTxAndGetCompensationRequest(proposalDisplay.nameTextField.getText(), proposalDisplay.titleTextField.getText(), proposalDisplay.descriptionTextArea.getText(), proposalDisplay.linkInputTextField.getText(), bsqFormatter.parseToCoin(Objects.requireNonNull(proposalDisplay.requestedBsqTextField).getText()), Objects.requireNonNull(proposalDisplay.bsqAddressTextField).getText()); - return compensationRequestService.createCompensationRequest(compensationRequestPayload); case GENERIC: - GenericProposalPayload genericProposalPayload = genericProposalService.createGenericProposalPayload( + return genericProposalService.makeTxAndGetGenericProposal( proposalDisplay.nameTextField.getText(), proposalDisplay.titleTextField.getText(), proposalDisplay.descriptionTextArea.getText(), proposalDisplay.linkInputTextField.getText()); - return genericProposalService.createGenericProposal(genericProposalPayload); case CHANGE_PARAM: //TODO return null; From b307cad2619900db970ea84ec7a9169d555fd157 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Fri, 13 Apr 2018 15:04:48 -0500 Subject: [PATCH 031/197] Pass Transaction at creating proposal instead of lookup in wallet --- .../dao/proposal/make/MakeProposalView.java | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index d161b0af5cb..22849d02abf 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -45,7 +45,7 @@ import bisq.network.p2p.P2PService; -import bisq.common.app.DevEnv; +import bisq.common.util.Tuple2; import org.bitcoinj.core.Coin; import org.bitcoinj.core.InsufficientMoneyException; @@ -167,17 +167,15 @@ protected void deactivate() { private void publishProposal(ProposalType type) { try { - Proposal proposal = createProposal(type); - final String txId = Objects.requireNonNull(proposal).getTxId(); - Transaction tx = Objects.requireNonNull(bsqWalletService.getTransaction(txId)); - - Coin miningFee = Objects.requireNonNull(tx).getFee(); - int txSize = tx.bitcoinSerialize().length; - + final Tuple2 tuple2 = createProposal(type); + Proposal proposal = tuple2.first; + Transaction transaction = tuple2.second; + Coin miningFee = transaction.getFee(); + int txSize = transaction.bitcoinSerialize().length; final Coin fee = ProposalConsensus.getFee(paramService, stateService.getChainHeadHeight()); GUIUtil.showBsqFeeInfoPopup(fee, miningFee, txSize, bsqFormatter, btcFormatter, - Res.get("dao.proposal"), () -> publishProposal(proposal)); + Res.get("dao.proposal"), () -> publishProposal(proposal, transaction)); } catch (InsufficientMoneyException e) { BSFormatter formatter = e instanceof InsufficientBsqException ? bsqFormatter : btcFormatter; @@ -199,8 +197,9 @@ private void publishProposal(ProposalType type) { } } - private void publishProposal(Proposal proposal) { + private void publishProposal(Proposal proposal, Transaction transaction) { myProposalService.publishProposal(proposal, + transaction, () -> { proposalDisplay.clearForm(); proposalTypeComboBox.getSelectionModel().clearSelection(); @@ -209,7 +208,7 @@ private void publishProposal(Proposal proposal) { errorMessage -> new Popup<>().warning(errorMessage).show()); } - private Proposal createProposal(ProposalType type) + private Tuple2 createProposal(ProposalType type) throws InsufficientMoneyException, TransactionVerificationException, ValidationException, WalletException, IOException { @@ -231,14 +230,14 @@ private Proposal createProposal(ProposalType type) proposalDisplay.linkInputTextField.getText()); case CHANGE_PARAM: //TODO - return null; + throw new RuntimeException("Not implemented yet"); case REMOVE_ALTCOIN: //TODO - return null; + throw new RuntimeException("Not implemented yet"); default: final String msg = "Undefined ProposalType " + selectedProposalType; - DevEnv.logErrorAndThrowIfDevMode(msg); - return null; + log.error(msg); + throw new RuntimeException(msg); } } From c279beec3075af9c0b4e26df6be1d8c53f6039f8 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Fri, 13 Apr 2018 19:53:33 -0500 Subject: [PATCH 032/197] Refactor BlindVoteService to be executed on parser thread only --- .../dao/proposal/active/ActiveProposalsView.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index ec505530f72..600d86c5deb 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -33,16 +33,16 @@ import bisq.core.btc.exceptions.WalletException; import bisq.core.btc.wallet.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.vote.proposal.param.ParamService; import bisq.core.dao.state.StateService; import bisq.core.dao.vote.BooleanVote; import bisq.core.dao.vote.PeriodService; import bisq.core.dao.vote.blindvote.BlindVoteConsensus; -import bisq.core.dao.vote.blindvote.BlindVoteService; +import bisq.core.dao.vote.myvote.MyVoteService; import bisq.core.dao.vote.proposal.MyProposalService; import bisq.core.dao.vote.proposal.Proposal; import bisq.core.dao.vote.proposal.ProposalListService; import bisq.core.dao.vote.proposal.ProposalService; +import bisq.core.dao.vote.proposal.param.ParamService; import bisq.core.locale.Res; import bisq.common.util.Tuple2; @@ -74,7 +74,7 @@ @FxmlView public class ActiveProposalsView extends BaseProposalView implements BsqBalanceListener { - private final BlindVoteService blindVoteService; + private final MyVoteService myVoteService; private Button removeButton, acceptButton, rejectButton, cancelVoteButton, voteButton; private InputTextField stakeInputTextField; @@ -92,7 +92,7 @@ private ActiveProposalsView(MyProposalService myProposalService, ProposalListService proposalListService, ProposalService proposalService, PeriodService periodService, - BlindVoteService blindVoteService, + MyVoteService myVoteService, BsqWalletService bsqWalletService, StateService stateService, ParamService paramService, @@ -101,7 +101,7 @@ private ActiveProposalsView(MyProposalService myProposalService, super(myProposalService, proposalListService, proposalService, bsqWalletService, stateService, paramService, periodService, bsqFormatter, btcFormatter); - this.blindVoteService = blindVoteService; + this.myVoteService = myVoteService; } @Override @@ -134,7 +134,7 @@ protected void activate() { Transaction dummyTx = null; try { // We create a tx with dummy opreturn data to get the mining fee for confirmation popup - dummyTx = blindVoteService.getBlindVoteTx(stake, fee, new byte[22]); + dummyTx = myVoteService.getBlindVoteTx(stake, fee, new byte[22]); } catch (InsufficientMoneyException | WalletException | TransactionVerificationException exception) { new Popup<>().warning(exception.toString()).show(); } @@ -152,7 +152,7 @@ protected void activate() { private void publishBlindVote(Coin stake) { voteButtonBusyAnimation.play(); voteButtonInfoLabel.setText(Res.get("dao.blindVote.startPublishing")); - blindVoteService.publishBlindVote(stake, + myVoteService.publishBlindVote(stake, () -> { voteButtonBusyAnimation.stop(); voteButtonInfoLabel.setText(""); From a0c2341babed958a1a2c9e019125a894a9b327fa Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Fri, 13 Apr 2018 20:54:57 -0500 Subject: [PATCH 033/197] FIx threading and persistence issue - Remove nodeExecutor.execute in stateService when processing the stateChangeEventsProviders to avoid delayed execution - Comment out removal of local lists as we have the state not persisted yet - Fix wrong phase check in BlindVoteService - Rename getChainHeadHeight to getHeadHeight --- .../java/bisq/desktop/main/dao/proposal/ProposalListItem.java | 2 +- .../desktop/main/dao/proposal/active/ActiveProposalsView.java | 4 ++-- .../bisq/desktop/main/dao/proposal/make/MakeProposalView.java | 2 +- src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index c834dcee3af..829b66994a2 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -126,7 +126,7 @@ public void applyState(PeriodService.Phase newValue, Vote vote) { actionButton.setVisible(false); actionButton.setOnAction(null); final boolean isTxInPastCycle = periodService.isTxInPastCycle(proposal.getTxId(), - stateService.getChainHeadHeight()); + stateService.getChainHeight()); switch (newValue) { case UNDEFINED: break; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index 600d86c5deb..e01ffadcdbd 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -130,7 +130,7 @@ protected void activate() { voteButton.setOnAction(e -> { // TODO verify stake Coin stake = bsqFormatter.parseToCoin(stakeInputTextField.getText()); - final Coin fee = BlindVoteConsensus.getFee(paramService, stateService.getChainHeadHeight()); + final Coin fee = BlindVoteConsensus.getFee(paramService, stateService.getChainHeight()); Transaction dummyTx = null; try { // We create a tx with dummy opreturn data to get the mining fee for confirmation popup @@ -270,7 +270,7 @@ protected void onPhaseChanged(PeriodService.Phase phase) { if (selectedProposalListItem != null && proposalDisplay != null && !periodService.isTxInPastCycle(selectedProposalListItem.getProposal().getTxId(), - stateService.getChainHeadHeight())) { + stateService.getChainHeight())) { final Proposal proposal = selectedProposalListItem.getProposal(); switch (phase) { case PROPOSAL: diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index 22849d02abf..4202c92ec0a 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -172,7 +172,7 @@ private void publishProposal(ProposalType type) { Transaction transaction = tuple2.second; Coin miningFee = transaction.getFee(); int txSize = transaction.bitcoinSerialize().length; - final Coin fee = ProposalConsensus.getFee(paramService, stateService.getChainHeadHeight()); + final Coin fee = ProposalConsensus.getFee(paramService, stateService.getChainHeight()); GUIUtil.showBsqFeeInfoPopup(fee, miningFee, txSize, bsqFormatter, btcFormatter, Res.get("dao.proposal"), () -> publishProposal(proposal, transaction)); diff --git a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java index 762e2dc4654..0a8eb859456 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java @@ -224,7 +224,7 @@ public void onBlockAdded(Block block) { private void onChainHeightChanged() { final int bsqWalletChainHeight = bsqWalletService.getChainHeightProperty().get(); - final int bsqBlockChainHeight = stateService.getChainHeadHeight(); + final int bsqBlockChainHeight = stateService.getChainHeight(); if (bsqWalletChainHeight > 0) { final boolean synced = bsqWalletChainHeight == bsqBlockChainHeight; chainSyncIndicator.setVisible(!synced); From 52c9a184117d72451e78839017a8ae655349478c Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sat, 14 Apr 2018 23:25:52 -0500 Subject: [PATCH 034/197] Use params for period service - Set initial durations at genesis height with default values of params - Update durations when a changeParamEvent triggers a change - Add Cycle class - Add threadsafe wrapper - Update UI period component --- .../components/SeparatedPhaseBars.java | 36 ++++---- .../main/dao/proposal/BaseProposalView.java | 15 +-- .../main/dao/proposal/ProposalListItem.java | 11 ++- .../proposal/active/ActiveProposalsView.java | 9 +- .../proposal/closed/ClosedProposalsView.java | 6 +- .../dashboard/ProposalDashboardView.java | 91 ++++++++++--------- .../dao/proposal/myvotes/MyVotesView.java | 6 +- 7 files changed, 93 insertions(+), 81 deletions(-) diff --git a/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java b/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java index e68b155d851..07516936f9f 100644 --- a/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java +++ b/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java @@ -17,7 +17,7 @@ package bisq.desktop.components; -import bisq.core.dao.vote.PeriodService; +import bisq.core.dao.vote.Phase; import bisq.core.locale.Res; import bisq.common.UserThread; @@ -55,12 +55,12 @@ public SeparatedPhaseBars(List items) { addLabels(); - items.stream().forEach(item -> { + items.forEach(item -> { Label titleLabel = new Label(Res.get("dao.phase.short." + item.phase)); item.setTitleLabel(titleLabel); Label startLabel = new Label(); - item.startValueProperty.addListener((observable, oldValue, newValue) -> { + item.startBlockProperty.addListener((observable, oldValue, newValue) -> { startLabel.setText(String.valueOf((int) newValue)); }); startLabel.setVisible(item.isShowBlocks()); @@ -69,7 +69,7 @@ public SeparatedPhaseBars(List items) { startLabelPane.getChildren().add(startLabel); Label endLabel = new Label(); - item.endValueProperty.addListener((observable, oldValue, newValue) -> { + item.lastBlockProperty.addListener((observable, oldValue, newValue) -> { endLabel.setText(String.valueOf((int) newValue)); }); endLabel.setVisible(item.isShowBlocks()); @@ -94,9 +94,13 @@ public SeparatedPhaseBars(List items) { }); widthProperty().addListener((observable, oldValue, newValue) -> { - adjustWidth((double) newValue); + updateWidth((double) newValue); }); - UserThread.execute(() -> adjustWidth(getWidth())); + UserThread.execute(() -> updateWidth(getWidth())); + } + + public void updateWidth() { + updateWidth(getWidth()); } private void addLabels() { @@ -125,12 +129,12 @@ private void addLabels() { getChildren().add(vBoxLabels); } - private void adjustWidth(double availableWidth) { + private void updateWidth(double availableWidth) { totalDuration = items.stream().mapToInt(SeparatedPhaseBarsItem::getDuration).sum(); availableWidth -= vBoxLabels.getWidth(); if (availableWidth > 0 && totalDuration > 0) { final double finalAvailableWidth = availableWidth; - items.stream().forEach(item -> { + items.forEach(item -> { final double width = (double) item.duration / (double) totalDuration * finalAvailableWidth; item.getVBox().setPrefWidth(width); }); @@ -139,10 +143,10 @@ private void adjustWidth(double availableWidth) { @Getter public static class SeparatedPhaseBarsItem { - private final PeriodService.Phase phase; + private final Phase phase; private final boolean showBlocks; - private final IntegerProperty startValueProperty = new SimpleIntegerProperty(); - private final IntegerProperty endValueProperty = new SimpleIntegerProperty(); + private final IntegerProperty startBlockProperty = new SimpleIntegerProperty(); + private final IntegerProperty lastBlockProperty = new SimpleIntegerProperty(); private final DoubleProperty progressProperty = new SimpleDoubleProperty(); private int duration; @Setter @@ -150,7 +154,7 @@ public static class SeparatedPhaseBarsItem { @Setter private Label titleLabel; - public SeparatedPhaseBarsItem(PeriodService.Phase phase, boolean showBlocks) { + public SeparatedPhaseBarsItem(Phase phase, boolean showBlocks) { this.phase = phase; this.showBlocks = showBlocks; } @@ -163,10 +167,10 @@ public void setActive() { titleLabel.setStyle("-fx-text-fill: -fx-accent;"); } - public void setStartAndEnd(int startBlock, int endBlock) { - startValueProperty.set(startBlock); - endValueProperty.set(endBlock); - duration = endValueProperty.get() - startValueProperty.get() + 1; + public void setPeriodRange(int firstBlock, int lastBlock, int duration) { + startBlockProperty.set(firstBlock); + lastBlockProperty.set(lastBlock); + this.duration = duration; } } } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java index 33c97e9d912..6297ca8bd66 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java @@ -27,14 +27,15 @@ import bisq.desktop.util.BsqFormatter; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.vote.proposal.param.ParamService; import bisq.core.dao.state.StateService; -import bisq.core.dao.vote.PeriodService; +import bisq.core.dao.vote.Phase; +import bisq.core.dao.vote.ThreadSafePeriodService; import bisq.core.dao.vote.proposal.MyProposalService; import bisq.core.dao.vote.proposal.Proposal; import bisq.core.dao.vote.proposal.ProposalListService; import bisq.core.dao.vote.proposal.ProposalPayload; import bisq.core.dao.vote.proposal.ProposalService; +import bisq.core.dao.vote.proposal.param.ParamService; import bisq.core.locale.Res; import javax.inject.Inject; @@ -90,9 +91,9 @@ public abstract class BaseProposalView extends ActivatableView { protected GridPane detailsGridPane, gridPane; protected ProposalListItem selectedProposalListItem; protected ListChangeListener proposalListChangeListener; - protected ChangeListener phaseChangeListener; - protected final PeriodService periodService; - protected PeriodService.Phase currentPhase; + protected ChangeListener phaseChangeListener; + protected final ThreadSafePeriodService periodService; + protected Phase currentPhase; protected Subscription phaseSubscription; private ScrollPane proposalDisplayView; @@ -108,7 +109,7 @@ protected BaseProposalView(MyProposalService myProposalService, BsqWalletService bsqWalletService, StateService stateService, ParamService paramService, - PeriodService periodService, + ThreadSafePeriodService periodService, BsqFormatter bsqFormatter, BSFormatter btcFormatter) { this.myProposalService = myProposalService; @@ -233,7 +234,7 @@ protected void onSelectProposal(ProposalListItem item) { hideProposalDisplay(); } - protected void onPhaseChanged(PeriodService.Phase phase) { + protected void onPhaseChanged(Phase phase) { if (!phase.equals(this.currentPhase)) { this.currentPhase = phase; onSelectProposal(selectedProposalListItem); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index 829b66994a2..831af8bb03b 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -27,7 +27,8 @@ import bisq.core.dao.state.StateService; import bisq.core.dao.state.blockchain.Tx; import bisq.core.dao.vote.BooleanVote; -import bisq.core.dao.vote.PeriodService; +import bisq.core.dao.vote.Phase; +import bisq.core.dao.vote.ThreadSafePeriodService; import bisq.core.dao.vote.Vote; import bisq.core.dao.vote.proposal.Proposal; import bisq.core.dao.vote.proposal.ProposalService; @@ -57,7 +58,7 @@ public class ProposalListItem implements StateService.BlockListener { @Getter private final Proposal proposal; private final ProposalService proposalService; - private final PeriodService periodService; + private final ThreadSafePeriodService periodService; private final BsqWalletService bsqWalletService; private final StateService stateService; private final BsqFormatter bsqFormatter; @@ -71,7 +72,7 @@ public class ProposalListItem implements StateService.BlockListener { private TxConfidenceListener txConfidenceListener; private Tooltip tooltip = new Tooltip(Res.get("confidence.unknown")); private Transaction walletTransaction; - private ChangeListener phaseChangeListener; + private ChangeListener phaseChangeListener; private AutoTooltipButton actionButton; private ImageView actionButtonIconView; @Setter @@ -80,7 +81,7 @@ public class ProposalListItem implements StateService.BlockListener { ProposalListItem(Proposal proposal, ProposalService proposalService, - PeriodService periodService, + ThreadSafePeriodService periodService, BsqWalletService bsqWalletService, StateService stateService, BsqFormatter bsqFormatter) { @@ -121,7 +122,7 @@ public class ProposalListItem implements StateService.BlockListener { proposal.getVoteResultProperty().addListener(voteResultChangeListener); } - public void applyState(PeriodService.Phase newValue, Vote vote) { + public void applyState(Phase newValue, Vote vote) { actionButton.setText(""); actionButton.setVisible(false); actionButton.setOnAction(null); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index e01ffadcdbd..36c1751c4be 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -35,7 +35,8 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.state.StateService; import bisq.core.dao.vote.BooleanVote; -import bisq.core.dao.vote.PeriodService; +import bisq.core.dao.vote.Phase; +import bisq.core.dao.vote.ThreadSafePeriodService; import bisq.core.dao.vote.blindvote.BlindVoteConsensus; import bisq.core.dao.vote.myvote.MyVoteService; import bisq.core.dao.vote.proposal.MyProposalService; @@ -91,7 +92,7 @@ public class ActiveProposalsView extends BaseProposalView implements BsqBalanceL private ActiveProposalsView(MyProposalService myProposalService, ProposalListService proposalListService, ProposalService proposalService, - PeriodService periodService, + ThreadSafePeriodService periodService, MyVoteService myVoteService, BsqWalletService bsqWalletService, StateService stateService, @@ -257,10 +258,10 @@ private void onCancelVote() { } @Override - protected void onPhaseChanged(PeriodService.Phase phase) { + protected void onPhaseChanged(Phase phase) { super.onPhaseChanged(phase); - changeVoteViewItemsVisibility(phase == PeriodService.Phase.BLIND_VOTE); + changeVoteViewItemsVisibility(phase == Phase.BLIND_VOTE); if (removeButton != null) { removeButton.setManaged(false); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java index 386955241ad..3faf28973a0 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java @@ -23,12 +23,12 @@ import bisq.desktop.util.BsqFormatter; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.vote.proposal.param.ParamService; import bisq.core.dao.state.StateService; -import bisq.core.dao.vote.PeriodService; +import bisq.core.dao.vote.ThreadSafePeriodService; import bisq.core.dao.vote.proposal.MyProposalService; import bisq.core.dao.vote.proposal.ProposalListService; import bisq.core.dao.vote.proposal.ProposalService; +import bisq.core.dao.vote.proposal.param.ParamService; import javax.inject.Inject; @@ -43,7 +43,7 @@ public class ClosedProposalsView extends BaseProposalView { private ClosedProposalsView(MyProposalService myProposalService, ProposalListService proposalListService, ProposalService proposalService, - PeriodService periodService, + ThreadSafePeriodService periodService, BsqWalletService bsqWalletService, StateService stateService, ParamService paramService, diff --git a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java index 197be5c2535..51f3da1276f 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java @@ -22,8 +22,10 @@ import bisq.desktop.components.SeparatedPhaseBars; import bisq.desktop.util.Layout; -import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.vote.PeriodService; +import bisq.core.dao.state.Block; +import bisq.core.dao.state.StateService; +import bisq.core.dao.vote.Phase; +import bisq.core.dao.vote.ThreadSafePeriodService; import bisq.core.locale.Res; import javax.inject.Inject; @@ -36,24 +38,22 @@ import org.fxmisc.easybind.EasyBind; import org.fxmisc.easybind.Subscription; -import javafx.beans.value.ChangeListener; - import java.util.Arrays; import java.util.List; import static bisq.desktop.util.FormBuilder.addTitledGroupBg; @FxmlView -public class ProposalDashboardView extends ActivatableView { +public class ProposalDashboardView extends ActivatableView implements StateService.BlockListener { private List phaseBarsItems; - private final BsqWalletService bsqWalletService; - private final PeriodService periodService; - private PeriodService.Phase currentPhase; + private final ThreadSafePeriodService periodService; + private final StateService stateService; + private Phase currentPhase; private Subscription phaseSubscription; private GridPane gridPane; private int gridRow = 0; - private ChangeListener chainHeightChangeListener; + private SeparatedPhaseBars separatedPhaseBars; /////////////////////////////////////////////////////////////////////////////////////////// @@ -61,10 +61,9 @@ public class ProposalDashboardView extends ActivatableView { /////////////////////////////////////////////////////////////////////////////////////////// @Inject - private ProposalDashboardView(PeriodService periodService, - BsqWalletService bsqWalletService) { + private ProposalDashboardView(ThreadSafePeriodService periodService, StateService stateService) { this.periodService = periodService; - this.bsqWalletService = bsqWalletService; + this.stateService = stateService; } @Override @@ -84,27 +83,25 @@ public void initialize() { // Add phase info addTitledGroupBg(gridPane, gridRow, 1, Res.get("dao.proposal.active.phase.header")); - SeparatedPhaseBars separatedPhaseBars = createSeparatedPhaseBars(); + separatedPhaseBars = createSeparatedPhaseBars(); GridPane.setColumnSpan(separatedPhaseBars, 2); GridPane.setColumnIndex(separatedPhaseBars, 0); GridPane.setMargin(separatedPhaseBars, new Insets(Layout.FIRST_ROW_DISTANCE - 6, 0, 0, 0)); GridPane.setRowIndex(separatedPhaseBars, gridRow); gridPane.getChildren().add(separatedPhaseBars); - - chainHeightChangeListener = (observable, oldValue, newValue) -> onChainHeightChanged((int) newValue); } private SeparatedPhaseBars createSeparatedPhaseBars() { phaseBarsItems = Arrays.asList( - new SeparatedPhaseBars.SeparatedPhaseBarsItem(PeriodService.Phase.PROPOSAL, true), - new SeparatedPhaseBars.SeparatedPhaseBarsItem(PeriodService.Phase.BREAK1, false), - new SeparatedPhaseBars.SeparatedPhaseBarsItem(PeriodService.Phase.BLIND_VOTE, true), - new SeparatedPhaseBars.SeparatedPhaseBarsItem(PeriodService.Phase.BREAK2, false), - new SeparatedPhaseBars.SeparatedPhaseBarsItem(PeriodService.Phase.VOTE_REVEAL, true), - new SeparatedPhaseBars.SeparatedPhaseBarsItem(PeriodService.Phase.BREAK3, false), - new SeparatedPhaseBars.SeparatedPhaseBarsItem(PeriodService.Phase.ISSUANCE, false), - new SeparatedPhaseBars.SeparatedPhaseBarsItem(PeriodService.Phase.BREAK4, false)); + new SeparatedPhaseBars.SeparatedPhaseBarsItem(Phase.PROPOSAL, true), + new SeparatedPhaseBars.SeparatedPhaseBarsItem(Phase.BREAK1, false), + new SeparatedPhaseBars.SeparatedPhaseBarsItem(Phase.BLIND_VOTE, true), + new SeparatedPhaseBars.SeparatedPhaseBarsItem(Phase.BREAK2, false), + new SeparatedPhaseBars.SeparatedPhaseBarsItem(Phase.VOTE_REVEAL, true), + new SeparatedPhaseBars.SeparatedPhaseBarsItem(Phase.BREAK3, false), + new SeparatedPhaseBars.SeparatedPhaseBarsItem(Phase.ISSUANCE, false), + new SeparatedPhaseBars.SeparatedPhaseBarsItem(Phase.BREAK4, false)); return new SeparatedPhaseBars(phaseBarsItems); } @@ -112,8 +109,6 @@ private SeparatedPhaseBars createSeparatedPhaseBars() { protected void activate() { super.activate(); - bsqWalletService.getChainHeightProperty().addListener(chainHeightChangeListener); - phaseSubscription = EasyBind.subscribe(periodService.getPhaseProperty(), phase -> { if (!phase.equals(this.currentPhase)) { this.currentPhase = phase; @@ -125,34 +120,44 @@ protected void activate() { item.setInActive(); } }); - }); - onChainHeightChanged(bsqWalletService.getChainHeightProperty().get()); + }); + stateService.addBlockListener(this); + onChainHeightChanged(periodService.getChainHeight()); } @Override protected void deactivate() { super.deactivate(); - - bsqWalletService.getChainHeightProperty().removeListener(chainHeightChangeListener); + stateService.removeBlockListener(this); phaseSubscription.unsubscribe(); } + @Override + public void onBlockAdded(Block block) { + onChainHeightChanged(block.getHeight()); + } private void onChainHeightChanged(int height) { - phaseBarsItems.forEach(item -> { - int startBlock = periodService.getAbsoluteStartBlockOfPhase(height, item.getPhase()); - int endBlock = periodService.getAbsoluteEndBlockOfPhase(height, item.getPhase()); - item.setStartAndEnd(startBlock, endBlock); - double progress = 0; - if (height >= startBlock && height <= endBlock) { - progress = (double) (height - startBlock + 1) / (double) item.getPhase().getDurationInBlocks(); - } else if (height < startBlock) { - progress = 0; - } else if (height > endBlock) { - progress = 1; - } - item.getProgressProperty().set(progress); - }); + if (height > 0) { + separatedPhaseBars.updateWidth(); + phaseBarsItems.forEach(item -> { + int firstBlock = periodService.getFirstBlockOfPhase(height, item.getPhase()); + int lastBlock = periodService.getLastBlockOfPhase(height, item.getPhase()); + final int duration = periodService.getDurationForPhase(item.getPhase(), periodService.getChainHeight()); + item.setPeriodRange(firstBlock, lastBlock, duration); + + double progress = 0; + if (height >= firstBlock && height <= lastBlock) { + progress = (double) (height - firstBlock + 1) / (double) duration; + } else if (height < firstBlock) { + progress = 0; + } else if (height > lastBlock) { + progress = 1; + } + item.getProgressProperty().set(progress); + }); + } } + } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java index 77be838556e..ad6d0cb5791 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java @@ -30,16 +30,16 @@ import bisq.desktop.util.Layout; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.vote.proposal.param.ParamService; import bisq.core.dao.state.StateService; import bisq.core.dao.vote.BooleanVote; -import bisq.core.dao.vote.PeriodService; +import bisq.core.dao.vote.ThreadSafePeriodService; import bisq.core.dao.vote.Vote; import bisq.core.dao.vote.myvote.MyVoteService; import bisq.core.dao.vote.proposal.MyProposalService; import bisq.core.dao.vote.proposal.ProposalList; import bisq.core.dao.vote.proposal.ProposalListService; import bisq.core.dao.vote.proposal.ProposalService; +import bisq.core.dao.vote.proposal.param.ParamService; import bisq.core.locale.Res; import bisq.core.user.Preferences; @@ -93,7 +93,7 @@ public class MyVotesView extends BaseProposalView { private MyVotesView(MyProposalService myProposalService, ProposalListService proposalListService, ProposalService proposalService, - PeriodService periodService, + ThreadSafePeriodService periodService, BsqWalletService bsqWalletService, StateService stateService, ParamService paramService, From 11f51357359a8f5b888fff0c161b318745ee945a Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sun, 15 Apr 2018 20:55:10 -0500 Subject: [PATCH 035/197] Refactor periodService - Move mutual state to PeriodState - Move stateless methods to BasePeriodService - Use provider methods for accessing the state - Use PeriodService for parser thread - Use UserThreadPeriodService for userThread - Use PhaseWrapper for holding enum and duration - Move classes to vote.period package --- .../desktop/components/SeparatedPhaseBars.java | 2 +- .../main/dao/proposal/BaseProposalView.java | 16 ++++++++-------- .../main/dao/proposal/ProposalListItem.java | 14 +++++++------- .../dao/proposal/active/ActiveProposalsView.java | 8 ++++---- .../dao/proposal/closed/ClosedProposalsView.java | 4 ++-- .../dashboard/ProposalDashboardView.java | 10 +++++----- .../main/dao/proposal/myvotes/MyVotesView.java | 4 ++-- 7 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java b/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java index 07516936f9f..323619452f9 100644 --- a/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java +++ b/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java @@ -17,7 +17,7 @@ package bisq.desktop.components; -import bisq.core.dao.vote.Phase; +import bisq.core.dao.vote.period.Phase; import bisq.core.locale.Res; import bisq.common.UserThread; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java index 6297ca8bd66..18427d9857f 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java @@ -28,8 +28,8 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.state.StateService; -import bisq.core.dao.vote.Phase; -import bisq.core.dao.vote.ThreadSafePeriodService; +import bisq.core.dao.vote.period.Phase; +import bisq.core.dao.vote.period.UserThreadPeriodService; import bisq.core.dao.vote.proposal.MyProposalService; import bisq.core.dao.vote.proposal.Proposal; import bisq.core.dao.vote.proposal.ProposalListService; @@ -92,7 +92,7 @@ public abstract class BaseProposalView extends ActivatableView { protected ProposalListItem selectedProposalListItem; protected ListChangeListener proposalListChangeListener; protected ChangeListener phaseChangeListener; - protected final ThreadSafePeriodService periodService; + protected final UserThreadPeriodService periodService; protected Phase currentPhase; protected Subscription phaseSubscription; private ScrollPane proposalDisplayView; @@ -109,7 +109,7 @@ protected BaseProposalView(MyProposalService myProposalService, BsqWalletService bsqWalletService, StateService stateService, ParamService paramService, - ThreadSafePeriodService periodService, + UserThreadPeriodService periodService, BsqFormatter bsqFormatter, BSFormatter btcFormatter) { this.myProposalService = myProposalService; @@ -136,12 +136,12 @@ public void initialize() { @Override protected void activate() { - phaseSubscription = EasyBind.subscribe(periodService.getPhaseProperty(), this::onPhaseChanged); + phaseSubscription = EasyBind.subscribe(periodService.phaseProperty(), this::onPhaseChanged); selectedProposalSubscription = EasyBind.subscribe(proposalTableView.getSelectionModel().selectedItemProperty(), this::onSelectProposal); - periodService.getPhaseProperty().addListener(phaseChangeListener); + periodService.phaseProperty().addListener(phaseChangeListener); - onPhaseChanged(periodService.getPhaseProperty().get()); + onPhaseChanged(periodService.phaseProperty().get()); sortedList.comparatorProperty().bind(proposalTableView.comparatorProperty()); @@ -153,7 +153,7 @@ protected void deactivate() { phaseSubscription.unsubscribe(); selectedProposalSubscription.unsubscribe(); - periodService.getPhaseProperty().removeListener(phaseChangeListener); + periodService.phaseProperty().removeListener(phaseChangeListener); sortedList.comparatorProperty().unbind(); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index 831af8bb03b..77204270480 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -27,9 +27,9 @@ import bisq.core.dao.state.StateService; import bisq.core.dao.state.blockchain.Tx; import bisq.core.dao.vote.BooleanVote; -import bisq.core.dao.vote.Phase; -import bisq.core.dao.vote.ThreadSafePeriodService; import bisq.core.dao.vote.Vote; +import bisq.core.dao.vote.period.Phase; +import bisq.core.dao.vote.period.UserThreadPeriodService; import bisq.core.dao.vote.proposal.Proposal; import bisq.core.dao.vote.proposal.ProposalService; import bisq.core.locale.Res; @@ -58,7 +58,7 @@ public class ProposalListItem implements StateService.BlockListener { @Getter private final Proposal proposal; private final ProposalService proposalService; - private final ThreadSafePeriodService periodService; + private final UserThreadPeriodService periodService; private final BsqWalletService bsqWalletService; private final StateService stateService; private final BsqFormatter bsqFormatter; @@ -81,7 +81,7 @@ public class ProposalListItem implements StateService.BlockListener { ProposalListItem(Proposal proposal, ProposalService proposalService, - ThreadSafePeriodService periodService, + UserThreadPeriodService periodService, BsqWalletService bsqWalletService, StateService stateService, BsqFormatter bsqFormatter) { @@ -115,10 +115,10 @@ public class ProposalListItem implements StateService.BlockListener { }; voteResultChangeListener = (observable, oldValue, newValue) -> { - applyState(periodService.getPhaseProperty().get(), newValue); + applyState(periodService.phaseProperty().get(), newValue); }; - periodService.getPhaseProperty().addListener(phaseChangeListener); + periodService.phaseProperty().addListener(phaseChangeListener); proposal.getVoteResultProperty().addListener(voteResultChangeListener); } @@ -247,7 +247,7 @@ public void cleanup() { if (txConfidenceListener != null) bsqWalletService.removeTxConfidenceListener(txConfidenceListener); - periodService.getPhaseProperty().removeListener(phaseChangeListener); + periodService.phaseProperty().removeListener(phaseChangeListener); proposal.getVoteResultProperty().removeListener(voteResultChangeListener); } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index 36c1751c4be..54f17e11fff 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -35,10 +35,10 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.state.StateService; import bisq.core.dao.vote.BooleanVote; -import bisq.core.dao.vote.Phase; -import bisq.core.dao.vote.ThreadSafePeriodService; import bisq.core.dao.vote.blindvote.BlindVoteConsensus; import bisq.core.dao.vote.myvote.MyVoteService; +import bisq.core.dao.vote.period.Phase; +import bisq.core.dao.vote.period.UserThreadPeriodService; import bisq.core.dao.vote.proposal.MyProposalService; import bisq.core.dao.vote.proposal.Proposal; import bisq.core.dao.vote.proposal.ProposalListService; @@ -92,7 +92,7 @@ public class ActiveProposalsView extends BaseProposalView implements BsqBalanceL private ActiveProposalsView(MyProposalService myProposalService, ProposalListService proposalListService, ProposalService proposalService, - ThreadSafePeriodService periodService, + UserThreadPeriodService periodService, MyVoteService myVoteService, BsqWalletService bsqWalletService, StateService stateService, @@ -238,7 +238,7 @@ protected void onSelectProposal(ProposalListItem item) { cancelVoteButton = null; } - onPhaseChanged(periodService.getPhaseProperty().get()); + onPhaseChanged(periodService.phaseProperty().get()); } } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java index 3faf28973a0..ddd91258a3c 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java @@ -24,7 +24,7 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.state.StateService; -import bisq.core.dao.vote.ThreadSafePeriodService; +import bisq.core.dao.vote.period.UserThreadPeriodService; import bisq.core.dao.vote.proposal.MyProposalService; import bisq.core.dao.vote.proposal.ProposalListService; import bisq.core.dao.vote.proposal.ProposalService; @@ -43,7 +43,7 @@ public class ClosedProposalsView extends BaseProposalView { private ClosedProposalsView(MyProposalService myProposalService, ProposalListService proposalListService, ProposalService proposalService, - ThreadSafePeriodService periodService, + UserThreadPeriodService periodService, BsqWalletService bsqWalletService, StateService stateService, ParamService paramService, diff --git a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java index 51f3da1276f..5897d29c475 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java @@ -24,8 +24,8 @@ import bisq.core.dao.state.Block; import bisq.core.dao.state.StateService; -import bisq.core.dao.vote.Phase; -import bisq.core.dao.vote.ThreadSafePeriodService; +import bisq.core.dao.vote.period.Phase; +import bisq.core.dao.vote.period.UserThreadPeriodService; import bisq.core.locale.Res; import javax.inject.Inject; @@ -47,7 +47,7 @@ public class ProposalDashboardView extends ActivatableView implements StateService.BlockListener { private List phaseBarsItems; - private final ThreadSafePeriodService periodService; + private final UserThreadPeriodService periodService; private final StateService stateService; private Phase currentPhase; private Subscription phaseSubscription; @@ -61,7 +61,7 @@ public class ProposalDashboardView extends ActivatableView imple /////////////////////////////////////////////////////////////////////////////////////////// @Inject - private ProposalDashboardView(ThreadSafePeriodService periodService, StateService stateService) { + private ProposalDashboardView(UserThreadPeriodService periodService, StateService stateService) { this.periodService = periodService; this.stateService = stateService; } @@ -109,7 +109,7 @@ private SeparatedPhaseBars createSeparatedPhaseBars() { protected void activate() { super.activate(); - phaseSubscription = EasyBind.subscribe(periodService.getPhaseProperty(), phase -> { + phaseSubscription = EasyBind.subscribe(periodService.phaseProperty(), phase -> { if (!phase.equals(this.currentPhase)) { this.currentPhase = phase; } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java index ad6d0cb5791..677324dbeda 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java @@ -32,9 +32,9 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.state.StateService; import bisq.core.dao.vote.BooleanVote; -import bisq.core.dao.vote.ThreadSafePeriodService; import bisq.core.dao.vote.Vote; import bisq.core.dao.vote.myvote.MyVoteService; +import bisq.core.dao.vote.period.UserThreadPeriodService; import bisq.core.dao.vote.proposal.MyProposalService; import bisq.core.dao.vote.proposal.ProposalList; import bisq.core.dao.vote.proposal.ProposalListService; @@ -93,7 +93,7 @@ public class MyVotesView extends BaseProposalView { private MyVotesView(MyProposalService myProposalService, ProposalListService proposalListService, ProposalService proposalService, - ThreadSafePeriodService periodService, + UserThreadPeriodService periodService, BsqWalletService bsqWalletService, StateService stateService, ParamService paramService, From eae31eff38f15b16f2e56971fe8ca6a1dfb73424 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Mon, 16 Apr 2018 22:38:26 -0500 Subject: [PATCH 036/197] Refactor state - Break up state and stateService - Add UserThreadStateService for access from user thread - Map state changes to UserThreadStateService - Add execute method to ThreadAwareListener --- .../main/dao/proposal/BaseProposalView.java | 6 ++--- .../main/dao/proposal/ProposalListItem.java | 11 +++++---- .../proposal/active/ActiveProposalsView.java | 4 ++-- .../proposal/closed/ClosedProposalsView.java | 4 ++-- .../dashboard/ProposalDashboardView.java | 9 ++++---- .../dao/proposal/make/MakeProposalView.java | 6 ++--- .../dao/proposal/myvotes/MyVotesView.java | 4 ++-- .../dao/proposal/myvotes/VoteListItem.java | 11 +++++---- .../wallet/dashboard/BsqDashboardView.java | 23 ++++++++++--------- .../main/dao/wallet/tx/BsqTxListItem.java | 6 ++--- .../desktop/main/dao/wallet/tx/BsqTxView.java | 11 +++++---- .../TransactionListItemFactory.java | 6 ++--- .../transactions/TransactionsListItem.java | 4 ++-- 13 files changed, 55 insertions(+), 50 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java index 18427d9857f..7b1b2bb7fcf 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java @@ -27,7 +27,7 @@ import bisq.desktop.util.BsqFormatter; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.state.StateService; +import bisq.core.dao.state.UserThreadStateService; import bisq.core.dao.vote.period.Phase; import bisq.core.dao.vote.period.UserThreadPeriodService; import bisq.core.dao.vote.proposal.MyProposalService; @@ -73,7 +73,7 @@ public abstract class BaseProposalView extends ActivatableView { protected final MyProposalService myProposalService; - protected final StateService stateService; + protected final UserThreadStateService stateService; protected final ParamService paramService; protected final ProposalListService proposalListService; protected final ProposalService proposalService; @@ -107,7 +107,7 @@ protected BaseProposalView(MyProposalService myProposalService, ProposalListService proposalListService, ProposalService proposalService, BsqWalletService bsqWalletService, - StateService stateService, + UserThreadStateService stateService, ParamService paramService, UserThreadPeriodService periodService, BsqFormatter bsqFormatter, diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index 77204270480..1b5742740f2 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -24,7 +24,8 @@ import bisq.core.btc.listeners.TxConfidenceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.state.Block; -import bisq.core.dao.state.StateService; +import bisq.core.dao.state.BlockListener; +import bisq.core.dao.state.UserThreadStateService; import bisq.core.dao.state.blockchain.Tx; import bisq.core.dao.vote.BooleanVote; import bisq.core.dao.vote.Vote; @@ -54,13 +55,13 @@ @ToString @Slf4j @EqualsAndHashCode -public class ProposalListItem implements StateService.BlockListener { +public class ProposalListItem implements BlockListener { @Getter private final Proposal proposal; private final ProposalService proposalService; private final UserThreadPeriodService periodService; private final BsqWalletService bsqWalletService; - private final StateService stateService; + private final UserThreadStateService stateService; private final BsqFormatter bsqFormatter; private final ChangeListener chainHeightListener; private final ChangeListener voteResultChangeListener; @@ -83,7 +84,7 @@ public class ProposalListItem implements StateService.BlockListener { ProposalService proposalService, UserThreadPeriodService periodService, BsqWalletService bsqWalletService, - StateService stateService, + UserThreadStateService stateService, BsqFormatter bsqFormatter) { this.proposal = proposal; this.proposalService = proposalService; @@ -187,7 +188,7 @@ public void applyState(Phase newValue, Vote vote) { /////////////////////////////////////////////////////////////////////////////////////////// - // StateService.BlockListener + // BlockListener /////////////////////////////////////////////////////////////////////////////////////////// @Override diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index 54f17e11fff..29d5c68d4f9 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -33,7 +33,7 @@ import bisq.core.btc.exceptions.WalletException; import bisq.core.btc.wallet.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.state.StateService; +import bisq.core.dao.state.UserThreadStateService; import bisq.core.dao.vote.BooleanVote; import bisq.core.dao.vote.blindvote.BlindVoteConsensus; import bisq.core.dao.vote.myvote.MyVoteService; @@ -95,7 +95,7 @@ private ActiveProposalsView(MyProposalService myProposalService, UserThreadPeriodService periodService, MyVoteService myVoteService, BsqWalletService bsqWalletService, - StateService stateService, + UserThreadStateService stateService, ParamService paramService, BsqFormatter bsqFormatter, BSFormatter btcFormatter) { diff --git a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java index ddd91258a3c..1eabe75722e 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java @@ -23,7 +23,7 @@ import bisq.desktop.util.BsqFormatter; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.state.StateService; +import bisq.core.dao.state.UserThreadStateService; import bisq.core.dao.vote.period.UserThreadPeriodService; import bisq.core.dao.vote.proposal.MyProposalService; import bisq.core.dao.vote.proposal.ProposalListService; @@ -45,7 +45,7 @@ private ClosedProposalsView(MyProposalService myProposalService, ProposalService proposalService, UserThreadPeriodService periodService, BsqWalletService bsqWalletService, - StateService stateService, + UserThreadStateService stateService, ParamService paramService, BsqFormatter bsqFormatter, BSFormatter btcFormatter) { diff --git a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java index 5897d29c475..249ed3fcd02 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java @@ -23,7 +23,8 @@ import bisq.desktop.util.Layout; import bisq.core.dao.state.Block; -import bisq.core.dao.state.StateService; +import bisq.core.dao.state.BlockListener; +import bisq.core.dao.state.UserThreadStateService; import bisq.core.dao.vote.period.Phase; import bisq.core.dao.vote.period.UserThreadPeriodService; import bisq.core.locale.Res; @@ -44,11 +45,11 @@ import static bisq.desktop.util.FormBuilder.addTitledGroupBg; @FxmlView -public class ProposalDashboardView extends ActivatableView implements StateService.BlockListener { +public class ProposalDashboardView extends ActivatableView implements BlockListener { private List phaseBarsItems; private final UserThreadPeriodService periodService; - private final StateService stateService; + private final UserThreadStateService stateService; private Phase currentPhase; private Subscription phaseSubscription; private GridPane gridPane; @@ -61,7 +62,7 @@ public class ProposalDashboardView extends ActivatableView imple /////////////////////////////////////////////////////////////////////////////////////////// @Inject - private ProposalDashboardView(UserThreadPeriodService periodService, StateService stateService) { + private ProposalDashboardView(UserThreadPeriodService periodService, UserThreadStateService stateService) { this.periodService = periodService; this.stateService = stateService; } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index 4202c92ec0a..f84b3a029e1 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -31,7 +31,7 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.InsufficientBsqException; import bisq.core.btc.wallet.WalletsSetup; -import bisq.core.dao.state.StateService; +import bisq.core.dao.state.UserThreadStateService; import bisq.core.dao.vote.proposal.MyProposalService; import bisq.core.dao.vote.proposal.Proposal; import bisq.core.dao.vote.proposal.ProposalConsensus; @@ -86,7 +86,7 @@ public class MakeProposalView extends ActivatableView { private final MyProposalService myProposalService; private final CompensationRequestService compensationRequestService; private final GenericProposalService genericProposalService; - private final StateService stateService; + private final UserThreadStateService stateService; private final ParamService paramService; private final BSFormatter btcFormatter; private final BsqFormatter bsqFormatter; @@ -107,7 +107,7 @@ private MakeProposalView(BsqWalletService bsqWalletService, MyProposalService myProposalService, CompensationRequestService compensationRequestService, GenericProposalService genericProposalService, - StateService stateService, + UserThreadStateService stateService, ParamService paramService, BSFormatter btcFormatter, BsqFormatter bsqFormatter) { diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java index 677324dbeda..c2f1ebbd21d 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java @@ -30,7 +30,7 @@ import bisq.desktop.util.Layout; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.state.StateService; +import bisq.core.dao.state.UserThreadStateService; import bisq.core.dao.vote.BooleanVote; import bisq.core.dao.vote.Vote; import bisq.core.dao.vote.myvote.MyVoteService; @@ -95,7 +95,7 @@ private MyVotesView(MyProposalService myProposalService, ProposalService proposalService, UserThreadPeriodService periodService, BsqWalletService bsqWalletService, - StateService stateService, + UserThreadStateService stateService, ParamService paramService, BsqFormatter bsqFormatter, BSFormatter btcFormatter, diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java index 7476ba9c939..27b78bd749e 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java @@ -23,7 +23,8 @@ import bisq.core.btc.listeners.TxConfidenceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.state.Block; -import bisq.core.dao.state.StateService; +import bisq.core.dao.state.BlockListener; +import bisq.core.dao.state.UserThreadStateService; import bisq.core.dao.state.blockchain.Tx; import bisq.core.dao.state.blockchain.TxOutput; import bisq.core.dao.vote.myvote.MyVote; @@ -50,11 +51,11 @@ @ToString @Slf4j @EqualsAndHashCode -public class VoteListItem implements StateService.BlockListener { +public class VoteListItem implements BlockListener { @Getter private final MyVote myVote; private final BsqWalletService bsqWalletService; - private final StateService stateService; + private final UserThreadStateService stateService; private final BsqFormatter bsqFormatter; private final ChangeListener chainHeightListener; @Getter @@ -74,7 +75,7 @@ public class VoteListItem implements StateService.BlockListener { VoteListItem(MyVote myVote, BsqWalletService bsqWalletService, - StateService stateService, + UserThreadStateService stateService, BsqFormatter bsqFormatter) { this.myVote = myVote; this.bsqWalletService = bsqWalletService; @@ -97,7 +98,7 @@ public class VoteListItem implements StateService.BlockListener { /////////////////////////////////////////////////////////////////////////////////////////// - // StateService.BlockListener + // BlockListener /////////////////////////////////////////////////////////////////////////////////////////// @Override diff --git a/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java b/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java index 53ea0e81994..005b24b4e62 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java @@ -27,7 +27,8 @@ import bisq.desktop.util.Layout; import bisq.core.dao.state.Block; -import bisq.core.dao.state.StateService; +import bisq.core.dao.state.BlockListener; +import bisq.core.dao.state.UserThreadStateService; import bisq.core.locale.Res; import bisq.core.monetary.Altcoin; import bisq.core.monetary.Price; @@ -56,10 +57,10 @@ import static bisq.desktop.util.FormBuilder.addTitledGroupBg; @FxmlView -public class BsqDashboardView extends ActivatableView implements StateService.BlockListener { +public class BsqDashboardView extends ActivatableView implements BlockListener { private final BsqBalanceUtil bsqBalanceUtil; - private final StateService stateService; + private final UserThreadStateService stateService; private final PriceFeedService priceFeedService; private final Preferences preferences; private final BsqFormatter bsqFormatter; @@ -78,7 +79,7 @@ public class BsqDashboardView extends ActivatableView implements @Inject private BsqDashboardView(BsqBalanceUtil bsqBalanceUtil, - StateService stateService, + UserThreadStateService stateService, PriceFeedService priceFeedService, Preferences preferences, BsqFormatter bsqFormatter) { @@ -147,7 +148,7 @@ protected void deactivate() { /////////////////////////////////////////////////////////////////////////////////////////// - // StateService.BlockListener + // BlockListener /////////////////////////////////////////////////////////////////////////////////////////// @Override @@ -157,25 +158,25 @@ public void onBlockAdded(Block block) { private void updateWithBsqBlockChainData() { - final Coin issuedAmountFromGenesis = stateService.getIssuedAmountAtGenesis(); + final Coin issuedAmountFromGenesis = stateService.getGenesisTotalSupply(); genesisIssueAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(issuedAmountFromGenesis)); - final Coin issuedAmountFromCompRequests = stateService.getIssuedAmountFromCompRequests(); + final Coin issuedAmountFromCompRequests = Coin.valueOf(stateService.getTotalIssuedAmountFromCompRequests()); compRequestIssueAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(issuedAmountFromCompRequests)); - final Coin burntFee = stateService.getTotalBurntFee(); + final Coin burntFee = Coin.valueOf(stateService.getTotalBurntFee()); final Coin availableAmount = issuedAmountFromGenesis.add(issuedAmountFromCompRequests).subtract(burntFee); availableAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(availableAmount)); burntAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(burntFee)); - allTxTextField.setText(String.valueOf(stateService.getTransactions().size())); + allTxTextField.setText(String.valueOf(stateService.getTxs().size())); utxoTextField.setText(String.valueOf(stateService.getUnspentTxOutputs().size())); //spentTxTextField.setText(String.valueOf(stateService.getSpentTxOutputs().size())); - burntTxTextField.setText(String.valueOf(stateService.getFeeTransactions().size())); + burntTxTextField.setText(String.valueOf(stateService.getFeeTxs().size())); } private void updatePrice() { - final Coin issuedAmount = stateService.getIssuedAmountAtGenesis(); + final Coin issuedAmount = stateService.getGenesisTotalSupply(); final MarketPrice bsqMarketPrice = priceFeedService.getMarketPrice("BSQ"); if (bsqMarketPrice != null) { long bsqPrice = MathUtils.roundDoubleToLong(MathUtils.scaleUpByPowerOf10(bsqMarketPrice.getPrice(), Altcoin.SMALLEST_UNIT_EXPONENT)); diff --git a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java index ea3079cc0ee..dd1b4f28c8f 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java @@ -25,7 +25,7 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; import bisq.core.btc.wallet.WalletService; -import bisq.core.dao.state.StateService; +import bisq.core.dao.state.UserThreadStateService; import bisq.core.dao.state.blockchain.Tx; import bisq.core.dao.state.blockchain.TxType; import bisq.core.locale.Res; @@ -51,7 +51,7 @@ class BsqTxListItem { private final Optional optionalTx; private final BsqWalletService bsqWalletService; private final BtcWalletService btcWalletService; - private final StateService stateService; + private final UserThreadStateService stateService; private final BsqFormatter bsqFormatter; private final Date date; private final String txId; @@ -71,7 +71,7 @@ class BsqTxListItem { Optional optionalTx, BsqWalletService bsqWalletService, BtcWalletService btcWalletService, - StateService stateService, + UserThreadStateService stateService, boolean isBurnedBsqTx, Date date, BsqFormatter bsqFormatter) { diff --git a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java index 0a8eb859456..acd8bc7249b 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java @@ -33,7 +33,8 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; import bisq.core.dao.state.Block; -import bisq.core.dao.state.StateService; +import bisq.core.dao.state.BlockListener; +import bisq.core.dao.state.UserThreadStateService; import bisq.core.dao.state.blockchain.Tx; import bisq.core.dao.state.blockchain.TxType; import bisq.core.locale.Res; @@ -80,14 +81,14 @@ import java.util.stream.Collectors; @FxmlView -public class BsqTxView extends ActivatableView implements BsqBalanceListener, StateService.BlockListener { +public class BsqTxView extends ActivatableView implements BsqBalanceListener, BlockListener { private TableView tableView; private Pane rootParent; private final BsqFormatter bsqFormatter; private final BsqWalletService bsqWalletService; - private final StateService stateService; + private final UserThreadStateService stateService; private final BtcWalletService btcWalletService; private final BsqBalanceUtil bsqBalanceUtil; private final Preferences preferences; @@ -111,7 +112,7 @@ public class BsqTxView extends ActivatableView implements BsqBal private BsqTxView(BsqFormatter bsqFormatter, BsqWalletService bsqWalletService, Preferences preferences, - StateService stateService, + UserThreadStateService stateService, BtcWalletService btcWalletService, BsqBalanceUtil bsqBalanceUtil) { this.bsqFormatter = bsqFormatter; @@ -213,7 +214,7 @@ public void onUpdateBalances(Coin confirmedBalance, /////////////////////////////////////////////////////////////////////////////////////////// - // StateService.BlockListener + // BlockListener /////////////////////////////////////////////////////////////////////////////////////////// @Override diff --git a/src/main/java/bisq/desktop/main/funds/transactions/TransactionListItemFactory.java b/src/main/java/bisq/desktop/main/funds/transactions/TransactionListItemFactory.java index 7fc5b61ff1a..732fb2855d5 100644 --- a/src/main/java/bisq/desktop/main/funds/transactions/TransactionListItemFactory.java +++ b/src/main/java/bisq/desktop/main/funds/transactions/TransactionListItemFactory.java @@ -21,7 +21,7 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; -import bisq.core.dao.state.StateService; +import bisq.core.dao.state.UserThreadStateService; import bisq.core.trade.Tradable; import org.bitcoinj.core.Transaction; @@ -35,12 +35,12 @@ public class TransactionListItemFactory { private final BtcWalletService btcWalletService; private final BsqWalletService bsqWalletService; - private final StateService stateService; + private final UserThreadStateService stateService; private final BSFormatter formatter; @Inject TransactionListItemFactory(BtcWalletService btcWalletService, BsqWalletService bsqWalletService, - StateService stateService, BSFormatter formatter) { + UserThreadStateService stateService, BSFormatter formatter) { this.btcWalletService = btcWalletService; this.bsqWalletService = bsqWalletService; this.stateService = stateService; diff --git a/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java b/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java index f1bdd17577f..0eca8cfa7d3 100644 --- a/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java +++ b/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java @@ -26,7 +26,7 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; import bisq.core.btc.wallet.WalletService; -import bisq.core.dao.state.StateService; +import bisq.core.dao.state.UserThreadStateService; import bisq.core.dao.state.blockchain.TxType; import bisq.core.locale.Res; import bisq.core.offer.Offer; @@ -80,7 +80,7 @@ public TransactionsListItem(Transaction transaction, BtcWalletService btcWalletService, BsqWalletService bsqWalletService, Optional tradableOptional, - StateService stateService, + UserThreadStateService stateService, BSFormatter formatter) { this.formatter = formatter; txId = transaction.getHashAsString(); From c1862aceebef10b8431f590506f8a0da263e21eb Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Tue, 17 Apr 2018 10:27:55 -0500 Subject: [PATCH 037/197] Move package bisq.core.dao.vote.period to bisq.core.dao.period --- src/main/java/bisq/desktop/components/SeparatedPhaseBars.java | 2 +- .../java/bisq/desktop/main/dao/proposal/BaseProposalView.java | 4 ++-- .../java/bisq/desktop/main/dao/proposal/ProposalListItem.java | 4 ++-- .../desktop/main/dao/proposal/active/ActiveProposalsView.java | 4 ++-- .../desktop/main/dao/proposal/closed/ClosedProposalsView.java | 2 +- .../main/dao/proposal/dashboard/ProposalDashboardView.java | 4 ++-- .../bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java | 2 +- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java b/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java index 323619452f9..b714f626142 100644 --- a/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java +++ b/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java @@ -17,7 +17,7 @@ package bisq.desktop.components; -import bisq.core.dao.vote.period.Phase; +import bisq.core.dao.period.Phase; import bisq.core.locale.Res; import bisq.common.UserThread; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java index 7b1b2bb7fcf..be3863bc101 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java @@ -27,9 +27,9 @@ import bisq.desktop.util.BsqFormatter; import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.dao.period.Phase; +import bisq.core.dao.period.UserThreadPeriodService; import bisq.core.dao.state.UserThreadStateService; -import bisq.core.dao.vote.period.Phase; -import bisq.core.dao.vote.period.UserThreadPeriodService; import bisq.core.dao.vote.proposal.MyProposalService; import bisq.core.dao.vote.proposal.Proposal; import bisq.core.dao.vote.proposal.ProposalListService; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index 1b5742740f2..80e2265499d 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -23,14 +23,14 @@ import bisq.core.btc.listeners.TxConfidenceListener; import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.dao.period.Phase; +import bisq.core.dao.period.UserThreadPeriodService; import bisq.core.dao.state.Block; import bisq.core.dao.state.BlockListener; import bisq.core.dao.state.UserThreadStateService; import bisq.core.dao.state.blockchain.Tx; import bisq.core.dao.vote.BooleanVote; import bisq.core.dao.vote.Vote; -import bisq.core.dao.vote.period.Phase; -import bisq.core.dao.vote.period.UserThreadPeriodService; import bisq.core.dao.vote.proposal.Proposal; import bisq.core.dao.vote.proposal.ProposalService; import bisq.core.locale.Res; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index 29d5c68d4f9..89f33ba95dc 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -33,12 +33,12 @@ import bisq.core.btc.exceptions.WalletException; import bisq.core.btc.wallet.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.dao.period.Phase; +import bisq.core.dao.period.UserThreadPeriodService; import bisq.core.dao.state.UserThreadStateService; import bisq.core.dao.vote.BooleanVote; import bisq.core.dao.vote.blindvote.BlindVoteConsensus; import bisq.core.dao.vote.myvote.MyVoteService; -import bisq.core.dao.vote.period.Phase; -import bisq.core.dao.vote.period.UserThreadPeriodService; import bisq.core.dao.vote.proposal.MyProposalService; import bisq.core.dao.vote.proposal.Proposal; import bisq.core.dao.vote.proposal.ProposalListService; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java index 1eabe75722e..64434c0f342 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java @@ -23,8 +23,8 @@ import bisq.desktop.util.BsqFormatter; import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.dao.period.UserThreadPeriodService; import bisq.core.dao.state.UserThreadStateService; -import bisq.core.dao.vote.period.UserThreadPeriodService; import bisq.core.dao.vote.proposal.MyProposalService; import bisq.core.dao.vote.proposal.ProposalListService; import bisq.core.dao.vote.proposal.ProposalService; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java index 249ed3fcd02..f0a644d51ee 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java @@ -22,11 +22,11 @@ import bisq.desktop.components.SeparatedPhaseBars; import bisq.desktop.util.Layout; +import bisq.core.dao.period.Phase; +import bisq.core.dao.period.UserThreadPeriodService; import bisq.core.dao.state.Block; import bisq.core.dao.state.BlockListener; import bisq.core.dao.state.UserThreadStateService; -import bisq.core.dao.vote.period.Phase; -import bisq.core.dao.vote.period.UserThreadPeriodService; import bisq.core.locale.Res; import javax.inject.Inject; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java index c2f1ebbd21d..739eaa659d1 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java @@ -30,11 +30,11 @@ import bisq.desktop.util.Layout; import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.dao.period.UserThreadPeriodService; import bisq.core.dao.state.UserThreadStateService; import bisq.core.dao.vote.BooleanVote; import bisq.core.dao.vote.Vote; import bisq.core.dao.vote.myvote.MyVoteService; -import bisq.core.dao.vote.period.UserThreadPeriodService; import bisq.core.dao.vote.proposal.MyProposalService; import bisq.core.dao.vote.proposal.ProposalList; import bisq.core.dao.vote.proposal.ProposalListService; From 9e4a30ec977a1cf192f7049dce4ca9dd1382fb2c Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Wed, 18 Apr 2018 20:49:39 -0500 Subject: [PATCH 038/197] Moving packages and rename classes - Use consensus package for all consensus relevant code - Move UserThreadStateService from bisq.core.dao.state to bisq.core.dao.presentation.state - Rename UserThreadStateService to StateServiceFacade --- .../components/SeparatedPhaseBars.java | 2 +- .../main/dao/proposal/BaseProposalView.java | 22 ++++++++--------- .../dao/proposal/ProposalDetailsWindow.java | 2 +- .../main/dao/proposal/ProposalDisplay.java | 10 ++++---- .../main/dao/proposal/ProposalListItem.java | 24 +++++++++---------- .../proposal/active/ActiveProposalsView.java | 24 +++++++++---------- .../proposal/closed/ClosedProposalsView.java | 14 +++++------ .../dashboard/ProposalDashboardView.java | 14 +++++------ .../dao/proposal/make/MakeProposalView.java | 22 ++++++++--------- .../dao/proposal/myvotes/MyVotesView.java | 22 ++++++++--------- .../dao/proposal/myvotes/VoteListItem.java | 16 ++++++------- .../wallet/dashboard/BsqDashboardView.java | 10 ++++---- .../main/dao/wallet/tx/BsqTxListItem.java | 10 ++++---- .../desktop/main/dao/wallet/tx/BsqTxView.java | 14 +++++------ .../TransactionListItemFactory.java | 6 ++--- .../transactions/TransactionsListItem.java | 6 ++--- 16 files changed, 109 insertions(+), 109 deletions(-) diff --git a/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java b/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java index b714f626142..d02dc29adb6 100644 --- a/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java +++ b/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java @@ -17,7 +17,7 @@ package bisq.desktop.components; -import bisq.core.dao.period.Phase; +import bisq.core.dao.consensus.period.Phase; import bisq.core.locale.Res; import bisq.common.UserThread; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java index be3863bc101..18b3c2bfc9a 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java @@ -27,15 +27,15 @@ import bisq.desktop.util.BsqFormatter; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.period.Phase; -import bisq.core.dao.period.UserThreadPeriodService; -import bisq.core.dao.state.UserThreadStateService; -import bisq.core.dao.vote.proposal.MyProposalService; -import bisq.core.dao.vote.proposal.Proposal; -import bisq.core.dao.vote.proposal.ProposalListService; -import bisq.core.dao.vote.proposal.ProposalPayload; -import bisq.core.dao.vote.proposal.ProposalService; -import bisq.core.dao.vote.proposal.param.ParamService; +import bisq.core.dao.consensus.period.Phase; +import bisq.core.dao.consensus.period.UserThreadPeriodService; +import bisq.core.dao.consensus.vote.proposal.MyProposalService; +import bisq.core.dao.consensus.vote.proposal.Proposal; +import bisq.core.dao.consensus.vote.proposal.ProposalListService; +import bisq.core.dao.consensus.vote.proposal.ProposalPayload; +import bisq.core.dao.consensus.vote.proposal.ProposalService; +import bisq.core.dao.consensus.vote.proposal.param.ParamService; +import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; import javax.inject.Inject; @@ -73,7 +73,7 @@ public abstract class BaseProposalView extends ActivatableView { protected final MyProposalService myProposalService; - protected final UserThreadStateService stateService; + protected final StateServiceFacade stateService; protected final ParamService paramService; protected final ProposalListService proposalListService; protected final ProposalService proposalService; @@ -107,7 +107,7 @@ protected BaseProposalView(MyProposalService myProposalService, ProposalListService proposalListService, ProposalService proposalService, BsqWalletService bsqWalletService, - UserThreadStateService stateService, + StateServiceFacade stateService, ParamService paramService, UserThreadPeriodService periodService, BsqFormatter bsqFormatter, diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java index ab62952b147..f79afec1217 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java @@ -22,7 +22,7 @@ import bisq.desktop.util.Layout; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.vote.proposal.ProposalPayload; +import bisq.core.dao.consensus.vote.proposal.ProposalPayload; import bisq.core.locale.Res; import javafx.geometry.Insets; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java index 7592dafcfac..535b65b96b1 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java @@ -28,11 +28,11 @@ import bisq.desktop.util.validation.BsqValidator; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.vote.proposal.ProposalConsensus; -import bisq.core.dao.vote.proposal.ProposalPayload; -import bisq.core.dao.vote.proposal.ProposalType; -import bisq.core.dao.vote.proposal.compensation.CompensationRequestConsensus; -import bisq.core.dao.vote.proposal.compensation.CompensationRequestPayload; +import bisq.core.dao.consensus.vote.proposal.ProposalConsensus; +import bisq.core.dao.consensus.vote.proposal.ProposalPayload; +import bisq.core.dao.consensus.vote.proposal.ProposalType; +import bisq.core.dao.consensus.vote.proposal.compensation.CompensationRequestConsensus; +import bisq.core.dao.consensus.vote.proposal.compensation.CompensationRequestPayload; import bisq.core.locale.Res; import bisq.core.provider.fee.FeeService; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index 80e2265499d..ce79fa1b022 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -23,16 +23,16 @@ import bisq.core.btc.listeners.TxConfidenceListener; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.period.Phase; -import bisq.core.dao.period.UserThreadPeriodService; -import bisq.core.dao.state.Block; -import bisq.core.dao.state.BlockListener; -import bisq.core.dao.state.UserThreadStateService; -import bisq.core.dao.state.blockchain.Tx; -import bisq.core.dao.vote.BooleanVote; -import bisq.core.dao.vote.Vote; -import bisq.core.dao.vote.proposal.Proposal; -import bisq.core.dao.vote.proposal.ProposalService; +import bisq.core.dao.consensus.period.Phase; +import bisq.core.dao.consensus.period.UserThreadPeriodService; +import bisq.core.dao.consensus.state.Block; +import bisq.core.dao.consensus.state.BlockListener; +import bisq.core.dao.consensus.state.blockchain.Tx; +import bisq.core.dao.consensus.vote.BooleanVote; +import bisq.core.dao.consensus.vote.Vote; +import bisq.core.dao.consensus.vote.proposal.Proposal; +import bisq.core.dao.consensus.vote.proposal.ProposalService; +import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; import org.bitcoinj.core.Transaction; @@ -61,7 +61,7 @@ public class ProposalListItem implements BlockListener { private final ProposalService proposalService; private final UserThreadPeriodService periodService; private final BsqWalletService bsqWalletService; - private final UserThreadStateService stateService; + private final StateServiceFacade stateService; private final BsqFormatter bsqFormatter; private final ChangeListener chainHeightListener; private final ChangeListener voteResultChangeListener; @@ -84,7 +84,7 @@ public class ProposalListItem implements BlockListener { ProposalService proposalService, UserThreadPeriodService periodService, BsqWalletService bsqWalletService, - UserThreadStateService stateService, + StateServiceFacade stateService, BsqFormatter bsqFormatter) { this.proposal = proposal; this.proposalService = proposalService; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index 89f33ba95dc..18a92d1f792 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -33,17 +33,17 @@ import bisq.core.btc.exceptions.WalletException; import bisq.core.btc.wallet.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.period.Phase; -import bisq.core.dao.period.UserThreadPeriodService; -import bisq.core.dao.state.UserThreadStateService; -import bisq.core.dao.vote.BooleanVote; -import bisq.core.dao.vote.blindvote.BlindVoteConsensus; -import bisq.core.dao.vote.myvote.MyVoteService; -import bisq.core.dao.vote.proposal.MyProposalService; -import bisq.core.dao.vote.proposal.Proposal; -import bisq.core.dao.vote.proposal.ProposalListService; -import bisq.core.dao.vote.proposal.ProposalService; -import bisq.core.dao.vote.proposal.param.ParamService; +import bisq.core.dao.consensus.period.Phase; +import bisq.core.dao.consensus.period.UserThreadPeriodService; +import bisq.core.dao.consensus.vote.BooleanVote; +import bisq.core.dao.consensus.vote.blindvote.BlindVoteConsensus; +import bisq.core.dao.consensus.vote.myvote.MyVoteService; +import bisq.core.dao.consensus.vote.proposal.MyProposalService; +import bisq.core.dao.consensus.vote.proposal.Proposal; +import bisq.core.dao.consensus.vote.proposal.ProposalListService; +import bisq.core.dao.consensus.vote.proposal.ProposalService; +import bisq.core.dao.consensus.vote.proposal.param.ParamService; +import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; import bisq.common.util.Tuple2; @@ -95,7 +95,7 @@ private ActiveProposalsView(MyProposalService myProposalService, UserThreadPeriodService periodService, MyVoteService myVoteService, BsqWalletService bsqWalletService, - UserThreadStateService stateService, + StateServiceFacade stateService, ParamService paramService, BsqFormatter bsqFormatter, BSFormatter btcFormatter) { diff --git a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java index 64434c0f342..96a616c0584 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java @@ -23,12 +23,12 @@ import bisq.desktop.util.BsqFormatter; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.period.UserThreadPeriodService; -import bisq.core.dao.state.UserThreadStateService; -import bisq.core.dao.vote.proposal.MyProposalService; -import bisq.core.dao.vote.proposal.ProposalListService; -import bisq.core.dao.vote.proposal.ProposalService; -import bisq.core.dao.vote.proposal.param.ParamService; +import bisq.core.dao.consensus.period.UserThreadPeriodService; +import bisq.core.dao.consensus.vote.proposal.MyProposalService; +import bisq.core.dao.consensus.vote.proposal.ProposalListService; +import bisq.core.dao.consensus.vote.proposal.ProposalService; +import bisq.core.dao.consensus.vote.proposal.param.ParamService; +import bisq.core.dao.presentation.state.StateServiceFacade; import javax.inject.Inject; @@ -45,7 +45,7 @@ private ClosedProposalsView(MyProposalService myProposalService, ProposalService proposalService, UserThreadPeriodService periodService, BsqWalletService bsqWalletService, - UserThreadStateService stateService, + StateServiceFacade stateService, ParamService paramService, BsqFormatter bsqFormatter, BSFormatter btcFormatter) { diff --git a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java index f0a644d51ee..8c0f5ac68a8 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java @@ -22,11 +22,11 @@ import bisq.desktop.components.SeparatedPhaseBars; import bisq.desktop.util.Layout; -import bisq.core.dao.period.Phase; -import bisq.core.dao.period.UserThreadPeriodService; -import bisq.core.dao.state.Block; -import bisq.core.dao.state.BlockListener; -import bisq.core.dao.state.UserThreadStateService; +import bisq.core.dao.consensus.period.Phase; +import bisq.core.dao.consensus.period.UserThreadPeriodService; +import bisq.core.dao.consensus.state.Block; +import bisq.core.dao.consensus.state.BlockListener; +import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; import javax.inject.Inject; @@ -49,7 +49,7 @@ public class ProposalDashboardView extends ActivatableView imple private List phaseBarsItems; private final UserThreadPeriodService periodService; - private final UserThreadStateService stateService; + private final StateServiceFacade stateService; private Phase currentPhase; private Subscription phaseSubscription; private GridPane gridPane; @@ -62,7 +62,7 @@ public class ProposalDashboardView extends ActivatableView imple /////////////////////////////////////////////////////////////////////////////////////////// @Inject - private ProposalDashboardView(UserThreadPeriodService periodService, UserThreadStateService stateService) { + private ProposalDashboardView(UserThreadPeriodService periodService, StateServiceFacade stateService) { this.periodService = periodService; this.stateService = stateService; } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index f84b3a029e1..750c103a815 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -31,15 +31,15 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.InsufficientBsqException; import bisq.core.btc.wallet.WalletsSetup; -import bisq.core.dao.state.UserThreadStateService; -import bisq.core.dao.vote.proposal.MyProposalService; -import bisq.core.dao.vote.proposal.Proposal; -import bisq.core.dao.vote.proposal.ProposalConsensus; -import bisq.core.dao.vote.proposal.ProposalType; -import bisq.core.dao.vote.proposal.ValidationException; -import bisq.core.dao.vote.proposal.compensation.CompensationRequestService; -import bisq.core.dao.vote.proposal.generic.GenericProposalService; -import bisq.core.dao.vote.proposal.param.ParamService; +import bisq.core.dao.consensus.vote.proposal.MyProposalService; +import bisq.core.dao.consensus.vote.proposal.Proposal; +import bisq.core.dao.consensus.vote.proposal.ProposalConsensus; +import bisq.core.dao.consensus.vote.proposal.ProposalType; +import bisq.core.dao.consensus.vote.proposal.ValidationException; +import bisq.core.dao.consensus.vote.proposal.compensation.CompensationRequestService; +import bisq.core.dao.consensus.vote.proposal.generic.GenericProposalService; +import bisq.core.dao.consensus.vote.proposal.param.ParamService; +import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; import bisq.core.provider.fee.FeeService; @@ -86,7 +86,7 @@ public class MakeProposalView extends ActivatableView { private final MyProposalService myProposalService; private final CompensationRequestService compensationRequestService; private final GenericProposalService genericProposalService; - private final UserThreadStateService stateService; + private final StateServiceFacade stateService; private final ParamService paramService; private final BSFormatter btcFormatter; private final BsqFormatter bsqFormatter; @@ -107,7 +107,7 @@ private MakeProposalView(BsqWalletService bsqWalletService, MyProposalService myProposalService, CompensationRequestService compensationRequestService, GenericProposalService genericProposalService, - UserThreadStateService stateService, + StateServiceFacade stateService, ParamService paramService, BSFormatter btcFormatter, BsqFormatter bsqFormatter) { diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java index 739eaa659d1..148930ba93f 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java @@ -30,16 +30,16 @@ import bisq.desktop.util.Layout; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.period.UserThreadPeriodService; -import bisq.core.dao.state.UserThreadStateService; -import bisq.core.dao.vote.BooleanVote; -import bisq.core.dao.vote.Vote; -import bisq.core.dao.vote.myvote.MyVoteService; -import bisq.core.dao.vote.proposal.MyProposalService; -import bisq.core.dao.vote.proposal.ProposalList; -import bisq.core.dao.vote.proposal.ProposalListService; -import bisq.core.dao.vote.proposal.ProposalService; -import bisq.core.dao.vote.proposal.param.ParamService; +import bisq.core.dao.consensus.period.UserThreadPeriodService; +import bisq.core.dao.consensus.vote.BooleanVote; +import bisq.core.dao.consensus.vote.Vote; +import bisq.core.dao.consensus.vote.myvote.MyVoteService; +import bisq.core.dao.consensus.vote.proposal.MyProposalService; +import bisq.core.dao.consensus.vote.proposal.ProposalList; +import bisq.core.dao.consensus.vote.proposal.ProposalListService; +import bisq.core.dao.consensus.vote.proposal.ProposalService; +import bisq.core.dao.consensus.vote.proposal.param.ParamService; +import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; import bisq.core.user.Preferences; @@ -95,7 +95,7 @@ private MyVotesView(MyProposalService myProposalService, ProposalService proposalService, UserThreadPeriodService periodService, BsqWalletService bsqWalletService, - UserThreadStateService stateService, + StateServiceFacade stateService, ParamService paramService, BsqFormatter bsqFormatter, BSFormatter btcFormatter, diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java index 27b78bd749e..3485b060588 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java @@ -22,12 +22,12 @@ import bisq.core.btc.listeners.TxConfidenceListener; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.state.Block; -import bisq.core.dao.state.BlockListener; -import bisq.core.dao.state.UserThreadStateService; -import bisq.core.dao.state.blockchain.Tx; -import bisq.core.dao.state.blockchain.TxOutput; -import bisq.core.dao.vote.myvote.MyVote; +import bisq.core.dao.consensus.state.Block; +import bisq.core.dao.consensus.state.BlockListener; +import bisq.core.dao.consensus.state.blockchain.Tx; +import bisq.core.dao.consensus.state.blockchain.TxOutput; +import bisq.core.dao.consensus.vote.myvote.MyVote; +import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; import org.bitcoinj.core.Coin; @@ -55,7 +55,7 @@ public class VoteListItem implements BlockListener { @Getter private final MyVote myVote; private final BsqWalletService bsqWalletService; - private final UserThreadStateService stateService; + private final StateServiceFacade stateService; private final BsqFormatter bsqFormatter; private final ChangeListener chainHeightListener; @Getter @@ -75,7 +75,7 @@ public class VoteListItem implements BlockListener { VoteListItem(MyVote myVote, BsqWalletService bsqWalletService, - UserThreadStateService stateService, + StateServiceFacade stateService, BsqFormatter bsqFormatter) { this.myVote = myVote; this.bsqWalletService = bsqWalletService; diff --git a/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java b/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java index 005b24b4e62..22394bcb804 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java @@ -26,9 +26,9 @@ import bisq.desktop.util.GUIUtil; import bisq.desktop.util.Layout; -import bisq.core.dao.state.Block; -import bisq.core.dao.state.BlockListener; -import bisq.core.dao.state.UserThreadStateService; +import bisq.core.dao.consensus.state.Block; +import bisq.core.dao.consensus.state.BlockListener; +import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; import bisq.core.monetary.Altcoin; import bisq.core.monetary.Price; @@ -60,7 +60,7 @@ public class BsqDashboardView extends ActivatableView implements BlockListener { private final BsqBalanceUtil bsqBalanceUtil; - private final UserThreadStateService stateService; + private final StateServiceFacade stateService; private final PriceFeedService priceFeedService; private final Preferences preferences; private final BsqFormatter bsqFormatter; @@ -79,7 +79,7 @@ public class BsqDashboardView extends ActivatableView implements @Inject private BsqDashboardView(BsqBalanceUtil bsqBalanceUtil, - UserThreadStateService stateService, + StateServiceFacade stateService, PriceFeedService priceFeedService, Preferences preferences, BsqFormatter bsqFormatter) { diff --git a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java index dd1b4f28c8f..f97ad43350d 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java @@ -25,9 +25,9 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; import bisq.core.btc.wallet.WalletService; -import bisq.core.dao.state.UserThreadStateService; -import bisq.core.dao.state.blockchain.Tx; -import bisq.core.dao.state.blockchain.TxType; +import bisq.core.dao.consensus.state.blockchain.Tx; +import bisq.core.dao.consensus.state.blockchain.TxType; +import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; import org.bitcoinj.core.Coin; @@ -51,7 +51,7 @@ class BsqTxListItem { private final Optional optionalTx; private final BsqWalletService bsqWalletService; private final BtcWalletService btcWalletService; - private final UserThreadStateService stateService; + private final StateServiceFacade stateService; private final BsqFormatter bsqFormatter; private final Date date; private final String txId; @@ -71,7 +71,7 @@ class BsqTxListItem { Optional optionalTx, BsqWalletService bsqWalletService, BtcWalletService btcWalletService, - UserThreadStateService stateService, + StateServiceFacade stateService, boolean isBurnedBsqTx, Date date, BsqFormatter bsqFormatter) { diff --git a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java index acd8bc7249b..124691f30fb 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java @@ -32,11 +32,11 @@ import bisq.core.btc.wallet.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; -import bisq.core.dao.state.Block; -import bisq.core.dao.state.BlockListener; -import bisq.core.dao.state.UserThreadStateService; -import bisq.core.dao.state.blockchain.Tx; -import bisq.core.dao.state.blockchain.TxType; +import bisq.core.dao.consensus.state.Block; +import bisq.core.dao.consensus.state.BlockListener; +import bisq.core.dao.consensus.state.blockchain.Tx; +import bisq.core.dao.consensus.state.blockchain.TxType; +import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; import bisq.core.user.Preferences; @@ -88,7 +88,7 @@ public class BsqTxView extends ActivatableView implements BsqBal private final BsqFormatter bsqFormatter; private final BsqWalletService bsqWalletService; - private final UserThreadStateService stateService; + private final StateServiceFacade stateService; private final BtcWalletService btcWalletService; private final BsqBalanceUtil bsqBalanceUtil; private final Preferences preferences; @@ -112,7 +112,7 @@ public class BsqTxView extends ActivatableView implements BsqBal private BsqTxView(BsqFormatter bsqFormatter, BsqWalletService bsqWalletService, Preferences preferences, - UserThreadStateService stateService, + StateServiceFacade stateService, BtcWalletService btcWalletService, BsqBalanceUtil bsqBalanceUtil) { this.bsqFormatter = bsqFormatter; diff --git a/src/main/java/bisq/desktop/main/funds/transactions/TransactionListItemFactory.java b/src/main/java/bisq/desktop/main/funds/transactions/TransactionListItemFactory.java index 732fb2855d5..dcb98e1fdb0 100644 --- a/src/main/java/bisq/desktop/main/funds/transactions/TransactionListItemFactory.java +++ b/src/main/java/bisq/desktop/main/funds/transactions/TransactionListItemFactory.java @@ -21,7 +21,7 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; -import bisq.core.dao.state.UserThreadStateService; +import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.trade.Tradable; import org.bitcoinj.core.Transaction; @@ -35,12 +35,12 @@ public class TransactionListItemFactory { private final BtcWalletService btcWalletService; private final BsqWalletService bsqWalletService; - private final UserThreadStateService stateService; + private final StateServiceFacade stateService; private final BSFormatter formatter; @Inject TransactionListItemFactory(BtcWalletService btcWalletService, BsqWalletService bsqWalletService, - UserThreadStateService stateService, BSFormatter formatter) { + StateServiceFacade stateService, BSFormatter formatter) { this.btcWalletService = btcWalletService; this.bsqWalletService = bsqWalletService; this.stateService = stateService; diff --git a/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java b/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java index 0eca8cfa7d3..184203f9626 100644 --- a/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java +++ b/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java @@ -26,8 +26,8 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; import bisq.core.btc.wallet.WalletService; -import bisq.core.dao.state.UserThreadStateService; -import bisq.core.dao.state.blockchain.TxType; +import bisq.core.dao.consensus.state.blockchain.TxType; +import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; import bisq.core.offer.Offer; import bisq.core.offer.OpenOffer; @@ -80,7 +80,7 @@ public TransactionsListItem(Transaction transaction, BtcWalletService btcWalletService, BsqWalletService bsqWalletService, Optional tradableOptional, - UserThreadStateService stateService, + StateServiceFacade stateService, BSFormatter formatter) { this.formatter = formatter; txId = transaction.getHashAsString(); From 945663b33d918fb311ea7736a31f04fd00bbea4c Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Wed, 18 Apr 2018 20:59:50 -0500 Subject: [PATCH 039/197] Move Payload classes to bisq.core.dao.consensus.state.events.payloads --- .../java/bisq/desktop/main/dao/proposal/BaseProposalView.java | 2 +- .../bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java | 2 +- .../java/bisq/desktop/main/dao/proposal/ProposalDisplay.java | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java index 18b3c2bfc9a..2b908dd1de4 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java @@ -32,7 +32,7 @@ import bisq.core.dao.consensus.vote.proposal.MyProposalService; import bisq.core.dao.consensus.vote.proposal.Proposal; import bisq.core.dao.consensus.vote.proposal.ProposalListService; -import bisq.core.dao.consensus.vote.proposal.ProposalPayload; +import bisq.core.dao.consensus.state.events.payloads.ProposalPayload; import bisq.core.dao.consensus.vote.proposal.ProposalService; import bisq.core.dao.consensus.vote.proposal.param.ParamService; import bisq.core.dao.presentation.state.StateServiceFacade; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java index f79afec1217..a7af7811259 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java @@ -22,7 +22,7 @@ import bisq.desktop.util.Layout; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.consensus.vote.proposal.ProposalPayload; +import bisq.core.dao.consensus.state.events.payloads.ProposalPayload; import bisq.core.locale.Res; import javafx.geometry.Insets; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java index 535b65b96b1..db3a4ed8160 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java @@ -29,10 +29,10 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.consensus.vote.proposal.ProposalConsensus; -import bisq.core.dao.consensus.vote.proposal.ProposalPayload; +import bisq.core.dao.consensus.state.events.payloads.ProposalPayload; import bisq.core.dao.consensus.vote.proposal.ProposalType; import bisq.core.dao.consensus.vote.proposal.compensation.CompensationRequestConsensus; -import bisq.core.dao.consensus.vote.proposal.compensation.CompensationRequestPayload; +import bisq.core.dao.consensus.state.events.payloads.CompensationRequestPayload; import bisq.core.locale.Res; import bisq.core.provider.fee.FeeService; From 27ac78f98bbfa5c93d34f254d99b889a4c5551cf Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Wed, 18 Apr 2018 22:26:55 -0500 Subject: [PATCH 040/197] Rename Proposal to Ballot and ProposalPayload to Proposal --- .../main/dao/proposal/BaseProposalView.java | 52 +++++++++---------- .../dao/proposal/ProposalDetailsWindow.java | 12 ++--- .../main/dao/proposal/ProposalDisplay.java | 28 +++++----- .../main/dao/proposal/ProposalListItem.java | 28 +++++----- .../proposal/active/ActiveProposalsView.java | 36 ++++++------- .../proposal/closed/ClosedProposalsView.java | 16 +++--- .../dashboard/ProposalDashboardView.java | 16 +++--- .../dao/proposal/make/MakeProposalView.java | 24 ++++----- .../dao/proposal/myvotes/MyVotesView.java | 22 ++++---- 9 files changed, 119 insertions(+), 115 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java index 2b908dd1de4..0b48596a095 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java @@ -28,13 +28,13 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.consensus.period.Phase; -import bisq.core.dao.consensus.period.UserThreadPeriodService; +import bisq.core.dao.consensus.state.events.payloads.Proposal; +import bisq.core.dao.consensus.vote.proposal.Ballot; import bisq.core.dao.consensus.vote.proposal.MyProposalService; -import bisq.core.dao.consensus.vote.proposal.Proposal; import bisq.core.dao.consensus.vote.proposal.ProposalListService; -import bisq.core.dao.consensus.state.events.payloads.ProposalPayload; import bisq.core.dao.consensus.vote.proposal.ProposalService; -import bisq.core.dao.consensus.vote.proposal.param.ParamService; +import bisq.core.dao.consensus.vote.proposal.param.ChangeParamService; +import bisq.core.dao.presentation.period.PeriodServiceFacade; import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; @@ -74,7 +74,7 @@ public abstract class BaseProposalView extends ActivatableView { protected final MyProposalService myProposalService; protected final StateServiceFacade stateService; - protected final ParamService paramService; + protected final ChangeParamService changeParamService; protected final ProposalListService proposalListService; protected final ProposalService proposalService; protected final BsqWalletService bsqWalletService; @@ -90,9 +90,9 @@ public abstract class BaseProposalView extends ActivatableView { protected int gridRow = 0; protected GridPane detailsGridPane, gridPane; protected ProposalListItem selectedProposalListItem; - protected ListChangeListener proposalListChangeListener; + protected ListChangeListener proposalListChangeListener; protected ChangeListener phaseChangeListener; - protected final UserThreadPeriodService periodService; + protected final PeriodServiceFacade periodService; protected Phase currentPhase; protected Subscription phaseSubscription; private ScrollPane proposalDisplayView; @@ -108,8 +108,8 @@ protected BaseProposalView(MyProposalService myProposalService, ProposalService proposalService, BsqWalletService bsqWalletService, StateServiceFacade stateService, - ParamService paramService, - UserThreadPeriodService periodService, + ChangeParamService changeParamService, + PeriodServiceFacade periodService, BsqFormatter bsqFormatter, BSFormatter btcFormatter) { this.myProposalService = myProposalService; @@ -117,7 +117,7 @@ protected BaseProposalView(MyProposalService myProposalService, this.proposalService = proposalService; this.bsqWalletService = bsqWalletService; this.stateService = stateService; - this.paramService = paramService; + this.changeParamService = changeParamService; this.periodService = periodService; this.bsqFormatter = bsqFormatter; this.btcFormatter = btcFormatter; @@ -211,14 +211,14 @@ protected void hideProposalDisplay() { proposalDisplayView.setManaged(false); } - protected void showProposalDisplay(Proposal proposal) { + protected void showProposalDisplay(Ballot ballot) { proposalDisplayView.setVisible(true); proposalDisplayView.setManaged(true); - proposalDisplay.createAllFields(Res.get("dao.proposal.selectedProposal"), 0, 0, proposal.getType(), + proposalDisplay.createAllFields(Res.get("dao.proposal.selectedProposal"), 0, 0, ballot.getType(), false, false); proposalDisplay.setEditable(false); - proposalDisplay.applyProposalPayload(proposal.getProposalPayload()); + proposalDisplay.applyProposalPayload(ballot.getProposal()); } @@ -229,7 +229,7 @@ protected void showProposalDisplay(Proposal proposal) { protected void onSelectProposal(ProposalListItem item) { selectedProposalListItem = item; if (item != null) - showProposalDisplay(item.getProposal()); + showProposalDisplay(item.getBallot()); else hideProposalDisplay(); } @@ -248,7 +248,7 @@ protected void onPhaseChanged(Phase phase) { abstract protected void updateProposalList(); - protected void doUpdateProposalList(List list) { + protected void doUpdateProposalList(List list) { proposalListItems.forEach(ProposalListItem::cleanup); proposalListItems.setAll(list.stream() @@ -295,14 +295,14 @@ public TableCell call( public void updateItem(final ProposalListItem item, boolean empty) { super.updateItem(item, empty); if (item != null) - setText(bsqFormatter.formatDateTime(item.getProposal().getProposalPayload().getCreationDate())); + setText(bsqFormatter.formatDateTime(item.getBallot().getProposal().getCreationDate())); else setText(""); } }; } }); - dateColumn.setComparator(Comparator.comparing(o3 -> o3.getProposal().getProposalPayload().getCreationDate())); + dateColumn.setComparator(Comparator.comparing(o3 -> o3.getBallot().getProposal().getCreationDate())); dateColumn.setSortType(TableColumn.SortType.DESCENDING); tableView.getColumns().add(dateColumn); tableView.getSortOrder().add(dateColumn); @@ -320,14 +320,14 @@ public TableCell call( public void updateItem(final ProposalListItem item, boolean empty) { super.updateItem(item, empty); if (item != null) - setText(item.getProposal().getProposalPayload().getName()); + setText(item.getBallot().getProposal().getName()); else setText(""); } }; } }); - nameColumn.setComparator(Comparator.comparing(o2 -> o2.getProposal().getProposalPayload().getName())); + nameColumn.setComparator(Comparator.comparing(o2 -> o2.getBallot().getProposal().getName())); tableView.getColumns().add(nameColumn); TableColumn titleColumn = new AutoTooltipTableColumn<>(Res.get("dao.proposal.title")); @@ -344,14 +344,14 @@ public TableCell call( public void updateItem(final ProposalListItem item, boolean empty) { super.updateItem(item, empty); if (item != null) - setText(item.getProposal().getProposalPayload().getTitle()); + setText(item.getBallot().getProposal().getTitle()); else setText(""); } }; } }); - titleColumn.setComparator(Comparator.comparing(o2 -> o2.getProposal().getProposalPayload().getTitle())); + titleColumn.setComparator(Comparator.comparing(o2 -> o2.getBallot().getProposal().getTitle())); tableView.getColumns().add(titleColumn); TableColumn uidColumn = new AutoTooltipTableColumn<>(Res.get("shared.id")); @@ -370,11 +370,11 @@ public TableCell call(TableColumn { - new ProposalDetailsWindow(bsqFormatter, bsqWalletService, proposalPayload).show(); + new ProposalDetailsWindow(bsqFormatter, bsqWalletService, proposal).show(); }); field.setTooltip(new Tooltip(Res.get("tooltip.openPopupForDetails"))); setGraphic(field); @@ -387,7 +387,7 @@ public void updateItem(final ProposalListItem item, boolean empty) { }; } }); - uidColumn.setComparator(Comparator.comparing(o -> o.getProposal().getUid())); + uidColumn.setComparator(Comparator.comparing(o -> o.getBallot().getUid())); tableView.getColumns().add(uidColumn); } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java index a7af7811259..59ff540082c 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java @@ -22,7 +22,7 @@ import bisq.desktop.util.Layout; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.consensus.state.events.payloads.ProposalPayload; +import bisq.core.dao.consensus.state.events.payloads.Proposal; import bisq.core.locale.Res; import javafx.geometry.Insets; @@ -36,7 +36,7 @@ public class ProposalDetailsWindow extends Overlay { protected static final Logger log = LoggerFactory.getLogger(ProposalDetailsWindow.class); private final BsqFormatter bsqFormatter; private final BsqWalletService bsqWalletService; - private ProposalPayload proposalPayload; + private Proposal proposal; private ProposalDisplay proposalDisplay; @@ -44,10 +44,10 @@ public class ProposalDetailsWindow extends Overlay { // Public API /////////////////////////////////////////////////////////////////////////////////////////// - public ProposalDetailsWindow(BsqFormatter bsqFormatter, BsqWalletService bsqWalletService, ProposalPayload proposalPayload) { + public ProposalDetailsWindow(BsqFormatter bsqFormatter, BsqWalletService bsqWalletService, Proposal proposal) { this.bsqFormatter = bsqFormatter; this.bsqWalletService = bsqWalletService; - this.proposalPayload = proposalPayload; + this.proposal = proposal; type = Type.Confirmation; width = 950; @@ -58,10 +58,10 @@ public void show() { proposalDisplay = new ProposalDisplay(gridPane, bsqFormatter, bsqWalletService, null); proposalDisplay.createAllFields(Res.get("dao.proposal.details"), 1, Layout.GROUP_DISTANCE, - proposalPayload.getType(), false, true); + proposal.getType(), false, true); proposalDisplay.setEditable(false); - proposalDisplay.applyProposalPayload(proposalPayload); + proposalDisplay.applyProposalPayload(proposal); closeButton = addButtonAfterGroup(gridPane, proposalDisplay.incrementAndGetGridRow(), Res.get("shared.close")); closeButton.setOnAction(e -> doClose()); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java index db3a4ed8160..07c1b133006 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java @@ -28,11 +28,11 @@ import bisq.desktop.util.validation.BsqValidator; import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.dao.consensus.state.events.payloads.CompensationRequestProposal; +import bisq.core.dao.consensus.state.events.payloads.Proposal; import bisq.core.dao.consensus.vote.proposal.ProposalConsensus; -import bisq.core.dao.consensus.state.events.payloads.ProposalPayload; import bisq.core.dao.consensus.vote.proposal.ProposalType; import bisq.core.dao.consensus.vote.proposal.compensation.CompensationRequestConsensus; -import bisq.core.dao.consensus.state.events.payloads.CompensationRequestPayload; import bisq.core.locale.Res; import bisq.core.provider.fee.FeeService; @@ -153,26 +153,26 @@ public void createAllFields(String title, int gridRowStartIndex, double top, Pro Res.get("dao.proposal.display.txId"), "").second; } - public void applyProposalPayload(ProposalPayload proposalPayload) { + public void applyProposalPayload(Proposal proposal) { if (uidTextField != null) - uidTextField.setText(proposalPayload.getUid()); - nameTextField.setText(proposalPayload.getName()); - titleTextField.setText(proposalPayload.getTitle()); - descriptionTextArea.setText(proposalPayload.getDescription()); + uidTextField.setText(proposal.getUid()); + nameTextField.setText(proposal.getName()); + titleTextField.setText(proposal.getTitle()); + descriptionTextArea.setText(proposal.getDescription()); linkInputTextField.setVisible(false); linkInputTextField.setManaged(false); linkHyperlinkWithIcon.setVisible(true); linkHyperlinkWithIcon.setManaged(true); - linkHyperlinkWithIcon.setText(proposalPayload.getLink()); - linkHyperlinkWithIcon.setOnAction(e -> GUIUtil.openWebPage(proposalPayload.getLink())); - if (proposalPayload instanceof CompensationRequestPayload) { - CompensationRequestPayload compensationRequestPayload = (CompensationRequestPayload) proposalPayload; - Objects.requireNonNull(requestedBsqTextField).setText(bsqFormatter.formatCoinWithCode(compensationRequestPayload.getRequestedBsq())); + linkHyperlinkWithIcon.setText(proposal.getLink()); + linkHyperlinkWithIcon.setOnAction(e -> GUIUtil.openWebPage(proposal.getLink())); + if (proposal instanceof CompensationRequestProposal) { + CompensationRequestProposal compensationRequestProposal = (CompensationRequestProposal) proposal; + Objects.requireNonNull(requestedBsqTextField).setText(bsqFormatter.formatCoinWithCode(compensationRequestProposal.getRequestedBsq())); if (bsqAddressTextField != null) - bsqAddressTextField.setText(compensationRequestPayload.getBsqAddress()); + bsqAddressTextField.setText(compensationRequestProposal.getBsqAddress()); } if (txIdTextField != null) - txIdTextField.setup(proposalPayload.getTxId()); + txIdTextField.setup(proposal.getTxId()); } public void clearForm() { diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index ce79fa1b022..bd734156b2e 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -24,14 +24,14 @@ import bisq.core.btc.listeners.TxConfidenceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.consensus.period.Phase; -import bisq.core.dao.consensus.period.UserThreadPeriodService; import bisq.core.dao.consensus.state.Block; import bisq.core.dao.consensus.state.BlockListener; import bisq.core.dao.consensus.state.blockchain.Tx; import bisq.core.dao.consensus.vote.BooleanVote; import bisq.core.dao.consensus.vote.Vote; -import bisq.core.dao.consensus.vote.proposal.Proposal; +import bisq.core.dao.consensus.vote.proposal.Ballot; import bisq.core.dao.consensus.vote.proposal.ProposalService; +import bisq.core.dao.presentation.period.PeriodServiceFacade; import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; @@ -57,9 +57,9 @@ @EqualsAndHashCode public class ProposalListItem implements BlockListener { @Getter - private final Proposal proposal; + private final Ballot ballot; private final ProposalService proposalService; - private final UserThreadPeriodService periodService; + private final PeriodServiceFacade periodService; private final BsqWalletService bsqWalletService; private final StateServiceFacade stateService; private final BsqFormatter bsqFormatter; @@ -80,13 +80,13 @@ public class ProposalListItem implements BlockListener { private Runnable onRemoveHandler; private Node actionNode; - ProposalListItem(Proposal proposal, + ProposalListItem(Ballot ballot, ProposalService proposalService, - UserThreadPeriodService periodService, + PeriodServiceFacade periodService, BsqWalletService bsqWalletService, StateServiceFacade stateService, BsqFormatter bsqFormatter) { - this.proposal = proposal; + this.ballot = ballot; this.proposalService = proposalService; this.periodService = periodService; this.bsqWalletService = bsqWalletService; @@ -112,7 +112,7 @@ public class ProposalListItem implements BlockListener { stateService.addBlockListener(this); phaseChangeListener = (observable, oldValue, newValue) -> { - applyState(newValue, proposal.getVote()); + applyState(newValue, ballot.getVote()); }; voteResultChangeListener = (observable, oldValue, newValue) -> { @@ -120,20 +120,20 @@ public class ProposalListItem implements BlockListener { }; periodService.phaseProperty().addListener(phaseChangeListener); - proposal.getVoteResultProperty().addListener(voteResultChangeListener); + ballot.getVoteResultProperty().addListener(voteResultChangeListener); } public void applyState(Phase newValue, Vote vote) { actionButton.setText(""); actionButton.setVisible(false); actionButton.setOnAction(null); - final boolean isTxInPastCycle = periodService.isTxInPastCycle(proposal.getTxId(), + final boolean isTxInPastCycle = periodService.isTxInPastCycle(ballot.getTxId(), stateService.getChainHeight()); switch (newValue) { case UNDEFINED: break; case PROPOSAL: - if (proposalService.isMine(proposal.getProposalPayload())) { + if (proposalService.isMine(ballot.getProposal())) { actionButton.setVisible(!isTxInPastCycle); actionButtonIconView.setVisible(actionButton.isVisible()); actionButton.setText(Res.get("shared.remove")); @@ -152,7 +152,7 @@ public void applyState(Phase newValue, Vote vote) { if (!isTxInPastCycle) { actionNode = actionButtonIconView; actionButton.setVisible(false); - if (proposal.getVote() != null) { + if (ballot.getVote() != null) { actionButtonIconView.setVisible(true); if (vote instanceof BooleanVote) { if (((BooleanVote) vote).isAccepted()) { @@ -199,7 +199,7 @@ public void onBlockAdded(Block block) { private void setupConfidence() { - final Tx tx = stateService.getTxMap().get(proposal.getProposalPayload().getTxId()); + final Tx tx = stateService.getTxMap().get(ballot.getProposal().getTxId()); if (tx != null) { final String txId = tx.getId(); @@ -249,7 +249,7 @@ public void cleanup() { bsqWalletService.removeTxConfidenceListener(txConfidenceListener); periodService.phaseProperty().removeListener(phaseChangeListener); - proposal.getVoteResultProperty().removeListener(voteResultChangeListener); + ballot.getVoteResultProperty().removeListener(voteResultChangeListener); } private void updateConfidence(TransactionConfidence.ConfidenceType confidenceType, int depthInBlocks, int numBroadcastPeers) { diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index 18a92d1f792..784ad06dfaa 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -34,15 +34,15 @@ import bisq.core.btc.wallet.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.consensus.period.Phase; -import bisq.core.dao.consensus.period.UserThreadPeriodService; import bisq.core.dao.consensus.vote.BooleanVote; import bisq.core.dao.consensus.vote.blindvote.BlindVoteConsensus; import bisq.core.dao.consensus.vote.myvote.MyVoteService; +import bisq.core.dao.consensus.vote.proposal.Ballot; import bisq.core.dao.consensus.vote.proposal.MyProposalService; -import bisq.core.dao.consensus.vote.proposal.Proposal; import bisq.core.dao.consensus.vote.proposal.ProposalListService; import bisq.core.dao.consensus.vote.proposal.ProposalService; -import bisq.core.dao.consensus.vote.proposal.param.ParamService; +import bisq.core.dao.consensus.vote.proposal.param.ChangeParamService; +import bisq.core.dao.presentation.period.PeriodServiceFacade; import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; @@ -92,16 +92,16 @@ public class ActiveProposalsView extends BaseProposalView implements BsqBalanceL private ActiveProposalsView(MyProposalService myProposalService, ProposalListService proposalListService, ProposalService proposalService, - UserThreadPeriodService periodService, + PeriodServiceFacade periodService, MyVoteService myVoteService, BsqWalletService bsqWalletService, StateServiceFacade stateService, - ParamService paramService, + ChangeParamService changeParamService, BsqFormatter bsqFormatter, BSFormatter btcFormatter) { super(myProposalService, proposalListService, proposalService, bsqWalletService, stateService, - paramService, periodService, bsqFormatter, btcFormatter); + changeParamService, periodService, bsqFormatter, btcFormatter); this.myVoteService = myVoteService; } @@ -119,7 +119,7 @@ public void initialize() { protected void activate() { super.activate(); - proposalListService.getActiveOrMyUnconfirmedProposals().addListener(proposalListChangeListener); + proposalListService.getActiveOrMyUnconfirmedBallots().addListener(proposalListChangeListener); bsqWalletService.addBsqBalanceListener(this); onUpdateBalances(bsqWalletService.getAvailableBalance(), @@ -131,7 +131,7 @@ protected void activate() { voteButton.setOnAction(e -> { // TODO verify stake Coin stake = bsqFormatter.parseToCoin(stakeInputTextField.getText()); - final Coin fee = BlindVoteConsensus.getFee(paramService, stateService.getChainHeight()); + final Coin fee = BlindVoteConsensus.getFee(changeParamService, stateService.getChainHeight()); Transaction dummyTx = null; try { // We create a tx with dummy opreturn data to get the mining fee for confirmation popup @@ -170,7 +170,7 @@ private void publishBlindVote(Coin stake) { protected void deactivate() { super.deactivate(); - proposalListService.getActiveOrMyUnconfirmedProposals().removeListener(proposalListChangeListener); + proposalListService.getActiveOrMyUnconfirmedBallots().removeListener(proposalListChangeListener); bsqWalletService.removeBsqBalanceListener(this); } @@ -243,17 +243,17 @@ protected void onSelectProposal(ProposalListItem item) { } private void onAccept() { - selectedProposalListItem.getProposal().setVote(new BooleanVote(true)); + selectedProposalListItem.getBallot().setVote(new BooleanVote(true)); updateStateAfterVote(); } private void onReject() { - selectedProposalListItem.getProposal().setVote(new BooleanVote(false)); + selectedProposalListItem.getBallot().setVote(new BooleanVote(false)); updateStateAfterVote(); } private void onCancelVote() { - selectedProposalListItem.getProposal().setVote(null); + selectedProposalListItem.getBallot().setVote(null); updateStateAfterVote(); } @@ -270,12 +270,12 @@ protected void onPhaseChanged(Phase phase) { } if (selectedProposalListItem != null && proposalDisplay != null && - !periodService.isTxInPastCycle(selectedProposalListItem.getProposal().getTxId(), + !periodService.isTxInPastCycle(selectedProposalListItem.getBallot().getTxId(), stateService.getChainHeight())) { - final Proposal proposal = selectedProposalListItem.getProposal(); + final Ballot ballot = selectedProposalListItem.getBallot(); switch (phase) { case PROPOSAL: - if (proposalService.isMine(proposal.getProposalPayload())) { + if (proposalService.isMine(ballot.getProposal())) { if (removeButton == null) { removeButton = addButtonAfterGroup(detailsGridPane, proposalDisplay.incrementAndGetGridRow(), Res.get("dao.proposal.active.remove")); removeButton.setOnAction(event -> onRemove()); @@ -334,7 +334,7 @@ protected void onPhaseChanged(Phase phase) { @Override protected void updateProposalList() { - doUpdateProposalList(proposalListService.getActiveOrMyUnconfirmedProposals()); + doUpdateProposalList(proposalListService.getActiveOrMyUnconfirmedBallots()); } private void updateStateAfterVote() { @@ -351,7 +351,7 @@ private void changeVoteViewItemsVisibility(boolean value) { } private void onRemove() { - if (myProposalService.removeProposal(selectedProposalListItem.getProposal())) + if (myProposalService.removeProposal(selectedProposalListItem.getBallot())) hideProposalDisplay(); else new Popup<>().warning(Res.get("dao.proposal.active.remove.failed")).show(); @@ -396,7 +396,7 @@ public void updateItem(final ProposalListItem item, boolean empty) { ActiveProposalsView.this.selectedProposalListItem = item; ActiveProposalsView.this.onRemove(); }); - item.applyState(currentPhase, item.getProposal().getVoteResultProperty().get()); + item.applyState(currentPhase, item.getBallot().getVoteResultProperty().get()); } } else { setGraphic(null); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java index 96a616c0584..120a3a5d601 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java @@ -23,11 +23,11 @@ import bisq.desktop.util.BsqFormatter; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.consensus.period.UserThreadPeriodService; import bisq.core.dao.consensus.vote.proposal.MyProposalService; import bisq.core.dao.consensus.vote.proposal.ProposalListService; import bisq.core.dao.consensus.vote.proposal.ProposalService; -import bisq.core.dao.consensus.vote.proposal.param.ParamService; +import bisq.core.dao.consensus.vote.proposal.param.ChangeParamService; +import bisq.core.dao.presentation.period.PeriodServiceFacade; import bisq.core.dao.presentation.state.StateServiceFacade; import javax.inject.Inject; @@ -43,15 +43,15 @@ public class ClosedProposalsView extends BaseProposalView { private ClosedProposalsView(MyProposalService myProposalService, ProposalListService proposalListService, ProposalService proposalService, - UserThreadPeriodService periodService, + PeriodServiceFacade periodService, BsqWalletService bsqWalletService, StateServiceFacade stateService, - ParamService paramService, + ChangeParamService changeParamService, BsqFormatter bsqFormatter, BSFormatter btcFormatter) { super(myProposalService, proposalListService, proposalService, bsqWalletService, stateService, - paramService, periodService, bsqFormatter, btcFormatter); + changeParamService, periodService, bsqFormatter, btcFormatter); } @Override @@ -65,18 +65,18 @@ public void initialize() { @Override protected void activate() { super.activate(); - proposalListService.getClosedProposals().addListener(proposalListChangeListener); + proposalListService.getClosedBallots().addListener(proposalListChangeListener); } @Override protected void deactivate() { super.deactivate(); - proposalListService.getClosedProposals().removeListener(proposalListChangeListener); + proposalListService.getClosedBallots().removeListener(proposalListChangeListener); } @Override protected void updateProposalList() { - doUpdateProposalList(proposalListService.getClosedProposals()); + doUpdateProposalList(proposalListService.getClosedBallots()); } } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java index 8c0f5ac68a8..3b2625eaab7 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java @@ -23,12 +23,14 @@ import bisq.desktop.util.Layout; import bisq.core.dao.consensus.period.Phase; -import bisq.core.dao.consensus.period.UserThreadPeriodService; import bisq.core.dao.consensus.state.Block; import bisq.core.dao.consensus.state.BlockListener; +import bisq.core.dao.presentation.period.PeriodServiceFacade; import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; +import bisq.common.UserThread; + import javax.inject.Inject; import javafx.scene.layout.AnchorPane; @@ -48,7 +50,7 @@ public class ProposalDashboardView extends ActivatableView implements BlockListener { private List phaseBarsItems; - private final UserThreadPeriodService periodService; + private final PeriodServiceFacade periodService; private final StateServiceFacade stateService; private Phase currentPhase; private Subscription phaseSubscription; @@ -62,7 +64,7 @@ public class ProposalDashboardView extends ActivatableView imple /////////////////////////////////////////////////////////////////////////////////////////// @Inject - private ProposalDashboardView(UserThreadPeriodService periodService, StateServiceFacade stateService) { + private ProposalDashboardView(PeriodServiceFacade periodService, StateServiceFacade stateService) { this.periodService = periodService; this.stateService = stateService; } @@ -123,14 +125,16 @@ protected void activate() { }); }); - stateService.addBlockListener(this); - onChainHeightChanged(periodService.getChainHeight()); + periodService.addBlockListener(this); + + // We need to delay as otherwise the periodService has not been updated yet. + UserThread.execute(() -> onChainHeightChanged(periodService.getChainHeight())); } @Override protected void deactivate() { super.deactivate(); - stateService.removeBlockListener(this); + periodService.removeBlockListener(this); phaseSubscription.unsubscribe(); } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index 750c103a815..b39268ac423 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -31,14 +31,14 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.InsufficientBsqException; import bisq.core.btc.wallet.WalletsSetup; +import bisq.core.dao.consensus.vote.proposal.Ballot; import bisq.core.dao.consensus.vote.proposal.MyProposalService; -import bisq.core.dao.consensus.vote.proposal.Proposal; import bisq.core.dao.consensus.vote.proposal.ProposalConsensus; import bisq.core.dao.consensus.vote.proposal.ProposalType; import bisq.core.dao.consensus.vote.proposal.ValidationException; import bisq.core.dao.consensus.vote.proposal.compensation.CompensationRequestService; import bisq.core.dao.consensus.vote.proposal.generic.GenericProposalService; -import bisq.core.dao.consensus.vote.proposal.param.ParamService; +import bisq.core.dao.consensus.vote.proposal.param.ChangeParamService; import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; import bisq.core.provider.fee.FeeService; @@ -87,7 +87,7 @@ public class MakeProposalView extends ActivatableView { private final CompensationRequestService compensationRequestService; private final GenericProposalService genericProposalService; private final StateServiceFacade stateService; - private final ParamService paramService; + private final ChangeParamService changeParamService; private final BSFormatter btcFormatter; private final BsqFormatter bsqFormatter; private ComboBox proposalTypeComboBox; @@ -108,7 +108,7 @@ private MakeProposalView(BsqWalletService bsqWalletService, CompensationRequestService compensationRequestService, GenericProposalService genericProposalService, StateServiceFacade stateService, - ParamService paramService, + ChangeParamService changeParamService, BSFormatter btcFormatter, BsqFormatter bsqFormatter) { this.bsqWalletService = bsqWalletService; @@ -119,7 +119,7 @@ private MakeProposalView(BsqWalletService bsqWalletService, this.compensationRequestService = compensationRequestService; this.genericProposalService = genericProposalService; this.stateService = stateService; - this.paramService = paramService; + this.changeParamService = changeParamService; this.btcFormatter = btcFormatter; this.bsqFormatter = bsqFormatter; } @@ -167,15 +167,15 @@ protected void deactivate() { private void publishProposal(ProposalType type) { try { - final Tuple2 tuple2 = createProposal(type); - Proposal proposal = tuple2.first; + final Tuple2 tuple2 = createProposal(type); + Ballot ballot = tuple2.first; Transaction transaction = tuple2.second; Coin miningFee = transaction.getFee(); int txSize = transaction.bitcoinSerialize().length; - final Coin fee = ProposalConsensus.getFee(paramService, stateService.getChainHeight()); + final Coin fee = ProposalConsensus.getFee(changeParamService, stateService.getChainHeight()); GUIUtil.showBsqFeeInfoPopup(fee, miningFee, txSize, bsqFormatter, btcFormatter, - Res.get("dao.proposal"), () -> publishProposal(proposal, transaction)); + Res.get("dao.proposal"), () -> publishProposal(ballot, transaction)); } catch (InsufficientMoneyException e) { BSFormatter formatter = e instanceof InsufficientBsqException ? bsqFormatter : btcFormatter; @@ -197,8 +197,8 @@ private void publishProposal(ProposalType type) { } } - private void publishProposal(Proposal proposal, Transaction transaction) { - myProposalService.publishProposal(proposal, + private void publishProposal(Ballot ballot, Transaction transaction) { + myProposalService.publishProposal(ballot, transaction, () -> { proposalDisplay.clearForm(); @@ -208,7 +208,7 @@ private void publishProposal(Proposal proposal, Transaction transaction) { errorMessage -> new Popup<>().warning(errorMessage).show()); } - private Tuple2 createProposal(ProposalType type) + private Tuple2 createProposal(ProposalType type) throws InsufficientMoneyException, TransactionVerificationException, ValidationException, WalletException, IOException { diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java index 148930ba93f..a8e76a9497e 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java @@ -30,15 +30,15 @@ import bisq.desktop.util.Layout; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.consensus.period.UserThreadPeriodService; import bisq.core.dao.consensus.vote.BooleanVote; import bisq.core.dao.consensus.vote.Vote; import bisq.core.dao.consensus.vote.myvote.MyVoteService; +import bisq.core.dao.consensus.vote.proposal.BallotList; import bisq.core.dao.consensus.vote.proposal.MyProposalService; -import bisq.core.dao.consensus.vote.proposal.ProposalList; import bisq.core.dao.consensus.vote.proposal.ProposalListService; import bisq.core.dao.consensus.vote.proposal.ProposalService; -import bisq.core.dao.consensus.vote.proposal.param.ParamService; +import bisq.core.dao.consensus.vote.proposal.param.ChangeParamService; +import bisq.core.dao.presentation.period.PeriodServiceFacade; import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; import bisq.core.user.Preferences; @@ -93,17 +93,17 @@ public class MyVotesView extends BaseProposalView { private MyVotesView(MyProposalService myProposalService, ProposalListService proposalListService, ProposalService proposalService, - UserThreadPeriodService periodService, + PeriodServiceFacade periodService, BsqWalletService bsqWalletService, StateServiceFacade stateService, - ParamService paramService, + ChangeParamService changeParamService, BsqFormatter bsqFormatter, BSFormatter btcFormatter, MyVoteService myVoteService, Preferences preferences) { super(myProposalService, proposalListService, proposalService, bsqWalletService, stateService, - paramService, periodService, bsqFormatter, btcFormatter); + changeParamService, periodService, bsqFormatter, btcFormatter); this.myVoteService = myVoteService; this.preferences = preferences; } @@ -182,7 +182,7 @@ private void createVoteTableView() { // Handler /////////////////////////////////////////////////////////////////////////////////////////// - private void onShowProposalList(ProposalList proposalList) { + private void onShowProposalList(BallotList ballotList) { } @@ -194,7 +194,7 @@ private void onShowProposalList(ProposalList proposalList) { @Override protected void updateProposalList() { if (selectedVoteListItem != null) - doUpdateProposalList(selectedVoteListItem.getMyVote().getProposalList().getList()); + doUpdateProposalList(selectedVoteListItem.getMyVote().getBallotList().getList()); } @@ -249,9 +249,9 @@ public void updateItem(final VoteListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { - ProposalList proposalList = item.getMyVote().getProposalList(); + BallotList ballotList = item.getMyVote().getBallotList(); HyperlinkWithIcon field = new HyperlinkWithIcon(Res.get("dao.proposal.myVotes.showProposalList"), AwesomeIcon.INFO_SIGN); - field.setOnAction(event -> onShowProposalList(proposalList)); + field.setOnAction(event -> onShowProposalList(ballotList)); field.setTooltip(new Tooltip(Res.get("dao.proposal.myVotes.tooltip.showProposalList"))); setGraphic(field); } else { @@ -378,7 +378,7 @@ public void updateItem(final ProposalListItem item, boolean empty) { if (item != null && !empty) { actionButtonIconView = new ImageView(); - Vote vote = item.getProposal().getVote(); + Vote vote = item.getBallot().getVote(); if (vote instanceof BooleanVote) { if (((BooleanVote) vote).isAccepted()) { actionButtonIconView.setId("accepted"); From 3e6f125250beb09a5655eea456d42598c637b382 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Thu, 19 Apr 2018 18:15:32 -0500 Subject: [PATCH 041/197] Move classes to other packages --- .../java/bisq/desktop/main/dao/proposal/BaseProposalView.java | 2 +- .../bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java | 2 +- .../java/bisq/desktop/main/dao/proposal/ProposalDisplay.java | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java index 0b48596a095..5909da5402e 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java @@ -28,9 +28,9 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.consensus.period.Phase; -import bisq.core.dao.consensus.state.events.payloads.Proposal; import bisq.core.dao.consensus.vote.proposal.Ballot; import bisq.core.dao.consensus.vote.proposal.MyProposalService; +import bisq.core.dao.consensus.vote.proposal.Proposal; import bisq.core.dao.consensus.vote.proposal.ProposalListService; import bisq.core.dao.consensus.vote.proposal.ProposalService; import bisq.core.dao.consensus.vote.proposal.param.ChangeParamService; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java index 59ff540082c..820449f4e3e 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java @@ -22,7 +22,7 @@ import bisq.desktop.util.Layout; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.consensus.state.events.payloads.Proposal; +import bisq.core.dao.consensus.vote.proposal.Proposal; import bisq.core.locale.Res; import javafx.geometry.Insets; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java index 07c1b133006..e18935b0a40 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java @@ -28,11 +28,11 @@ import bisq.desktop.util.validation.BsqValidator; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.consensus.state.events.payloads.CompensationRequestProposal; -import bisq.core.dao.consensus.state.events.payloads.Proposal; +import bisq.core.dao.consensus.vote.proposal.Proposal; import bisq.core.dao.consensus.vote.proposal.ProposalConsensus; import bisq.core.dao.consensus.vote.proposal.ProposalType; import bisq.core.dao.consensus.vote.proposal.compensation.CompensationRequestConsensus; +import bisq.core.dao.consensus.vote.proposal.compensation.CompensationRequestProposal; import bisq.core.locale.Res; import bisq.core.provider.fee.FeeService; From 68d854a1144fa8299f8b9b35fa4917383ac91e17 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Thu, 19 Apr 2018 19:01:45 -0500 Subject: [PATCH 042/197] Rename classed with term CompensationRequest to Compensation --- .../desktop/main/dao/proposal/ProposalDisplay.java | 14 +++++++------- .../main/dao/proposal/make/MakeProposalView.java | 10 +++++----- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java index e18935b0a40..463bca15086 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java @@ -31,8 +31,8 @@ import bisq.core.dao.consensus.vote.proposal.Proposal; import bisq.core.dao.consensus.vote.proposal.ProposalConsensus; import bisq.core.dao.consensus.vote.proposal.ProposalType; -import bisq.core.dao.consensus.vote.proposal.compensation.CompensationRequestConsensus; -import bisq.core.dao.consensus.vote.proposal.compensation.CompensationRequestProposal; +import bisq.core.dao.consensus.vote.proposal.compensation.CompensationConsensus; +import bisq.core.dao.consensus.vote.proposal.compensation.CompensationProposal; import bisq.core.locale.Res; import bisq.core.provider.fee.FeeService; @@ -136,7 +136,7 @@ public void createAllFields(String title, int gridRowStartIndex, double top, Pro BsqValidator bsqValidator = new BsqValidator(bsqFormatter); //TODO should we use the BSQ or a BTC validator? Technically it is BTC at that stage... //bsqValidator.setMinValue(feeService.getCreateCompensationRequestFee()); - bsqValidator.setMinValue(CompensationRequestConsensus.getMinCompensationRequestAmount()); + bsqValidator.setMinValue(CompensationConsensus.getMinCompensationRequestAmount()); Objects.requireNonNull(requestedBsqTextField).setValidator(bsqValidator); } // TODO validator, addressTF @@ -165,11 +165,11 @@ public void applyProposalPayload(Proposal proposal) { linkHyperlinkWithIcon.setManaged(true); linkHyperlinkWithIcon.setText(proposal.getLink()); linkHyperlinkWithIcon.setOnAction(e -> GUIUtil.openWebPage(proposal.getLink())); - if (proposal instanceof CompensationRequestProposal) { - CompensationRequestProposal compensationRequestProposal = (CompensationRequestProposal) proposal; - Objects.requireNonNull(requestedBsqTextField).setText(bsqFormatter.formatCoinWithCode(compensationRequestProposal.getRequestedBsq())); + if (proposal instanceof CompensationProposal) { + CompensationProposal compensationProposal = (CompensationProposal) proposal; + Objects.requireNonNull(requestedBsqTextField).setText(bsqFormatter.formatCoinWithCode(compensationProposal.getRequestedBsq())); if (bsqAddressTextField != null) - bsqAddressTextField.setText(compensationRequestProposal.getBsqAddress()); + bsqAddressTextField.setText(compensationProposal.getBsqAddress()); } if (txIdTextField != null) txIdTextField.setup(proposal.getTxId()); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index b39268ac423..67d7d5b5eb7 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -36,7 +36,7 @@ import bisq.core.dao.consensus.vote.proposal.ProposalConsensus; import bisq.core.dao.consensus.vote.proposal.ProposalType; import bisq.core.dao.consensus.vote.proposal.ValidationException; -import bisq.core.dao.consensus.vote.proposal.compensation.CompensationRequestService; +import bisq.core.dao.consensus.vote.proposal.compensation.CompensationService; import bisq.core.dao.consensus.vote.proposal.generic.GenericProposalService; import bisq.core.dao.consensus.vote.proposal.param.ChangeParamService; import bisq.core.dao.presentation.state.StateServiceFacade; @@ -84,7 +84,7 @@ public class MakeProposalView extends ActivatableView { private final P2PService p2PService; private final FeeService feeService; private final MyProposalService myProposalService; - private final CompensationRequestService compensationRequestService; + private final CompensationService compensationService; private final GenericProposalService genericProposalService; private final StateServiceFacade stateService; private final ChangeParamService changeParamService; @@ -105,7 +105,7 @@ private MakeProposalView(BsqWalletService bsqWalletService, P2PService p2PService, FeeService feeService, MyProposalService myProposalService, - CompensationRequestService compensationRequestService, + CompensationService compensationService, GenericProposalService genericProposalService, StateServiceFacade stateService, ChangeParamService changeParamService, @@ -116,7 +116,7 @@ private MakeProposalView(BsqWalletService bsqWalletService, this.p2PService = p2PService; this.feeService = feeService; this.myProposalService = myProposalService; - this.compensationRequestService = compensationRequestService; + this.compensationService = compensationService; this.genericProposalService = genericProposalService; this.stateService = stateService; this.changeParamService = changeParamService; @@ -216,7 +216,7 @@ private Tuple2 createProposal(ProposalType type) switch (type) { case COMPENSATION_REQUEST: - return compensationRequestService.makeTxAndGetCompensationRequest(proposalDisplay.nameTextField.getText(), + return compensationService.makeTxAndGetCompensationRequest(proposalDisplay.nameTextField.getText(), proposalDisplay.titleTextField.getText(), proposalDisplay.descriptionTextArea.getText(), proposalDisplay.linkInputTextField.getText(), From 8cf2b6c730fff348cd8c793f869a061442549a1e Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Thu, 19 Apr 2018 19:11:21 -0500 Subject: [PATCH 043/197] Deactivate removeAsset, generic adn changeParam domains. - To not have too much extra work while refactoring we deactivate those incomplete domains. Once refactoring is complete we apply the changes there. --- .../desktop/main/dao/proposal/make/MakeProposalView.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index 67d7d5b5eb7..37f17af7c14 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -223,11 +223,14 @@ private Tuple2 createProposal(ProposalType type) bsqFormatter.parseToCoin(Objects.requireNonNull(proposalDisplay.requestedBsqTextField).getText()), Objects.requireNonNull(proposalDisplay.bsqAddressTextField).getText()); case GENERIC: + //TODO + throw new RuntimeException("Not implemented yet"); + /* return genericProposalService.makeTxAndGetGenericProposal( proposalDisplay.nameTextField.getText(), proposalDisplay.titleTextField.getText(), proposalDisplay.descriptionTextArea.getText(), - proposalDisplay.linkInputTextField.getText()); + proposalDisplay.linkInputTextField.getText());*/ case CHANGE_PARAM: //TODO throw new RuntimeException("Not implemented yet"); From 20b2957eb905acd7794f050c09b480e4d81173d4 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Thu, 19 Apr 2018 20:11:25 -0500 Subject: [PATCH 044/197] Split Proposal into Proposal and ProposalPayload --- .../bisq/desktop/main/dao/proposal/BaseProposalView.java | 3 ++- .../bisq/desktop/main/dao/proposal/ProposalListItem.java | 6 +++++- .../main/dao/proposal/active/ActiveProposalsView.java | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java index 5909da5402e..9b87a851bc4 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java @@ -252,8 +252,9 @@ protected void doUpdateProposalList(List list) { proposalListItems.forEach(ProposalListItem::cleanup); proposalListItems.setAll(list.stream() - .map(proposal -> new ProposalListItem(proposal, + .map(ballot -> new ProposalListItem(ballot, proposalService, + myProposalService, periodService, bsqWalletService, stateService, diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index bd734156b2e..12a78c30a35 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -30,6 +30,7 @@ import bisq.core.dao.consensus.vote.BooleanVote; import bisq.core.dao.consensus.vote.Vote; import bisq.core.dao.consensus.vote.proposal.Ballot; +import bisq.core.dao.consensus.vote.proposal.MyProposalService; import bisq.core.dao.consensus.vote.proposal.ProposalService; import bisq.core.dao.presentation.period.PeriodServiceFacade; import bisq.core.dao.presentation.state.StateServiceFacade; @@ -59,6 +60,7 @@ public class ProposalListItem implements BlockListener { @Getter private final Ballot ballot; private final ProposalService proposalService; + private final MyProposalService myProposalService; private final PeriodServiceFacade periodService; private final BsqWalletService bsqWalletService; private final StateServiceFacade stateService; @@ -82,12 +84,14 @@ public class ProposalListItem implements BlockListener { ProposalListItem(Ballot ballot, ProposalService proposalService, + MyProposalService myProposalService, PeriodServiceFacade periodService, BsqWalletService bsqWalletService, StateServiceFacade stateService, BsqFormatter bsqFormatter) { this.ballot = ballot; this.proposalService = proposalService; + this.myProposalService = myProposalService; this.periodService = periodService; this.bsqWalletService = bsqWalletService; this.stateService = stateService; @@ -133,7 +137,7 @@ public void applyState(Phase newValue, Vote vote) { case UNDEFINED: break; case PROPOSAL: - if (proposalService.isMine(ballot.getProposal())) { + if (myProposalService.isMine(ballot.getProposal())) { actionButton.setVisible(!isTxInPastCycle); actionButtonIconView.setVisible(actionButton.isVisible()); actionButton.setText(Res.get("shared.remove")); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index 784ad06dfaa..1fb88ff89c4 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -275,7 +275,7 @@ protected void onPhaseChanged(Phase phase) { final Ballot ballot = selectedProposalListItem.getBallot(); switch (phase) { case PROPOSAL: - if (proposalService.isMine(ballot.getProposal())) { + if (myProposalService.isMine(ballot.getProposal())) { if (removeButton == null) { removeButton = addButtonAfterGroup(detailsGridPane, proposalDisplay.incrementAndGetGridRow(), Res.get("dao.proposal.active.remove")); removeButton.setOnAction(event -> onRemove()); From 006e682249e322c005437f61d8752dbf67e260bf Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Thu, 19 Apr 2018 20:17:42 -0500 Subject: [PATCH 045/197] Merge branch 'master' into voting # Conflicts: # src/main/java/bisq/desktop/main/account/content/fiataccounts/FiatAccountsView.java --- .../fiataccounts/FiatAccountsView.java | 27 ++++++------------- .../desktop/main/offer/EditableOfferView.java | 6 ++--- .../portfolio/openoffer/OpenOffersView.java | 6 ++--- .../java/bisq/desktop/util/FormBuilder.java | 7 ++--- 4 files changed, 14 insertions(+), 32 deletions(-) diff --git a/src/main/java/bisq/desktop/main/account/content/fiataccounts/FiatAccountsView.java b/src/main/java/bisq/desktop/main/account/content/fiataccounts/FiatAccountsView.java index b0428c93c80..907082f23b2 100644 --- a/src/main/java/bisq/desktop/main/account/content/fiataccounts/FiatAccountsView.java +++ b/src/main/java/bisq/desktop/main/account/content/fiataccounts/FiatAccountsView.java @@ -17,18 +17,6 @@ package bisq.desktop.main.account.content.fiataccounts; -import bisq.common.UserThread; -import bisq.common.util.Tuple2; -import bisq.common.util.Tuple3; -import bisq.core.app.BisqEnvironment; -import bisq.core.locale.Res; -import bisq.core.payment.AccountAgeWitnessService; -import bisq.core.payment.ClearXchangeAccount; -import bisq.core.payment.PaymentAccount; -import bisq.core.payment.PaymentAccountFactory; -import bisq.core.payment.WesternUnionAccount; -import bisq.core.payment.payload.PaymentMethod; -import bisq.core.util.validation.InputValidator; import bisq.desktop.common.view.ActivatableViewAndModel; import bisq.desktop.common.view.FxmlView; import bisq.desktop.components.AutoTooltipButton; @@ -110,20 +98,21 @@ import javafx.scene.layout.AnchorPane; import javafx.scene.layout.GridPane; import javafx.scene.text.TextAlignment; + +import javafx.geometry.VPos; + +import javafx.beans.value.ChangeListener; + +import javafx.collections.FXCollections; + import javafx.util.Callback; import javafx.util.StringConverter; -import org.bitcoinj.core.Coin; -import javax.inject.Inject; import java.util.List; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; -import static bisq.desktop.util.FormBuilder.add2ButtonsAfterGroup; -import static bisq.desktop.util.FormBuilder.add3ButtonsAfterGroup; -import static bisq.desktop.util.FormBuilder.addLabelComboBox; -import static bisq.desktop.util.FormBuilder.addLabelListView; -import static bisq.desktop.util.FormBuilder.addTitledGroupBg; +import static bisq.desktop.util.FormBuilder.*; @FxmlView public class FiatAccountsView extends ActivatableViewAndModel { diff --git a/src/main/java/bisq/desktop/main/offer/EditableOfferView.java b/src/main/java/bisq/desktop/main/offer/EditableOfferView.java index b9b2a25157b..2e4dad5c3dd 100644 --- a/src/main/java/bisq/desktop/main/offer/EditableOfferView.java +++ b/src/main/java/bisq/desktop/main/offer/EditableOfferView.java @@ -71,6 +71,8 @@ import net.glxn.qrgen.QRCode; import net.glxn.qrgen.image.ImageType; +import de.jensd.fx.glyphs.materialdesignicons.MaterialDesignIcon; + import javafx.scene.Node; import javafx.scene.control.Button; import javafx.scene.control.ComboBox; @@ -120,10 +122,6 @@ import static bisq.desktop.util.FormBuilder.*; import static javafx.beans.binding.Bindings.createStringBinding; - - -import de.jensd.fx.glyphs.materialdesignicons.MaterialDesignIcon; - public abstract class EditableOfferView extends ActivatableViewAndModel { protected final Navigation navigation; private final Preferences preferences; diff --git a/src/main/java/bisq/desktop/main/portfolio/openoffer/OpenOffersView.java b/src/main/java/bisq/desktop/main/portfolio/openoffer/OpenOffersView.java index 0630b02102b..d283fc7d335 100644 --- a/src/main/java/bisq/desktop/main/portfolio/openoffer/OpenOffersView.java +++ b/src/main/java/bisq/desktop/main/portfolio/openoffer/OpenOffersView.java @@ -38,6 +38,8 @@ import javax.inject.Inject; +import de.jensd.fx.glyphs.materialdesignicons.MaterialDesignIcon; + import javafx.fxml.FXML; import javafx.scene.control.Button; @@ -59,10 +61,6 @@ import static bisq.desktop.util.FormBuilder.getIconButton; - - -import de.jensd.fx.glyphs.materialdesignicons.MaterialDesignIcon; - @FxmlView public class OpenOffersView extends ActivatableViewAndModel { diff --git a/src/main/java/bisq/desktop/util/FormBuilder.java b/src/main/java/bisq/desktop/util/FormBuilder.java index 5e406a445d8..70ecc01291f 100644 --- a/src/main/java/bisq/desktop/util/FormBuilder.java +++ b/src/main/java/bisq/desktop/util/FormBuilder.java @@ -44,6 +44,8 @@ import de.jensd.fx.fontawesome.AwesomeDude; import de.jensd.fx.fontawesome.AwesomeIcon; +import de.jensd.fx.glyphs.GlyphIcons; +import de.jensd.fx.glyphs.materialdesignicons.utils.MaterialDesignIconFactory; import javafx.scene.Node; import javafx.scene.control.Button; @@ -77,11 +79,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; - - -import de.jensd.fx.glyphs.GlyphIcons; -import de.jensd.fx.glyphs.materialdesignicons.utils.MaterialDesignIconFactory; - public class FormBuilder { private static final Logger log = LoggerFactory.getLogger(FormBuilder.class); public static final String MATERIAL_DESIGN_ICONS = "'Material Design Icons'"; From 41b615527388ccfb2e4af528a53840fd7edbf65d Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Thu, 19 Apr 2018 20:51:03 -0500 Subject: [PATCH 046/197] Add option key daoActivated to enable all dao features for dev --- src/main/java/bisq/desktop/main/dao/DaoView.java | 2 +- src/main/java/bisq/desktop/main/offer/EditableOfferView.java | 2 +- .../java/bisq/desktop/main/offer/takeoffer/TakeOfferView.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/DaoView.java b/src/main/java/bisq/desktop/main/dao/DaoView.java index ab8ae989b60..e86494d8c70 100644 --- a/src/main/java/bisq/desktop/main/dao/DaoView.java +++ b/src/main/java/bisq/desktop/main/dao/DaoView.java @@ -73,7 +73,7 @@ public void initialize() { votingTab.setClosable(false); root.getTabs().addAll(compensationTab, votingTab); - if (!BisqEnvironment.isDAOActivatedAndBaseCurrencySupportingBsq() || !DevEnv.DAO_PHASE2_ACTIVATED) { + if (!BisqEnvironment.isDAOActivatedAndBaseCurrencySupportingBsq() || !DevEnv.isDaoPhase2Activated()) { votingTab.setDisable(true); compensationTab.setDisable(true); } diff --git a/src/main/java/bisq/desktop/main/offer/EditableOfferView.java b/src/main/java/bisq/desktop/main/offer/EditableOfferView.java index 2e4dad5c3dd..cee94163a96 100644 --- a/src/main/java/bisq/desktop/main/offer/EditableOfferView.java +++ b/src/main/java/bisq/desktop/main/offer/EditableOfferView.java @@ -952,7 +952,7 @@ private void addOptionsGroup() { GridPane.setMargin(nextButton, new Insets(-35, 0, 0, 0)); nextButton.setOnAction(e -> { if (model.isPriceInRange()) { - if (DevEnv.DAO_TRADING_ACTIVATED) + if (DevEnv.isDaoTradingActivated()) showFeeOption(); else onShowPayFundsScreen(); diff --git a/src/main/java/bisq/desktop/main/offer/takeoffer/TakeOfferView.java b/src/main/java/bisq/desktop/main/offer/takeoffer/TakeOfferView.java index 16d508a3096..02879f21b14 100644 --- a/src/main/java/bisq/desktop/main/offer/takeoffer/TakeOfferView.java +++ b/src/main/java/bisq/desktop/main/offer/takeoffer/TakeOfferView.java @@ -763,7 +763,7 @@ private void addButtons() { } private void showNextStepAfterAmountIsSet() { - if (DevEnv.DAO_TRADING_ACTIVATED) + if (DevEnv.isDaoTradingActivated()) showFeeOption(); else onShowPayFundsScreen(); From 4460882adc2fd730b771c5c220bc852b96f156b9 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Thu, 19 Apr 2018 22:57:39 -0500 Subject: [PATCH 047/197] Move code for writing to periodState to mutator class. - Use local periodState object in PeriodStateFacade --- .../main/dao/proposal/dashboard/ProposalDashboardView.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java index 3b2625eaab7..2832839021c 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java @@ -125,7 +125,7 @@ protected void activate() { }); }); - periodService.addBlockListener(this); + stateService.addBlockListener(this); // We need to delay as otherwise the periodService has not been updated yet. UserThread.execute(() -> onChainHeightChanged(periodService.getChainHeight())); @@ -134,7 +134,7 @@ protected void activate() { @Override protected void deactivate() { super.deactivate(); - periodService.removeBlockListener(this); + stateService.removeBlockListener(this); phaseSubscription.unsubscribe(); } From 01f4731700b8c9ab0b9444783a91bb2fe3949d0a Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Fri, 20 Apr 2018 00:03:54 -0500 Subject: [PATCH 048/197] Remove BlockListener from StateService - Use PeriodStateChangeListener instead of BlockListener for getting notified about block height changes. --- .../main/dao/proposal/BaseProposalView.java | 16 +++---- .../main/dao/proposal/ProposalListItem.java | 29 ++++++------ .../proposal/active/ActiveProposalsView.java | 8 ++-- .../proposal/closed/ClosedProposalsView.java | 4 +- .../dashboard/ProposalDashboardView.java | 33 +++++-------- .../dao/proposal/myvotes/MyVotesView.java | 6 +-- .../dao/proposal/myvotes/VoteListItem.java | 19 ++++---- .../wallet/dashboard/BsqDashboardView.java | 46 +++++++++--------- .../desktop/main/dao/wallet/tx/BsqTxView.java | 47 +++++++++---------- 9 files changed, 102 insertions(+), 106 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java index 9b87a851bc4..8a897e6f9fa 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java @@ -74,6 +74,7 @@ public abstract class BaseProposalView extends ActivatableView { protected final MyProposalService myProposalService; protected final StateServiceFacade stateService; + protected final PeriodServiceFacade periodServiceFacade; protected final ChangeParamService changeParamService; protected final ProposalListService proposalListService; protected final ProposalService proposalService; @@ -92,7 +93,6 @@ public abstract class BaseProposalView extends ActivatableView { protected ProposalListItem selectedProposalListItem; protected ListChangeListener proposalListChangeListener; protected ChangeListener phaseChangeListener; - protected final PeriodServiceFacade periodService; protected Phase currentPhase; protected Subscription phaseSubscription; private ScrollPane proposalDisplayView; @@ -108,8 +108,8 @@ protected BaseProposalView(MyProposalService myProposalService, ProposalService proposalService, BsqWalletService bsqWalletService, StateServiceFacade stateService, + PeriodServiceFacade periodServiceFacade, ChangeParamService changeParamService, - PeriodServiceFacade periodService, BsqFormatter bsqFormatter, BSFormatter btcFormatter) { this.myProposalService = myProposalService; @@ -117,8 +117,8 @@ protected BaseProposalView(MyProposalService myProposalService, this.proposalService = proposalService; this.bsqWalletService = bsqWalletService; this.stateService = stateService; + this.periodServiceFacade = periodServiceFacade; this.changeParamService = changeParamService; - this.periodService = periodService; this.bsqFormatter = bsqFormatter; this.btcFormatter = btcFormatter; } @@ -136,12 +136,12 @@ public void initialize() { @Override protected void activate() { - phaseSubscription = EasyBind.subscribe(periodService.phaseProperty(), this::onPhaseChanged); + phaseSubscription = EasyBind.subscribe(periodServiceFacade.phaseProperty(), this::onPhaseChanged); selectedProposalSubscription = EasyBind.subscribe(proposalTableView.getSelectionModel().selectedItemProperty(), this::onSelectProposal); - periodService.phaseProperty().addListener(phaseChangeListener); + periodServiceFacade.phaseProperty().addListener(phaseChangeListener); - onPhaseChanged(periodService.phaseProperty().get()); + onPhaseChanged(periodServiceFacade.phaseProperty().get()); sortedList.comparatorProperty().bind(proposalTableView.comparatorProperty()); @@ -153,7 +153,7 @@ protected void deactivate() { phaseSubscription.unsubscribe(); selectedProposalSubscription.unsubscribe(); - periodService.phaseProperty().removeListener(phaseChangeListener); + periodServiceFacade.phaseProperty().removeListener(phaseChangeListener); sortedList.comparatorProperty().unbind(); @@ -255,7 +255,7 @@ protected void doUpdateProposalList(List list) { .map(ballot -> new ProposalListItem(ballot, proposalService, myProposalService, - periodService, + periodServiceFacade, bsqWalletService, stateService, bsqFormatter)) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index 12a78c30a35..50ac189f847 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -23,9 +23,8 @@ import bisq.core.btc.listeners.TxConfidenceListener; import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.dao.consensus.period.PeriodStateChangeListener; import bisq.core.dao.consensus.period.Phase; -import bisq.core.dao.consensus.state.Block; -import bisq.core.dao.consensus.state.BlockListener; import bisq.core.dao.consensus.state.blockchain.Tx; import bisq.core.dao.consensus.vote.BooleanVote; import bisq.core.dao.consensus.vote.Vote; @@ -56,12 +55,12 @@ @ToString @Slf4j @EqualsAndHashCode -public class ProposalListItem implements BlockListener { +public class ProposalListItem implements PeriodStateChangeListener { @Getter private final Ballot ballot; private final ProposalService proposalService; private final MyProposalService myProposalService; - private final PeriodServiceFacade periodService; + private final PeriodServiceFacade periodServiceFacade; private final BsqWalletService bsqWalletService; private final StateServiceFacade stateService; private final BsqFormatter bsqFormatter; @@ -85,16 +84,16 @@ public class ProposalListItem implements BlockListener { ProposalListItem(Ballot ballot, ProposalService proposalService, MyProposalService myProposalService, - PeriodServiceFacade periodService, + PeriodServiceFacade periodServiceFacade, BsqWalletService bsqWalletService, - StateServiceFacade stateService, + StateServiceFacade stateServiceFacade, BsqFormatter bsqFormatter) { this.ballot = ballot; this.proposalService = proposalService; this.myProposalService = myProposalService; - this.periodService = periodService; + this.periodServiceFacade = periodServiceFacade; this.bsqWalletService = bsqWalletService; - this.stateService = stateService; + this.stateService = stateServiceFacade; this.bsqFormatter = bsqFormatter; @@ -113,17 +112,17 @@ public class ProposalListItem implements BlockListener { bsqWalletService.getChainHeightProperty().addListener(chainHeightListener); setupConfidence(); - stateService.addBlockListener(this); + periodServiceFacade.addPeriodStateChangeListener(this); phaseChangeListener = (observable, oldValue, newValue) -> { applyState(newValue, ballot.getVote()); }; voteResultChangeListener = (observable, oldValue, newValue) -> { - applyState(periodService.phaseProperty().get(), newValue); + applyState(periodServiceFacade.phaseProperty().get(), newValue); }; - periodService.phaseProperty().addListener(phaseChangeListener); + periodServiceFacade.phaseProperty().addListener(phaseChangeListener); ballot.getVoteResultProperty().addListener(voteResultChangeListener); } @@ -131,7 +130,7 @@ public void applyState(Phase newValue, Vote vote) { actionButton.setText(""); actionButton.setVisible(false); actionButton.setOnAction(null); - final boolean isTxInPastCycle = periodService.isTxInPastCycle(ballot.getTxId(), + final boolean isTxInPastCycle = periodServiceFacade.isTxInPastCycle(ballot.getTxId(), stateService.getChainHeight()); switch (newValue) { case UNDEFINED: @@ -196,7 +195,7 @@ public void applyState(Phase newValue, Vote vote) { /////////////////////////////////////////////////////////////////////////////////////////// @Override - public void onBlockAdded(Block block) { + public void onChainHeightChanged(int chainHeight) { //TODO do we want that here??? setupConfidence(); } @@ -247,12 +246,12 @@ private void updateConfidence(TransactionConfidence confidence, int depthInBlock } public void cleanup() { - stateService.removeBlockListener(this); + periodServiceFacade.removePeriodStateChangeListener(this); bsqWalletService.getChainHeightProperty().removeListener(chainHeightListener); if (txConfidenceListener != null) bsqWalletService.removeTxConfidenceListener(txConfidenceListener); - periodService.phaseProperty().removeListener(phaseChangeListener); + periodServiceFacade.phaseProperty().removeListener(phaseChangeListener); ballot.getVoteResultProperty().removeListener(voteResultChangeListener); } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index 1fb88ff89c4..639785ce958 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -92,7 +92,7 @@ public class ActiveProposalsView extends BaseProposalView implements BsqBalanceL private ActiveProposalsView(MyProposalService myProposalService, ProposalListService proposalListService, ProposalService proposalService, - PeriodServiceFacade periodService, + PeriodServiceFacade periodServiceFacade, MyVoteService myVoteService, BsqWalletService bsqWalletService, StateServiceFacade stateService, @@ -101,7 +101,7 @@ private ActiveProposalsView(MyProposalService myProposalService, BSFormatter btcFormatter) { super(myProposalService, proposalListService, proposalService, bsqWalletService, stateService, - changeParamService, periodService, bsqFormatter, btcFormatter); + periodServiceFacade, changeParamService, bsqFormatter, btcFormatter); this.myVoteService = myVoteService; } @@ -238,7 +238,7 @@ protected void onSelectProposal(ProposalListItem item) { cancelVoteButton = null; } - onPhaseChanged(periodService.phaseProperty().get()); + onPhaseChanged(periodServiceFacade.phaseProperty().get()); } } @@ -270,7 +270,7 @@ protected void onPhaseChanged(Phase phase) { } if (selectedProposalListItem != null && proposalDisplay != null && - !periodService.isTxInPastCycle(selectedProposalListItem.getBallot().getTxId(), + !periodServiceFacade.isTxInPastCycle(selectedProposalListItem.getBallot().getTxId(), stateService.getChainHeight())) { final Ballot ballot = selectedProposalListItem.getBallot(); switch (phase) { diff --git a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java index 120a3a5d601..67684ce8f0b 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java @@ -43,7 +43,7 @@ public class ClosedProposalsView extends BaseProposalView { private ClosedProposalsView(MyProposalService myProposalService, ProposalListService proposalListService, ProposalService proposalService, - PeriodServiceFacade periodService, + PeriodServiceFacade periodServiceFacade, BsqWalletService bsqWalletService, StateServiceFacade stateService, ChangeParamService changeParamService, @@ -51,7 +51,7 @@ private ClosedProposalsView(MyProposalService myProposalService, BSFormatter btcFormatter) { super(myProposalService, proposalListService, proposalService, bsqWalletService, stateService, - changeParamService, periodService, bsqFormatter, btcFormatter); + periodServiceFacade, changeParamService, bsqFormatter, btcFormatter); } @Override diff --git a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java index 2832839021c..e43afea1f6c 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java @@ -22,9 +22,8 @@ import bisq.desktop.components.SeparatedPhaseBars; import bisq.desktop.util.Layout; +import bisq.core.dao.consensus.period.PeriodStateChangeListener; import bisq.core.dao.consensus.period.Phase; -import bisq.core.dao.consensus.state.Block; -import bisq.core.dao.consensus.state.BlockListener; import bisq.core.dao.presentation.period.PeriodServiceFacade; import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; @@ -47,11 +46,10 @@ import static bisq.desktop.util.FormBuilder.addTitledGroupBg; @FxmlView -public class ProposalDashboardView extends ActivatableView implements BlockListener { +public class ProposalDashboardView extends ActivatableView implements PeriodStateChangeListener { private List phaseBarsItems; - private final PeriodServiceFacade periodService; - private final StateServiceFacade stateService; + private final PeriodServiceFacade periodServiceFacade; private Phase currentPhase; private Subscription phaseSubscription; private GridPane gridPane; @@ -64,9 +62,8 @@ public class ProposalDashboardView extends ActivatableView imple /////////////////////////////////////////////////////////////////////////////////////////// @Inject - private ProposalDashboardView(PeriodServiceFacade periodService, StateServiceFacade stateService) { - this.periodService = periodService; - this.stateService = stateService; + private ProposalDashboardView(PeriodServiceFacade periodServiceFacade, StateServiceFacade stateService) { + this.periodServiceFacade = periodServiceFacade; } @Override @@ -112,7 +109,7 @@ private SeparatedPhaseBars createSeparatedPhaseBars() { protected void activate() { super.activate(); - phaseSubscription = EasyBind.subscribe(periodService.phaseProperty(), phase -> { + phaseSubscription = EasyBind.subscribe(periodServiceFacade.phaseProperty(), phase -> { if (!phase.equals(this.currentPhase)) { this.currentPhase = phase; } @@ -125,31 +122,27 @@ protected void activate() { }); }); - stateService.addBlockListener(this); + periodServiceFacade.addPeriodStateChangeListener(this); // We need to delay as otherwise the periodService has not been updated yet. - UserThread.execute(() -> onChainHeightChanged(periodService.getChainHeight())); + UserThread.execute(() -> onChainHeightChanged(periodServiceFacade.getChainHeight())); } @Override protected void deactivate() { super.deactivate(); - stateService.removeBlockListener(this); + periodServiceFacade.removePeriodStateChangeListener(this); phaseSubscription.unsubscribe(); } @Override - public void onBlockAdded(Block block) { - onChainHeightChanged(block.getHeight()); - } - - private void onChainHeightChanged(int height) { + public void onChainHeightChanged(int height) { if (height > 0) { separatedPhaseBars.updateWidth(); phaseBarsItems.forEach(item -> { - int firstBlock = periodService.getFirstBlockOfPhase(height, item.getPhase()); - int lastBlock = periodService.getLastBlockOfPhase(height, item.getPhase()); - final int duration = periodService.getDurationForPhase(item.getPhase(), periodService.getChainHeight()); + int firstBlock = periodServiceFacade.getFirstBlockOfPhase(height, item.getPhase()); + int lastBlock = periodServiceFacade.getLastBlockOfPhase(height, item.getPhase()); + final int duration = periodServiceFacade.getDurationForPhase(item.getPhase(), periodServiceFacade.getChainHeight()); item.setPeriodRange(firstBlock, lastBlock, duration); double progress = 0; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java index a8e76a9497e..cec4951998b 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java @@ -93,9 +93,9 @@ public class MyVotesView extends BaseProposalView { private MyVotesView(MyProposalService myProposalService, ProposalListService proposalListService, ProposalService proposalService, - PeriodServiceFacade periodService, BsqWalletService bsqWalletService, StateServiceFacade stateService, + PeriodServiceFacade periodServiceFacade, ChangeParamService changeParamService, BsqFormatter bsqFormatter, BSFormatter btcFormatter, @@ -103,7 +103,7 @@ private MyVotesView(MyProposalService myProposalService, Preferences preferences) { super(myProposalService, proposalListService, proposalService, bsqWalletService, stateService, - changeParamService, periodService, bsqFormatter, btcFormatter); + periodServiceFacade, changeParamService, bsqFormatter, btcFormatter); this.myVoteService = myVoteService; this.preferences = preferences; } @@ -130,7 +130,7 @@ protected void activate() { voteListItems.clear(); List items = myVoteService.getMyVoteList().stream() - .map(vote -> new VoteListItem(vote, bsqWalletService, stateService, bsqFormatter)) + .map(vote -> new VoteListItem(vote, bsqWalletService, stateService, periodServiceFacade, bsqFormatter)) .collect(Collectors.toList()); voteListItems.addAll(items); } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java index 3485b060588..5b5d3a0a5ec 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java @@ -22,11 +22,11 @@ import bisq.core.btc.listeners.TxConfidenceListener; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.consensus.state.Block; -import bisq.core.dao.consensus.state.BlockListener; +import bisq.core.dao.consensus.period.PeriodStateChangeListener; import bisq.core.dao.consensus.state.blockchain.Tx; import bisq.core.dao.consensus.state.blockchain.TxOutput; import bisq.core.dao.consensus.vote.myvote.MyVote; +import bisq.core.dao.presentation.period.PeriodServiceFacade; import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; @@ -51,11 +51,12 @@ @ToString @Slf4j @EqualsAndHashCode -public class VoteListItem implements BlockListener { +public class VoteListItem implements PeriodStateChangeListener { @Getter private final MyVote myVote; private final BsqWalletService bsqWalletService; private final StateServiceFacade stateService; + private final PeriodServiceFacade periodServiceFacade; private final BsqFormatter bsqFormatter; private final ChangeListener chainHeightListener; @Getter @@ -75,11 +76,13 @@ public class VoteListItem implements BlockListener { VoteListItem(MyVote myVote, BsqWalletService bsqWalletService, - StateServiceFacade stateService, + StateServiceFacade stateServiceFacade, + PeriodServiceFacade periodServiceFacade, BsqFormatter bsqFormatter) { this.myVote = myVote; this.bsqWalletService = bsqWalletService; - this.stateService = stateService; + this.stateService = stateServiceFacade; + this.periodServiceFacade = periodServiceFacade; this.bsqFormatter = bsqFormatter; txConfidenceIndicator = new TxConfidenceIndicator(); @@ -88,7 +91,7 @@ public class VoteListItem implements BlockListener { txConfidenceIndicator.setProgress(-1); txConfidenceIndicator.setPrefSize(24, 24); txConfidenceIndicator.setTooltip(tooltip); - stateService.addBlockListener(this); + periodServiceFacade.addPeriodStateChangeListener(this); chainHeightListener = (observable, oldValue, newValue) -> setupConfidence(); bsqWalletService.getChainHeightProperty().addListener(chainHeightListener); @@ -102,7 +105,7 @@ public class VoteListItem implements BlockListener { /////////////////////////////////////////////////////////////////////////////////////////// @Override - public void onBlockAdded(Block block) { + public void onChainHeightChanged(int chainHeight) { //TODO do we want that here??? setupConfidence(); } @@ -167,7 +170,7 @@ private void updateConfidence(TransactionConfidence confidence, int depthInBlock public void cleanup() { bsqWalletService.getChainHeightProperty().removeListener(chainHeightListener); - stateService.removeBlockListener(this); + periodServiceFacade.removePeriodStateChangeListener(this); if (txConfidenceListener != null) bsqWalletService.removeTxConfidenceListener(txConfidenceListener); } diff --git a/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java b/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java index 22394bcb804..3acefff843a 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java @@ -26,8 +26,8 @@ import bisq.desktop.util.GUIUtil; import bisq.desktop.util.Layout; -import bisq.core.dao.consensus.state.Block; -import bisq.core.dao.consensus.state.BlockListener; +import bisq.core.dao.consensus.period.PeriodStateChangeListener; +import bisq.core.dao.presentation.period.PeriodServiceFacade; import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; import bisq.core.monetary.Altcoin; @@ -57,10 +57,11 @@ import static bisq.desktop.util.FormBuilder.addTitledGroupBg; @FxmlView -public class BsqDashboardView extends ActivatableView implements BlockListener { +public class BsqDashboardView extends ActivatableView implements PeriodStateChangeListener { private final BsqBalanceUtil bsqBalanceUtil; - private final StateServiceFacade stateService; + private final StateServiceFacade stateServiceFacade; + private final PeriodServiceFacade periodServiceFacade; private final PriceFeedService priceFeedService; private final Preferences preferences; private final BsqFormatter bsqFormatter; @@ -79,12 +80,14 @@ public class BsqDashboardView extends ActivatableView implements @Inject private BsqDashboardView(BsqBalanceUtil bsqBalanceUtil, - StateServiceFacade stateService, + StateServiceFacade stateServiceFacade, + PeriodServiceFacade periodServiceFacade, PriceFeedService priceFeedService, Preferences preferences, BsqFormatter bsqFormatter) { this.bsqBalanceUtil = bsqBalanceUtil; - this.stateService = stateService; + this.stateServiceFacade = stateServiceFacade; + this.periodServiceFacade = periodServiceFacade; this.priceFeedService = priceFeedService; this.preferences = preferences; this.bsqFormatter = bsqFormatter; @@ -97,13 +100,13 @@ public void initialize() { addTitledGroupBg(root, ++gridRow, 11, Res.get("dao.wallet.dashboard.statistics"), Layout.GROUP_DISTANCE); addLabelTextField(root, gridRow, Res.get("dao.wallet.dashboard.genesisBlockHeight"), - String.valueOf(stateService.getGenesisBlockHeight()), Layout.FIRST_ROW_AND_GROUP_DISTANCE); + String.valueOf(stateServiceFacade.getGenesisBlockHeight()), Layout.FIRST_ROW_AND_GROUP_DISTANCE); Label label = new AutoTooltipLabel(Res.get("dao.wallet.dashboard.genesisTxId")); GridPane.setRowIndex(label, ++gridRow); root.getChildren().add(label); - hyperlinkWithIcon = new HyperlinkWithIcon(stateService.getGenesisTxId(), AwesomeIcon.EXTERNAL_LINK); - hyperlinkWithIcon.setTooltip(new Tooltip(Res.get("tooltip.openBlockchainForTx", stateService.getGenesisTxId()))); + hyperlinkWithIcon = new HyperlinkWithIcon(stateServiceFacade.getGenesisTxId(), AwesomeIcon.EXTERNAL_LINK); + hyperlinkWithIcon.setTooltip(new Tooltip(Res.get("tooltip.openBlockchainForTx", stateServiceFacade.getGenesisTxId()))); GridPane.setRowIndex(hyperlinkWithIcon, gridRow); GridPane.setColumnIndex(hyperlinkWithIcon, 1); GridPane.setMargin(hyperlinkWithIcon, new Insets(0, 0, 0, -4)); @@ -129,10 +132,10 @@ public void initialize() { protected void activate() { bsqBalanceUtil.activate(); - stateService.addBlockListener(this); + periodServiceFacade.addPeriodStateChangeListener(this); priceFeedService.updateCounterProperty().addListener(priceChangeListener); - hyperlinkWithIcon.setOnAction(event -> GUIUtil.openWebPage(preferences.getBsqBlockChainExplorer().txUrl + stateService.getGenesisTxId())); + hyperlinkWithIcon.setOnAction(event -> GUIUtil.openWebPage(preferences.getBsqBlockChainExplorer().txUrl + stateServiceFacade.getGenesisTxId())); updateWithBsqBlockChainData(); updatePrice(); @@ -141,42 +144,41 @@ protected void activate() { @Override protected void deactivate() { bsqBalanceUtil.deactivate(); - stateService.removeBlockListener(this); + periodServiceFacade.addPeriodStateChangeListener(this); priceFeedService.updateCounterProperty().removeListener(priceChangeListener); hyperlinkWithIcon.setOnAction(null); } /////////////////////////////////////////////////////////////////////////////////////////// - // BlockListener + // PeriodStateChangeListener /////////////////////////////////////////////////////////////////////////////////////////// @Override - public void onBlockAdded(Block block) { + public void onChainHeightChanged(int chainHeight) { updateWithBsqBlockChainData(); } - private void updateWithBsqBlockChainData() { - final Coin issuedAmountFromGenesis = stateService.getGenesisTotalSupply(); + final Coin issuedAmountFromGenesis = stateServiceFacade.getGenesisTotalSupply(); genesisIssueAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(issuedAmountFromGenesis)); - final Coin issuedAmountFromCompRequests = Coin.valueOf(stateService.getTotalIssuedAmountFromCompRequests()); + final Coin issuedAmountFromCompRequests = Coin.valueOf(stateServiceFacade.getTotalIssuedAmountFromCompRequests()); compRequestIssueAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(issuedAmountFromCompRequests)); - final Coin burntFee = Coin.valueOf(stateService.getTotalBurntFee()); + final Coin burntFee = Coin.valueOf(stateServiceFacade.getTotalBurntFee()); final Coin availableAmount = issuedAmountFromGenesis.add(issuedAmountFromCompRequests).subtract(burntFee); availableAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(availableAmount)); burntAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(burntFee)); - allTxTextField.setText(String.valueOf(stateService.getTxs().size())); - utxoTextField.setText(String.valueOf(stateService.getUnspentTxOutputs().size())); + allTxTextField.setText(String.valueOf(stateServiceFacade.getTxs().size())); + utxoTextField.setText(String.valueOf(stateServiceFacade.getUnspentTxOutputs().size())); //spentTxTextField.setText(String.valueOf(stateService.getSpentTxOutputs().size())); - burntTxTextField.setText(String.valueOf(stateService.getFeeTxs().size())); + burntTxTextField.setText(String.valueOf(stateServiceFacade.getFeeTxs().size())); } private void updatePrice() { - final Coin issuedAmount = stateService.getGenesisTotalSupply(); + final Coin issuedAmount = stateServiceFacade.getGenesisTotalSupply(); final MarketPrice bsqMarketPrice = priceFeedService.getMarketPrice("BSQ"); if (bsqMarketPrice != null) { long bsqPrice = MathUtils.roundDoubleToLong(MathUtils.scaleUpByPowerOf10(bsqMarketPrice.getPrice(), Altcoin.SMALLEST_UNIT_EXPONENT)); diff --git a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java index 124691f30fb..00b957d5e63 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java @@ -32,10 +32,10 @@ import bisq.core.btc.wallet.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; -import bisq.core.dao.consensus.state.Block; -import bisq.core.dao.consensus.state.BlockListener; +import bisq.core.dao.consensus.period.PeriodStateChangeListener; import bisq.core.dao.consensus.state.blockchain.Tx; import bisq.core.dao.consensus.state.blockchain.TxType; +import bisq.core.dao.presentation.period.PeriodServiceFacade; import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; import bisq.core.user.Preferences; @@ -81,14 +81,15 @@ import java.util.stream.Collectors; @FxmlView -public class BsqTxView extends ActivatableView implements BsqBalanceListener, BlockListener { +public class BsqTxView extends ActivatableView implements BsqBalanceListener, PeriodStateChangeListener { private TableView tableView; private Pane rootParent; private final BsqFormatter bsqFormatter; private final BsqWalletService bsqWalletService; - private final StateServiceFacade stateService; + private final StateServiceFacade stateServiceFacade; + private final PeriodServiceFacade periodServiceFacade; private final BtcWalletService btcWalletService; private final BsqBalanceUtil bsqBalanceUtil; private final Preferences preferences; @@ -112,13 +113,15 @@ public class BsqTxView extends ActivatableView implements BsqBal private BsqTxView(BsqFormatter bsqFormatter, BsqWalletService bsqWalletService, Preferences preferences, - StateServiceFacade stateService, + StateServiceFacade stateServiceFacade, + PeriodServiceFacade periodServiceFacade, BtcWalletService btcWalletService, BsqBalanceUtil bsqBalanceUtil) { this.bsqFormatter = bsqFormatter; this.bsqWalletService = bsqWalletService; this.preferences = preferences; - this.stateService = stateService; + this.stateServiceFacade = stateServiceFacade; + this.periodServiceFacade = periodServiceFacade; this.btcWalletService = btcWalletService; this.bsqBalanceUtil = bsqBalanceUtil; } @@ -163,7 +166,8 @@ public void initialize() { walletBsqTransactionsListener = change -> updateList(); parentHeightListener = (observable, oldValue, newValue) -> layout(); - chainHeightChangedListener = (observable, oldValue, newValue) -> onChainHeightChanged(); + //TODO do we want to get notified from wallet side? + chainHeightChangedListener = (observable, oldValue, newValue) -> onChainHeightChanged((int) newValue); } @Override @@ -176,7 +180,7 @@ protected void activate() { sortedList.comparatorProperty().bind(tableView.comparatorProperty()); tableView.setItems(sortedList); - stateService.addBlockListener(this); + periodServiceFacade.addPeriodStateChangeListener(this); if (root.getParent() instanceof Pane) { rootParent = (Pane) root.getParent(); @@ -184,7 +188,7 @@ protected void activate() { } updateList(); - onChainHeightChanged(); + onChainHeightChanged(periodServiceFacade.getChainHeight()); layout(); } @@ -195,7 +199,7 @@ protected void deactivate() { bsqWalletService.getWalletTransactions().removeListener(walletBsqTransactionsListener); bsqWalletService.removeBsqBalanceListener(this); btcWalletService.getChainHeightProperty().removeListener(chainHeightChangedListener); - stateService.removeBlockListener(this); + periodServiceFacade.removePeriodStateChangeListener(this); observableList.forEach(BsqTxListItem::cleanup); @@ -218,14 +222,9 @@ public void onUpdateBalances(Coin confirmedBalance, /////////////////////////////////////////////////////////////////////////////////////////// @Override - public void onBlockAdded(Block block) { - onChainHeightChanged(); - } - - - private void onChainHeightChanged() { + public void onChainHeightChanged(int chainHeight) { final int bsqWalletChainHeight = bsqWalletService.getChainHeightProperty().get(); - final int bsqBlockChainHeight = stateService.getChainHeight(); + final int bsqBlockChainHeight = periodServiceFacade.getChainHeight(); if (bsqWalletChainHeight > 0) { final boolean synced = bsqWalletChainHeight == bsqBlockChainHeight; chainSyncIndicator.setVisible(!synced); @@ -256,13 +255,13 @@ private void updateList() { final List walletTransactions = new ArrayList<>(bsqWalletService.getWalletTransactions()); List items = walletTransactions.stream() .map(transaction -> { - final Optional optionalTx = stateService.getTx(transaction.getHashAsString()); + final Optional optionalTx = stateServiceFacade.getTx(transaction.getHashAsString()); return new BsqTxListItem(transaction, optionalTx, bsqWalletService, btcWalletService, - stateService, - stateService.hasTxBurntFee(transaction.getHashAsString()), + stateServiceFacade, + stateServiceFacade.hasTxBurntFee(transaction.getHashAsString()), transaction.getUpdateTime(), bsqFormatter); }) @@ -372,7 +371,7 @@ public void updateItem(final BsqTxListItem item, boolean empty) { if (txType == TxType.COMPENSATION_REQUEST && optionalTx.isPresent() && - stateService.isIssuanceTx(optionalTx.get().getId())) { + stateServiceFacade.isIssuanceTx(optionalTx.get().getId())) { if (field != null) field.setOnAction(null); @@ -534,11 +533,11 @@ public void updateItem(final BsqTxListItem item, boolean empty) { case PROPOSAL: case COMPENSATION_REQUEST: final String txId = item.getOptionalTx().get().getId(); - if (item.getOptionalTx().isPresent() && stateService.isIssuanceTx(txId)) { + if (item.getOptionalTx().isPresent() && stateServiceFacade.isIssuanceTx(txId)) { awesomeIcon = AwesomeIcon.MONEY; style = "dao-tx-type-issuance-icon"; - final int issuanceBlockHeight = stateService.getIssuanceBlockHeight(txId); - long blockTimeInSec = stateService.getBlockTime(issuanceBlockHeight); + final int issuanceBlockHeight = stateServiceFacade.getIssuanceBlockHeight(txId); + long blockTimeInSec = stateServiceFacade.getBlockTime(issuanceBlockHeight); final String formattedDate = bsqFormatter.formatDateTime(new Date(blockTimeInSec * 1000)); toolTipText = Res.get("dao.tx.issuance.tooltip", formattedDate); } else { From 5bdef18fcb29ec23092f6089d0c3a7542cbc5e76 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Fri, 20 Apr 2018 10:39:37 -0500 Subject: [PATCH 049/197] Move bisq.core.dao.consensus.vote.myvote package to bisq.core.dao --- .../desktop/main/dao/proposal/active/ActiveProposalsView.java | 2 +- .../bisq/desktop/main/dao/proposal/make/MakeProposalView.java | 2 +- .../bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java | 2 +- .../bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index 639785ce958..4470641f9aa 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -36,12 +36,12 @@ import bisq.core.dao.consensus.period.Phase; import bisq.core.dao.consensus.vote.BooleanVote; import bisq.core.dao.consensus.vote.blindvote.BlindVoteConsensus; -import bisq.core.dao.consensus.vote.myvote.MyVoteService; import bisq.core.dao.consensus.vote.proposal.Ballot; import bisq.core.dao.consensus.vote.proposal.MyProposalService; import bisq.core.dao.consensus.vote.proposal.ProposalListService; import bisq.core.dao.consensus.vote.proposal.ProposalService; import bisq.core.dao.consensus.vote.proposal.param.ChangeParamService; +import bisq.core.dao.presentation.myvote.MyVoteService; import bisq.core.dao.presentation.period.PeriodServiceFacade; import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index 37f17af7c14..1f1cc0d4ddf 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -31,11 +31,11 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.InsufficientBsqException; import bisq.core.btc.wallet.WalletsSetup; +import bisq.core.dao.ValidationException; import bisq.core.dao.consensus.vote.proposal.Ballot; import bisq.core.dao.consensus.vote.proposal.MyProposalService; import bisq.core.dao.consensus.vote.proposal.ProposalConsensus; import bisq.core.dao.consensus.vote.proposal.ProposalType; -import bisq.core.dao.consensus.vote.proposal.ValidationException; import bisq.core.dao.consensus.vote.proposal.compensation.CompensationService; import bisq.core.dao.consensus.vote.proposal.generic.GenericProposalService; import bisq.core.dao.consensus.vote.proposal.param.ChangeParamService; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java index cec4951998b..f50c121ec60 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java @@ -32,12 +32,12 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.consensus.vote.BooleanVote; import bisq.core.dao.consensus.vote.Vote; -import bisq.core.dao.consensus.vote.myvote.MyVoteService; import bisq.core.dao.consensus.vote.proposal.BallotList; import bisq.core.dao.consensus.vote.proposal.MyProposalService; import bisq.core.dao.consensus.vote.proposal.ProposalListService; import bisq.core.dao.consensus.vote.proposal.ProposalService; import bisq.core.dao.consensus.vote.proposal.param.ChangeParamService; +import bisq.core.dao.presentation.myvote.MyVoteService; import bisq.core.dao.presentation.period.PeriodServiceFacade; import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java index 5b5d3a0a5ec..e186d9d51f4 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java @@ -25,7 +25,7 @@ import bisq.core.dao.consensus.period.PeriodStateChangeListener; import bisq.core.dao.consensus.state.blockchain.Tx; import bisq.core.dao.consensus.state.blockchain.TxOutput; -import bisq.core.dao.consensus.vote.myvote.MyVote; +import bisq.core.dao.presentation.myvote.MyVote; import bisq.core.dao.presentation.period.PeriodServiceFacade; import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; From 2e959715027f9337cbcdb4c6632ac0619418e196 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Fri, 20 Apr 2018 11:28:58 -0500 Subject: [PATCH 050/197] Add BlockListener - Reintroduce BlockListener and use it instead of PeriodStateChangeListener in most use cases as we are usually interested in the event when a block is complete not when the periods service chain height change gets triggered before parsing starts. --- .../main/dao/proposal/ProposalListItem.java | 21 ++++---- .../dashboard/ProposalDashboardView.java | 10 ++-- .../dao/proposal/myvotes/VoteListItem.java | 21 ++++---- .../wallet/dashboard/BsqDashboardView.java | 17 +++---- .../desktop/main/dao/wallet/tx/BsqTxView.java | 49 ++++++++++--------- .../main/offer/offerbook/OfferBook.java | 2 +- 6 files changed, 62 insertions(+), 58 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index 50ac189f847..7257e3a444a 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -23,8 +23,9 @@ import bisq.core.btc.listeners.TxConfidenceListener; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.consensus.period.PeriodStateChangeListener; import bisq.core.dao.consensus.period.Phase; +import bisq.core.dao.consensus.state.Block; +import bisq.core.dao.consensus.state.BlockListener; import bisq.core.dao.consensus.state.blockchain.Tx; import bisq.core.dao.consensus.vote.BooleanVote; import bisq.core.dao.consensus.vote.Vote; @@ -55,14 +56,14 @@ @ToString @Slf4j @EqualsAndHashCode -public class ProposalListItem implements PeriodStateChangeListener { +public class ProposalListItem implements BlockListener { @Getter private final Ballot ballot; private final ProposalService proposalService; private final MyProposalService myProposalService; private final PeriodServiceFacade periodServiceFacade; private final BsqWalletService bsqWalletService; - private final StateServiceFacade stateService; + private final StateServiceFacade stateServiceFacade; private final BsqFormatter bsqFormatter; private final ChangeListener chainHeightListener; private final ChangeListener voteResultChangeListener; @@ -93,7 +94,7 @@ public class ProposalListItem implements PeriodStateChangeListener { this.myProposalService = myProposalService; this.periodServiceFacade = periodServiceFacade; this.bsqWalletService = bsqWalletService; - this.stateService = stateServiceFacade; + this.stateServiceFacade = stateServiceFacade; this.bsqFormatter = bsqFormatter; @@ -112,7 +113,7 @@ public class ProposalListItem implements PeriodStateChangeListener { bsqWalletService.getChainHeightProperty().addListener(chainHeightListener); setupConfidence(); - periodServiceFacade.addPeriodStateChangeListener(this); + stateServiceFacade.addBlockListener(this); phaseChangeListener = (observable, oldValue, newValue) -> { applyState(newValue, ballot.getVote()); @@ -131,7 +132,7 @@ public void applyState(Phase newValue, Vote vote) { actionButton.setVisible(false); actionButton.setOnAction(null); final boolean isTxInPastCycle = periodServiceFacade.isTxInPastCycle(ballot.getTxId(), - stateService.getChainHeight()); + stateServiceFacade.getChainHeight()); switch (newValue) { case UNDEFINED: break; @@ -191,18 +192,18 @@ public void applyState(Phase newValue, Vote vote) { /////////////////////////////////////////////////////////////////////////////////////////// - // BlockListener + // Listener /////////////////////////////////////////////////////////////////////////////////////////// @Override - public void onChainHeightChanged(int chainHeight) { + public void onBlockAdded(Block block) { //TODO do we want that here??? setupConfidence(); } private void setupConfidence() { - final Tx tx = stateService.getTxMap().get(ballot.getProposal().getTxId()); + final Tx tx = stateServiceFacade.getTxMap().get(ballot.getProposal().getTxId()); if (tx != null) { final String txId = tx.getId(); @@ -246,7 +247,7 @@ private void updateConfidence(TransactionConfidence confidence, int depthInBlock } public void cleanup() { - periodServiceFacade.removePeriodStateChangeListener(this); + stateServiceFacade.removeBlockListener(this); bsqWalletService.getChainHeightProperty().removeListener(chainHeightListener); if (txConfidenceListener != null) bsqWalletService.removeTxConfidenceListener(txConfidenceListener); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java index e43afea1f6c..ca0e8b5a80b 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java @@ -25,7 +25,6 @@ import bisq.core.dao.consensus.period.PeriodStateChangeListener; import bisq.core.dao.consensus.period.Phase; import bisq.core.dao.presentation.period.PeriodServiceFacade; -import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; import bisq.common.UserThread; @@ -45,6 +44,9 @@ import static bisq.desktop.util.FormBuilder.addTitledGroupBg; +// We use here PeriodStateChangeListener because we are interested in period changes not in the result of a completed +// block. The event from the PeriodStateChangeListener is sent before parsing starts. +// The event from the StateServiceFacade.Listener would notify after parsing a new block. @FxmlView public class ProposalDashboardView extends ActivatableView implements PeriodStateChangeListener { @@ -62,7 +64,7 @@ public class ProposalDashboardView extends ActivatableView imple /////////////////////////////////////////////////////////////////////////////////////////// @Inject - private ProposalDashboardView(PeriodServiceFacade periodServiceFacade, StateServiceFacade stateService) { + private ProposalDashboardView(PeriodServiceFacade periodServiceFacade) { this.periodServiceFacade = periodServiceFacade; } @@ -125,7 +127,7 @@ protected void activate() { periodServiceFacade.addPeriodStateChangeListener(this); // We need to delay as otherwise the periodService has not been updated yet. - UserThread.execute(() -> onChainHeightChanged(periodServiceFacade.getChainHeight())); + UserThread.execute(() -> onPreParserChainHeightChanged(periodServiceFacade.getChainHeight())); } @Override @@ -136,7 +138,7 @@ protected void deactivate() { } @Override - public void onChainHeightChanged(int height) { + public void onPreParserChainHeightChanged(int height) { if (height > 0) { separatedPhaseBars.updateWidth(); phaseBarsItems.forEach(item -> { diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java index e186d9d51f4..f51c99e74bc 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java @@ -22,7 +22,8 @@ import bisq.core.btc.listeners.TxConfidenceListener; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.consensus.period.PeriodStateChangeListener; +import bisq.core.dao.consensus.state.Block; +import bisq.core.dao.consensus.state.BlockListener; import bisq.core.dao.consensus.state.blockchain.Tx; import bisq.core.dao.consensus.state.blockchain.TxOutput; import bisq.core.dao.presentation.myvote.MyVote; @@ -51,11 +52,11 @@ @ToString @Slf4j @EqualsAndHashCode -public class VoteListItem implements PeriodStateChangeListener { +public class VoteListItem implements BlockListener { @Getter private final MyVote myVote; private final BsqWalletService bsqWalletService; - private final StateServiceFacade stateService; + private final StateServiceFacade stateServiceFacade; private final PeriodServiceFacade periodServiceFacade; private final BsqFormatter bsqFormatter; private final ChangeListener chainHeightListener; @@ -81,7 +82,7 @@ public class VoteListItem implements PeriodStateChangeListener { BsqFormatter bsqFormatter) { this.myVote = myVote; this.bsqWalletService = bsqWalletService; - this.stateService = stateServiceFacade; + this.stateServiceFacade = stateServiceFacade; this.periodServiceFacade = periodServiceFacade; this.bsqFormatter = bsqFormatter; @@ -91,7 +92,7 @@ public class VoteListItem implements PeriodStateChangeListener { txConfidenceIndicator.setProgress(-1); txConfidenceIndicator.setPrefSize(24, 24); txConfidenceIndicator.setTooltip(tooltip); - periodServiceFacade.addPeriodStateChangeListener(this); + stateServiceFacade.addBlockListener(this); chainHeightListener = (observable, oldValue, newValue) -> setupConfidence(); bsqWalletService.getChainHeightProperty().addListener(chainHeightListener); @@ -101,11 +102,11 @@ public class VoteListItem implements PeriodStateChangeListener { /////////////////////////////////////////////////////////////////////////////////////////// - // BlockListener + // Listener /////////////////////////////////////////////////////////////////////////////////////////// @Override - public void onChainHeightChanged(int chainHeight) { + public void onBlockAdded(Block block) { //TODO do we want that here??? setupConfidence(); } @@ -113,7 +114,7 @@ public void onChainHeightChanged(int chainHeight) { private void setupConfidence() { calculateStake(); - final Tx tx = stateService.getTxMap().get(myVote.getBlindVote().getTxId()); + final Tx tx = stateServiceFacade.getTxMap().get(myVote.getBlindVote().getTxId()); if (tx != null) { final String txId = tx.getId(); @@ -152,7 +153,7 @@ public void onTransactionConfidenceChanged(TransactionConfidence confidence) { private void calculateStake() { if (stake == 0) { String txId = myVote.getTxId(); - stake = stateService.getUnspentBlindVoteStakeTxOutputs().stream() + stake = stateServiceFacade.getUnspentBlindVoteStakeTxOutputs().stream() .filter(txOutput -> txOutput.getTxId().equals(txId)) .filter(txOutput -> txOutput.getIndex() == 0) .mapToLong(TxOutput::getValue) @@ -170,7 +171,7 @@ private void updateConfidence(TransactionConfidence confidence, int depthInBlock public void cleanup() { bsqWalletService.getChainHeightProperty().removeListener(chainHeightListener); - periodServiceFacade.removePeriodStateChangeListener(this); + stateServiceFacade.removeBlockListener(this); if (txConfidenceListener != null) bsqWalletService.removeTxConfidenceListener(txConfidenceListener); } diff --git a/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java b/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java index 3acefff843a..33342b16971 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java @@ -26,8 +26,8 @@ import bisq.desktop.util.GUIUtil; import bisq.desktop.util.Layout; -import bisq.core.dao.consensus.period.PeriodStateChangeListener; -import bisq.core.dao.presentation.period.PeriodServiceFacade; +import bisq.core.dao.consensus.state.Block; +import bisq.core.dao.consensus.state.BlockListener; import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; import bisq.core.monetary.Altcoin; @@ -57,11 +57,10 @@ import static bisq.desktop.util.FormBuilder.addTitledGroupBg; @FxmlView -public class BsqDashboardView extends ActivatableView implements PeriodStateChangeListener { +public class BsqDashboardView extends ActivatableView implements BlockListener { private final BsqBalanceUtil bsqBalanceUtil; private final StateServiceFacade stateServiceFacade; - private final PeriodServiceFacade periodServiceFacade; private final PriceFeedService priceFeedService; private final Preferences preferences; private final BsqFormatter bsqFormatter; @@ -81,13 +80,11 @@ public class BsqDashboardView extends ActivatableView implements @Inject private BsqDashboardView(BsqBalanceUtil bsqBalanceUtil, StateServiceFacade stateServiceFacade, - PeriodServiceFacade periodServiceFacade, PriceFeedService priceFeedService, Preferences preferences, BsqFormatter bsqFormatter) { this.bsqBalanceUtil = bsqBalanceUtil; this.stateServiceFacade = stateServiceFacade; - this.periodServiceFacade = periodServiceFacade; this.priceFeedService = priceFeedService; this.preferences = preferences; this.bsqFormatter = bsqFormatter; @@ -132,7 +129,7 @@ public void initialize() { protected void activate() { bsqBalanceUtil.activate(); - periodServiceFacade.addPeriodStateChangeListener(this); + stateServiceFacade.addBlockListener(this); priceFeedService.updateCounterProperty().addListener(priceChangeListener); hyperlinkWithIcon.setOnAction(event -> GUIUtil.openWebPage(preferences.getBsqBlockChainExplorer().txUrl + stateServiceFacade.getGenesisTxId())); @@ -144,18 +141,18 @@ protected void activate() { @Override protected void deactivate() { bsqBalanceUtil.deactivate(); - periodServiceFacade.addPeriodStateChangeListener(this); + stateServiceFacade.addBlockListener(this); priceFeedService.updateCounterProperty().removeListener(priceChangeListener); hyperlinkWithIcon.setOnAction(null); } /////////////////////////////////////////////////////////////////////////////////////////// - // PeriodStateChangeListener + // StateServiceFacade.Listener /////////////////////////////////////////////////////////////////////////////////////////// @Override - public void onChainHeightChanged(int chainHeight) { + public void onBlockAdded(Block block) { updateWithBsqBlockChainData(); } diff --git a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java index 00b957d5e63..5f429ff7857 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java @@ -32,10 +32,10 @@ import bisq.core.btc.wallet.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; -import bisq.core.dao.consensus.period.PeriodStateChangeListener; +import bisq.core.dao.consensus.state.Block; +import bisq.core.dao.consensus.state.BlockListener; import bisq.core.dao.consensus.state.blockchain.Tx; import bisq.core.dao.consensus.state.blockchain.TxType; -import bisq.core.dao.presentation.period.PeriodServiceFacade; import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; import bisq.core.user.Preferences; @@ -81,7 +81,7 @@ import java.util.stream.Collectors; @FxmlView -public class BsqTxView extends ActivatableView implements BsqBalanceListener, PeriodStateChangeListener { +public class BsqTxView extends ActivatableView implements BsqBalanceListener, BlockListener { private TableView tableView; private Pane rootParent; @@ -89,7 +89,6 @@ public class BsqTxView extends ActivatableView implements BsqBal private final BsqFormatter bsqFormatter; private final BsqWalletService bsqWalletService; private final StateServiceFacade stateServiceFacade; - private final PeriodServiceFacade periodServiceFacade; private final BtcWalletService btcWalletService; private final BsqBalanceUtil bsqBalanceUtil; private final Preferences preferences; @@ -102,7 +101,7 @@ public class BsqTxView extends ActivatableView implements BsqBal private int gridRow = 0; private Label chainHeightLabel; private ProgressBar chainSyncIndicator; - private ChangeListener chainHeightChangedListener; + private ChangeListener walletChainHeightListener; /////////////////////////////////////////////////////////////////////////////////////////// @@ -114,14 +113,12 @@ private BsqTxView(BsqFormatter bsqFormatter, BsqWalletService bsqWalletService, Preferences preferences, StateServiceFacade stateServiceFacade, - PeriodServiceFacade periodServiceFacade, BtcWalletService btcWalletService, BsqBalanceUtil bsqBalanceUtil) { this.bsqFormatter = bsqFormatter; this.bsqWalletService = bsqWalletService; this.preferences = preferences; this.stateServiceFacade = stateServiceFacade; - this.periodServiceFacade = periodServiceFacade; this.btcWalletService = btcWalletService; this.bsqBalanceUtil = bsqBalanceUtil; } @@ -167,7 +164,7 @@ public void initialize() { walletBsqTransactionsListener = change -> updateList(); parentHeightListener = (observable, oldValue, newValue) -> layout(); //TODO do we want to get notified from wallet side? - chainHeightChangedListener = (observable, oldValue, newValue) -> onChainHeightChanged((int) newValue); + walletChainHeightListener = (observable, oldValue, newValue) -> onUpdateAnyChainHeight(); } @Override @@ -175,12 +172,12 @@ protected void activate() { bsqBalanceUtil.activate(); bsqWalletService.getWalletTransactions().addListener(walletBsqTransactionsListener); bsqWalletService.addBsqBalanceListener(this); - btcWalletService.getChainHeightProperty().addListener(chainHeightChangedListener); + btcWalletService.getChainHeightProperty().addListener(walletChainHeightListener); sortedList.comparatorProperty().bind(tableView.comparatorProperty()); tableView.setItems(sortedList); - periodServiceFacade.addPeriodStateChangeListener(this); + stateServiceFacade.addBlockListener(this); if (root.getParent() instanceof Pane) { rootParent = (Pane) root.getParent(); @@ -188,7 +185,7 @@ protected void activate() { } updateList(); - onChainHeightChanged(periodServiceFacade.getChainHeight()); + onUpdateAnyChainHeight(); layout(); } @@ -198,8 +195,8 @@ protected void deactivate() { sortedList.comparatorProperty().unbind(); bsqWalletService.getWalletTransactions().removeListener(walletBsqTransactionsListener); bsqWalletService.removeBsqBalanceListener(this); - btcWalletService.getChainHeightProperty().removeListener(chainHeightChangedListener); - periodServiceFacade.removePeriodStateChangeListener(this); + btcWalletService.getChainHeightProperty().removeListener(walletChainHeightListener); + stateServiceFacade.removeBlockListener(this); observableList.forEach(BsqTxListItem::cleanup); @@ -218,32 +215,38 @@ public void onUpdateBalances(Coin confirmedBalance, /////////////////////////////////////////////////////////////////////////////////////////// - // BlockListener + // Listener /////////////////////////////////////////////////////////////////////////////////////////// @Override - public void onChainHeightChanged(int chainHeight) { - final int bsqWalletChainHeight = bsqWalletService.getChainHeightProperty().get(); - final int bsqBlockChainHeight = periodServiceFacade.getChainHeight(); + public void onBlockAdded(Block block) { + onUpdateAnyChainHeight(); + } + + // If chain height from wallet of from the BSQ blockchain parsing changed we update our state. + private void onUpdateAnyChainHeight() { + final int bsqBlockChainHeight = stateServiceFacade.getChainHeight(); + final int bsqWalletChainHeight = bsqWalletService.getBestChainHeight(); if (bsqWalletChainHeight > 0) { final boolean synced = bsqWalletChainHeight == bsqBlockChainHeight; chainSyncIndicator.setVisible(!synced); chainSyncIndicator.setManaged(!synced); if (bsqBlockChainHeight > 0) - chainSyncIndicator.setProgress((double) bsqBlockChainHeight / (double) bsqWalletService.getBestChainHeight()); + chainSyncIndicator.setProgress((double) bsqBlockChainHeight / (double) bsqWalletChainHeight); - if (synced) + if (synced) { chainHeightLabel.setText(Res.get("dao.wallet.chainHeightSynced", bsqBlockChainHeight, - bsqWalletService.getBestChainHeight())); - else + bsqWalletChainHeight)); + } else { chainHeightLabel.setText(Res.get("dao.wallet.chainHeightSyncing", bsqBlockChainHeight, - bsqWalletService.getBestChainHeight())); + bsqWalletChainHeight)); + } } else { chainHeightLabel.setText(Res.get("dao.wallet.chainHeightSyncing", bsqBlockChainHeight, - bsqWalletService.getBestChainHeight())); + bsqWalletChainHeight)); } updateList(); } diff --git a/src/main/java/bisq/desktop/main/offer/offerbook/OfferBook.java b/src/main/java/bisq/desktop/main/offer/offerbook/OfferBook.java index 05e4df07ec4..1aa16f3f275 100644 --- a/src/main/java/bisq/desktop/main/offer/offerbook/OfferBook.java +++ b/src/main/java/bisq/desktop/main/offer/offerbook/OfferBook.java @@ -41,7 +41,7 @@ * Holds and manages the unsorted and unfiltered offerbook list of both buy and sell offers. * It is handled as singleton by Guice and is used by 2 instances of OfferBookDataModel (one for Buy one for Sell). * As it is used only by the Buy and Sell UIs we treat it as local UI model. - * It also use OfferRepository.BlockListener as the lists items class and we don't want to get any dependency out of the + * It also use OfferRepository.Listener as the lists items class and we don't want to get any dependency out of the * package for that. */ @Slf4j From 8fcab9b1e77f1dd974940a9b8e3ebfb738b48ac4 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Fri, 20 Apr 2018 11:34:21 -0500 Subject: [PATCH 051/197] Rename ISSUANCE to VOTE_RESULT and openBallotList to ballotList --- .../java/bisq/desktop/main/dao/proposal/ProposalListItem.java | 2 +- .../desktop/main/dao/proposal/active/ActiveProposalsView.java | 2 +- .../main/dao/proposal/dashboard/ProposalDashboardView.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index 7257e3a444a..10ceb4fbb5c 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -178,7 +178,7 @@ public void applyState(Phase newValue, Vote vote) { break; case BREAK3: break; - case ISSUANCE: + case VOTE_RESULT: break; case BREAK4: break; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index 4470641f9aa..dd5ec9caaa8 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -316,7 +316,7 @@ protected void onPhaseChanged(Phase phase) { break; case BREAK3: break; - case ISSUANCE: + case VOTE_RESULT: break; case BREAK4: break; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java index ca0e8b5a80b..c7d22df5922 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java @@ -102,7 +102,7 @@ private SeparatedPhaseBars createSeparatedPhaseBars() { new SeparatedPhaseBars.SeparatedPhaseBarsItem(Phase.BREAK2, false), new SeparatedPhaseBars.SeparatedPhaseBarsItem(Phase.VOTE_REVEAL, true), new SeparatedPhaseBars.SeparatedPhaseBarsItem(Phase.BREAK3, false), - new SeparatedPhaseBars.SeparatedPhaseBarsItem(Phase.ISSUANCE, false), + new SeparatedPhaseBars.SeparatedPhaseBarsItem(Phase.VOTE_RESULT, false), new SeparatedPhaseBars.SeparatedPhaseBarsItem(Phase.BREAK4, false)); return new SeparatedPhaseBars(phaseBarsItems); } From 75f84a0fa5a07dcf2f29785c88e6246bfc8094d0 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Fri, 20 Apr 2018 14:02:45 -0500 Subject: [PATCH 052/197] Refactoring - Add PeriodStateMutator to guice module - Add ConsensusServicesSetup and PresentationServicesSetup - Separate code from onAllServicesInitialized into listener registration and start method - Move MyProposalService and ProposalListService to bisq.core.dao.presentation.proposal (WIP) - Add PresentationService marker interface - Rename PHASE_ISSUANCE to PHASE_VOTE_RESULT - Remove onInitialState from PeriodStateChangeListener - Add getCloneOnUserThread method to PeriodState - Change addListenerAndGetNotified to addPeriodStateChangeListener - Call start on PeriodStateMutator from ConsensusServicesSetup instead of own constructor - Use explicit interface StateChangeEventsProvider for registerStateChangeEventsProvider - Set setChainHeight at onStartParsingNewBlock at the end to avoid that listeners get called before the cycle is added - Use PeriodServiceFacade instead of PeriodService in ProposalListService - Use StateServiceFacade instead of StateService in ProposalListService - Add market interface StateChangeEventsProvider --- .../bisq/desktop/main/dao/proposal/BaseProposalView.java | 4 ++-- .../bisq/desktop/main/dao/proposal/ProposalListItem.java | 5 ++++- .../main/dao/proposal/active/ActiveProposalsView.java | 6 +++--- .../main/dao/proposal/closed/ClosedProposalsView.java | 4 ++-- .../main/dao/proposal/dashboard/ProposalDashboardView.java | 1 - .../desktop/main/dao/proposal/make/MakeProposalView.java | 2 +- .../bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java | 4 ++-- 7 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java index 8a897e6f9fa..de5a079e7aa 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java @@ -29,12 +29,12 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.consensus.period.Phase; import bisq.core.dao.consensus.vote.proposal.Ballot; -import bisq.core.dao.consensus.vote.proposal.MyProposalService; import bisq.core.dao.consensus.vote.proposal.Proposal; -import bisq.core.dao.consensus.vote.proposal.ProposalListService; import bisq.core.dao.consensus.vote.proposal.ProposalService; import bisq.core.dao.consensus.vote.proposal.param.ChangeParamService; import bisq.core.dao.presentation.period.PeriodServiceFacade; +import bisq.core.dao.presentation.proposal.MyProposalService; +import bisq.core.dao.presentation.proposal.ProposalListService; import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index 10ceb4fbb5c..6f390ac788b 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -30,9 +30,9 @@ import bisq.core.dao.consensus.vote.BooleanVote; import bisq.core.dao.consensus.vote.Vote; import bisq.core.dao.consensus.vote.proposal.Ballot; -import bisq.core.dao.consensus.vote.proposal.MyProposalService; import bisq.core.dao.consensus.vote.proposal.ProposalService; import bisq.core.dao.presentation.period.PeriodServiceFacade; +import bisq.core.dao.presentation.proposal.MyProposalService; import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; @@ -135,6 +135,7 @@ public void applyState(Phase newValue, Vote vote) { stateServiceFacade.getChainHeight()); switch (newValue) { case UNDEFINED: + log.error("invalid state UNDEFINED"); break; case PROPOSAL: if (myProposalService.isMine(ballot.getProposal())) { @@ -182,6 +183,8 @@ public void applyState(Phase newValue, Vote vote) { break; case BREAK4: break; + default: + log.error("invalid state " + newValue); } actionButton.setManaged(actionButton.isVisible()); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index dd5ec9caaa8..60a7f260823 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -37,12 +37,12 @@ import bisq.core.dao.consensus.vote.BooleanVote; import bisq.core.dao.consensus.vote.blindvote.BlindVoteConsensus; import bisq.core.dao.consensus.vote.proposal.Ballot; -import bisq.core.dao.consensus.vote.proposal.MyProposalService; -import bisq.core.dao.consensus.vote.proposal.ProposalListService; import bisq.core.dao.consensus.vote.proposal.ProposalService; import bisq.core.dao.consensus.vote.proposal.param.ChangeParamService; import bisq.core.dao.presentation.myvote.MyVoteService; import bisq.core.dao.presentation.period.PeriodServiceFacade; +import bisq.core.dao.presentation.proposal.MyProposalService; +import bisq.core.dao.presentation.proposal.ProposalListService; import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; @@ -322,7 +322,7 @@ protected void onPhaseChanged(Phase phase) { break; case UNDEFINED: default: - log.warn("Undefined phase: " + phase); + log.error("Undefined phase: " + phase); break; } } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java index 67684ce8f0b..29ccac0e114 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java @@ -23,11 +23,11 @@ import bisq.desktop.util.BsqFormatter; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.consensus.vote.proposal.MyProposalService; -import bisq.core.dao.consensus.vote.proposal.ProposalListService; import bisq.core.dao.consensus.vote.proposal.ProposalService; import bisq.core.dao.consensus.vote.proposal.param.ChangeParamService; import bisq.core.dao.presentation.period.PeriodServiceFacade; +import bisq.core.dao.presentation.proposal.MyProposalService; +import bisq.core.dao.presentation.proposal.ProposalListService; import bisq.core.dao.presentation.state.StateServiceFacade; import javax.inject.Inject; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java index c7d22df5922..ca7c4504b86 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java @@ -146,7 +146,6 @@ public void onPreParserChainHeightChanged(int height) { int lastBlock = periodServiceFacade.getLastBlockOfPhase(height, item.getPhase()); final int duration = periodServiceFacade.getDurationForPhase(item.getPhase(), periodServiceFacade.getChainHeight()); item.setPeriodRange(firstBlock, lastBlock, duration); - double progress = 0; if (height >= firstBlock && height <= lastBlock) { progress = (double) (height - firstBlock + 1) / (double) duration; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index 1f1cc0d4ddf..af0847db5e4 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -33,12 +33,12 @@ import bisq.core.btc.wallet.WalletsSetup; import bisq.core.dao.ValidationException; import bisq.core.dao.consensus.vote.proposal.Ballot; -import bisq.core.dao.consensus.vote.proposal.MyProposalService; import bisq.core.dao.consensus.vote.proposal.ProposalConsensus; import bisq.core.dao.consensus.vote.proposal.ProposalType; import bisq.core.dao.consensus.vote.proposal.compensation.CompensationService; import bisq.core.dao.consensus.vote.proposal.generic.GenericProposalService; import bisq.core.dao.consensus.vote.proposal.param.ChangeParamService; +import bisq.core.dao.presentation.proposal.MyProposalService; import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; import bisq.core.provider.fee.FeeService; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java index f50c121ec60..62f33638142 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java @@ -33,12 +33,12 @@ import bisq.core.dao.consensus.vote.BooleanVote; import bisq.core.dao.consensus.vote.Vote; import bisq.core.dao.consensus.vote.proposal.BallotList; -import bisq.core.dao.consensus.vote.proposal.MyProposalService; -import bisq.core.dao.consensus.vote.proposal.ProposalListService; import bisq.core.dao.consensus.vote.proposal.ProposalService; import bisq.core.dao.consensus.vote.proposal.param.ChangeParamService; import bisq.core.dao.presentation.myvote.MyVoteService; import bisq.core.dao.presentation.period.PeriodServiceFacade; +import bisq.core.dao.presentation.proposal.MyProposalService; +import bisq.core.dao.presentation.proposal.ProposalListService; import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; import bisq.core.user.Preferences; From 9becb6d25fabf455819d9f1054cad0e5ea05b3d5 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Fri, 20 Apr 2018 14:07:49 -0500 Subject: [PATCH 053/197] Move packages level up --- .../desktop/main/dao/proposal/BaseProposalView.java | 8 ++++---- .../main/dao/proposal/ProposalDetailsWindow.java | 2 +- .../desktop/main/dao/proposal/ProposalDisplay.java | 10 +++++----- .../desktop/main/dao/proposal/ProposalListItem.java | 4 ++-- .../dao/proposal/active/ActiveProposalsView.java | 8 ++++---- .../dao/proposal/closed/ClosedProposalsView.java | 4 ++-- .../main/dao/proposal/make/MakeProposalView.java | 12 ++++++------ .../main/dao/proposal/myvotes/MyVotesView.java | 6 +++--- 8 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java index de5a079e7aa..d97a3f39b40 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java @@ -28,10 +28,10 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.consensus.period.Phase; -import bisq.core.dao.consensus.vote.proposal.Ballot; -import bisq.core.dao.consensus.vote.proposal.Proposal; -import bisq.core.dao.consensus.vote.proposal.ProposalService; -import bisq.core.dao.consensus.vote.proposal.param.ChangeParamService; +import bisq.core.dao.consensus.proposal.Ballot; +import bisq.core.dao.consensus.proposal.Proposal; +import bisq.core.dao.consensus.proposal.ProposalService; +import bisq.core.dao.consensus.proposal.param.ChangeParamService; import bisq.core.dao.presentation.period.PeriodServiceFacade; import bisq.core.dao.presentation.proposal.MyProposalService; import bisq.core.dao.presentation.proposal.ProposalListService; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java index 820449f4e3e..992e5828582 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java @@ -22,7 +22,7 @@ import bisq.desktop.util.Layout; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.consensus.vote.proposal.Proposal; +import bisq.core.dao.consensus.proposal.Proposal; import bisq.core.locale.Res; import javafx.geometry.Insets; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java index 463bca15086..00635b0dc03 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java @@ -28,11 +28,11 @@ import bisq.desktop.util.validation.BsqValidator; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.consensus.vote.proposal.Proposal; -import bisq.core.dao.consensus.vote.proposal.ProposalConsensus; -import bisq.core.dao.consensus.vote.proposal.ProposalType; -import bisq.core.dao.consensus.vote.proposal.compensation.CompensationConsensus; -import bisq.core.dao.consensus.vote.proposal.compensation.CompensationProposal; +import bisq.core.dao.consensus.proposal.Proposal; +import bisq.core.dao.consensus.proposal.ProposalConsensus; +import bisq.core.dao.consensus.proposal.ProposalType; +import bisq.core.dao.consensus.proposal.compensation.CompensationConsensus; +import bisq.core.dao.consensus.proposal.compensation.CompensationProposal; import bisq.core.locale.Res; import bisq.core.provider.fee.FeeService; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index 6f390ac788b..5b077546c5c 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -24,13 +24,13 @@ import bisq.core.btc.listeners.TxConfidenceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.consensus.period.Phase; +import bisq.core.dao.consensus.proposal.Ballot; +import bisq.core.dao.consensus.proposal.ProposalService; import bisq.core.dao.consensus.state.Block; import bisq.core.dao.consensus.state.BlockListener; import bisq.core.dao.consensus.state.blockchain.Tx; import bisq.core.dao.consensus.vote.BooleanVote; import bisq.core.dao.consensus.vote.Vote; -import bisq.core.dao.consensus.vote.proposal.Ballot; -import bisq.core.dao.consensus.vote.proposal.ProposalService; import bisq.core.dao.presentation.period.PeriodServiceFacade; import bisq.core.dao.presentation.proposal.MyProposalService; import bisq.core.dao.presentation.state.StateServiceFacade; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index 60a7f260823..40ca2068c38 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -33,12 +33,12 @@ import bisq.core.btc.exceptions.WalletException; import bisq.core.btc.wallet.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.dao.consensus.blindvote.BlindVoteConsensus; import bisq.core.dao.consensus.period.Phase; +import bisq.core.dao.consensus.proposal.Ballot; +import bisq.core.dao.consensus.proposal.ProposalService; +import bisq.core.dao.consensus.proposal.param.ChangeParamService; import bisq.core.dao.consensus.vote.BooleanVote; -import bisq.core.dao.consensus.vote.blindvote.BlindVoteConsensus; -import bisq.core.dao.consensus.vote.proposal.Ballot; -import bisq.core.dao.consensus.vote.proposal.ProposalService; -import bisq.core.dao.consensus.vote.proposal.param.ChangeParamService; import bisq.core.dao.presentation.myvote.MyVoteService; import bisq.core.dao.presentation.period.PeriodServiceFacade; import bisq.core.dao.presentation.proposal.MyProposalService; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java index 29ccac0e114..e61dd722210 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java @@ -23,8 +23,8 @@ import bisq.desktop.util.BsqFormatter; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.consensus.vote.proposal.ProposalService; -import bisq.core.dao.consensus.vote.proposal.param.ChangeParamService; +import bisq.core.dao.consensus.proposal.ProposalService; +import bisq.core.dao.consensus.proposal.param.ChangeParamService; import bisq.core.dao.presentation.period.PeriodServiceFacade; import bisq.core.dao.presentation.proposal.MyProposalService; import bisq.core.dao.presentation.proposal.ProposalListService; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index af0847db5e4..a1940b8e155 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -32,12 +32,12 @@ import bisq.core.btc.wallet.InsufficientBsqException; import bisq.core.btc.wallet.WalletsSetup; import bisq.core.dao.ValidationException; -import bisq.core.dao.consensus.vote.proposal.Ballot; -import bisq.core.dao.consensus.vote.proposal.ProposalConsensus; -import bisq.core.dao.consensus.vote.proposal.ProposalType; -import bisq.core.dao.consensus.vote.proposal.compensation.CompensationService; -import bisq.core.dao.consensus.vote.proposal.generic.GenericProposalService; -import bisq.core.dao.consensus.vote.proposal.param.ChangeParamService; +import bisq.core.dao.consensus.proposal.Ballot; +import bisq.core.dao.consensus.proposal.ProposalConsensus; +import bisq.core.dao.consensus.proposal.ProposalType; +import bisq.core.dao.consensus.proposal.compensation.CompensationService; +import bisq.core.dao.consensus.proposal.generic.GenericProposalService; +import bisq.core.dao.consensus.proposal.param.ChangeParamService; import bisq.core.dao.presentation.proposal.MyProposalService; import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java index 62f33638142..d322615d328 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java @@ -30,11 +30,11 @@ import bisq.desktop.util.Layout; import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.dao.consensus.proposal.BallotList; +import bisq.core.dao.consensus.proposal.ProposalService; +import bisq.core.dao.consensus.proposal.param.ChangeParamService; import bisq.core.dao.consensus.vote.BooleanVote; import bisq.core.dao.consensus.vote.Vote; -import bisq.core.dao.consensus.vote.proposal.BallotList; -import bisq.core.dao.consensus.vote.proposal.ProposalService; -import bisq.core.dao.consensus.vote.proposal.param.ChangeParamService; import bisq.core.dao.presentation.myvote.MyVoteService; import bisq.core.dao.presentation.period.PeriodServiceFacade; import bisq.core.dao.presentation.proposal.MyProposalService; From 0389fb03e0f9755c2c06ad65cd63e7ea97aa6182 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Fri, 20 Apr 2018 14:10:51 -0500 Subject: [PATCH 054/197] Move ballot classed to own package --- .../java/bisq/desktop/main/dao/proposal/BaseProposalView.java | 2 +- .../java/bisq/desktop/main/dao/proposal/ProposalListItem.java | 2 +- .../desktop/main/dao/proposal/active/ActiveProposalsView.java | 2 +- .../bisq/desktop/main/dao/proposal/make/MakeProposalView.java | 2 +- .../bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java index d97a3f39b40..164a3dc707e 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java @@ -28,7 +28,7 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.consensus.period.Phase; -import bisq.core.dao.consensus.proposal.Ballot; +import bisq.core.dao.consensus.ballot.Ballot; import bisq.core.dao.consensus.proposal.Proposal; import bisq.core.dao.consensus.proposal.ProposalService; import bisq.core.dao.consensus.proposal.param.ChangeParamService; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index 5b077546c5c..37b3cb1a251 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -24,7 +24,7 @@ import bisq.core.btc.listeners.TxConfidenceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.consensus.period.Phase; -import bisq.core.dao.consensus.proposal.Ballot; +import bisq.core.dao.consensus.ballot.Ballot; import bisq.core.dao.consensus.proposal.ProposalService; import bisq.core.dao.consensus.state.Block; import bisq.core.dao.consensus.state.BlockListener; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index 40ca2068c38..88e9cb3ce6f 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -35,7 +35,7 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.consensus.blindvote.BlindVoteConsensus; import bisq.core.dao.consensus.period.Phase; -import bisq.core.dao.consensus.proposal.Ballot; +import bisq.core.dao.consensus.ballot.Ballot; import bisq.core.dao.consensus.proposal.ProposalService; import bisq.core.dao.consensus.proposal.param.ChangeParamService; import bisq.core.dao.consensus.vote.BooleanVote; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index a1940b8e155..a3d0e92fe4a 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -32,7 +32,7 @@ import bisq.core.btc.wallet.InsufficientBsqException; import bisq.core.btc.wallet.WalletsSetup; import bisq.core.dao.ValidationException; -import bisq.core.dao.consensus.proposal.Ballot; +import bisq.core.dao.consensus.ballot.Ballot; import bisq.core.dao.consensus.proposal.ProposalConsensus; import bisq.core.dao.consensus.proposal.ProposalType; import bisq.core.dao.consensus.proposal.compensation.CompensationService; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java index d322615d328..233dd36b7a3 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java @@ -30,7 +30,7 @@ import bisq.desktop.util.Layout; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.consensus.proposal.BallotList; +import bisq.core.dao.consensus.ballot.BallotList; import bisq.core.dao.consensus.proposal.ProposalService; import bisq.core.dao.consensus.proposal.param.ChangeParamService; import bisq.core.dao.consensus.vote.BooleanVote; From ca1ab3d3f05fca2318510d49aca022997c4b1de9 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Fri, 20 Apr 2018 14:17:00 -0500 Subject: [PATCH 055/197] Remove proposalService from views --- .../bisq/desktop/main/dao/proposal/BaseProposalView.java | 7 +------ .../bisq/desktop/main/dao/proposal/ProposalListItem.java | 6 +----- .../main/dao/proposal/active/ActiveProposalsView.java | 8 +++----- .../main/dao/proposal/closed/ClosedProposalsView.java | 4 +--- .../desktop/main/dao/proposal/myvotes/MyVotesView.java | 4 +--- 5 files changed, 7 insertions(+), 22 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java index 164a3dc707e..522c072b3cd 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java @@ -27,10 +27,9 @@ import bisq.desktop.util.BsqFormatter; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.consensus.period.Phase; import bisq.core.dao.consensus.ballot.Ballot; +import bisq.core.dao.consensus.period.Phase; import bisq.core.dao.consensus.proposal.Proposal; -import bisq.core.dao.consensus.proposal.ProposalService; import bisq.core.dao.consensus.proposal.param.ChangeParamService; import bisq.core.dao.presentation.period.PeriodServiceFacade; import bisq.core.dao.presentation.proposal.MyProposalService; @@ -77,7 +76,6 @@ public abstract class BaseProposalView extends ActivatableView { protected final PeriodServiceFacade periodServiceFacade; protected final ChangeParamService changeParamService; protected final ProposalListService proposalListService; - protected final ProposalService proposalService; protected final BsqWalletService bsqWalletService; protected final BsqFormatter bsqFormatter; protected final BSFormatter btcFormatter; @@ -105,7 +103,6 @@ public abstract class BaseProposalView extends ActivatableView { @Inject protected BaseProposalView(MyProposalService myProposalService, ProposalListService proposalListService, - ProposalService proposalService, BsqWalletService bsqWalletService, StateServiceFacade stateService, PeriodServiceFacade periodServiceFacade, @@ -114,7 +111,6 @@ protected BaseProposalView(MyProposalService myProposalService, BSFormatter btcFormatter) { this.myProposalService = myProposalService; this.proposalListService = proposalListService; - this.proposalService = proposalService; this.bsqWalletService = bsqWalletService; this.stateService = stateService; this.periodServiceFacade = periodServiceFacade; @@ -253,7 +249,6 @@ protected void doUpdateProposalList(List list) { proposalListItems.setAll(list.stream() .map(ballot -> new ProposalListItem(ballot, - proposalService, myProposalService, periodServiceFacade, bsqWalletService, diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index 37b3cb1a251..2b15a2f8185 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -23,9 +23,8 @@ import bisq.core.btc.listeners.TxConfidenceListener; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.consensus.period.Phase; import bisq.core.dao.consensus.ballot.Ballot; -import bisq.core.dao.consensus.proposal.ProposalService; +import bisq.core.dao.consensus.period.Phase; import bisq.core.dao.consensus.state.Block; import bisq.core.dao.consensus.state.BlockListener; import bisq.core.dao.consensus.state.blockchain.Tx; @@ -59,7 +58,6 @@ public class ProposalListItem implements BlockListener { @Getter private final Ballot ballot; - private final ProposalService proposalService; private final MyProposalService myProposalService; private final PeriodServiceFacade periodServiceFacade; private final BsqWalletService bsqWalletService; @@ -83,14 +81,12 @@ public class ProposalListItem implements BlockListener { private Node actionNode; ProposalListItem(Ballot ballot, - ProposalService proposalService, MyProposalService myProposalService, PeriodServiceFacade periodServiceFacade, BsqWalletService bsqWalletService, StateServiceFacade stateServiceFacade, BsqFormatter bsqFormatter) { this.ballot = ballot; - this.proposalService = proposalService; this.myProposalService = myProposalService; this.periodServiceFacade = periodServiceFacade; this.bsqWalletService = bsqWalletService; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index 88e9cb3ce6f..195b499cea4 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -33,10 +33,9 @@ import bisq.core.btc.exceptions.WalletException; import bisq.core.btc.wallet.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.dao.consensus.ballot.Ballot; import bisq.core.dao.consensus.blindvote.BlindVoteConsensus; import bisq.core.dao.consensus.period.Phase; -import bisq.core.dao.consensus.ballot.Ballot; -import bisq.core.dao.consensus.proposal.ProposalService; import bisq.core.dao.consensus.proposal.param.ChangeParamService; import bisq.core.dao.consensus.vote.BooleanVote; import bisq.core.dao.presentation.myvote.MyVoteService; @@ -91,7 +90,6 @@ public class ActiveProposalsView extends BaseProposalView implements BsqBalanceL @Inject private ActiveProposalsView(MyProposalService myProposalService, ProposalListService proposalListService, - ProposalService proposalService, PeriodServiceFacade periodServiceFacade, MyVoteService myVoteService, BsqWalletService bsqWalletService, @@ -100,7 +98,7 @@ private ActiveProposalsView(MyProposalService myProposalService, BsqFormatter bsqFormatter, BSFormatter btcFormatter) { - super(myProposalService, proposalListService, proposalService, bsqWalletService, stateService, + super(myProposalService, proposalListService, bsqWalletService, stateService, periodServiceFacade, changeParamService, bsqFormatter, btcFormatter); this.myVoteService = myVoteService; } @@ -339,7 +337,7 @@ protected void updateProposalList() { private void updateStateAfterVote() { hideProposalDisplay(); - proposalService.persist(); + proposalListService.persist(); proposalTableView.getSelectionModel().clearSelection(); } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java index e61dd722210..7e2b06a95ab 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java @@ -23,7 +23,6 @@ import bisq.desktop.util.BsqFormatter; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.consensus.proposal.ProposalService; import bisq.core.dao.consensus.proposal.param.ChangeParamService; import bisq.core.dao.presentation.period.PeriodServiceFacade; import bisq.core.dao.presentation.proposal.MyProposalService; @@ -42,7 +41,6 @@ public class ClosedProposalsView extends BaseProposalView { @Inject private ClosedProposalsView(MyProposalService myProposalService, ProposalListService proposalListService, - ProposalService proposalService, PeriodServiceFacade periodServiceFacade, BsqWalletService bsqWalletService, StateServiceFacade stateService, @@ -50,7 +48,7 @@ private ClosedProposalsView(MyProposalService myProposalService, BsqFormatter bsqFormatter, BSFormatter btcFormatter) { - super(myProposalService, proposalListService, proposalService, bsqWalletService, stateService, + super(myProposalService, proposalListService, bsqWalletService, stateService, periodServiceFacade, changeParamService, bsqFormatter, btcFormatter); } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java index 233dd36b7a3..986c6351af0 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java @@ -31,7 +31,6 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.consensus.ballot.BallotList; -import bisq.core.dao.consensus.proposal.ProposalService; import bisq.core.dao.consensus.proposal.param.ChangeParamService; import bisq.core.dao.consensus.vote.BooleanVote; import bisq.core.dao.consensus.vote.Vote; @@ -92,7 +91,6 @@ public class MyVotesView extends BaseProposalView { @Inject private MyVotesView(MyProposalService myProposalService, ProposalListService proposalListService, - ProposalService proposalService, BsqWalletService bsqWalletService, StateServiceFacade stateService, PeriodServiceFacade periodServiceFacade, @@ -102,7 +100,7 @@ private MyVotesView(MyProposalService myProposalService, MyVoteService myVoteService, Preferences preferences) { - super(myProposalService, proposalListService, proposalService, bsqWalletService, stateService, + super(myProposalService, proposalListService, bsqWalletService, stateService, periodServiceFacade, changeParamService, bsqFormatter, btcFormatter); this.myVoteService = myVoteService; this.preferences = preferences; From 46a440d84b1580403580f93fb36e8ef92076dfcc Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Fri, 20 Apr 2018 20:29:31 -0500 Subject: [PATCH 056/197] Change ballot list services to user thread services --- .../main/dao/proposal/BaseProposalView.java | 24 +-- .../main/dao/proposal/ProposalListItem.java | 126 +++++++-------- .../proposal/active/ActiveProposalsView.java | 144 +++++++++--------- .../proposal/closed/ClosedProposalsView.java | 16 +- .../dao/proposal/make/MakeProposalView.java | 46 +++--- .../dao/proposal/myvotes/MyVotesView.java | 10 +- 6 files changed, 185 insertions(+), 181 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java index 522c072b3cd..d3142656d28 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java @@ -32,8 +32,8 @@ import bisq.core.dao.consensus.proposal.Proposal; import bisq.core.dao.consensus.proposal.param.ChangeParamService; import bisq.core.dao.presentation.period.PeriodServiceFacade; -import bisq.core.dao.presentation.proposal.MyProposalService; -import bisq.core.dao.presentation.proposal.ProposalListService; +import bisq.core.dao.presentation.proposal.MyBallotListService; +import bisq.core.dao.presentation.proposal.FilteredBallotListService; import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; @@ -71,11 +71,11 @@ @FxmlView public abstract class BaseProposalView extends ActivatableView { - protected final MyProposalService myProposalService; + protected final MyBallotListService myBallotListService; protected final StateServiceFacade stateService; protected final PeriodServiceFacade periodServiceFacade; protected final ChangeParamService changeParamService; - protected final ProposalListService proposalListService; + protected final FilteredBallotListService filteredBallotListService; protected final BsqWalletService bsqWalletService; protected final BsqFormatter bsqFormatter; protected final BSFormatter btcFormatter; @@ -101,16 +101,16 @@ public abstract class BaseProposalView extends ActivatableView { /////////////////////////////////////////////////////////////////////////////////////////// @Inject - protected BaseProposalView(MyProposalService myProposalService, - ProposalListService proposalListService, + protected BaseProposalView(MyBallotListService myBallotListService, + FilteredBallotListService filteredBallotListService, BsqWalletService bsqWalletService, StateServiceFacade stateService, PeriodServiceFacade periodServiceFacade, ChangeParamService changeParamService, BsqFormatter bsqFormatter, BSFormatter btcFormatter) { - this.myProposalService = myProposalService; - this.proposalListService = proposalListService; + this.myBallotListService = myBallotListService; + this.filteredBallotListService = filteredBallotListService; this.bsqWalletService = bsqWalletService; this.stateService = stateService; this.periodServiceFacade = periodServiceFacade; @@ -231,8 +231,8 @@ protected void onSelectProposal(ProposalListItem item) { } protected void onPhaseChanged(Phase phase) { - if (!phase.equals(this.currentPhase)) { - this.currentPhase = phase; + if (phase != null && !phase.equals(currentPhase)) { + currentPhase = phase; onSelectProposal(selectedProposalListItem); } } @@ -246,10 +246,10 @@ protected void onPhaseChanged(Phase phase) { protected void doUpdateProposalList(List list) { proposalListItems.forEach(ProposalListItem::cleanup); - + proposalListItems.clear(); proposalListItems.setAll(list.stream() .map(ballot -> new ProposalListItem(ballot, - myProposalService, + myBallotListService, periodServiceFacade, bsqWalletService, stateService, diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index 2b15a2f8185..7abbf0b859c 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -31,7 +31,7 @@ import bisq.core.dao.consensus.vote.BooleanVote; import bisq.core.dao.consensus.vote.Vote; import bisq.core.dao.presentation.period.PeriodServiceFacade; -import bisq.core.dao.presentation.proposal.MyProposalService; +import bisq.core.dao.presentation.proposal.MyBallotListService; import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; @@ -58,7 +58,7 @@ public class ProposalListItem implements BlockListener { @Getter private final Ballot ballot; - private final MyProposalService myProposalService; + private final MyBallotListService myBallotListService; private final PeriodServiceFacade periodServiceFacade; private final BsqWalletService bsqWalletService; private final StateServiceFacade stateServiceFacade; @@ -81,13 +81,13 @@ public class ProposalListItem implements BlockListener { private Node actionNode; ProposalListItem(Ballot ballot, - MyProposalService myProposalService, + MyBallotListService myBallotListService, PeriodServiceFacade periodServiceFacade, BsqWalletService bsqWalletService, StateServiceFacade stateServiceFacade, BsqFormatter bsqFormatter) { this.ballot = ballot; - this.myProposalService = myProposalService; + this.myBallotListService = myBallotListService; this.periodServiceFacade = periodServiceFacade; this.bsqWalletService = bsqWalletService; this.stateServiceFacade = stateServiceFacade; @@ -123,70 +123,72 @@ public class ProposalListItem implements BlockListener { ballot.getVoteResultProperty().addListener(voteResultChangeListener); } - public void applyState(Phase newValue, Vote vote) { - actionButton.setText(""); - actionButton.setVisible(false); - actionButton.setOnAction(null); - final boolean isTxInPastCycle = periodServiceFacade.isTxInPastCycle(ballot.getTxId(), - stateServiceFacade.getChainHeight()); - switch (newValue) { - case UNDEFINED: - log.error("invalid state UNDEFINED"); - break; - case PROPOSAL: - if (myProposalService.isMine(ballot.getProposal())) { - actionButton.setVisible(!isTxInPastCycle); - actionButtonIconView.setVisible(actionButton.isVisible()); - actionButton.setText(Res.get("shared.remove")); - actionButton.setGraphic(actionButtonIconView); - actionButtonIconView.setId("image-remove"); - actionButton.setOnAction(e -> { - if (onRemoveHandler != null) - onRemoveHandler.run(); - }); - actionNode = actionButton; - } - break; - case BREAK1: - break; - case BLIND_VOTE: - if (!isTxInPastCycle) { - actionNode = actionButtonIconView; - actionButton.setVisible(false); - if (ballot.getVote() != null) { - actionButtonIconView.setVisible(true); - if (vote instanceof BooleanVote) { - if (((BooleanVote) vote).isAccepted()) { - actionButtonIconView.setId("accepted"); + public void applyState(Phase phase, Vote vote) { + if (phase != null) { + actionButton.setText(""); + actionButton.setVisible(false); + actionButton.setOnAction(null); + final boolean isTxInPastCycle = periodServiceFacade.isTxInPastCycle(ballot.getTxId(), + stateServiceFacade.getChainHeight()); + switch (phase) { + case UNDEFINED: + log.error("invalid state UNDEFINED"); + break; + case PROPOSAL: + if (myBallotListService.isMine(ballot.getProposal())) { + actionButton.setVisible(!isTxInPastCycle); + actionButtonIconView.setVisible(actionButton.isVisible()); + actionButton.setText(Res.get("shared.remove")); + actionButton.setGraphic(actionButtonIconView); + actionButtonIconView.setId("image-remove"); + actionButton.setOnAction(e -> { + if (onRemoveHandler != null) + onRemoveHandler.run(); + }); + actionNode = actionButton; + } + break; + case BREAK1: + break; + case BLIND_VOTE: + if (!isTxInPastCycle) { + actionNode = actionButtonIconView; + actionButton.setVisible(false); + if (ballot.getVote() != null) { + actionButtonIconView.setVisible(true); + if (vote instanceof BooleanVote) { + if (((BooleanVote) vote).isAccepted()) { + actionButtonIconView.setId("accepted"); + } else { + actionButtonIconView.setId("rejected"); + } } else { - actionButtonIconView.setId("rejected"); + //TODO } } else { - //TODO + actionButtonIconView.setVisible(false); } - } else { - actionButtonIconView.setVisible(false); } - } - break; - case BREAK2: - break; - case VOTE_REVEAL: - break; - case BREAK3: - break; - case VOTE_RESULT: - break; - case BREAK4: - break; - default: - log.error("invalid state " + newValue); - } - actionButton.setManaged(actionButton.isVisible()); + break; + case BREAK2: + break; + case VOTE_REVEAL: + break; + case BREAK3: + break; + case VOTE_RESULT: + break; + case BREAK4: + break; + default: + log.error("invalid state " + phase); + } + actionButton.setManaged(actionButton.isVisible()); - // Don't set managed as otherwise the update does not work (not sure why but probably table - // cell item issue) - //actionButtonIconView.setManaged(actionButtonIconView.isVisible()); + // Don't set managed as otherwise the update does not work (not sure why but probably table + // cell item issue) + //actionButtonIconView.setManaged(actionButtonIconView.isVisible()); + } } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index 195b499cea4..4dc07cffaba 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -40,8 +40,8 @@ import bisq.core.dao.consensus.vote.BooleanVote; import bisq.core.dao.presentation.myvote.MyVoteService; import bisq.core.dao.presentation.period.PeriodServiceFacade; -import bisq.core.dao.presentation.proposal.MyProposalService; -import bisq.core.dao.presentation.proposal.ProposalListService; +import bisq.core.dao.presentation.proposal.MyBallotListService; +import bisq.core.dao.presentation.proposal.FilteredBallotListService; import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; @@ -88,8 +88,8 @@ public class ActiveProposalsView extends BaseProposalView implements BsqBalanceL /////////////////////////////////////////////////////////////////////////////////////////// @Inject - private ActiveProposalsView(MyProposalService myProposalService, - ProposalListService proposalListService, + private ActiveProposalsView(MyBallotListService myBallotListService, + FilteredBallotListService filteredBallotListService, PeriodServiceFacade periodServiceFacade, MyVoteService myVoteService, BsqWalletService bsqWalletService, @@ -98,7 +98,7 @@ private ActiveProposalsView(MyProposalService myProposalService, BsqFormatter bsqFormatter, BSFormatter btcFormatter) { - super(myProposalService, proposalListService, bsqWalletService, stateService, + super(myBallotListService, filteredBallotListService, bsqWalletService, stateService, periodServiceFacade, changeParamService, bsqFormatter, btcFormatter); this.myVoteService = myVoteService; } @@ -117,7 +117,7 @@ public void initialize() { protected void activate() { super.activate(); - proposalListService.getActiveOrMyUnconfirmedBallots().addListener(proposalListChangeListener); + filteredBallotListService.getActiveOrMyUnconfirmedBallots().addListener(proposalListChangeListener); bsqWalletService.addBsqBalanceListener(this); onUpdateBalances(bsqWalletService.getAvailableBalance(), @@ -168,7 +168,7 @@ private void publishBlindVote(Coin stake) { protected void deactivate() { super.deactivate(); - proposalListService.getActiveOrMyUnconfirmedBallots().removeListener(proposalListChangeListener); + filteredBallotListService.getActiveOrMyUnconfirmedBallots().removeListener(proposalListChangeListener); bsqWalletService.removeBsqBalanceListener(this); } @@ -257,71 +257,73 @@ private void onCancelVote() { @Override protected void onPhaseChanged(Phase phase) { - super.onPhaseChanged(phase); + if (phase != null) { + super.onPhaseChanged(phase); - changeVoteViewItemsVisibility(phase == Phase.BLIND_VOTE); + changeVoteViewItemsVisibility(phase == Phase.BLIND_VOTE); - if (removeButton != null) { - removeButton.setManaged(false); - removeButton.setVisible(false); - removeButton = null; - } - if (selectedProposalListItem != null && - proposalDisplay != null && - !periodServiceFacade.isTxInPastCycle(selectedProposalListItem.getBallot().getTxId(), - stateService.getChainHeight())) { - final Ballot ballot = selectedProposalListItem.getBallot(); - switch (phase) { - case PROPOSAL: - if (myProposalService.isMine(ballot.getProposal())) { - if (removeButton == null) { - removeButton = addButtonAfterGroup(detailsGridPane, proposalDisplay.incrementAndGetGridRow(), Res.get("dao.proposal.active.remove")); - removeButton.setOnAction(event -> onRemove()); + if (removeButton != null) { + removeButton.setManaged(false); + removeButton.setVisible(false); + removeButton = null; + } + if (selectedProposalListItem != null && + proposalDisplay != null && + !periodServiceFacade.isTxInPastCycle(selectedProposalListItem.getBallot().getTxId(), + stateService.getChainHeight())) { + final Ballot ballot = selectedProposalListItem.getBallot(); + switch (phase) { + case PROPOSAL: + if (myBallotListService.isMine(ballot.getProposal())) { + if (removeButton == null) { + removeButton = addButtonAfterGroup(detailsGridPane, proposalDisplay.incrementAndGetGridRow(), Res.get("dao.proposal.active.remove")); + removeButton.setOnAction(event -> onRemove()); + } else { + removeButton.setManaged(true); + removeButton.setVisible(true); + } + } + break; + case BREAK1: + break; + case BLIND_VOTE: + if (acceptButton == null) { + Tuple3 tuple = add3ButtonsAfterGroup(detailsGridPane, proposalDisplay + .incrementAndGetGridRow(), + Res.get("dao.proposal.myVote.accept"), + Res.get("dao.proposal.myVote.reject"), + Res.get("dao.proposal.myVote.cancelVote")); + acceptButton = tuple.first; + acceptButton.setDefaultButton(false); + rejectButton = tuple.second; + cancelVoteButton = tuple.third; + acceptButton.setOnAction(event -> onAccept()); + rejectButton.setOnAction(event -> onReject()); + cancelVoteButton.setOnAction(event -> onCancelVote()); } else { - removeButton.setManaged(true); - removeButton.setVisible(true); + acceptButton.setManaged(true); + acceptButton.setVisible(true); + rejectButton.setManaged(true); + rejectButton.setVisible(true); + cancelVoteButton.setManaged(true); + cancelVoteButton.setVisible(true); } - } - break; - case BREAK1: - break; - case BLIND_VOTE: - if (acceptButton == null) { - Tuple3 tuple = add3ButtonsAfterGroup(detailsGridPane, proposalDisplay - .incrementAndGetGridRow(), - Res.get("dao.proposal.myVote.accept"), - Res.get("dao.proposal.myVote.reject"), - Res.get("dao.proposal.myVote.cancelVote")); - acceptButton = tuple.first; - acceptButton.setDefaultButton(false); - rejectButton = tuple.second; - cancelVoteButton = tuple.third; - acceptButton.setOnAction(event -> onAccept()); - rejectButton.setOnAction(event -> onReject()); - cancelVoteButton.setOnAction(event -> onCancelVote()); - } else { - acceptButton.setManaged(true); - acceptButton.setVisible(true); - rejectButton.setManaged(true); - rejectButton.setVisible(true); - cancelVoteButton.setManaged(true); - cancelVoteButton.setVisible(true); - } - break; - case BREAK2: - break; - case VOTE_REVEAL: - break; - case BREAK3: - break; - case VOTE_RESULT: - break; - case BREAK4: - break; - case UNDEFINED: - default: - log.error("Undefined phase: " + phase); - break; + break; + case BREAK2: + break; + case VOTE_REVEAL: + break; + case BREAK3: + break; + case VOTE_RESULT: + break; + case BREAK4: + break; + case UNDEFINED: + default: + log.error("Undefined phase: " + phase); + break; + } } } } @@ -332,12 +334,12 @@ protected void onPhaseChanged(Phase phase) { @Override protected void updateProposalList() { - doUpdateProposalList(proposalListService.getActiveOrMyUnconfirmedBallots()); + doUpdateProposalList(filteredBallotListService.getActiveOrMyUnconfirmedBallots()); } private void updateStateAfterVote() { hideProposalDisplay(); - proposalListService.persist(); + filteredBallotListService.persist(); proposalTableView.getSelectionModel().clearSelection(); } @@ -349,7 +351,7 @@ private void changeVoteViewItemsVisibility(boolean value) { } private void onRemove() { - if (myProposalService.removeProposal(selectedProposalListItem.getBallot())) + if (myBallotListService.removeProposal(selectedProposalListItem.getBallot())) hideProposalDisplay(); else new Popup<>().warning(Res.get("dao.proposal.active.remove.failed")).show(); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java index 7e2b06a95ab..2f97fd46797 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java @@ -25,8 +25,8 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.consensus.proposal.param.ChangeParamService; import bisq.core.dao.presentation.period.PeriodServiceFacade; -import bisq.core.dao.presentation.proposal.MyProposalService; -import bisq.core.dao.presentation.proposal.ProposalListService; +import bisq.core.dao.presentation.proposal.MyBallotListService; +import bisq.core.dao.presentation.proposal.FilteredBallotListService; import bisq.core.dao.presentation.state.StateServiceFacade; import javax.inject.Inject; @@ -39,8 +39,8 @@ public class ClosedProposalsView extends BaseProposalView { /////////////////////////////////////////////////////////////////////////////////////////// @Inject - private ClosedProposalsView(MyProposalService myProposalService, - ProposalListService proposalListService, + private ClosedProposalsView(MyBallotListService myBallotListService, + FilteredBallotListService filteredBallotListService, PeriodServiceFacade periodServiceFacade, BsqWalletService bsqWalletService, StateServiceFacade stateService, @@ -48,7 +48,7 @@ private ClosedProposalsView(MyProposalService myProposalService, BsqFormatter bsqFormatter, BSFormatter btcFormatter) { - super(myProposalService, proposalListService, bsqWalletService, stateService, + super(myBallotListService, filteredBallotListService, bsqWalletService, stateService, periodServiceFacade, changeParamService, bsqFormatter, btcFormatter); } @@ -63,18 +63,18 @@ public void initialize() { @Override protected void activate() { super.activate(); - proposalListService.getClosedBallots().addListener(proposalListChangeListener); + filteredBallotListService.getClosedBallots().addListener(proposalListChangeListener); } @Override protected void deactivate() { super.deactivate(); - proposalListService.getClosedBallots().removeListener(proposalListChangeListener); + filteredBallotListService.getClosedBallots().removeListener(proposalListChangeListener); } @Override protected void updateProposalList() { - doUpdateProposalList(proposalListService.getClosedBallots()); + doUpdateProposalList(filteredBallotListService.getClosedBallots()); } } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index a3d0e92fe4a..dce77cbfc6e 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -35,10 +35,10 @@ import bisq.core.dao.consensus.ballot.Ballot; import bisq.core.dao.consensus.proposal.ProposalConsensus; import bisq.core.dao.consensus.proposal.ProposalType; -import bisq.core.dao.consensus.proposal.compensation.CompensationService; -import bisq.core.dao.consensus.proposal.generic.GenericProposalService; +import bisq.core.dao.presentation.ballot.CompensationBallotFactory; +import bisq.core.dao.presentation.ballot.GenericBallotFactory; import bisq.core.dao.consensus.proposal.param.ChangeParamService; -import bisq.core.dao.presentation.proposal.MyProposalService; +import bisq.core.dao.presentation.proposal.MyBallotListService; import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; import bisq.core.provider.fee.FeeService; @@ -83,9 +83,9 @@ public class MakeProposalView extends ActivatableView { private final WalletsSetup walletsSetup; private final P2PService p2PService; private final FeeService feeService; - private final MyProposalService myProposalService; - private final CompensationService compensationService; - private final GenericProposalService genericProposalService; + private final MyBallotListService myBallotListService; + private final CompensationBallotFactory compensationBallotFactory; + private final GenericBallotFactory genericBallotFactory; private final StateServiceFacade stateService; private final ChangeParamService changeParamService; private final BSFormatter btcFormatter; @@ -104,9 +104,9 @@ private MakeProposalView(BsqWalletService bsqWalletService, WalletsSetup walletsSetup, P2PService p2PService, FeeService feeService, - MyProposalService myProposalService, - CompensationService compensationService, - GenericProposalService genericProposalService, + MyBallotListService myBallotListService, + CompensationBallotFactory compensationBallotFactory, + GenericBallotFactory genericBallotFactory, StateServiceFacade stateService, ChangeParamService changeParamService, BSFormatter btcFormatter, @@ -115,9 +115,9 @@ private MakeProposalView(BsqWalletService bsqWalletService, this.walletsSetup = walletsSetup; this.p2PService = p2PService; this.feeService = feeService; - this.myProposalService = myProposalService; - this.compensationService = compensationService; - this.genericProposalService = genericProposalService; + this.myBallotListService = myBallotListService; + this.compensationBallotFactory = compensationBallotFactory; + this.genericBallotFactory = genericBallotFactory; this.stateService = stateService; this.changeParamService = changeParamService; this.btcFormatter = btcFormatter; @@ -165,17 +165,17 @@ protected void deactivate() { createButton.setOnAction(null); } - private void publishProposal(ProposalType type) { + private void publishProposalAndStoreBallot(ProposalType type) { try { - final Tuple2 tuple2 = createProposal(type); - Ballot ballot = tuple2.first; - Transaction transaction = tuple2.second; + final Tuple2 tuple = getTuple(type); + Ballot ballot = tuple.first; + Transaction transaction = tuple.second; Coin miningFee = transaction.getFee(); int txSize = transaction.bitcoinSerialize().length; final Coin fee = ProposalConsensus.getFee(changeParamService, stateService.getChainHeight()); GUIUtil.showBsqFeeInfoPopup(fee, miningFee, txSize, bsqFormatter, btcFormatter, - Res.get("dao.proposal"), () -> publishProposal(ballot, transaction)); + Res.get("dao.proposal"), () -> publishProposalAndStoreBallot(ballot, transaction)); } catch (InsufficientMoneyException e) { BSFormatter formatter = e instanceof InsufficientBsqException ? bsqFormatter : btcFormatter; @@ -197,8 +197,8 @@ private void publishProposal(ProposalType type) { } } - private void publishProposal(Ballot ballot, Transaction transaction) { - myProposalService.publishProposal(ballot, + private void publishProposalAndStoreBallot(Ballot ballot, Transaction transaction) { + myBallotListService.publishProposalAndStoreBallot(ballot, transaction, () -> { proposalDisplay.clearForm(); @@ -208,7 +208,7 @@ private void publishProposal(Ballot ballot, Transaction transaction) { errorMessage -> new Popup<>().warning(errorMessage).show()); } - private Tuple2 createProposal(ProposalType type) + private Tuple2 getTuple(ProposalType type) throws InsufficientMoneyException, TransactionVerificationException, ValidationException, WalletException, IOException { @@ -216,7 +216,7 @@ private Tuple2 createProposal(ProposalType type) switch (type) { case COMPENSATION_REQUEST: - return compensationService.makeTxAndGetCompensationRequest(proposalDisplay.nameTextField.getText(), + return compensationBallotFactory.getTuple(proposalDisplay.nameTextField.getText(), proposalDisplay.titleTextField.getText(), proposalDisplay.descriptionTextArea.getText(), proposalDisplay.linkInputTextField.getText(), @@ -226,7 +226,7 @@ private Tuple2 createProposal(ProposalType type) //TODO throw new RuntimeException("Not implemented yet"); /* - return genericProposalService.makeTxAndGetGenericProposal( + return genericBallotFactory.makeTxAndGetGenericProposal( proposalDisplay.nameTextField.getText(), proposalDisplay.titleTextField.getText(), proposalDisplay.descriptionTextArea.getText(), @@ -265,7 +265,7 @@ private void setCreateButtonHandler() { createButton.setOnAction(event -> { // TODO break up in methods if (GUIUtil.isReadyForTxBroadcast(p2PService, walletsSetup)) { - publishProposal(selectedProposalType); + publishProposalAndStoreBallot(selectedProposalType); } else { GUIUtil.showNotReadyForTxBroadcastPopups(p2PService, walletsSetup); } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java index 986c6351af0..fe9957429a9 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java @@ -36,8 +36,8 @@ import bisq.core.dao.consensus.vote.Vote; import bisq.core.dao.presentation.myvote.MyVoteService; import bisq.core.dao.presentation.period.PeriodServiceFacade; -import bisq.core.dao.presentation.proposal.MyProposalService; -import bisq.core.dao.presentation.proposal.ProposalListService; +import bisq.core.dao.presentation.proposal.MyBallotListService; +import bisq.core.dao.presentation.proposal.FilteredBallotListService; import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; import bisq.core.user.Preferences; @@ -89,8 +89,8 @@ public class MyVotesView extends BaseProposalView { /////////////////////////////////////////////////////////////////////////////////////////// @Inject - private MyVotesView(MyProposalService myProposalService, - ProposalListService proposalListService, + private MyVotesView(MyBallotListService myBallotListService, + FilteredBallotListService filteredBallotListService, BsqWalletService bsqWalletService, StateServiceFacade stateService, PeriodServiceFacade periodServiceFacade, @@ -100,7 +100,7 @@ private MyVotesView(MyProposalService myProposalService, MyVoteService myVoteService, Preferences preferences) { - super(myProposalService, proposalListService, bsqWalletService, stateService, + super(myBallotListService, filteredBallotListService, bsqWalletService, stateService, periodServiceFacade, changeParamService, bsqFormatter, btcFormatter); this.myVoteService = myVoteService; this.preferences = preferences; From 4fd29557f576b3762ebe3ffbef626714fa6725b9 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Fri, 20 Apr 2018 22:04:23 -0500 Subject: [PATCH 057/197] Apply separation of thread access to myVote domain --- .../main/dao/proposal/BaseProposalView.java | 10 ++++---- .../proposal/active/ActiveProposalsView.java | 23 +++++++++---------- .../dao/proposal/myvotes/MyVotesView.java | 14 +++++------ .../dao/proposal/myvotes/VoteListItem.java | 2 +- 4 files changed, 24 insertions(+), 25 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java index d3142656d28..4bbdbd12c78 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java @@ -32,8 +32,8 @@ import bisq.core.dao.consensus.proposal.Proposal; import bisq.core.dao.consensus.proposal.param.ChangeParamService; import bisq.core.dao.presentation.period.PeriodServiceFacade; -import bisq.core.dao.presentation.proposal.MyBallotListService; import bisq.core.dao.presentation.proposal.FilteredBallotListService; +import bisq.core.dao.presentation.proposal.MyBallotListService; import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; @@ -72,7 +72,7 @@ public abstract class BaseProposalView extends ActivatableView { protected final MyBallotListService myBallotListService; - protected final StateServiceFacade stateService; + protected final StateServiceFacade stateServiceFacade; protected final PeriodServiceFacade periodServiceFacade; protected final ChangeParamService changeParamService; protected final FilteredBallotListService filteredBallotListService; @@ -104,7 +104,7 @@ public abstract class BaseProposalView extends ActivatableView { protected BaseProposalView(MyBallotListService myBallotListService, FilteredBallotListService filteredBallotListService, BsqWalletService bsqWalletService, - StateServiceFacade stateService, + StateServiceFacade stateServiceFacade, PeriodServiceFacade periodServiceFacade, ChangeParamService changeParamService, BsqFormatter bsqFormatter, @@ -112,7 +112,7 @@ protected BaseProposalView(MyBallotListService myBallotListService, this.myBallotListService = myBallotListService; this.filteredBallotListService = filteredBallotListService; this.bsqWalletService = bsqWalletService; - this.stateService = stateService; + this.stateServiceFacade = stateServiceFacade; this.periodServiceFacade = periodServiceFacade; this.changeParamService = changeParamService; this.bsqFormatter = bsqFormatter; @@ -252,7 +252,7 @@ protected void doUpdateProposalList(List list) { myBallotListService, periodServiceFacade, bsqWalletService, - stateService, + stateServiceFacade, bsqFormatter)) .collect(Collectors.toSet())); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index 4dc07cffaba..96fc88d6f1d 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -34,14 +34,13 @@ import bisq.core.btc.wallet.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.consensus.ballot.Ballot; -import bisq.core.dao.consensus.blindvote.BlindVoteConsensus; import bisq.core.dao.consensus.period.Phase; import bisq.core.dao.consensus.proposal.param.ChangeParamService; import bisq.core.dao.consensus.vote.BooleanVote; -import bisq.core.dao.presentation.myvote.MyVoteService; +import bisq.core.dao.presentation.myvote.MyVoteServiceFacade; import bisq.core.dao.presentation.period.PeriodServiceFacade; -import bisq.core.dao.presentation.proposal.MyBallotListService; import bisq.core.dao.presentation.proposal.FilteredBallotListService; +import bisq.core.dao.presentation.proposal.MyBallotListService; import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; @@ -74,7 +73,7 @@ @FxmlView public class ActiveProposalsView extends BaseProposalView implements BsqBalanceListener { - private final MyVoteService myVoteService; + private final MyVoteServiceFacade myVoteServiceFacade; private Button removeButton, acceptButton, rejectButton, cancelVoteButton, voteButton; private InputTextField stakeInputTextField; @@ -91,7 +90,7 @@ public class ActiveProposalsView extends BaseProposalView implements BsqBalanceL private ActiveProposalsView(MyBallotListService myBallotListService, FilteredBallotListService filteredBallotListService, PeriodServiceFacade periodServiceFacade, - MyVoteService myVoteService, + MyVoteServiceFacade myVoteServiceFacade, BsqWalletService bsqWalletService, StateServiceFacade stateService, ChangeParamService changeParamService, @@ -100,7 +99,7 @@ private ActiveProposalsView(MyBallotListService myBallotListService, super(myBallotListService, filteredBallotListService, bsqWalletService, stateService, periodServiceFacade, changeParamService, bsqFormatter, btcFormatter); - this.myVoteService = myVoteService; + this.myVoteServiceFacade = myVoteServiceFacade; } @Override @@ -129,11 +128,11 @@ protected void activate() { voteButton.setOnAction(e -> { // TODO verify stake Coin stake = bsqFormatter.parseToCoin(stakeInputTextField.getText()); - final Coin fee = BlindVoteConsensus.getFee(changeParamService, stateService.getChainHeight()); + final Coin blindVoteFee = myVoteServiceFacade.getBlindVoteFee(); Transaction dummyTx = null; try { - // We create a tx with dummy opreturn data to get the mining fee for confirmation popup - dummyTx = myVoteService.getBlindVoteTx(stake, fee, new byte[22]); + // We create a dummy tx to get the mining blindVoteFee for confirmation popup + dummyTx = myVoteServiceFacade.getDummyBlindVoteTx(stake, blindVoteFee); } catch (InsufficientMoneyException | WalletException | TransactionVerificationException exception) { new Popup<>().warning(exception.toString()).show(); } @@ -141,7 +140,7 @@ protected void activate() { if (dummyTx != null) { Coin miningFee = dummyTx.getFee(); int txSize = dummyTx.bitcoinSerialize().length; - GUIUtil.showBsqFeeInfoPopup(fee, miningFee, txSize, bsqFormatter, btcFormatter, + GUIUtil.showBsqFeeInfoPopup(blindVoteFee, miningFee, txSize, bsqFormatter, btcFormatter, Res.get("dao.blindVote"), () -> publishBlindVote(stake)); } }); @@ -151,7 +150,7 @@ protected void activate() { private void publishBlindVote(Coin stake) { voteButtonBusyAnimation.play(); voteButtonInfoLabel.setText(Res.get("dao.blindVote.startPublishing")); - myVoteService.publishBlindVote(stake, + myVoteServiceFacade.publishBlindVote(stake, () -> { voteButtonBusyAnimation.stop(); voteButtonInfoLabel.setText(""); @@ -270,7 +269,7 @@ protected void onPhaseChanged(Phase phase) { if (selectedProposalListItem != null && proposalDisplay != null && !periodServiceFacade.isTxInPastCycle(selectedProposalListItem.getBallot().getTxId(), - stateService.getChainHeight())) { + stateServiceFacade.getChainHeight())) { final Ballot ballot = selectedProposalListItem.getBallot(); switch (phase) { case PROPOSAL: diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java index fe9957429a9..a13546c7a1b 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java @@ -34,10 +34,10 @@ import bisq.core.dao.consensus.proposal.param.ChangeParamService; import bisq.core.dao.consensus.vote.BooleanVote; import bisq.core.dao.consensus.vote.Vote; -import bisq.core.dao.presentation.myvote.MyVoteService; +import bisq.core.dao.presentation.myvote.MyVoteServiceFacade; import bisq.core.dao.presentation.period.PeriodServiceFacade; -import bisq.core.dao.presentation.proposal.MyBallotListService; import bisq.core.dao.presentation.proposal.FilteredBallotListService; +import bisq.core.dao.presentation.proposal.MyBallotListService; import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; import bisq.core.user.Preferences; @@ -74,7 +74,7 @@ @FxmlView public class MyVotesView extends BaseProposalView { - private final MyVoteService myVoteService; + private final MyVoteServiceFacade myVoteServiceFacade; private final Preferences preferences; private final ObservableList voteListItems = FXCollections.observableArrayList(); @@ -97,12 +97,12 @@ private MyVotesView(MyBallotListService myBallotListService, ChangeParamService changeParamService, BsqFormatter bsqFormatter, BSFormatter btcFormatter, - MyVoteService myVoteService, + MyVoteServiceFacade myVoteServiceFacade, Preferences preferences) { super(myBallotListService, filteredBallotListService, bsqWalletService, stateService, periodServiceFacade, changeParamService, bsqFormatter, btcFormatter); - this.myVoteService = myVoteService; + this.myVoteServiceFacade = myVoteServiceFacade; this.preferences = preferences; } @@ -127,8 +127,8 @@ protected void activate() { sortedList.comparatorProperty().bind(votesTableView.comparatorProperty()); voteListItems.clear(); - List items = myVoteService.getMyVoteList().stream() - .map(vote -> new VoteListItem(vote, bsqWalletService, stateService, periodServiceFacade, bsqFormatter)) + List items = myVoteServiceFacade.getMyVoteList().stream() + .map(vote -> new VoteListItem(vote, bsqWalletService, stateServiceFacade, periodServiceFacade, bsqFormatter)) .collect(Collectors.toList()); voteListItems.addAll(items); } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java index f51c99e74bc..ee2b4d0bf82 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java @@ -22,11 +22,11 @@ import bisq.core.btc.listeners.TxConfidenceListener; import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.dao.consensus.myvote.MyVote; import bisq.core.dao.consensus.state.Block; import bisq.core.dao.consensus.state.BlockListener; import bisq.core.dao.consensus.state.blockchain.Tx; import bisq.core.dao.consensus.state.blockchain.TxOutput; -import bisq.core.dao.presentation.myvote.MyVote; import bisq.core.dao.presentation.period.PeriodServiceFacade; import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; From 30b4e56b61b55dfe73b7f602d7aa29ac60a94a02 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Fri, 20 Apr 2018 22:33:37 -0500 Subject: [PATCH 058/197] Separate blindVoteService --- .../dao/proposal/active/ActiveProposalsView.java | 14 +++++++------- .../main/dao/proposal/myvotes/MyVotesView.java | 10 +++++----- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index 96fc88d6f1d..fb8040fe024 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -37,7 +37,7 @@ import bisq.core.dao.consensus.period.Phase; import bisq.core.dao.consensus.proposal.param.ChangeParamService; import bisq.core.dao.consensus.vote.BooleanVote; -import bisq.core.dao.presentation.myvote.MyVoteServiceFacade; +import bisq.core.dao.presentation.myvote.MyBlindVoteServiceFacade; import bisq.core.dao.presentation.period.PeriodServiceFacade; import bisq.core.dao.presentation.proposal.FilteredBallotListService; import bisq.core.dao.presentation.proposal.MyBallotListService; @@ -73,7 +73,7 @@ @FxmlView public class ActiveProposalsView extends BaseProposalView implements BsqBalanceListener { - private final MyVoteServiceFacade myVoteServiceFacade; + private final MyBlindVoteServiceFacade myBlindVoteServiceFacade; private Button removeButton, acceptButton, rejectButton, cancelVoteButton, voteButton; private InputTextField stakeInputTextField; @@ -90,7 +90,7 @@ public class ActiveProposalsView extends BaseProposalView implements BsqBalanceL private ActiveProposalsView(MyBallotListService myBallotListService, FilteredBallotListService filteredBallotListService, PeriodServiceFacade periodServiceFacade, - MyVoteServiceFacade myVoteServiceFacade, + MyBlindVoteServiceFacade myBlindVoteServiceFacade, BsqWalletService bsqWalletService, StateServiceFacade stateService, ChangeParamService changeParamService, @@ -99,7 +99,7 @@ private ActiveProposalsView(MyBallotListService myBallotListService, super(myBallotListService, filteredBallotListService, bsqWalletService, stateService, periodServiceFacade, changeParamService, bsqFormatter, btcFormatter); - this.myVoteServiceFacade = myVoteServiceFacade; + this.myBlindVoteServiceFacade = myBlindVoteServiceFacade; } @Override @@ -128,11 +128,11 @@ protected void activate() { voteButton.setOnAction(e -> { // TODO verify stake Coin stake = bsqFormatter.parseToCoin(stakeInputTextField.getText()); - final Coin blindVoteFee = myVoteServiceFacade.getBlindVoteFee(); + final Coin blindVoteFee = myBlindVoteServiceFacade.getBlindVoteFee(); Transaction dummyTx = null; try { // We create a dummy tx to get the mining blindVoteFee for confirmation popup - dummyTx = myVoteServiceFacade.getDummyBlindVoteTx(stake, blindVoteFee); + dummyTx = myBlindVoteServiceFacade.getDummyBlindVoteTx(stake, blindVoteFee); } catch (InsufficientMoneyException | WalletException | TransactionVerificationException exception) { new Popup<>().warning(exception.toString()).show(); } @@ -150,7 +150,7 @@ protected void activate() { private void publishBlindVote(Coin stake) { voteButtonBusyAnimation.play(); voteButtonInfoLabel.setText(Res.get("dao.blindVote.startPublishing")); - myVoteServiceFacade.publishBlindVote(stake, + myBlindVoteServiceFacade.publishBlindVote(stake, () -> { voteButtonBusyAnimation.stop(); voteButtonInfoLabel.setText(""); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java index a13546c7a1b..b1f10f5151f 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java @@ -34,7 +34,7 @@ import bisq.core.dao.consensus.proposal.param.ChangeParamService; import bisq.core.dao.consensus.vote.BooleanVote; import bisq.core.dao.consensus.vote.Vote; -import bisq.core.dao.presentation.myvote.MyVoteServiceFacade; +import bisq.core.dao.presentation.myvote.MyBlindVoteServiceFacade; import bisq.core.dao.presentation.period.PeriodServiceFacade; import bisq.core.dao.presentation.proposal.FilteredBallotListService; import bisq.core.dao.presentation.proposal.MyBallotListService; @@ -74,7 +74,7 @@ @FxmlView public class MyVotesView extends BaseProposalView { - private final MyVoteServiceFacade myVoteServiceFacade; + private final MyBlindVoteServiceFacade myBlindVoteServiceFacade; private final Preferences preferences; private final ObservableList voteListItems = FXCollections.observableArrayList(); @@ -97,12 +97,12 @@ private MyVotesView(MyBallotListService myBallotListService, ChangeParamService changeParamService, BsqFormatter bsqFormatter, BSFormatter btcFormatter, - MyVoteServiceFacade myVoteServiceFacade, + MyBlindVoteServiceFacade myBlindVoteServiceFacade, Preferences preferences) { super(myBallotListService, filteredBallotListService, bsqWalletService, stateService, periodServiceFacade, changeParamService, bsqFormatter, btcFormatter); - this.myVoteServiceFacade = myVoteServiceFacade; + this.myBlindVoteServiceFacade = myBlindVoteServiceFacade; this.preferences = preferences; } @@ -127,7 +127,7 @@ protected void activate() { sortedList.comparatorProperty().bind(votesTableView.comparatorProperty()); voteListItems.clear(); - List items = myVoteServiceFacade.getMyVoteList().stream() + List items = myBlindVoteServiceFacade.getMyVoteList().stream() .map(vote -> new VoteListItem(vote, bsqWalletService, stateServiceFacade, periodServiceFacade, bsqFormatter)) .collect(Collectors.toList()); voteListItems.addAll(items); From c9a4d546159b33844aac96dd26bdb6faac1d7c25 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sat, 21 Apr 2018 14:40:42 -0500 Subject: [PATCH 059/197] Rename package bisq.core.dao.presentation.proposal to ballot --- .../java/bisq/desktop/main/dao/proposal/BaseProposalView.java | 4 ++-- .../java/bisq/desktop/main/dao/proposal/ProposalListItem.java | 2 +- .../desktop/main/dao/proposal/active/ActiveProposalsView.java | 4 ++-- .../desktop/main/dao/proposal/closed/ClosedProposalsView.java | 4 ++-- .../bisq/desktop/main/dao/proposal/make/MakeProposalView.java | 4 ++-- .../bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java | 4 ++-- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java index 4bbdbd12c78..c595b4a5fc0 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java @@ -31,9 +31,9 @@ import bisq.core.dao.consensus.period.Phase; import bisq.core.dao.consensus.proposal.Proposal; import bisq.core.dao.consensus.proposal.param.ChangeParamService; +import bisq.core.dao.presentation.ballot.FilteredBallotListService; +import bisq.core.dao.presentation.ballot.MyBallotListService; import bisq.core.dao.presentation.period.PeriodServiceFacade; -import bisq.core.dao.presentation.proposal.FilteredBallotListService; -import bisq.core.dao.presentation.proposal.MyBallotListService; import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index 7abbf0b859c..43bdaadc024 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -30,8 +30,8 @@ import bisq.core.dao.consensus.state.blockchain.Tx; import bisq.core.dao.consensus.vote.BooleanVote; import bisq.core.dao.consensus.vote.Vote; +import bisq.core.dao.presentation.ballot.MyBallotListService; import bisq.core.dao.presentation.period.PeriodServiceFacade; -import bisq.core.dao.presentation.proposal.MyBallotListService; import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index fb8040fe024..d22d3abfb0f 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -37,10 +37,10 @@ import bisq.core.dao.consensus.period.Phase; import bisq.core.dao.consensus.proposal.param.ChangeParamService; import bisq.core.dao.consensus.vote.BooleanVote; +import bisq.core.dao.presentation.ballot.FilteredBallotListService; +import bisq.core.dao.presentation.ballot.MyBallotListService; import bisq.core.dao.presentation.myvote.MyBlindVoteServiceFacade; import bisq.core.dao.presentation.period.PeriodServiceFacade; -import bisq.core.dao.presentation.proposal.FilteredBallotListService; -import bisq.core.dao.presentation.proposal.MyBallotListService; import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java index 2f97fd46797..04010717dc2 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java @@ -24,9 +24,9 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.consensus.proposal.param.ChangeParamService; +import bisq.core.dao.presentation.ballot.FilteredBallotListService; +import bisq.core.dao.presentation.ballot.MyBallotListService; import bisq.core.dao.presentation.period.PeriodServiceFacade; -import bisq.core.dao.presentation.proposal.MyBallotListService; -import bisq.core.dao.presentation.proposal.FilteredBallotListService; import bisq.core.dao.presentation.state.StateServiceFacade; import javax.inject.Inject; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index dce77cbfc6e..d00036f03dc 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -35,10 +35,10 @@ import bisq.core.dao.consensus.ballot.Ballot; import bisq.core.dao.consensus.proposal.ProposalConsensus; import bisq.core.dao.consensus.proposal.ProposalType; +import bisq.core.dao.consensus.proposal.param.ChangeParamService; import bisq.core.dao.presentation.ballot.CompensationBallotFactory; import bisq.core.dao.presentation.ballot.GenericBallotFactory; -import bisq.core.dao.consensus.proposal.param.ChangeParamService; -import bisq.core.dao.presentation.proposal.MyBallotListService; +import bisq.core.dao.presentation.ballot.MyBallotListService; import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; import bisq.core.provider.fee.FeeService; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java index b1f10f5151f..4d6a39cf899 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java @@ -34,10 +34,10 @@ import bisq.core.dao.consensus.proposal.param.ChangeParamService; import bisq.core.dao.consensus.vote.BooleanVote; import bisq.core.dao.consensus.vote.Vote; +import bisq.core.dao.presentation.ballot.FilteredBallotListService; +import bisq.core.dao.presentation.ballot.MyBallotListService; import bisq.core.dao.presentation.myvote.MyBlindVoteServiceFacade; import bisq.core.dao.presentation.period.PeriodServiceFacade; -import bisq.core.dao.presentation.proposal.FilteredBallotListService; -import bisq.core.dao.presentation.proposal.MyBallotListService; import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; import bisq.core.user.Preferences; From 7e207d380df7fa1fc03546ff294df79d74875162 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sat, 21 Apr 2018 20:52:33 -0500 Subject: [PATCH 060/197] Remove usage of PeriodServiceFacade and ThreadAwareListener --- .../main/dao/proposal/BaseProposalView.java | 18 +++++++-------- .../main/dao/proposal/ProposalListItem.java | 16 +++++++------- .../proposal/active/ActiveProposalsView.java | 10 ++++----- .../proposal/closed/ClosedProposalsView.java | 6 ++--- .../dashboard/ProposalDashboardView.java | 22 +++++++++---------- .../dao/proposal/myvotes/MyVotesView.java | 8 +++---- .../dao/proposal/myvotes/VoteListItem.java | 8 +++---- 7 files changed, 44 insertions(+), 44 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java index c595b4a5fc0..95297118582 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java @@ -28,12 +28,12 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.consensus.ballot.Ballot; +import bisq.core.dao.consensus.period.PeriodService; import bisq.core.dao.consensus.period.Phase; import bisq.core.dao.consensus.proposal.Proposal; import bisq.core.dao.consensus.proposal.param.ChangeParamService; import bisq.core.dao.presentation.ballot.FilteredBallotListService; import bisq.core.dao.presentation.ballot.MyBallotListService; -import bisq.core.dao.presentation.period.PeriodServiceFacade; import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; @@ -73,7 +73,7 @@ public abstract class BaseProposalView extends ActivatableView { protected final MyBallotListService myBallotListService; protected final StateServiceFacade stateServiceFacade; - protected final PeriodServiceFacade periodServiceFacade; + protected final PeriodService PeriodService; protected final ChangeParamService changeParamService; protected final FilteredBallotListService filteredBallotListService; protected final BsqWalletService bsqWalletService; @@ -105,7 +105,7 @@ protected BaseProposalView(MyBallotListService myBallotListService, FilteredBallotListService filteredBallotListService, BsqWalletService bsqWalletService, StateServiceFacade stateServiceFacade, - PeriodServiceFacade periodServiceFacade, + PeriodService PeriodService, ChangeParamService changeParamService, BsqFormatter bsqFormatter, BSFormatter btcFormatter) { @@ -113,7 +113,7 @@ protected BaseProposalView(MyBallotListService myBallotListService, this.filteredBallotListService = filteredBallotListService; this.bsqWalletService = bsqWalletService; this.stateServiceFacade = stateServiceFacade; - this.periodServiceFacade = periodServiceFacade; + this.PeriodService = PeriodService; this.changeParamService = changeParamService; this.bsqFormatter = bsqFormatter; this.btcFormatter = btcFormatter; @@ -132,12 +132,12 @@ public void initialize() { @Override protected void activate() { - phaseSubscription = EasyBind.subscribe(periodServiceFacade.phaseProperty(), this::onPhaseChanged); + phaseSubscription = EasyBind.subscribe(PeriodService.phaseProperty(), this::onPhaseChanged); selectedProposalSubscription = EasyBind.subscribe(proposalTableView.getSelectionModel().selectedItemProperty(), this::onSelectProposal); - periodServiceFacade.phaseProperty().addListener(phaseChangeListener); + PeriodService.phaseProperty().addListener(phaseChangeListener); - onPhaseChanged(periodServiceFacade.phaseProperty().get()); + onPhaseChanged(PeriodService.phaseProperty().get()); sortedList.comparatorProperty().bind(proposalTableView.comparatorProperty()); @@ -149,7 +149,7 @@ protected void deactivate() { phaseSubscription.unsubscribe(); selectedProposalSubscription.unsubscribe(); - periodServiceFacade.phaseProperty().removeListener(phaseChangeListener); + PeriodService.phaseProperty().removeListener(phaseChangeListener); sortedList.comparatorProperty().unbind(); @@ -250,7 +250,7 @@ protected void doUpdateProposalList(List list) { proposalListItems.setAll(list.stream() .map(ballot -> new ProposalListItem(ballot, myBallotListService, - periodServiceFacade, + PeriodService, bsqWalletService, stateServiceFacade, bsqFormatter)) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index 43bdaadc024..a6d9bfbed9d 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -24,6 +24,7 @@ import bisq.core.btc.listeners.TxConfidenceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.consensus.ballot.Ballot; +import bisq.core.dao.consensus.period.PeriodService; import bisq.core.dao.consensus.period.Phase; import bisq.core.dao.consensus.state.Block; import bisq.core.dao.consensus.state.BlockListener; @@ -31,7 +32,6 @@ import bisq.core.dao.consensus.vote.BooleanVote; import bisq.core.dao.consensus.vote.Vote; import bisq.core.dao.presentation.ballot.MyBallotListService; -import bisq.core.dao.presentation.period.PeriodServiceFacade; import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; @@ -59,7 +59,7 @@ public class ProposalListItem implements BlockListener { @Getter private final Ballot ballot; private final MyBallotListService myBallotListService; - private final PeriodServiceFacade periodServiceFacade; + private final PeriodService PeriodService; private final BsqWalletService bsqWalletService; private final StateServiceFacade stateServiceFacade; private final BsqFormatter bsqFormatter; @@ -82,13 +82,13 @@ public class ProposalListItem implements BlockListener { ProposalListItem(Ballot ballot, MyBallotListService myBallotListService, - PeriodServiceFacade periodServiceFacade, + PeriodService PeriodService, BsqWalletService bsqWalletService, StateServiceFacade stateServiceFacade, BsqFormatter bsqFormatter) { this.ballot = ballot; this.myBallotListService = myBallotListService; - this.periodServiceFacade = periodServiceFacade; + this.PeriodService = PeriodService; this.bsqWalletService = bsqWalletService; this.stateServiceFacade = stateServiceFacade; this.bsqFormatter = bsqFormatter; @@ -116,10 +116,10 @@ public class ProposalListItem implements BlockListener { }; voteResultChangeListener = (observable, oldValue, newValue) -> { - applyState(periodServiceFacade.phaseProperty().get(), newValue); + applyState(PeriodService.phaseProperty().get(), newValue); }; - periodServiceFacade.phaseProperty().addListener(phaseChangeListener); + PeriodService.phaseProperty().addListener(phaseChangeListener); ballot.getVoteResultProperty().addListener(voteResultChangeListener); } @@ -128,7 +128,7 @@ public void applyState(Phase phase, Vote vote) { actionButton.setText(""); actionButton.setVisible(false); actionButton.setOnAction(null); - final boolean isTxInPastCycle = periodServiceFacade.isTxInPastCycle(ballot.getTxId(), + final boolean isTxInPastCycle = PeriodService.isTxInPastCycle(ballot.getTxId(), stateServiceFacade.getChainHeight()); switch (phase) { case UNDEFINED: @@ -253,7 +253,7 @@ public void cleanup() { if (txConfidenceListener != null) bsqWalletService.removeTxConfidenceListener(txConfidenceListener); - periodServiceFacade.phaseProperty().removeListener(phaseChangeListener); + PeriodService.phaseProperty().removeListener(phaseChangeListener); ballot.getVoteResultProperty().removeListener(voteResultChangeListener); } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index d22d3abfb0f..5cfd5e0c254 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -34,13 +34,13 @@ import bisq.core.btc.wallet.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.consensus.ballot.Ballot; +import bisq.core.dao.consensus.period.PeriodService; import bisq.core.dao.consensus.period.Phase; import bisq.core.dao.consensus.proposal.param.ChangeParamService; import bisq.core.dao.consensus.vote.BooleanVote; import bisq.core.dao.presentation.ballot.FilteredBallotListService; import bisq.core.dao.presentation.ballot.MyBallotListService; import bisq.core.dao.presentation.myvote.MyBlindVoteServiceFacade; -import bisq.core.dao.presentation.period.PeriodServiceFacade; import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; @@ -89,7 +89,7 @@ public class ActiveProposalsView extends BaseProposalView implements BsqBalanceL @Inject private ActiveProposalsView(MyBallotListService myBallotListService, FilteredBallotListService filteredBallotListService, - PeriodServiceFacade periodServiceFacade, + PeriodService PeriodService, MyBlindVoteServiceFacade myBlindVoteServiceFacade, BsqWalletService bsqWalletService, StateServiceFacade stateService, @@ -98,7 +98,7 @@ private ActiveProposalsView(MyBallotListService myBallotListService, BSFormatter btcFormatter) { super(myBallotListService, filteredBallotListService, bsqWalletService, stateService, - periodServiceFacade, changeParamService, bsqFormatter, btcFormatter); + PeriodService, changeParamService, bsqFormatter, btcFormatter); this.myBlindVoteServiceFacade = myBlindVoteServiceFacade; } @@ -235,7 +235,7 @@ protected void onSelectProposal(ProposalListItem item) { cancelVoteButton = null; } - onPhaseChanged(periodServiceFacade.phaseProperty().get()); + onPhaseChanged(PeriodService.phaseProperty().get()); } } @@ -268,7 +268,7 @@ protected void onPhaseChanged(Phase phase) { } if (selectedProposalListItem != null && proposalDisplay != null && - !periodServiceFacade.isTxInPastCycle(selectedProposalListItem.getBallot().getTxId(), + !PeriodService.isTxInPastCycle(selectedProposalListItem.getBallot().getTxId(), stateServiceFacade.getChainHeight())) { final Ballot ballot = selectedProposalListItem.getBallot(); switch (phase) { diff --git a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java index 04010717dc2..57afca4f1ab 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java @@ -23,10 +23,10 @@ import bisq.desktop.util.BsqFormatter; import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.dao.consensus.period.PeriodService; import bisq.core.dao.consensus.proposal.param.ChangeParamService; import bisq.core.dao.presentation.ballot.FilteredBallotListService; import bisq.core.dao.presentation.ballot.MyBallotListService; -import bisq.core.dao.presentation.period.PeriodServiceFacade; import bisq.core.dao.presentation.state.StateServiceFacade; import javax.inject.Inject; @@ -41,7 +41,7 @@ public class ClosedProposalsView extends BaseProposalView { @Inject private ClosedProposalsView(MyBallotListService myBallotListService, FilteredBallotListService filteredBallotListService, - PeriodServiceFacade periodServiceFacade, + PeriodService PeriodService, BsqWalletService bsqWalletService, StateServiceFacade stateService, ChangeParamService changeParamService, @@ -49,7 +49,7 @@ private ClosedProposalsView(MyBallotListService myBallotListService, BSFormatter btcFormatter) { super(myBallotListService, filteredBallotListService, bsqWalletService, stateService, - periodServiceFacade, changeParamService, bsqFormatter, btcFormatter); + PeriodService, changeParamService, bsqFormatter, btcFormatter); } @Override diff --git a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java index ca7c4504b86..f814c652da3 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java @@ -22,9 +22,9 @@ import bisq.desktop.components.SeparatedPhaseBars; import bisq.desktop.util.Layout; +import bisq.core.dao.consensus.period.PeriodService; import bisq.core.dao.consensus.period.PeriodStateChangeListener; import bisq.core.dao.consensus.period.Phase; -import bisq.core.dao.presentation.period.PeriodServiceFacade; import bisq.core.locale.Res; import bisq.common.UserThread; @@ -51,7 +51,7 @@ public class ProposalDashboardView extends ActivatableView implements PeriodStateChangeListener { private List phaseBarsItems; - private final PeriodServiceFacade periodServiceFacade; + private final PeriodService PeriodService; private Phase currentPhase; private Subscription phaseSubscription; private GridPane gridPane; @@ -64,8 +64,8 @@ public class ProposalDashboardView extends ActivatableView imple /////////////////////////////////////////////////////////////////////////////////////////// @Inject - private ProposalDashboardView(PeriodServiceFacade periodServiceFacade) { - this.periodServiceFacade = periodServiceFacade; + private ProposalDashboardView(PeriodService PeriodService) { + this.PeriodService = PeriodService; } @Override @@ -111,7 +111,7 @@ private SeparatedPhaseBars createSeparatedPhaseBars() { protected void activate() { super.activate(); - phaseSubscription = EasyBind.subscribe(periodServiceFacade.phaseProperty(), phase -> { + phaseSubscription = EasyBind.subscribe(PeriodService.phaseProperty(), phase -> { if (!phase.equals(this.currentPhase)) { this.currentPhase = phase; } @@ -124,16 +124,16 @@ protected void activate() { }); }); - periodServiceFacade.addPeriodStateChangeListener(this); + PeriodService.addPeriodStateChangeListener(this); // We need to delay as otherwise the periodService has not been updated yet. - UserThread.execute(() -> onPreParserChainHeightChanged(periodServiceFacade.getChainHeight())); + UserThread.execute(() -> onPreParserChainHeightChanged(PeriodService.getChainHeight())); } @Override protected void deactivate() { super.deactivate(); - periodServiceFacade.removePeriodStateChangeListener(this); + PeriodService.removePeriodStateChangeListener(this); phaseSubscription.unsubscribe(); } @@ -142,9 +142,9 @@ public void onPreParserChainHeightChanged(int height) { if (height > 0) { separatedPhaseBars.updateWidth(); phaseBarsItems.forEach(item -> { - int firstBlock = periodServiceFacade.getFirstBlockOfPhase(height, item.getPhase()); - int lastBlock = periodServiceFacade.getLastBlockOfPhase(height, item.getPhase()); - final int duration = periodServiceFacade.getDurationForPhase(item.getPhase(), periodServiceFacade.getChainHeight()); + int firstBlock = PeriodService.getFirstBlockOfPhase(height, item.getPhase()); + int lastBlock = PeriodService.getLastBlockOfPhase(height, item.getPhase()); + final int duration = PeriodService.getDurationForPhase(item.getPhase(), PeriodService.getChainHeight()); item.setPeriodRange(firstBlock, lastBlock, duration); double progress = 0; if (height >= firstBlock && height <= lastBlock) { diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java index 4d6a39cf899..78e5c6d4775 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java @@ -31,13 +31,13 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.consensus.ballot.BallotList; +import bisq.core.dao.consensus.period.PeriodService; import bisq.core.dao.consensus.proposal.param.ChangeParamService; import bisq.core.dao.consensus.vote.BooleanVote; import bisq.core.dao.consensus.vote.Vote; import bisq.core.dao.presentation.ballot.FilteredBallotListService; import bisq.core.dao.presentation.ballot.MyBallotListService; import bisq.core.dao.presentation.myvote.MyBlindVoteServiceFacade; -import bisq.core.dao.presentation.period.PeriodServiceFacade; import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; import bisq.core.user.Preferences; @@ -93,7 +93,7 @@ private MyVotesView(MyBallotListService myBallotListService, FilteredBallotListService filteredBallotListService, BsqWalletService bsqWalletService, StateServiceFacade stateService, - PeriodServiceFacade periodServiceFacade, + PeriodService PeriodService, ChangeParamService changeParamService, BsqFormatter bsqFormatter, BSFormatter btcFormatter, @@ -101,7 +101,7 @@ private MyVotesView(MyBallotListService myBallotListService, Preferences preferences) { super(myBallotListService, filteredBallotListService, bsqWalletService, stateService, - periodServiceFacade, changeParamService, bsqFormatter, btcFormatter); + PeriodService, changeParamService, bsqFormatter, btcFormatter); this.myBlindVoteServiceFacade = myBlindVoteServiceFacade; this.preferences = preferences; } @@ -128,7 +128,7 @@ protected void activate() { voteListItems.clear(); List items = myBlindVoteServiceFacade.getMyVoteList().stream() - .map(vote -> new VoteListItem(vote, bsqWalletService, stateServiceFacade, periodServiceFacade, bsqFormatter)) + .map(vote -> new VoteListItem(vote, bsqWalletService, stateServiceFacade, PeriodService, bsqFormatter)) .collect(Collectors.toList()); voteListItems.addAll(items); } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java index ee2b4d0bf82..18981cfcfb1 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java @@ -23,11 +23,11 @@ import bisq.core.btc.listeners.TxConfidenceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.consensus.myvote.MyVote; +import bisq.core.dao.consensus.period.PeriodService; import bisq.core.dao.consensus.state.Block; import bisq.core.dao.consensus.state.BlockListener; import bisq.core.dao.consensus.state.blockchain.Tx; import bisq.core.dao.consensus.state.blockchain.TxOutput; -import bisq.core.dao.presentation.period.PeriodServiceFacade; import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; @@ -57,7 +57,7 @@ public class VoteListItem implements BlockListener { private final MyVote myVote; private final BsqWalletService bsqWalletService; private final StateServiceFacade stateServiceFacade; - private final PeriodServiceFacade periodServiceFacade; + private final PeriodService PeriodService; private final BsqFormatter bsqFormatter; private final ChangeListener chainHeightListener; @Getter @@ -78,12 +78,12 @@ public class VoteListItem implements BlockListener { VoteListItem(MyVote myVote, BsqWalletService bsqWalletService, StateServiceFacade stateServiceFacade, - PeriodServiceFacade periodServiceFacade, + PeriodService PeriodService, BsqFormatter bsqFormatter) { this.myVote = myVote; this.bsqWalletService = bsqWalletService; this.stateServiceFacade = stateServiceFacade; - this.periodServiceFacade = periodServiceFacade; + this.PeriodService = PeriodService; this.bsqFormatter = bsqFormatter; txConfidenceIndicator = new TxConfidenceIndicator(); From 6551ad28dfe5c412518caac9528103c0c3423d44 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sat, 21 Apr 2018 21:03:47 -0500 Subject: [PATCH 061/197] Remove StateServiceFacade --- .../main/dao/proposal/BaseProposalView.java | 10 +++--- .../main/dao/proposal/ProposalListItem.java | 16 ++++----- .../proposal/active/ActiveProposalsView.java | 6 ++-- .../proposal/closed/ClosedProposalsView.java | 4 +-- .../dashboard/ProposalDashboardView.java | 2 +- .../dao/proposal/make/MakeProposalView.java | 6 ++-- .../dao/proposal/myvotes/MyVotesView.java | 6 ++-- .../dao/proposal/myvotes/VoteListItem.java | 16 ++++----- .../wallet/dashboard/BsqDashboardView.java | 36 +++++++++---------- .../main/dao/wallet/tx/BsqTxListItem.java | 6 ++-- .../desktop/main/dao/wallet/tx/BsqTxView.java | 28 +++++++-------- .../TransactionListItemFactory.java | 6 ++-- .../transactions/TransactionsListItem.java | 4 +-- 13 files changed, 73 insertions(+), 73 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java index 95297118582..d18e2e4d8b9 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java @@ -32,9 +32,9 @@ import bisq.core.dao.consensus.period.Phase; import bisq.core.dao.consensus.proposal.Proposal; import bisq.core.dao.consensus.proposal.param.ChangeParamService; +import bisq.core.dao.consensus.state.StateService; import bisq.core.dao.presentation.ballot.FilteredBallotListService; import bisq.core.dao.presentation.ballot.MyBallotListService; -import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; import javax.inject.Inject; @@ -72,7 +72,7 @@ public abstract class BaseProposalView extends ActivatableView { protected final MyBallotListService myBallotListService; - protected final StateServiceFacade stateServiceFacade; + protected final StateService stateService; protected final PeriodService PeriodService; protected final ChangeParamService changeParamService; protected final FilteredBallotListService filteredBallotListService; @@ -104,7 +104,7 @@ public abstract class BaseProposalView extends ActivatableView { protected BaseProposalView(MyBallotListService myBallotListService, FilteredBallotListService filteredBallotListService, BsqWalletService bsqWalletService, - StateServiceFacade stateServiceFacade, + StateService stateService, PeriodService PeriodService, ChangeParamService changeParamService, BsqFormatter bsqFormatter, @@ -112,7 +112,7 @@ protected BaseProposalView(MyBallotListService myBallotListService, this.myBallotListService = myBallotListService; this.filteredBallotListService = filteredBallotListService; this.bsqWalletService = bsqWalletService; - this.stateServiceFacade = stateServiceFacade; + this.stateService = stateService; this.PeriodService = PeriodService; this.changeParamService = changeParamService; this.bsqFormatter = bsqFormatter; @@ -252,7 +252,7 @@ protected void doUpdateProposalList(List list) { myBallotListService, PeriodService, bsqWalletService, - stateServiceFacade, + stateService, bsqFormatter)) .collect(Collectors.toSet())); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index a6d9bfbed9d..2301323e3e7 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -28,11 +28,11 @@ import bisq.core.dao.consensus.period.Phase; import bisq.core.dao.consensus.state.Block; import bisq.core.dao.consensus.state.BlockListener; +import bisq.core.dao.consensus.state.StateService; import bisq.core.dao.consensus.state.blockchain.Tx; import bisq.core.dao.consensus.vote.BooleanVote; import bisq.core.dao.consensus.vote.Vote; import bisq.core.dao.presentation.ballot.MyBallotListService; -import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; import org.bitcoinj.core.Transaction; @@ -61,7 +61,7 @@ public class ProposalListItem implements BlockListener { private final MyBallotListService myBallotListService; private final PeriodService PeriodService; private final BsqWalletService bsqWalletService; - private final StateServiceFacade stateServiceFacade; + private final StateService stateService; private final BsqFormatter bsqFormatter; private final ChangeListener chainHeightListener; private final ChangeListener voteResultChangeListener; @@ -84,13 +84,13 @@ public class ProposalListItem implements BlockListener { MyBallotListService myBallotListService, PeriodService PeriodService, BsqWalletService bsqWalletService, - StateServiceFacade stateServiceFacade, + StateService stateService, BsqFormatter bsqFormatter) { this.ballot = ballot; this.myBallotListService = myBallotListService; this.PeriodService = PeriodService; this.bsqWalletService = bsqWalletService; - this.stateServiceFacade = stateServiceFacade; + this.stateService = stateService; this.bsqFormatter = bsqFormatter; @@ -109,7 +109,7 @@ public class ProposalListItem implements BlockListener { bsqWalletService.getChainHeightProperty().addListener(chainHeightListener); setupConfidence(); - stateServiceFacade.addBlockListener(this); + stateService.addBlockListener(this); phaseChangeListener = (observable, oldValue, newValue) -> { applyState(newValue, ballot.getVote()); @@ -129,7 +129,7 @@ public void applyState(Phase phase, Vote vote) { actionButton.setVisible(false); actionButton.setOnAction(null); final boolean isTxInPastCycle = PeriodService.isTxInPastCycle(ballot.getTxId(), - stateServiceFacade.getChainHeight()); + stateService.getChainHeight()); switch (phase) { case UNDEFINED: log.error("invalid state UNDEFINED"); @@ -204,7 +204,7 @@ public void onBlockAdded(Block block) { private void setupConfidence() { - final Tx tx = stateServiceFacade.getTxMap().get(ballot.getProposal().getTxId()); + final Tx tx = stateService.getTxMap().get(ballot.getProposal().getTxId()); if (tx != null) { final String txId = tx.getId(); @@ -248,7 +248,7 @@ private void updateConfidence(TransactionConfidence confidence, int depthInBlock } public void cleanup() { - stateServiceFacade.removeBlockListener(this); + stateService.removeBlockListener(this); bsqWalletService.getChainHeightProperty().removeListener(chainHeightListener); if (txConfidenceListener != null) bsqWalletService.removeTxConfidenceListener(txConfidenceListener); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index 5cfd5e0c254..a325f2184d1 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -37,11 +37,11 @@ import bisq.core.dao.consensus.period.PeriodService; import bisq.core.dao.consensus.period.Phase; import bisq.core.dao.consensus.proposal.param.ChangeParamService; +import bisq.core.dao.consensus.state.StateService; import bisq.core.dao.consensus.vote.BooleanVote; import bisq.core.dao.presentation.ballot.FilteredBallotListService; import bisq.core.dao.presentation.ballot.MyBallotListService; import bisq.core.dao.presentation.myvote.MyBlindVoteServiceFacade; -import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; import bisq.common.util.Tuple2; @@ -92,7 +92,7 @@ private ActiveProposalsView(MyBallotListService myBallotListService, PeriodService PeriodService, MyBlindVoteServiceFacade myBlindVoteServiceFacade, BsqWalletService bsqWalletService, - StateServiceFacade stateService, + StateService stateService, ChangeParamService changeParamService, BsqFormatter bsqFormatter, BSFormatter btcFormatter) { @@ -269,7 +269,7 @@ protected void onPhaseChanged(Phase phase) { if (selectedProposalListItem != null && proposalDisplay != null && !PeriodService.isTxInPastCycle(selectedProposalListItem.getBallot().getTxId(), - stateServiceFacade.getChainHeight())) { + stateService.getChainHeight())) { final Ballot ballot = selectedProposalListItem.getBallot(); switch (phase) { case PROPOSAL: diff --git a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java index 57afca4f1ab..1c3a230007e 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java @@ -25,9 +25,9 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.consensus.period.PeriodService; import bisq.core.dao.consensus.proposal.param.ChangeParamService; +import bisq.core.dao.consensus.state.StateService; import bisq.core.dao.presentation.ballot.FilteredBallotListService; import bisq.core.dao.presentation.ballot.MyBallotListService; -import bisq.core.dao.presentation.state.StateServiceFacade; import javax.inject.Inject; @@ -43,7 +43,7 @@ private ClosedProposalsView(MyBallotListService myBallotListService, FilteredBallotListService filteredBallotListService, PeriodService PeriodService, BsqWalletService bsqWalletService, - StateServiceFacade stateService, + StateService stateService, ChangeParamService changeParamService, BsqFormatter bsqFormatter, BSFormatter btcFormatter) { diff --git a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java index f814c652da3..1cd8bac068a 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java @@ -46,7 +46,7 @@ // We use here PeriodStateChangeListener because we are interested in period changes not in the result of a completed // block. The event from the PeriodStateChangeListener is sent before parsing starts. -// The event from the StateServiceFacade.Listener would notify after parsing a new block. +// The event from the StateService.Listener would notify after parsing a new block. @FxmlView public class ProposalDashboardView extends ActivatableView implements PeriodStateChangeListener { diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index d00036f03dc..fb5dc6b1a27 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -36,10 +36,10 @@ import bisq.core.dao.consensus.proposal.ProposalConsensus; import bisq.core.dao.consensus.proposal.ProposalType; import bisq.core.dao.consensus.proposal.param.ChangeParamService; +import bisq.core.dao.consensus.state.StateService; import bisq.core.dao.presentation.ballot.CompensationBallotFactory; import bisq.core.dao.presentation.ballot.GenericBallotFactory; import bisq.core.dao.presentation.ballot.MyBallotListService; -import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; import bisq.core.provider.fee.FeeService; @@ -86,7 +86,7 @@ public class MakeProposalView extends ActivatableView { private final MyBallotListService myBallotListService; private final CompensationBallotFactory compensationBallotFactory; private final GenericBallotFactory genericBallotFactory; - private final StateServiceFacade stateService; + private final StateService stateService; private final ChangeParamService changeParamService; private final BSFormatter btcFormatter; private final BsqFormatter bsqFormatter; @@ -107,7 +107,7 @@ private MakeProposalView(BsqWalletService bsqWalletService, MyBallotListService myBallotListService, CompensationBallotFactory compensationBallotFactory, GenericBallotFactory genericBallotFactory, - StateServiceFacade stateService, + StateService stateService, ChangeParamService changeParamService, BSFormatter btcFormatter, BsqFormatter bsqFormatter) { diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java index 78e5c6d4775..abab9583b06 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java @@ -33,12 +33,12 @@ import bisq.core.dao.consensus.ballot.BallotList; import bisq.core.dao.consensus.period.PeriodService; import bisq.core.dao.consensus.proposal.param.ChangeParamService; +import bisq.core.dao.consensus.state.StateService; import bisq.core.dao.consensus.vote.BooleanVote; import bisq.core.dao.consensus.vote.Vote; import bisq.core.dao.presentation.ballot.FilteredBallotListService; import bisq.core.dao.presentation.ballot.MyBallotListService; import bisq.core.dao.presentation.myvote.MyBlindVoteServiceFacade; -import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; import bisq.core.user.Preferences; @@ -92,7 +92,7 @@ public class MyVotesView extends BaseProposalView { private MyVotesView(MyBallotListService myBallotListService, FilteredBallotListService filteredBallotListService, BsqWalletService bsqWalletService, - StateServiceFacade stateService, + StateService stateService, PeriodService PeriodService, ChangeParamService changeParamService, BsqFormatter bsqFormatter, @@ -128,7 +128,7 @@ protected void activate() { voteListItems.clear(); List items = myBlindVoteServiceFacade.getMyVoteList().stream() - .map(vote -> new VoteListItem(vote, bsqWalletService, stateServiceFacade, PeriodService, bsqFormatter)) + .map(vote -> new VoteListItem(vote, bsqWalletService, stateService, PeriodService, bsqFormatter)) .collect(Collectors.toList()); voteListItems.addAll(items); } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java index 18981cfcfb1..56a71585081 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java @@ -26,9 +26,9 @@ import bisq.core.dao.consensus.period.PeriodService; import bisq.core.dao.consensus.state.Block; import bisq.core.dao.consensus.state.BlockListener; +import bisq.core.dao.consensus.state.StateService; import bisq.core.dao.consensus.state.blockchain.Tx; import bisq.core.dao.consensus.state.blockchain.TxOutput; -import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; import org.bitcoinj.core.Coin; @@ -56,7 +56,7 @@ public class VoteListItem implements BlockListener { @Getter private final MyVote myVote; private final BsqWalletService bsqWalletService; - private final StateServiceFacade stateServiceFacade; + private final StateService stateService; private final PeriodService PeriodService; private final BsqFormatter bsqFormatter; private final ChangeListener chainHeightListener; @@ -77,12 +77,12 @@ public class VoteListItem implements BlockListener { VoteListItem(MyVote myVote, BsqWalletService bsqWalletService, - StateServiceFacade stateServiceFacade, + StateService stateService, PeriodService PeriodService, BsqFormatter bsqFormatter) { this.myVote = myVote; this.bsqWalletService = bsqWalletService; - this.stateServiceFacade = stateServiceFacade; + this.stateService = stateService; this.PeriodService = PeriodService; this.bsqFormatter = bsqFormatter; @@ -92,7 +92,7 @@ public class VoteListItem implements BlockListener { txConfidenceIndicator.setProgress(-1); txConfidenceIndicator.setPrefSize(24, 24); txConfidenceIndicator.setTooltip(tooltip); - stateServiceFacade.addBlockListener(this); + stateService.addBlockListener(this); chainHeightListener = (observable, oldValue, newValue) -> setupConfidence(); bsqWalletService.getChainHeightProperty().addListener(chainHeightListener); @@ -114,7 +114,7 @@ public void onBlockAdded(Block block) { private void setupConfidence() { calculateStake(); - final Tx tx = stateServiceFacade.getTxMap().get(myVote.getBlindVote().getTxId()); + final Tx tx = stateService.getTxMap().get(myVote.getBlindVote().getTxId()); if (tx != null) { final String txId = tx.getId(); @@ -153,7 +153,7 @@ public void onTransactionConfidenceChanged(TransactionConfidence confidence) { private void calculateStake() { if (stake == 0) { String txId = myVote.getTxId(); - stake = stateServiceFacade.getUnspentBlindVoteStakeTxOutputs().stream() + stake = stateService.getUnspentBlindVoteStakeTxOutputs().stream() .filter(txOutput -> txOutput.getTxId().equals(txId)) .filter(txOutput -> txOutput.getIndex() == 0) .mapToLong(TxOutput::getValue) @@ -171,7 +171,7 @@ private void updateConfidence(TransactionConfidence confidence, int depthInBlock public void cleanup() { bsqWalletService.getChainHeightProperty().removeListener(chainHeightListener); - stateServiceFacade.removeBlockListener(this); + stateService.removeBlockListener(this); if (txConfidenceListener != null) bsqWalletService.removeTxConfidenceListener(txConfidenceListener); } diff --git a/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java b/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java index 33342b16971..1904c7701e9 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java @@ -28,7 +28,7 @@ import bisq.core.dao.consensus.state.Block; import bisq.core.dao.consensus.state.BlockListener; -import bisq.core.dao.presentation.state.StateServiceFacade; +import bisq.core.dao.consensus.state.StateService; import bisq.core.locale.Res; import bisq.core.monetary.Altcoin; import bisq.core.monetary.Price; @@ -60,7 +60,7 @@ public class BsqDashboardView extends ActivatableView implements BlockListener { private final BsqBalanceUtil bsqBalanceUtil; - private final StateServiceFacade stateServiceFacade; + private final StateService stateService; private final PriceFeedService priceFeedService; private final Preferences preferences; private final BsqFormatter bsqFormatter; @@ -79,12 +79,12 @@ public class BsqDashboardView extends ActivatableView implements @Inject private BsqDashboardView(BsqBalanceUtil bsqBalanceUtil, - StateServiceFacade stateServiceFacade, + StateService stateService, PriceFeedService priceFeedService, Preferences preferences, BsqFormatter bsqFormatter) { this.bsqBalanceUtil = bsqBalanceUtil; - this.stateServiceFacade = stateServiceFacade; + this.stateService = stateService; this.priceFeedService = priceFeedService; this.preferences = preferences; this.bsqFormatter = bsqFormatter; @@ -97,13 +97,13 @@ public void initialize() { addTitledGroupBg(root, ++gridRow, 11, Res.get("dao.wallet.dashboard.statistics"), Layout.GROUP_DISTANCE); addLabelTextField(root, gridRow, Res.get("dao.wallet.dashboard.genesisBlockHeight"), - String.valueOf(stateServiceFacade.getGenesisBlockHeight()), Layout.FIRST_ROW_AND_GROUP_DISTANCE); + String.valueOf(stateService.getGenesisBlockHeight()), Layout.FIRST_ROW_AND_GROUP_DISTANCE); Label label = new AutoTooltipLabel(Res.get("dao.wallet.dashboard.genesisTxId")); GridPane.setRowIndex(label, ++gridRow); root.getChildren().add(label); - hyperlinkWithIcon = new HyperlinkWithIcon(stateServiceFacade.getGenesisTxId(), AwesomeIcon.EXTERNAL_LINK); - hyperlinkWithIcon.setTooltip(new Tooltip(Res.get("tooltip.openBlockchainForTx", stateServiceFacade.getGenesisTxId()))); + hyperlinkWithIcon = new HyperlinkWithIcon(stateService.getGenesisTxId(), AwesomeIcon.EXTERNAL_LINK); + hyperlinkWithIcon.setTooltip(new Tooltip(Res.get("tooltip.openBlockchainForTx", stateService.getGenesisTxId()))); GridPane.setRowIndex(hyperlinkWithIcon, gridRow); GridPane.setColumnIndex(hyperlinkWithIcon, 1); GridPane.setMargin(hyperlinkWithIcon, new Insets(0, 0, 0, -4)); @@ -129,10 +129,10 @@ public void initialize() { protected void activate() { bsqBalanceUtil.activate(); - stateServiceFacade.addBlockListener(this); + stateService.addBlockListener(this); priceFeedService.updateCounterProperty().addListener(priceChangeListener); - hyperlinkWithIcon.setOnAction(event -> GUIUtil.openWebPage(preferences.getBsqBlockChainExplorer().txUrl + stateServiceFacade.getGenesisTxId())); + hyperlinkWithIcon.setOnAction(event -> GUIUtil.openWebPage(preferences.getBsqBlockChainExplorer().txUrl + stateService.getGenesisTxId())); updateWithBsqBlockChainData(); updatePrice(); @@ -141,14 +141,14 @@ protected void activate() { @Override protected void deactivate() { bsqBalanceUtil.deactivate(); - stateServiceFacade.addBlockListener(this); + stateService.addBlockListener(this); priceFeedService.updateCounterProperty().removeListener(priceChangeListener); hyperlinkWithIcon.setOnAction(null); } /////////////////////////////////////////////////////////////////////////////////////////// - // StateServiceFacade.Listener + // StateService.Listener /////////////////////////////////////////////////////////////////////////////////////////// @Override @@ -157,25 +157,25 @@ public void onBlockAdded(Block block) { } private void updateWithBsqBlockChainData() { - final Coin issuedAmountFromGenesis = stateServiceFacade.getGenesisTotalSupply(); + final Coin issuedAmountFromGenesis = stateService.getGenesisTotalSupply(); genesisIssueAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(issuedAmountFromGenesis)); - final Coin issuedAmountFromCompRequests = Coin.valueOf(stateServiceFacade.getTotalIssuedAmountFromCompRequests()); + final Coin issuedAmountFromCompRequests = Coin.valueOf(stateService.getTotalIssuedAmountFromCompRequests()); compRequestIssueAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(issuedAmountFromCompRequests)); - final Coin burntFee = Coin.valueOf(stateServiceFacade.getTotalBurntFee()); + final Coin burntFee = Coin.valueOf(stateService.getTotalBurntFee()); final Coin availableAmount = issuedAmountFromGenesis.add(issuedAmountFromCompRequests).subtract(burntFee); availableAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(availableAmount)); burntAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(burntFee)); - allTxTextField.setText(String.valueOf(stateServiceFacade.getTxs().size())); - utxoTextField.setText(String.valueOf(stateServiceFacade.getUnspentTxOutputs().size())); + allTxTextField.setText(String.valueOf(stateService.getTxs().size())); + utxoTextField.setText(String.valueOf(stateService.getUnspentTxOutputs().size())); //spentTxTextField.setText(String.valueOf(stateService.getSpentTxOutputs().size())); - burntTxTextField.setText(String.valueOf(stateServiceFacade.getFeeTxs().size())); + burntTxTextField.setText(String.valueOf(stateService.getFeeTxs().size())); } private void updatePrice() { - final Coin issuedAmount = stateServiceFacade.getGenesisTotalSupply(); + final Coin issuedAmount = stateService.getGenesisTotalSupply(); final MarketPrice bsqMarketPrice = priceFeedService.getMarketPrice("BSQ"); if (bsqMarketPrice != null) { long bsqPrice = MathUtils.roundDoubleToLong(MathUtils.scaleUpByPowerOf10(bsqMarketPrice.getPrice(), Altcoin.SMALLEST_UNIT_EXPONENT)); diff --git a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java index f97ad43350d..63d05838b18 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java @@ -25,9 +25,9 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; import bisq.core.btc.wallet.WalletService; +import bisq.core.dao.consensus.state.StateService; import bisq.core.dao.consensus.state.blockchain.Tx; import bisq.core.dao.consensus.state.blockchain.TxType; -import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; import org.bitcoinj.core.Coin; @@ -51,7 +51,7 @@ class BsqTxListItem { private final Optional optionalTx; private final BsqWalletService bsqWalletService; private final BtcWalletService btcWalletService; - private final StateServiceFacade stateService; + private final StateService stateService; private final BsqFormatter bsqFormatter; private final Date date; private final String txId; @@ -71,7 +71,7 @@ class BsqTxListItem { Optional optionalTx, BsqWalletService bsqWalletService, BtcWalletService btcWalletService, - StateServiceFacade stateService, + StateService stateService, boolean isBurnedBsqTx, Date date, BsqFormatter bsqFormatter) { diff --git a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java index 5f429ff7857..9fe8343ddad 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java @@ -34,9 +34,9 @@ import bisq.core.btc.wallet.BtcWalletService; import bisq.core.dao.consensus.state.Block; import bisq.core.dao.consensus.state.BlockListener; +import bisq.core.dao.consensus.state.StateService; import bisq.core.dao.consensus.state.blockchain.Tx; import bisq.core.dao.consensus.state.blockchain.TxType; -import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; import bisq.core.user.Preferences; @@ -88,7 +88,7 @@ public class BsqTxView extends ActivatableView implements BsqBal private final BsqFormatter bsqFormatter; private final BsqWalletService bsqWalletService; - private final StateServiceFacade stateServiceFacade; + private final StateService stateService; private final BtcWalletService btcWalletService; private final BsqBalanceUtil bsqBalanceUtil; private final Preferences preferences; @@ -112,13 +112,13 @@ public class BsqTxView extends ActivatableView implements BsqBal private BsqTxView(BsqFormatter bsqFormatter, BsqWalletService bsqWalletService, Preferences preferences, - StateServiceFacade stateServiceFacade, + StateService stateService, BtcWalletService btcWalletService, BsqBalanceUtil bsqBalanceUtil) { this.bsqFormatter = bsqFormatter; this.bsqWalletService = bsqWalletService; this.preferences = preferences; - this.stateServiceFacade = stateServiceFacade; + this.stateService = stateService; this.btcWalletService = btcWalletService; this.bsqBalanceUtil = bsqBalanceUtil; } @@ -177,7 +177,7 @@ protected void activate() { sortedList.comparatorProperty().bind(tableView.comparatorProperty()); tableView.setItems(sortedList); - stateServiceFacade.addBlockListener(this); + stateService.addBlockListener(this); if (root.getParent() instanceof Pane) { rootParent = (Pane) root.getParent(); @@ -196,7 +196,7 @@ protected void deactivate() { bsqWalletService.getWalletTransactions().removeListener(walletBsqTransactionsListener); bsqWalletService.removeBsqBalanceListener(this); btcWalletService.getChainHeightProperty().removeListener(walletChainHeightListener); - stateServiceFacade.removeBlockListener(this); + stateService.removeBlockListener(this); observableList.forEach(BsqTxListItem::cleanup); @@ -225,7 +225,7 @@ public void onBlockAdded(Block block) { // If chain height from wallet of from the BSQ blockchain parsing changed we update our state. private void onUpdateAnyChainHeight() { - final int bsqBlockChainHeight = stateServiceFacade.getChainHeight(); + final int bsqBlockChainHeight = stateService.getChainHeight(); final int bsqWalletChainHeight = bsqWalletService.getBestChainHeight(); if (bsqWalletChainHeight > 0) { final boolean synced = bsqWalletChainHeight == bsqBlockChainHeight; @@ -258,13 +258,13 @@ private void updateList() { final List walletTransactions = new ArrayList<>(bsqWalletService.getWalletTransactions()); List items = walletTransactions.stream() .map(transaction -> { - final Optional optionalTx = stateServiceFacade.getTx(transaction.getHashAsString()); + final Optional optionalTx = stateService.getTx(transaction.getHashAsString()); return new BsqTxListItem(transaction, optionalTx, bsqWalletService, btcWalletService, - stateServiceFacade, - stateServiceFacade.hasTxBurntFee(transaction.getHashAsString()), + stateService, + stateService.hasTxBurntFee(transaction.getHashAsString()), transaction.getUpdateTime(), bsqFormatter); }) @@ -374,7 +374,7 @@ public void updateItem(final BsqTxListItem item, boolean empty) { if (txType == TxType.COMPENSATION_REQUEST && optionalTx.isPresent() && - stateServiceFacade.isIssuanceTx(optionalTx.get().getId())) { + stateService.isIssuanceTx(optionalTx.get().getId())) { if (field != null) field.setOnAction(null); @@ -536,11 +536,11 @@ public void updateItem(final BsqTxListItem item, boolean empty) { case PROPOSAL: case COMPENSATION_REQUEST: final String txId = item.getOptionalTx().get().getId(); - if (item.getOptionalTx().isPresent() && stateServiceFacade.isIssuanceTx(txId)) { + if (item.getOptionalTx().isPresent() && stateService.isIssuanceTx(txId)) { awesomeIcon = AwesomeIcon.MONEY; style = "dao-tx-type-issuance-icon"; - final int issuanceBlockHeight = stateServiceFacade.getIssuanceBlockHeight(txId); - long blockTimeInSec = stateServiceFacade.getBlockTime(issuanceBlockHeight); + final int issuanceBlockHeight = stateService.getIssuanceBlockHeight(txId); + long blockTimeInSec = stateService.getBlockTime(issuanceBlockHeight); final String formattedDate = bsqFormatter.formatDateTime(new Date(blockTimeInSec * 1000)); toolTipText = Res.get("dao.tx.issuance.tooltip", formattedDate); } else { diff --git a/src/main/java/bisq/desktop/main/funds/transactions/TransactionListItemFactory.java b/src/main/java/bisq/desktop/main/funds/transactions/TransactionListItemFactory.java index dcb98e1fdb0..cf1b055eaa5 100644 --- a/src/main/java/bisq/desktop/main/funds/transactions/TransactionListItemFactory.java +++ b/src/main/java/bisq/desktop/main/funds/transactions/TransactionListItemFactory.java @@ -21,7 +21,7 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; -import bisq.core.dao.presentation.state.StateServiceFacade; +import bisq.core.dao.consensus.state.StateService; import bisq.core.trade.Tradable; import org.bitcoinj.core.Transaction; @@ -35,12 +35,12 @@ public class TransactionListItemFactory { private final BtcWalletService btcWalletService; private final BsqWalletService bsqWalletService; - private final StateServiceFacade stateService; + private final StateService stateService; private final BSFormatter formatter; @Inject TransactionListItemFactory(BtcWalletService btcWalletService, BsqWalletService bsqWalletService, - StateServiceFacade stateService, BSFormatter formatter) { + StateService stateService, BSFormatter formatter) { this.btcWalletService = btcWalletService; this.bsqWalletService = bsqWalletService; this.stateService = stateService; diff --git a/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java b/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java index 184203f9626..79b22a4d3b9 100644 --- a/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java +++ b/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java @@ -26,8 +26,8 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; import bisq.core.btc.wallet.WalletService; +import bisq.core.dao.consensus.state.StateService; import bisq.core.dao.consensus.state.blockchain.TxType; -import bisq.core.dao.presentation.state.StateServiceFacade; import bisq.core.locale.Res; import bisq.core.offer.Offer; import bisq.core.offer.OpenOffer; @@ -80,7 +80,7 @@ public TransactionsListItem(Transaction transaction, BtcWalletService btcWalletService, BsqWalletService bsqWalletService, Optional tradableOptional, - StateServiceFacade stateService, + StateService stateService, BSFormatter formatter) { this.formatter = formatter; txId = transaction.getHashAsString(); From faa15f3da68bc445b0b823a0006ba29f6a2b125d Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sat, 21 Apr 2018 21:04:17 -0500 Subject: [PATCH 062/197] Move ballot classed from bisq.core.dao.presentation to consensus --- .../bisq/desktop/main/dao/proposal/BaseProposalView.java | 4 ++-- .../bisq/desktop/main/dao/proposal/ProposalListItem.java | 2 +- .../main/dao/proposal/active/ActiveProposalsView.java | 4 ++-- .../main/dao/proposal/closed/ClosedProposalsView.java | 4 ++-- .../desktop/main/dao/proposal/make/MakeProposalView.java | 6 +++--- .../bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java index d18e2e4d8b9..6d0c55d9d09 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java @@ -33,8 +33,8 @@ import bisq.core.dao.consensus.proposal.Proposal; import bisq.core.dao.consensus.proposal.param.ChangeParamService; import bisq.core.dao.consensus.state.StateService; -import bisq.core.dao.presentation.ballot.FilteredBallotListService; -import bisq.core.dao.presentation.ballot.MyBallotListService; +import bisq.core.dao.consensus.ballot.FilteredBallotListService; +import bisq.core.dao.consensus.ballot.MyBallotListService; import bisq.core.locale.Res; import javax.inject.Inject; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index 2301323e3e7..74e9d63f11b 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -32,7 +32,7 @@ import bisq.core.dao.consensus.state.blockchain.Tx; import bisq.core.dao.consensus.vote.BooleanVote; import bisq.core.dao.consensus.vote.Vote; -import bisq.core.dao.presentation.ballot.MyBallotListService; +import bisq.core.dao.consensus.ballot.MyBallotListService; import bisq.core.locale.Res; import org.bitcoinj.core.Transaction; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index a325f2184d1..427ec00cdee 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -39,8 +39,8 @@ import bisq.core.dao.consensus.proposal.param.ChangeParamService; import bisq.core.dao.consensus.state.StateService; import bisq.core.dao.consensus.vote.BooleanVote; -import bisq.core.dao.presentation.ballot.FilteredBallotListService; -import bisq.core.dao.presentation.ballot.MyBallotListService; +import bisq.core.dao.consensus.ballot.FilteredBallotListService; +import bisq.core.dao.consensus.ballot.MyBallotListService; import bisq.core.dao.presentation.myvote.MyBlindVoteServiceFacade; import bisq.core.locale.Res; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java index 1c3a230007e..8cde5a0b17b 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java @@ -26,8 +26,8 @@ import bisq.core.dao.consensus.period.PeriodService; import bisq.core.dao.consensus.proposal.param.ChangeParamService; import bisq.core.dao.consensus.state.StateService; -import bisq.core.dao.presentation.ballot.FilteredBallotListService; -import bisq.core.dao.presentation.ballot.MyBallotListService; +import bisq.core.dao.consensus.ballot.FilteredBallotListService; +import bisq.core.dao.consensus.ballot.MyBallotListService; import javax.inject.Inject; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index fb5dc6b1a27..33a222859f1 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -37,9 +37,9 @@ import bisq.core.dao.consensus.proposal.ProposalType; import bisq.core.dao.consensus.proposal.param.ChangeParamService; import bisq.core.dao.consensus.state.StateService; -import bisq.core.dao.presentation.ballot.CompensationBallotFactory; -import bisq.core.dao.presentation.ballot.GenericBallotFactory; -import bisq.core.dao.presentation.ballot.MyBallotListService; +import bisq.core.dao.consensus.ballot.CompensationBallotFactory; +import bisq.core.dao.consensus.ballot.GenericBallotFactory; +import bisq.core.dao.consensus.ballot.MyBallotListService; import bisq.core.locale.Res; import bisq.core.provider.fee.FeeService; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java index abab9583b06..f219ca8a918 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java @@ -36,8 +36,8 @@ import bisq.core.dao.consensus.state.StateService; import bisq.core.dao.consensus.vote.BooleanVote; import bisq.core.dao.consensus.vote.Vote; -import bisq.core.dao.presentation.ballot.FilteredBallotListService; -import bisq.core.dao.presentation.ballot.MyBallotListService; +import bisq.core.dao.consensus.ballot.FilteredBallotListService; +import bisq.core.dao.consensus.ballot.MyBallotListService; import bisq.core.dao.presentation.myvote.MyBlindVoteServiceFacade; import bisq.core.locale.Res; import bisq.core.user.Preferences; From 53b5b7b831babb4d34fede56c1bb196631ff4588 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sat, 21 Apr 2018 21:41:28 -0500 Subject: [PATCH 063/197] Remove presentation package and classes --- .../proposal/active/ActiveProposalsView.java | 18 +++++++++--------- .../main/dao/proposal/myvotes/MyVotesView.java | 14 +++++++------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index 427ec00cdee..e2f0607fbf6 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -34,14 +34,14 @@ import bisq.core.btc.wallet.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.consensus.ballot.Ballot; +import bisq.core.dao.consensus.ballot.FilteredBallotListService; +import bisq.core.dao.consensus.ballot.MyBallotListService; +import bisq.core.dao.consensus.myvote.MyBlindVoteService; import bisq.core.dao.consensus.period.PeriodService; import bisq.core.dao.consensus.period.Phase; import bisq.core.dao.consensus.proposal.param.ChangeParamService; import bisq.core.dao.consensus.state.StateService; import bisq.core.dao.consensus.vote.BooleanVote; -import bisq.core.dao.consensus.ballot.FilteredBallotListService; -import bisq.core.dao.consensus.ballot.MyBallotListService; -import bisq.core.dao.presentation.myvote.MyBlindVoteServiceFacade; import bisq.core.locale.Res; import bisq.common.util.Tuple2; @@ -73,7 +73,7 @@ @FxmlView public class ActiveProposalsView extends BaseProposalView implements BsqBalanceListener { - private final MyBlindVoteServiceFacade myBlindVoteServiceFacade; + private final MyBlindVoteService myBlindVoteService; private Button removeButton, acceptButton, rejectButton, cancelVoteButton, voteButton; private InputTextField stakeInputTextField; @@ -90,7 +90,7 @@ public class ActiveProposalsView extends BaseProposalView implements BsqBalanceL private ActiveProposalsView(MyBallotListService myBallotListService, FilteredBallotListService filteredBallotListService, PeriodService PeriodService, - MyBlindVoteServiceFacade myBlindVoteServiceFacade, + MyBlindVoteService myBlindVoteService, BsqWalletService bsqWalletService, StateService stateService, ChangeParamService changeParamService, @@ -99,7 +99,7 @@ private ActiveProposalsView(MyBallotListService myBallotListService, super(myBallotListService, filteredBallotListService, bsqWalletService, stateService, PeriodService, changeParamService, bsqFormatter, btcFormatter); - this.myBlindVoteServiceFacade = myBlindVoteServiceFacade; + this.myBlindVoteService = myBlindVoteService; } @Override @@ -128,11 +128,11 @@ protected void activate() { voteButton.setOnAction(e -> { // TODO verify stake Coin stake = bsqFormatter.parseToCoin(stakeInputTextField.getText()); - final Coin blindVoteFee = myBlindVoteServiceFacade.getBlindVoteFee(); + final Coin blindVoteFee = myBlindVoteService.getBlindVoteFee(); Transaction dummyTx = null; try { // We create a dummy tx to get the mining blindVoteFee for confirmation popup - dummyTx = myBlindVoteServiceFacade.getDummyBlindVoteTx(stake, blindVoteFee); + dummyTx = myBlindVoteService.getDummyBlindVoteTx(stake, blindVoteFee); } catch (InsufficientMoneyException | WalletException | TransactionVerificationException exception) { new Popup<>().warning(exception.toString()).show(); } @@ -150,7 +150,7 @@ protected void activate() { private void publishBlindVote(Coin stake) { voteButtonBusyAnimation.play(); voteButtonInfoLabel.setText(Res.get("dao.blindVote.startPublishing")); - myBlindVoteServiceFacade.publishBlindVote(stake, + myBlindVoteService.publishBlindVote(stake, () -> { voteButtonBusyAnimation.stop(); voteButtonInfoLabel.setText(""); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java index f219ca8a918..76d2ad090b2 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java @@ -31,14 +31,14 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.consensus.ballot.BallotList; +import bisq.core.dao.consensus.ballot.FilteredBallotListService; +import bisq.core.dao.consensus.ballot.MyBallotListService; +import bisq.core.dao.consensus.myvote.MyBlindVoteService; import bisq.core.dao.consensus.period.PeriodService; import bisq.core.dao.consensus.proposal.param.ChangeParamService; import bisq.core.dao.consensus.state.StateService; import bisq.core.dao.consensus.vote.BooleanVote; import bisq.core.dao.consensus.vote.Vote; -import bisq.core.dao.consensus.ballot.FilteredBallotListService; -import bisq.core.dao.consensus.ballot.MyBallotListService; -import bisq.core.dao.presentation.myvote.MyBlindVoteServiceFacade; import bisq.core.locale.Res; import bisq.core.user.Preferences; @@ -74,7 +74,7 @@ @FxmlView public class MyVotesView extends BaseProposalView { - private final MyBlindVoteServiceFacade myBlindVoteServiceFacade; + private final MyBlindVoteService myBlindVoteService; private final Preferences preferences; private final ObservableList voteListItems = FXCollections.observableArrayList(); @@ -97,12 +97,12 @@ private MyVotesView(MyBallotListService myBallotListService, ChangeParamService changeParamService, BsqFormatter bsqFormatter, BSFormatter btcFormatter, - MyBlindVoteServiceFacade myBlindVoteServiceFacade, + MyBlindVoteService myBlindVoteService, Preferences preferences) { super(myBallotListService, filteredBallotListService, bsqWalletService, stateService, PeriodService, changeParamService, bsqFormatter, btcFormatter); - this.myBlindVoteServiceFacade = myBlindVoteServiceFacade; + this.myBlindVoteService = myBlindVoteService; this.preferences = preferences; } @@ -127,7 +127,7 @@ protected void activate() { sortedList.comparatorProperty().bind(votesTableView.comparatorProperty()); voteListItems.clear(); - List items = myBlindVoteServiceFacade.getMyVoteList().stream() + List items = myBlindVoteService.getMyVoteList().stream() .map(vote -> new VoteListItem(vote, bsqWalletService, stateService, PeriodService, bsqFormatter)) .collect(Collectors.toList()); voteListItems.addAll(items); From 8a3e8c7a9642ab397ee1843b8dd528c0519b7971 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sun, 22 Apr 2018 00:09:47 -0500 Subject: [PATCH 064/197] Cleanup --- .../desktop/main/dao/proposal/active/ActiveProposalsView.java | 2 +- .../main/dao/proposal/dashboard/ProposalDashboardView.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index e2f0607fbf6..05fec537299 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -128,7 +128,7 @@ protected void activate() { voteButton.setOnAction(e -> { // TODO verify stake Coin stake = bsqFormatter.parseToCoin(stakeInputTextField.getText()); - final Coin blindVoteFee = myBlindVoteService.getBlindVoteFee(); + final Coin blindVoteFee = myBlindVoteService.getBlindVoteFeeForCycle(); Transaction dummyTx = null; try { // We create a dummy tx to get the mining blindVoteFee for confirmation popup diff --git a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java index 1cd8bac068a..08136e38e5a 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java @@ -127,7 +127,7 @@ protected void activate() { PeriodService.addPeriodStateChangeListener(this); // We need to delay as otherwise the periodService has not been updated yet. - UserThread.execute(() -> onPreParserChainHeightChanged(PeriodService.getChainHeight())); + UserThread.execute(() -> onChainHeightChanged(PeriodService.getChainHeight())); } @Override @@ -138,7 +138,7 @@ protected void deactivate() { } @Override - public void onPreParserChainHeightChanged(int height) { + public void onChainHeightChanged(int height) { if (height > 0) { separatedPhaseBars.updateWidth(); phaseBarsItems.forEach(item -> { From aa6a9226a2fb8dc322da7e3d45f380ff49b65820 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sun, 22 Apr 2018 19:16:00 -0500 Subject: [PATCH 065/197] Improve proposal and ballot domain - Add ProposalService for publishing proposal - Use ballotListService for maintaining ballotList - Add BallotUtil --- .../proposal/active/ActiveProposalsView.java | 12 ++++++--- .../dao/proposal/make/MakeProposalView.java | 26 +++++++++++-------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index 05fec537299..39c58a1493c 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -39,6 +39,7 @@ import bisq.core.dao.consensus.myvote.MyBlindVoteService; import bisq.core.dao.consensus.period.PeriodService; import bisq.core.dao.consensus.period.Phase; +import bisq.core.dao.consensus.proposal.ProposalService; import bisq.core.dao.consensus.proposal.param.ChangeParamService; import bisq.core.dao.consensus.state.StateService; import bisq.core.dao.consensus.vote.BooleanVote; @@ -73,6 +74,7 @@ @FxmlView public class ActiveProposalsView extends BaseProposalView implements BsqBalanceListener { + private ProposalService proposalService; private final MyBlindVoteService myBlindVoteService; private Button removeButton, acceptButton, rejectButton, cancelVoteButton, voteButton; @@ -88,6 +90,7 @@ public class ActiveProposalsView extends BaseProposalView implements BsqBalanceL @Inject private ActiveProposalsView(MyBallotListService myBallotListService, + ProposalService proposalService, FilteredBallotListService filteredBallotListService, PeriodService PeriodService, MyBlindVoteService myBlindVoteService, @@ -99,6 +102,7 @@ private ActiveProposalsView(MyBallotListService myBallotListService, super(myBallotListService, filteredBallotListService, bsqWalletService, stateService, PeriodService, changeParamService, bsqFormatter, btcFormatter); + this.proposalService = proposalService; this.myBlindVoteService = myBlindVoteService; } @@ -350,11 +354,13 @@ private void changeVoteViewItemsVisibility(boolean value) { } private void onRemove() { - if (myBallotListService.removeProposal(selectedProposalListItem.getBallot())) + final Ballot ballot = selectedProposalListItem.getBallot(); + if (proposalService.removeProposal(ballot)) { + myBallotListService.removeBallot(ballot); hideProposalDisplay(); - else + } else { new Popup<>().warning(Res.get("dao.proposal.active.remove.failed")).show(); - + } proposalTableView.getSelectionModel().clearSelection(); } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index 33a222859f1..b49a27634e0 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -33,20 +33,20 @@ import bisq.core.btc.wallet.WalletsSetup; import bisq.core.dao.ValidationException; import bisq.core.dao.consensus.ballot.Ballot; +import bisq.core.dao.consensus.ballot.BallotWithTransaction; +import bisq.core.dao.consensus.ballot.CompensationBallotFactory; +import bisq.core.dao.consensus.ballot.GenericBallotFactory; +import bisq.core.dao.consensus.ballot.MyBallotListService; import bisq.core.dao.consensus.proposal.ProposalConsensus; +import bisq.core.dao.consensus.proposal.ProposalService; import bisq.core.dao.consensus.proposal.ProposalType; import bisq.core.dao.consensus.proposal.param.ChangeParamService; import bisq.core.dao.consensus.state.StateService; -import bisq.core.dao.consensus.ballot.CompensationBallotFactory; -import bisq.core.dao.consensus.ballot.GenericBallotFactory; -import bisq.core.dao.consensus.ballot.MyBallotListService; import bisq.core.locale.Res; import bisq.core.provider.fee.FeeService; import bisq.network.p2p.P2PService; -import bisq.common.util.Tuple2; - import org.bitcoinj.core.Coin; import org.bitcoinj.core.InsufficientMoneyException; import org.bitcoinj.core.Transaction; @@ -84,6 +84,7 @@ public class MakeProposalView extends ActivatableView { private final P2PService p2PService; private final FeeService feeService; private final MyBallotListService myBallotListService; + private final ProposalService proposalService; private final CompensationBallotFactory compensationBallotFactory; private final GenericBallotFactory genericBallotFactory; private final StateService stateService; @@ -105,6 +106,7 @@ private MakeProposalView(BsqWalletService bsqWalletService, P2PService p2PService, FeeService feeService, MyBallotListService myBallotListService, + ProposalService proposalService, CompensationBallotFactory compensationBallotFactory, GenericBallotFactory genericBallotFactory, StateService stateService, @@ -116,6 +118,7 @@ private MakeProposalView(BsqWalletService bsqWalletService, this.p2PService = p2PService; this.feeService = feeService; this.myBallotListService = myBallotListService; + this.proposalService = proposalService; this.compensationBallotFactory = compensationBallotFactory; this.genericBallotFactory = genericBallotFactory; this.stateService = stateService; @@ -167,9 +170,9 @@ protected void deactivate() { private void publishProposalAndStoreBallot(ProposalType type) { try { - final Tuple2 tuple = getTuple(type); - Ballot ballot = tuple.first; - Transaction transaction = tuple.second; + final BallotWithTransaction ballotWithTransaction = getBallotWithTransaction(type); + Ballot ballot = ballotWithTransaction.getBallot(); + Transaction transaction = ballotWithTransaction.getTransaction(); Coin miningFee = transaction.getFee(); int txSize = transaction.bitcoinSerialize().length; final Coin fee = ProposalConsensus.getFee(changeParamService, stateService.getChainHeight()); @@ -198,9 +201,10 @@ private void publishProposalAndStoreBallot(ProposalType type) { } private void publishProposalAndStoreBallot(Ballot ballot, Transaction transaction) { - myBallotListService.publishProposalAndStoreBallot(ballot, + proposalService.publishBallot(ballot, transaction, () -> { + myBallotListService.storeBallot(ballot); proposalDisplay.clearForm(); proposalTypeComboBox.getSelectionModel().clearSelection(); new Popup<>().confirmation(Res.get("dao.tx.published.success")).show(); @@ -208,7 +212,7 @@ private void publishProposalAndStoreBallot(Ballot ballot, Transaction transactio errorMessage -> new Popup<>().warning(errorMessage).show()); } - private Tuple2 getTuple(ProposalType type) + private BallotWithTransaction getBallotWithTransaction(ProposalType type) throws InsufficientMoneyException, TransactionVerificationException, ValidationException, WalletException, IOException { @@ -216,7 +220,7 @@ private Tuple2 getTuple(ProposalType type) switch (type) { case COMPENSATION_REQUEST: - return compensationBallotFactory.getTuple(proposalDisplay.nameTextField.getText(), + return compensationBallotFactory.getBallotWithTransaction(proposalDisplay.nameTextField.getText(), proposalDisplay.titleTextField.getText(), proposalDisplay.descriptionTextArea.getText(), proposalDisplay.linkInputTextField.getText(), From dc2db746b7d5b1ada08cadc46e8da641f85565d0 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sun, 22 Apr 2018 19:32:16 -0500 Subject: [PATCH 066/197] Move classes out of consensus package --- .../components/SeparatedPhaseBars.java | 2 +- .../main/dao/proposal/BaseProposalView.java | 16 +++++++------- .../dao/proposal/ProposalDetailsWindow.java | 2 +- .../main/dao/proposal/ProposalDisplay.java | 10 ++++----- .../main/dao/proposal/ProposalListItem.java | 20 +++++++++--------- .../proposal/active/ActiveProposalsView.java | 20 +++++++++--------- .../proposal/closed/ClosedProposalsView.java | 10 ++++----- .../dashboard/ProposalDashboardView.java | 6 +++--- .../dao/proposal/make/MakeProposalView.java | 21 +++++++++---------- .../dao/proposal/myvotes/MyVotesView.java | 18 ++++++++-------- .../dao/proposal/myvotes/VoteListItem.java | 14 ++++++------- .../wallet/dashboard/BsqDashboardView.java | 6 +++--- .../main/dao/wallet/tx/BsqTxListItem.java | 6 +++--- .../desktop/main/dao/wallet/tx/BsqTxView.java | 10 ++++----- .../TransactionListItemFactory.java | 2 +- .../transactions/TransactionsListItem.java | 4 ++-- 16 files changed, 83 insertions(+), 84 deletions(-) diff --git a/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java b/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java index d02dc29adb6..b714f626142 100644 --- a/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java +++ b/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java @@ -17,7 +17,7 @@ package bisq.desktop.components; -import bisq.core.dao.consensus.period.Phase; +import bisq.core.dao.period.Phase; import bisq.core.locale.Res; import bisq.common.UserThread; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java index 6d0c55d9d09..7fa87ee55aa 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java @@ -27,14 +27,14 @@ import bisq.desktop.util.BsqFormatter; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.consensus.ballot.Ballot; -import bisq.core.dao.consensus.period.PeriodService; -import bisq.core.dao.consensus.period.Phase; -import bisq.core.dao.consensus.proposal.Proposal; -import bisq.core.dao.consensus.proposal.param.ChangeParamService; -import bisq.core.dao.consensus.state.StateService; -import bisq.core.dao.consensus.ballot.FilteredBallotListService; -import bisq.core.dao.consensus.ballot.MyBallotListService; +import bisq.core.dao.ballot.Ballot; +import bisq.core.dao.ballot.FilteredBallotListService; +import bisq.core.dao.ballot.MyBallotListService; +import bisq.core.dao.period.PeriodService; +import bisq.core.dao.period.Phase; +import bisq.core.dao.proposal.Proposal; +import bisq.core.dao.proposal.param.ChangeParamService; +import bisq.core.dao.state.StateService; import bisq.core.locale.Res; import javax.inject.Inject; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java index 992e5828582..bb7fe536899 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java @@ -22,7 +22,7 @@ import bisq.desktop.util.Layout; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.consensus.proposal.Proposal; +import bisq.core.dao.proposal.Proposal; import bisq.core.locale.Res; import javafx.geometry.Insets; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java index 00635b0dc03..9d954b67d9a 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java @@ -28,11 +28,11 @@ import bisq.desktop.util.validation.BsqValidator; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.consensus.proposal.Proposal; -import bisq.core.dao.consensus.proposal.ProposalConsensus; -import bisq.core.dao.consensus.proposal.ProposalType; -import bisq.core.dao.consensus.proposal.compensation.CompensationConsensus; -import bisq.core.dao.consensus.proposal.compensation.CompensationProposal; +import bisq.core.dao.proposal.Proposal; +import bisq.core.dao.proposal.ProposalConsensus; +import bisq.core.dao.proposal.ProposalType; +import bisq.core.dao.proposal.compensation.CompensationConsensus; +import bisq.core.dao.proposal.compensation.CompensationProposal; import bisq.core.locale.Res; import bisq.core.provider.fee.FeeService; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index 74e9d63f11b..c15460f33f5 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -23,16 +23,16 @@ import bisq.core.btc.listeners.TxConfidenceListener; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.consensus.ballot.Ballot; -import bisq.core.dao.consensus.period.PeriodService; -import bisq.core.dao.consensus.period.Phase; -import bisq.core.dao.consensus.state.Block; -import bisq.core.dao.consensus.state.BlockListener; -import bisq.core.dao.consensus.state.StateService; -import bisq.core.dao.consensus.state.blockchain.Tx; -import bisq.core.dao.consensus.vote.BooleanVote; -import bisq.core.dao.consensus.vote.Vote; -import bisq.core.dao.consensus.ballot.MyBallotListService; +import bisq.core.dao.ballot.Ballot; +import bisq.core.dao.ballot.MyBallotListService; +import bisq.core.dao.period.PeriodService; +import bisq.core.dao.period.Phase; +import bisq.core.dao.state.Block; +import bisq.core.dao.state.BlockListener; +import bisq.core.dao.state.StateService; +import bisq.core.dao.state.blockchain.Tx; +import bisq.core.dao.vote.BooleanVote; +import bisq.core.dao.vote.Vote; import bisq.core.locale.Res; import org.bitcoinj.core.Transaction; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index 39c58a1493c..e7855c1f9e4 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -33,16 +33,16 @@ import bisq.core.btc.exceptions.WalletException; import bisq.core.btc.wallet.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.consensus.ballot.Ballot; -import bisq.core.dao.consensus.ballot.FilteredBallotListService; -import bisq.core.dao.consensus.ballot.MyBallotListService; -import bisq.core.dao.consensus.myvote.MyBlindVoteService; -import bisq.core.dao.consensus.period.PeriodService; -import bisq.core.dao.consensus.period.Phase; -import bisq.core.dao.consensus.proposal.ProposalService; -import bisq.core.dao.consensus.proposal.param.ChangeParamService; -import bisq.core.dao.consensus.state.StateService; -import bisq.core.dao.consensus.vote.BooleanVote; +import bisq.core.dao.ballot.Ballot; +import bisq.core.dao.ballot.FilteredBallotListService; +import bisq.core.dao.ballot.MyBallotListService; +import bisq.core.dao.myvote.MyBlindVoteService; +import bisq.core.dao.period.PeriodService; +import bisq.core.dao.period.Phase; +import bisq.core.dao.proposal.ProposalService; +import bisq.core.dao.proposal.param.ChangeParamService; +import bisq.core.dao.state.StateService; +import bisq.core.dao.vote.BooleanVote; import bisq.core.locale.Res; import bisq.common.util.Tuple2; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java index 8cde5a0b17b..17b1af643d8 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java @@ -23,11 +23,11 @@ import bisq.desktop.util.BsqFormatter; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.consensus.period.PeriodService; -import bisq.core.dao.consensus.proposal.param.ChangeParamService; -import bisq.core.dao.consensus.state.StateService; -import bisq.core.dao.consensus.ballot.FilteredBallotListService; -import bisq.core.dao.consensus.ballot.MyBallotListService; +import bisq.core.dao.ballot.FilteredBallotListService; +import bisq.core.dao.ballot.MyBallotListService; +import bisq.core.dao.period.PeriodService; +import bisq.core.dao.proposal.param.ChangeParamService; +import bisq.core.dao.state.StateService; import javax.inject.Inject; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java index 08136e38e5a..e6eda4e4fb5 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java @@ -22,9 +22,9 @@ import bisq.desktop.components.SeparatedPhaseBars; import bisq.desktop.util.Layout; -import bisq.core.dao.consensus.period.PeriodService; -import bisq.core.dao.consensus.period.PeriodStateChangeListener; -import bisq.core.dao.consensus.period.Phase; +import bisq.core.dao.period.PeriodService; +import bisq.core.dao.period.PeriodStateChangeListener; +import bisq.core.dao.period.Phase; import bisq.core.locale.Res; import bisq.common.UserThread; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index b49a27634e0..7ebd7b63da6 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -32,16 +32,16 @@ import bisq.core.btc.wallet.InsufficientBsqException; import bisq.core.btc.wallet.WalletsSetup; import bisq.core.dao.ValidationException; -import bisq.core.dao.consensus.ballot.Ballot; -import bisq.core.dao.consensus.ballot.BallotWithTransaction; -import bisq.core.dao.consensus.ballot.CompensationBallotFactory; -import bisq.core.dao.consensus.ballot.GenericBallotFactory; -import bisq.core.dao.consensus.ballot.MyBallotListService; -import bisq.core.dao.consensus.proposal.ProposalConsensus; -import bisq.core.dao.consensus.proposal.ProposalService; -import bisq.core.dao.consensus.proposal.ProposalType; -import bisq.core.dao.consensus.proposal.param.ChangeParamService; -import bisq.core.dao.consensus.state.StateService; +import bisq.core.dao.ballot.Ballot; +import bisq.core.dao.ballot.BallotWithTransaction; +import bisq.core.dao.ballot.CompensationBallotFactory; +import bisq.core.dao.ballot.GenericBallotFactory; +import bisq.core.dao.ballot.MyBallotListService; +import bisq.core.dao.proposal.ProposalConsensus; +import bisq.core.dao.proposal.ProposalService; +import bisq.core.dao.proposal.ProposalType; +import bisq.core.dao.proposal.param.ChangeParamService; +import bisq.core.dao.state.StateService; import bisq.core.locale.Res; import bisq.core.provider.fee.FeeService; @@ -71,7 +71,6 @@ import static bisq.desktop.util.FormBuilder.addButtonAfterGroup; import static bisq.desktop.util.FormBuilder.addLabelComboBox; import static bisq.desktop.util.FormBuilder.addTitledGroupBg; -import static com.google.common.base.Preconditions.checkArgument; @FxmlView public class MakeProposalView extends ActivatableView { diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java index 76d2ad090b2..8cf33a29e05 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java @@ -30,15 +30,15 @@ import bisq.desktop.util.Layout; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.consensus.ballot.BallotList; -import bisq.core.dao.consensus.ballot.FilteredBallotListService; -import bisq.core.dao.consensus.ballot.MyBallotListService; -import bisq.core.dao.consensus.myvote.MyBlindVoteService; -import bisq.core.dao.consensus.period.PeriodService; -import bisq.core.dao.consensus.proposal.param.ChangeParamService; -import bisq.core.dao.consensus.state.StateService; -import bisq.core.dao.consensus.vote.BooleanVote; -import bisq.core.dao.consensus.vote.Vote; +import bisq.core.dao.ballot.BallotList; +import bisq.core.dao.ballot.FilteredBallotListService; +import bisq.core.dao.ballot.MyBallotListService; +import bisq.core.dao.myvote.MyBlindVoteService; +import bisq.core.dao.period.PeriodService; +import bisq.core.dao.proposal.param.ChangeParamService; +import bisq.core.dao.state.StateService; +import bisq.core.dao.vote.BooleanVote; +import bisq.core.dao.vote.Vote; import bisq.core.locale.Res; import bisq.core.user.Preferences; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java index 56a71585081..ef31ea147bb 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java @@ -22,13 +22,13 @@ import bisq.core.btc.listeners.TxConfidenceListener; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.consensus.myvote.MyVote; -import bisq.core.dao.consensus.period.PeriodService; -import bisq.core.dao.consensus.state.Block; -import bisq.core.dao.consensus.state.BlockListener; -import bisq.core.dao.consensus.state.StateService; -import bisq.core.dao.consensus.state.blockchain.Tx; -import bisq.core.dao.consensus.state.blockchain.TxOutput; +import bisq.core.dao.myvote.MyVote; +import bisq.core.dao.period.PeriodService; +import bisq.core.dao.state.Block; +import bisq.core.dao.state.BlockListener; +import bisq.core.dao.state.StateService; +import bisq.core.dao.state.blockchain.Tx; +import bisq.core.dao.state.blockchain.TxOutput; import bisq.core.locale.Res; import org.bitcoinj.core.Coin; diff --git a/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java b/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java index 1904c7701e9..641e362ec9c 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java @@ -26,9 +26,9 @@ import bisq.desktop.util.GUIUtil; import bisq.desktop.util.Layout; -import bisq.core.dao.consensus.state.Block; -import bisq.core.dao.consensus.state.BlockListener; -import bisq.core.dao.consensus.state.StateService; +import bisq.core.dao.state.Block; +import bisq.core.dao.state.BlockListener; +import bisq.core.dao.state.StateService; import bisq.core.locale.Res; import bisq.core.monetary.Altcoin; import bisq.core.monetary.Price; diff --git a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java index 63d05838b18..ea3079cc0ee 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java @@ -25,9 +25,9 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; import bisq.core.btc.wallet.WalletService; -import bisq.core.dao.consensus.state.StateService; -import bisq.core.dao.consensus.state.blockchain.Tx; -import bisq.core.dao.consensus.state.blockchain.TxType; +import bisq.core.dao.state.StateService; +import bisq.core.dao.state.blockchain.Tx; +import bisq.core.dao.state.blockchain.TxType; import bisq.core.locale.Res; import org.bitcoinj.core.Coin; diff --git a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java index 9fe8343ddad..ea2adc42b94 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java @@ -32,11 +32,11 @@ import bisq.core.btc.wallet.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; -import bisq.core.dao.consensus.state.Block; -import bisq.core.dao.consensus.state.BlockListener; -import bisq.core.dao.consensus.state.StateService; -import bisq.core.dao.consensus.state.blockchain.Tx; -import bisq.core.dao.consensus.state.blockchain.TxType; +import bisq.core.dao.state.Block; +import bisq.core.dao.state.BlockListener; +import bisq.core.dao.state.StateService; +import bisq.core.dao.state.blockchain.Tx; +import bisq.core.dao.state.blockchain.TxType; import bisq.core.locale.Res; import bisq.core.user.Preferences; diff --git a/src/main/java/bisq/desktop/main/funds/transactions/TransactionListItemFactory.java b/src/main/java/bisq/desktop/main/funds/transactions/TransactionListItemFactory.java index cf1b055eaa5..7fc5b61ff1a 100644 --- a/src/main/java/bisq/desktop/main/funds/transactions/TransactionListItemFactory.java +++ b/src/main/java/bisq/desktop/main/funds/transactions/TransactionListItemFactory.java @@ -21,7 +21,7 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; -import bisq.core.dao.consensus.state.StateService; +import bisq.core.dao.state.StateService; import bisq.core.trade.Tradable; import org.bitcoinj.core.Transaction; diff --git a/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java b/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java index 79b22a4d3b9..f1bdd17577f 100644 --- a/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java +++ b/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java @@ -26,8 +26,8 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; import bisq.core.btc.wallet.WalletService; -import bisq.core.dao.consensus.state.StateService; -import bisq.core.dao.consensus.state.blockchain.TxType; +import bisq.core.dao.state.StateService; +import bisq.core.dao.state.blockchain.TxType; import bisq.core.locale.Res; import bisq.core.offer.Offer; import bisq.core.offer.OpenOffer; From 3d99e92267a98bc2a3dbf9f6f46c83941d58422f Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sun, 22 Apr 2018 21:22:37 -0500 Subject: [PATCH 067/197] Add DaoFacade to provide a reduced API for clients (UI) --- .../main/dao/proposal/BaseProposalView.java | 36 +++------- .../main/dao/proposal/ProposalListItem.java | 65 ++++++++----------- .../proposal/active/ActiveProposalsView.java | 55 +++++----------- .../proposal/closed/ClosedProposalsView.java | 21 ++---- .../dashboard/ProposalDashboardView.java | 22 +++---- .../dao/proposal/make/MakeProposalView.java | 49 ++++---------- .../dao/proposal/myvotes/MyVotesView.java | 23 ++----- .../dao/proposal/myvotes/VoteListItem.java | 27 ++++---- .../wallet/dashboard/BsqDashboardView.java | 37 ++++++----- .../main/dao/wallet/tx/BsqTxListItem.java | 28 +++----- .../desktop/main/dao/wallet/tx/BsqTxView.java | 39 +++++------ .../TransactionListItemFactory.java | 10 +-- .../transactions/TransactionsListItem.java | 27 ++++---- 13 files changed, 162 insertions(+), 277 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java index 7fa87ee55aa..89554ee7cff 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java @@ -27,14 +27,10 @@ import bisq.desktop.util.BsqFormatter; import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.dao.DaoFacade; import bisq.core.dao.ballot.Ballot; -import bisq.core.dao.ballot.FilteredBallotListService; -import bisq.core.dao.ballot.MyBallotListService; -import bisq.core.dao.period.PeriodService; import bisq.core.dao.period.Phase; import bisq.core.dao.proposal.Proposal; -import bisq.core.dao.proposal.param.ChangeParamService; -import bisq.core.dao.state.StateService; import bisq.core.locale.Res; import javax.inject.Inject; @@ -71,11 +67,7 @@ @FxmlView public abstract class BaseProposalView extends ActivatableView { - protected final MyBallotListService myBallotListService; - protected final StateService stateService; - protected final PeriodService PeriodService; - protected final ChangeParamService changeParamService; - protected final FilteredBallotListService filteredBallotListService; + protected final DaoFacade daoFacade; protected final BsqWalletService bsqWalletService; protected final BsqFormatter bsqFormatter; protected final BSFormatter btcFormatter; @@ -101,20 +93,12 @@ public abstract class BaseProposalView extends ActivatableView { /////////////////////////////////////////////////////////////////////////////////////////// @Inject - protected BaseProposalView(MyBallotListService myBallotListService, - FilteredBallotListService filteredBallotListService, + protected BaseProposalView(DaoFacade daoFacade, BsqWalletService bsqWalletService, - StateService stateService, - PeriodService PeriodService, - ChangeParamService changeParamService, BsqFormatter bsqFormatter, BSFormatter btcFormatter) { - this.myBallotListService = myBallotListService; - this.filteredBallotListService = filteredBallotListService; + this.daoFacade = daoFacade; this.bsqWalletService = bsqWalletService; - this.stateService = stateService; - this.PeriodService = PeriodService; - this.changeParamService = changeParamService; this.bsqFormatter = bsqFormatter; this.btcFormatter = btcFormatter; } @@ -132,12 +116,12 @@ public void initialize() { @Override protected void activate() { - phaseSubscription = EasyBind.subscribe(PeriodService.phaseProperty(), this::onPhaseChanged); + phaseSubscription = EasyBind.subscribe(daoFacade.phaseProperty(), this::onPhaseChanged); selectedProposalSubscription = EasyBind.subscribe(proposalTableView.getSelectionModel().selectedItemProperty(), this::onSelectProposal); - PeriodService.phaseProperty().addListener(phaseChangeListener); + daoFacade.phaseProperty().addListener(phaseChangeListener); - onPhaseChanged(PeriodService.phaseProperty().get()); + onPhaseChanged(daoFacade.phaseProperty().get()); sortedList.comparatorProperty().bind(proposalTableView.comparatorProperty()); @@ -149,7 +133,7 @@ protected void deactivate() { phaseSubscription.unsubscribe(); selectedProposalSubscription.unsubscribe(); - PeriodService.phaseProperty().removeListener(phaseChangeListener); + daoFacade.phaseProperty().removeListener(phaseChangeListener); sortedList.comparatorProperty().unbind(); @@ -249,10 +233,8 @@ protected void doUpdateProposalList(List list) { proposalListItems.clear(); proposalListItems.setAll(list.stream() .map(ballot -> new ProposalListItem(ballot, - myBallotListService, - PeriodService, + daoFacade, bsqWalletService, - stateService, bsqFormatter)) .collect(Collectors.toSet())); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index c15460f33f5..d754444c9e9 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -23,13 +23,11 @@ import bisq.core.btc.listeners.TxConfidenceListener; import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.dao.DaoFacade; import bisq.core.dao.ballot.Ballot; -import bisq.core.dao.ballot.MyBallotListService; -import bisq.core.dao.period.PeriodService; import bisq.core.dao.period.Phase; import bisq.core.dao.state.Block; import bisq.core.dao.state.BlockListener; -import bisq.core.dao.state.StateService; import bisq.core.dao.state.blockchain.Tx; import bisq.core.dao.vote.BooleanVote; import bisq.core.dao.vote.Vote; @@ -58,10 +56,8 @@ public class ProposalListItem implements BlockListener { @Getter private final Ballot ballot; - private final MyBallotListService myBallotListService; - private final PeriodService PeriodService; + private final DaoFacade daoFacade; private final BsqWalletService bsqWalletService; - private final StateService stateService; private final BsqFormatter bsqFormatter; private final ChangeListener chainHeightListener; private final ChangeListener voteResultChangeListener; @@ -81,16 +77,12 @@ public class ProposalListItem implements BlockListener { private Node actionNode; ProposalListItem(Ballot ballot, - MyBallotListService myBallotListService, - PeriodService PeriodService, + DaoFacade daoFacade, BsqWalletService bsqWalletService, - StateService stateService, BsqFormatter bsqFormatter) { this.ballot = ballot; - this.myBallotListService = myBallotListService; - this.PeriodService = PeriodService; + this.daoFacade = daoFacade; this.bsqWalletService = bsqWalletService; - this.stateService = stateService; this.bsqFormatter = bsqFormatter; @@ -109,17 +101,17 @@ public class ProposalListItem implements BlockListener { bsqWalletService.getChainHeightProperty().addListener(chainHeightListener); setupConfidence(); - stateService.addBlockListener(this); + daoFacade.addBlockListener(this); phaseChangeListener = (observable, oldValue, newValue) -> { applyState(newValue, ballot.getVote()); }; voteResultChangeListener = (observable, oldValue, newValue) -> { - applyState(PeriodService.phaseProperty().get(), newValue); + applyState(daoFacade.phaseProperty().get(), newValue); }; - PeriodService.phaseProperty().addListener(phaseChangeListener); + daoFacade.phaseProperty().addListener(phaseChangeListener); ballot.getVoteResultProperty().addListener(voteResultChangeListener); } @@ -128,15 +120,12 @@ public void applyState(Phase phase, Vote vote) { actionButton.setText(""); actionButton.setVisible(false); actionButton.setOnAction(null); - final boolean isTxInPastCycle = PeriodService.isTxInPastCycle(ballot.getTxId(), - stateService.getChainHeight()); switch (phase) { case UNDEFINED: log.error("invalid state UNDEFINED"); break; case PROPOSAL: - if (myBallotListService.isMine(ballot.getProposal())) { - actionButton.setVisible(!isTxInPastCycle); + if (daoFacade.isMyProposal(ballot.getProposal())) { actionButtonIconView.setVisible(actionButton.isVisible()); actionButton.setText(Res.get("shared.remove")); actionButton.setGraphic(actionButtonIconView); @@ -151,23 +140,21 @@ public void applyState(Phase phase, Vote vote) { case BREAK1: break; case BLIND_VOTE: - if (!isTxInPastCycle) { - actionNode = actionButtonIconView; - actionButton.setVisible(false); - if (ballot.getVote() != null) { - actionButtonIconView.setVisible(true); - if (vote instanceof BooleanVote) { - if (((BooleanVote) vote).isAccepted()) { - actionButtonIconView.setId("accepted"); - } else { - actionButtonIconView.setId("rejected"); - } + actionNode = actionButtonIconView; + actionButton.setVisible(false); + if (ballot.getVote() != null) { + actionButtonIconView.setVisible(true); + if (vote instanceof BooleanVote) { + if (((BooleanVote) vote).isAccepted()) { + actionButtonIconView.setId("accepted"); } else { - //TODO + actionButtonIconView.setId("rejected"); } } else { - actionButtonIconView.setVisible(false); + //TODO } + } else { + actionButtonIconView.setVisible(false); } break; case BREAK2: @@ -202,12 +189,12 @@ public void onBlockAdded(Block block) { setupConfidence(); } - + // TODO reuse from other item private void setupConfidence() { - final Tx tx = stateService.getTxMap().get(ballot.getProposal().getTxId()); - if (tx != null) { - final String txId = tx.getId(); - + final String txId = ballot.getProposal().getTxId(); + Optional optionalTx = daoFacade.getTx(txId); + if (optionalTx.isPresent()) { + Tx tx = optionalTx.get(); // We cache the walletTransaction once found if (walletTransaction == null) { final Optional transactionOptional = bsqWalletService.isWalletTransaction(txId); @@ -248,12 +235,12 @@ private void updateConfidence(TransactionConfidence confidence, int depthInBlock } public void cleanup() { - stateService.removeBlockListener(this); + daoFacade.removeBlockListener(this); bsqWalletService.getChainHeightProperty().removeListener(chainHeightListener); if (txConfidenceListener != null) bsqWalletService.removeTxConfidenceListener(txConfidenceListener); - PeriodService.phaseProperty().removeListener(phaseChangeListener); + daoFacade.phaseProperty().removeListener(phaseChangeListener); ballot.getVoteResultProperty().removeListener(voteResultChangeListener); } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index e7855c1f9e4..7ce69c2d9b2 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -33,15 +33,9 @@ import bisq.core.btc.exceptions.WalletException; import bisq.core.btc.wallet.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.dao.DaoFacade; import bisq.core.dao.ballot.Ballot; -import bisq.core.dao.ballot.FilteredBallotListService; -import bisq.core.dao.ballot.MyBallotListService; -import bisq.core.dao.myvote.MyBlindVoteService; -import bisq.core.dao.period.PeriodService; import bisq.core.dao.period.Phase; -import bisq.core.dao.proposal.ProposalService; -import bisq.core.dao.proposal.param.ChangeParamService; -import bisq.core.dao.state.StateService; import bisq.core.dao.vote.BooleanVote; import bisq.core.locale.Res; @@ -74,9 +68,6 @@ @FxmlView public class ActiveProposalsView extends BaseProposalView implements BsqBalanceListener { - private ProposalService proposalService; - private final MyBlindVoteService myBlindVoteService; - private Button removeButton, acceptButton, rejectButton, cancelVoteButton, voteButton; private InputTextField stakeInputTextField; private List voteViewItems = new ArrayList<>(); @@ -89,21 +80,12 @@ public class ActiveProposalsView extends BaseProposalView implements BsqBalanceL /////////////////////////////////////////////////////////////////////////////////////////// @Inject - private ActiveProposalsView(MyBallotListService myBallotListService, - ProposalService proposalService, - FilteredBallotListService filteredBallotListService, - PeriodService PeriodService, - MyBlindVoteService myBlindVoteService, + private ActiveProposalsView(DaoFacade daoFacade, BsqWalletService bsqWalletService, - StateService stateService, - ChangeParamService changeParamService, BsqFormatter bsqFormatter, BSFormatter btcFormatter) { - super(myBallotListService, filteredBallotListService, bsqWalletService, stateService, - PeriodService, changeParamService, bsqFormatter, btcFormatter); - this.proposalService = proposalService; - this.myBlindVoteService = myBlindVoteService; + super(daoFacade, bsqWalletService, bsqFormatter, btcFormatter); } @Override @@ -120,7 +102,7 @@ public void initialize() { protected void activate() { super.activate(); - filteredBallotListService.getActiveOrMyUnconfirmedBallots().addListener(proposalListChangeListener); + daoFacade.getActiveOrMyUnconfirmedBallots().addListener(proposalListChangeListener); bsqWalletService.addBsqBalanceListener(this); onUpdateBalances(bsqWalletService.getAvailableBalance(), @@ -132,11 +114,11 @@ protected void activate() { voteButton.setOnAction(e -> { // TODO verify stake Coin stake = bsqFormatter.parseToCoin(stakeInputTextField.getText()); - final Coin blindVoteFee = myBlindVoteService.getBlindVoteFeeForCycle(); + final Coin blindVoteFee = daoFacade.getBlindVoteFeeForCycle(); Transaction dummyTx = null; try { // We create a dummy tx to get the mining blindVoteFee for confirmation popup - dummyTx = myBlindVoteService.getDummyBlindVoteTx(stake, blindVoteFee); + dummyTx = daoFacade.getDummyBlindVoteTx(stake, blindVoteFee); } catch (InsufficientMoneyException | WalletException | TransactionVerificationException exception) { new Popup<>().warning(exception.toString()).show(); } @@ -154,7 +136,7 @@ protected void activate() { private void publishBlindVote(Coin stake) { voteButtonBusyAnimation.play(); voteButtonInfoLabel.setText(Res.get("dao.blindVote.startPublishing")); - myBlindVoteService.publishBlindVote(stake, + daoFacade.publishBlindVote(stake, () -> { voteButtonBusyAnimation.stop(); voteButtonInfoLabel.setText(""); @@ -171,7 +153,7 @@ private void publishBlindVote(Coin stake) { protected void deactivate() { super.deactivate(); - filteredBallotListService.getActiveOrMyUnconfirmedBallots().removeListener(proposalListChangeListener); + daoFacade.getActiveOrMyUnconfirmedBallots().removeListener(proposalListChangeListener); bsqWalletService.removeBsqBalanceListener(this); } @@ -239,22 +221,22 @@ protected void onSelectProposal(ProposalListItem item) { cancelVoteButton = null; } - onPhaseChanged(PeriodService.phaseProperty().get()); + onPhaseChanged(daoFacade.phaseProperty().get()); } } private void onAccept() { - selectedProposalListItem.getBallot().setVote(new BooleanVote(true)); + daoFacade.setVote(selectedProposalListItem.getBallot(), new BooleanVote(true)); updateStateAfterVote(); } private void onReject() { - selectedProposalListItem.getBallot().setVote(new BooleanVote(false)); + daoFacade.setVote(selectedProposalListItem.getBallot(), new BooleanVote(false)); updateStateAfterVote(); } private void onCancelVote() { - selectedProposalListItem.getBallot().setVote(null); + daoFacade.setVote(selectedProposalListItem.getBallot(), null); updateStateAfterVote(); } @@ -270,14 +252,11 @@ protected void onPhaseChanged(Phase phase) { removeButton.setVisible(false); removeButton = null; } - if (selectedProposalListItem != null && - proposalDisplay != null && - !PeriodService.isTxInPastCycle(selectedProposalListItem.getBallot().getTxId(), - stateService.getChainHeight())) { + if (selectedProposalListItem != null && proposalDisplay != null) { final Ballot ballot = selectedProposalListItem.getBallot(); switch (phase) { case PROPOSAL: - if (myBallotListService.isMine(ballot.getProposal())) { + if (daoFacade.isMyProposal(ballot.getProposal())) { if (removeButton == null) { removeButton = addButtonAfterGroup(detailsGridPane, proposalDisplay.incrementAndGetGridRow(), Res.get("dao.proposal.active.remove")); removeButton.setOnAction(event -> onRemove()); @@ -337,12 +316,11 @@ protected void onPhaseChanged(Phase phase) { @Override protected void updateProposalList() { - doUpdateProposalList(filteredBallotListService.getActiveOrMyUnconfirmedBallots()); + doUpdateProposalList(daoFacade.getActiveOrMyUnconfirmedBallots()); } private void updateStateAfterVote() { hideProposalDisplay(); - filteredBallotListService.persist(); proposalTableView.getSelectionModel().clearSelection(); } @@ -355,8 +333,7 @@ private void changeVoteViewItemsVisibility(boolean value) { private void onRemove() { final Ballot ballot = selectedProposalListItem.getBallot(); - if (proposalService.removeProposal(ballot)) { - myBallotListService.removeBallot(ballot); + if (daoFacade.removeBallot(ballot)) { hideProposalDisplay(); } else { new Popup<>().warning(Res.get("dao.proposal.active.remove.failed")).show(); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java index 17b1af643d8..dd2f0486a5c 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java @@ -23,11 +23,7 @@ import bisq.desktop.util.BsqFormatter; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.ballot.FilteredBallotListService; -import bisq.core.dao.ballot.MyBallotListService; -import bisq.core.dao.period.PeriodService; -import bisq.core.dao.proposal.param.ChangeParamService; -import bisq.core.dao.state.StateService; +import bisq.core.dao.DaoFacade; import javax.inject.Inject; @@ -39,17 +35,12 @@ public class ClosedProposalsView extends BaseProposalView { /////////////////////////////////////////////////////////////////////////////////////////// @Inject - private ClosedProposalsView(MyBallotListService myBallotListService, - FilteredBallotListService filteredBallotListService, - PeriodService PeriodService, + private ClosedProposalsView(DaoFacade daoFacade, BsqWalletService bsqWalletService, - StateService stateService, - ChangeParamService changeParamService, BsqFormatter bsqFormatter, BSFormatter btcFormatter) { - super(myBallotListService, filteredBallotListService, bsqWalletService, stateService, - PeriodService, changeParamService, bsqFormatter, btcFormatter); + super(daoFacade, bsqWalletService, bsqFormatter, btcFormatter); } @Override @@ -63,18 +54,18 @@ public void initialize() { @Override protected void activate() { super.activate(); - filteredBallotListService.getClosedBallots().addListener(proposalListChangeListener); + daoFacade.getClosedBallots().addListener(proposalListChangeListener); } @Override protected void deactivate() { super.deactivate(); - filteredBallotListService.getClosedBallots().removeListener(proposalListChangeListener); + daoFacade.getClosedBallots().removeListener(proposalListChangeListener); } @Override protected void updateProposalList() { - doUpdateProposalList(filteredBallotListService.getClosedBallots()); + doUpdateProposalList(daoFacade.getClosedBallots()); } } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java index e6eda4e4fb5..1f41ba2084d 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java @@ -22,7 +22,7 @@ import bisq.desktop.components.SeparatedPhaseBars; import bisq.desktop.util.Layout; -import bisq.core.dao.period.PeriodService; +import bisq.core.dao.DaoFacade; import bisq.core.dao.period.PeriodStateChangeListener; import bisq.core.dao.period.Phase; import bisq.core.locale.Res; @@ -49,9 +49,9 @@ // The event from the StateService.Listener would notify after parsing a new block. @FxmlView public class ProposalDashboardView extends ActivatableView implements PeriodStateChangeListener { + private final DaoFacade daoFacade; private List phaseBarsItems; - private final PeriodService PeriodService; private Phase currentPhase; private Subscription phaseSubscription; private GridPane gridPane; @@ -64,8 +64,8 @@ public class ProposalDashboardView extends ActivatableView imple /////////////////////////////////////////////////////////////////////////////////////////// @Inject - private ProposalDashboardView(PeriodService PeriodService) { - this.PeriodService = PeriodService; + private ProposalDashboardView(DaoFacade daoFacade) { + this.daoFacade = daoFacade; } @Override @@ -111,7 +111,7 @@ private SeparatedPhaseBars createSeparatedPhaseBars() { protected void activate() { super.activate(); - phaseSubscription = EasyBind.subscribe(PeriodService.phaseProperty(), phase -> { + phaseSubscription = EasyBind.subscribe(daoFacade.phaseProperty(), phase -> { if (!phase.equals(this.currentPhase)) { this.currentPhase = phase; } @@ -124,16 +124,16 @@ protected void activate() { }); }); - PeriodService.addPeriodStateChangeListener(this); + daoFacade.addPeriodStateChangeListener(this); // We need to delay as otherwise the periodService has not been updated yet. - UserThread.execute(() -> onChainHeightChanged(PeriodService.getChainHeight())); + UserThread.execute(() -> onChainHeightChanged(daoFacade.getChainHeight())); } @Override protected void deactivate() { super.deactivate(); - PeriodService.removePeriodStateChangeListener(this); + daoFacade.removePeriodStateChangeListener(this); phaseSubscription.unsubscribe(); } @@ -142,9 +142,9 @@ public void onChainHeightChanged(int height) { if (height > 0) { separatedPhaseBars.updateWidth(); phaseBarsItems.forEach(item -> { - int firstBlock = PeriodService.getFirstBlockOfPhase(height, item.getPhase()); - int lastBlock = PeriodService.getLastBlockOfPhase(height, item.getPhase()); - final int duration = PeriodService.getDurationForPhase(item.getPhase(), PeriodService.getChainHeight()); + int firstBlock = daoFacade.getFirstBlockOfPhase(height, item.getPhase()); + int lastBlock = daoFacade.getLastBlockOfPhase(height, item.getPhase()); + final int duration = daoFacade.getDurationForPhase(item.getPhase()); item.setPeriodRange(firstBlock, lastBlock, duration); double progress = 0; if (height >= firstBlock && height <= lastBlock) { diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index 7ebd7b63da6..ca93bac3556 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -31,17 +31,12 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.InsufficientBsqException; import bisq.core.btc.wallet.WalletsSetup; +import bisq.core.dao.DaoFacade; import bisq.core.dao.ValidationException; import bisq.core.dao.ballot.Ballot; import bisq.core.dao.ballot.BallotWithTransaction; -import bisq.core.dao.ballot.CompensationBallotFactory; -import bisq.core.dao.ballot.GenericBallotFactory; -import bisq.core.dao.ballot.MyBallotListService; import bisq.core.dao.proposal.ProposalConsensus; -import bisq.core.dao.proposal.ProposalService; import bisq.core.dao.proposal.ProposalType; -import bisq.core.dao.proposal.param.ChangeParamService; -import bisq.core.dao.state.StateService; import bisq.core.locale.Res; import bisq.core.provider.fee.FeeService; @@ -71,25 +66,20 @@ import static bisq.desktop.util.FormBuilder.addButtonAfterGroup; import static bisq.desktop.util.FormBuilder.addLabelComboBox; import static bisq.desktop.util.FormBuilder.addTitledGroupBg; +import static com.google.common.base.Preconditions.checkArgument; @FxmlView public class MakeProposalView extends ActivatableView { - - private ProposalDisplay proposalDisplay; - private Button createButton; - + private final DaoFacade daoFacade; private final BsqWalletService bsqWalletService; private final WalletsSetup walletsSetup; private final P2PService p2PService; private final FeeService feeService; - private final MyBallotListService myBallotListService; - private final ProposalService proposalService; - private final CompensationBallotFactory compensationBallotFactory; - private final GenericBallotFactory genericBallotFactory; - private final StateService stateService; - private final ChangeParamService changeParamService; private final BSFormatter btcFormatter; private final BsqFormatter bsqFormatter; + + private ProposalDisplay proposalDisplay; + private Button createButton; private ComboBox proposalTypeComboBox; private ChangeListener proposalTypeChangeListener; private ProposalType selectedProposalType; @@ -100,28 +90,18 @@ public class MakeProposalView extends ActivatableView { /////////////////////////////////////////////////////////////////////////////////////////// @Inject - private MakeProposalView(BsqWalletService bsqWalletService, + private MakeProposalView(DaoFacade daoFacade, + BsqWalletService bsqWalletService, WalletsSetup walletsSetup, P2PService p2PService, FeeService feeService, - MyBallotListService myBallotListService, - ProposalService proposalService, - CompensationBallotFactory compensationBallotFactory, - GenericBallotFactory genericBallotFactory, - StateService stateService, - ChangeParamService changeParamService, BSFormatter btcFormatter, BsqFormatter bsqFormatter) { + this.daoFacade = daoFacade; this.bsqWalletService = bsqWalletService; this.walletsSetup = walletsSetup; this.p2PService = p2PService; this.feeService = feeService; - this.myBallotListService = myBallotListService; - this.proposalService = proposalService; - this.compensationBallotFactory = compensationBallotFactory; - this.genericBallotFactory = genericBallotFactory; - this.stateService = stateService; - this.changeParamService = changeParamService; this.btcFormatter = btcFormatter; this.bsqFormatter = bsqFormatter; } @@ -174,8 +154,7 @@ private void publishProposalAndStoreBallot(ProposalType type) { Transaction transaction = ballotWithTransaction.getTransaction(); Coin miningFee = transaction.getFee(); int txSize = transaction.bitcoinSerialize().length; - final Coin fee = ProposalConsensus.getFee(changeParamService, stateService.getChainHeight()); - + final Coin fee = daoFacade.getProposalFee(); GUIUtil.showBsqFeeInfoPopup(fee, miningFee, txSize, bsqFormatter, btcFormatter, Res.get("dao.proposal"), () -> publishProposalAndStoreBallot(ballot, transaction)); @@ -200,10 +179,9 @@ private void publishProposalAndStoreBallot(ProposalType type) { } private void publishProposalAndStoreBallot(Ballot ballot, Transaction transaction) { - proposalService.publishBallot(ballot, + daoFacade.publishBallot(ballot, transaction, () -> { - myBallotListService.storeBallot(ballot); proposalDisplay.clearForm(); proposalTypeComboBox.getSelectionModel().clearSelection(); new Popup<>().confirmation(Res.get("dao.tx.published.success")).show(); @@ -219,7 +197,7 @@ private BallotWithTransaction getBallotWithTransaction(ProposalType type) switch (type) { case COMPENSATION_REQUEST: - return compensationBallotFactory.getBallotWithTransaction(proposalDisplay.nameTextField.getText(), + return daoFacade.getCompensationBallotWithTransaction(proposalDisplay.nameTextField.getText(), proposalDisplay.titleTextField.getText(), proposalDisplay.descriptionTextArea.getText(), proposalDisplay.linkInputTextField.getText(), @@ -277,7 +255,8 @@ private void setCreateButtonHandler() { private void validateInputs() { // We check in proposalDisplay that no invalid input as allowed - checkArgument(ProposalConsensus.isDescriptionSizeValid(proposalDisplay.descriptionTextArea.getText()), "descriptionText must not be longer than " + + checkArgument(ProposalConsensus.isDescriptionSizeValid(proposalDisplay.descriptionTextArea.getText()), + "descriptionText must not be longer than " + ProposalConsensus.getMaxLengthDescriptionText() + " chars"); // TODO add more checks for all input fields diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java index 8cf33a29e05..466bfd6d737 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java @@ -30,13 +30,8 @@ import bisq.desktop.util.Layout; import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.dao.DaoFacade; import bisq.core.dao.ballot.BallotList; -import bisq.core.dao.ballot.FilteredBallotListService; -import bisq.core.dao.ballot.MyBallotListService; -import bisq.core.dao.myvote.MyBlindVoteService; -import bisq.core.dao.period.PeriodService; -import bisq.core.dao.proposal.param.ChangeParamService; -import bisq.core.dao.state.StateService; import bisq.core.dao.vote.BooleanVote; import bisq.core.dao.vote.Vote; import bisq.core.locale.Res; @@ -74,7 +69,6 @@ @FxmlView public class MyVotesView extends BaseProposalView { - private final MyBlindVoteService myBlindVoteService; private final Preferences preferences; private final ObservableList voteListItems = FXCollections.observableArrayList(); @@ -89,20 +83,13 @@ public class MyVotesView extends BaseProposalView { /////////////////////////////////////////////////////////////////////////////////////////// @Inject - private MyVotesView(MyBallotListService myBallotListService, - FilteredBallotListService filteredBallotListService, + private MyVotesView(DaoFacade daoFacade, BsqWalletService bsqWalletService, - StateService stateService, - PeriodService PeriodService, - ChangeParamService changeParamService, BsqFormatter bsqFormatter, BSFormatter btcFormatter, - MyBlindVoteService myBlindVoteService, Preferences preferences) { - super(myBallotListService, filteredBallotListService, bsqWalletService, stateService, - PeriodService, changeParamService, bsqFormatter, btcFormatter); - this.myBlindVoteService = myBlindVoteService; + super(daoFacade, bsqWalletService, bsqFormatter, btcFormatter); this.preferences = preferences; } @@ -127,8 +114,8 @@ protected void activate() { sortedList.comparatorProperty().bind(votesTableView.comparatorProperty()); voteListItems.clear(); - List items = myBlindVoteService.getMyVoteList().stream() - .map(vote -> new VoteListItem(vote, bsqWalletService, stateService, PeriodService, bsqFormatter)) + List items = daoFacade.getMyVoteList().stream() + .map(vote -> new VoteListItem(vote, daoFacade, bsqWalletService, bsqFormatter)) .collect(Collectors.toList()); voteListItems.addAll(items); } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java index ef31ea147bb..460361e199d 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java @@ -22,11 +22,10 @@ import bisq.core.btc.listeners.TxConfidenceListener; import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.dao.DaoFacade; import bisq.core.dao.myvote.MyVote; -import bisq.core.dao.period.PeriodService; import bisq.core.dao.state.Block; import bisq.core.dao.state.BlockListener; -import bisq.core.dao.state.StateService; import bisq.core.dao.state.blockchain.Tx; import bisq.core.dao.state.blockchain.TxOutput; import bisq.core.locale.Res; @@ -55,9 +54,8 @@ public class VoteListItem implements BlockListener { @Getter private final MyVote myVote; + private final DaoFacade daoFacade; private final BsqWalletService bsqWalletService; - private final StateService stateService; - private final PeriodService PeriodService; private final BsqFormatter bsqFormatter; private final ChangeListener chainHeightListener; @Getter @@ -76,14 +74,12 @@ public class VoteListItem implements BlockListener { private StringProperty stakeAsStringProperty = new SimpleStringProperty(""); VoteListItem(MyVote myVote, + DaoFacade daoFacade, BsqWalletService bsqWalletService, - StateService stateService, - PeriodService PeriodService, BsqFormatter bsqFormatter) { this.myVote = myVote; + this.daoFacade = daoFacade; this.bsqWalletService = bsqWalletService; - this.stateService = stateService; - this.PeriodService = PeriodService; this.bsqFormatter = bsqFormatter; txConfidenceIndicator = new TxConfidenceIndicator(); @@ -92,7 +88,7 @@ public class VoteListItem implements BlockListener { txConfidenceIndicator.setProgress(-1); txConfidenceIndicator.setPrefSize(24, 24); txConfidenceIndicator.setTooltip(tooltip); - stateService.addBlockListener(this); + daoFacade.addBlockListener(this); chainHeightListener = (observable, oldValue, newValue) -> setupConfidence(); bsqWalletService.getChainHeightProperty().addListener(chainHeightListener); @@ -111,13 +107,12 @@ public void onBlockAdded(Block block) { setupConfidence(); } - private void setupConfidence() { calculateStake(); - final Tx tx = stateService.getTxMap().get(myVote.getBlindVote().getTxId()); - if (tx != null) { - final String txId = tx.getId(); - + final String txId = myVote.getBlindVote().getTxId(); + Optional optionalTx = daoFacade.getTx(txId); + if (optionalTx.isPresent()) { + Tx tx = optionalTx.get(); // We cache the walletTransaction once found if (walletTransaction == null) { final Optional transactionOptional = bsqWalletService.isWalletTransaction(txId); @@ -153,7 +148,7 @@ public void onTransactionConfidenceChanged(TransactionConfidence confidence) { private void calculateStake() { if (stake == 0) { String txId = myVote.getTxId(); - stake = stateService.getUnspentBlindVoteStakeTxOutputs().stream() + stake = daoFacade.getUnspentBlindVoteStakeTxOutputs().stream() .filter(txOutput -> txOutput.getTxId().equals(txId)) .filter(txOutput -> txOutput.getIndex() == 0) .mapToLong(TxOutput::getValue) @@ -171,7 +166,7 @@ private void updateConfidence(TransactionConfidence confidence, int depthInBlock public void cleanup() { bsqWalletService.getChainHeightProperty().removeListener(chainHeightListener); - stateService.removeBlockListener(this); + daoFacade.removeBlockListener(this); if (txConfidenceListener != null) bsqWalletService.removeTxConfidenceListener(txConfidenceListener); } diff --git a/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java b/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java index 641e362ec9c..1a6f5db668c 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java @@ -26,9 +26,9 @@ import bisq.desktop.util.GUIUtil; import bisq.desktop.util.Layout; +import bisq.core.dao.DaoFacade; import bisq.core.dao.state.Block; import bisq.core.dao.state.BlockListener; -import bisq.core.dao.state.StateService; import bisq.core.locale.Res; import bisq.core.monetary.Altcoin; import bisq.core.monetary.Price; @@ -60,13 +60,14 @@ public class BsqDashboardView extends ActivatableView implements BlockListener { private final BsqBalanceUtil bsqBalanceUtil; - private final StateService stateService; + private final DaoFacade daoFacade; private final PriceFeedService priceFeedService; private final Preferences preferences; private final BsqFormatter bsqFormatter; private int gridRow = 0; - private TextField genesisIssueAmountTextField, compRequestIssueAmountTextField, availableAmountTextField, burntAmountTextField, allTxTextField, + private TextField genesisIssueAmountTextField, compRequestIssueAmountTextField, availableAmountTextField, + burntAmountTextField, allTxTextField, burntTxTextField/*, spentTxTextField*/, utxoTextField, priceTextField, marketCapTextField; private ChangeListener priceChangeListener; @@ -79,12 +80,12 @@ public class BsqDashboardView extends ActivatableView implements @Inject private BsqDashboardView(BsqBalanceUtil bsqBalanceUtil, - StateService stateService, + DaoFacade daoFacade, PriceFeedService priceFeedService, Preferences preferences, BsqFormatter bsqFormatter) { this.bsqBalanceUtil = bsqBalanceUtil; - this.stateService = stateService; + this.daoFacade = daoFacade; this.priceFeedService = priceFeedService; this.preferences = preferences; this.bsqFormatter = bsqFormatter; @@ -97,13 +98,13 @@ public void initialize() { addTitledGroupBg(root, ++gridRow, 11, Res.get("dao.wallet.dashboard.statistics"), Layout.GROUP_DISTANCE); addLabelTextField(root, gridRow, Res.get("dao.wallet.dashboard.genesisBlockHeight"), - String.valueOf(stateService.getGenesisBlockHeight()), Layout.FIRST_ROW_AND_GROUP_DISTANCE); + String.valueOf(daoFacade.getGenesisBlockHeight()), Layout.FIRST_ROW_AND_GROUP_DISTANCE); Label label = new AutoTooltipLabel(Res.get("dao.wallet.dashboard.genesisTxId")); GridPane.setRowIndex(label, ++gridRow); root.getChildren().add(label); - hyperlinkWithIcon = new HyperlinkWithIcon(stateService.getGenesisTxId(), AwesomeIcon.EXTERNAL_LINK); - hyperlinkWithIcon.setTooltip(new Tooltip(Res.get("tooltip.openBlockchainForTx", stateService.getGenesisTxId()))); + hyperlinkWithIcon = new HyperlinkWithIcon(daoFacade.getGenesisTxId(), AwesomeIcon.EXTERNAL_LINK); + hyperlinkWithIcon.setTooltip(new Tooltip(Res.get("tooltip.openBlockchainForTx", daoFacade.getGenesisTxId()))); GridPane.setRowIndex(hyperlinkWithIcon, gridRow); GridPane.setColumnIndex(hyperlinkWithIcon, 1); GridPane.setMargin(hyperlinkWithIcon, new Insets(0, 0, 0, -4)); @@ -129,10 +130,10 @@ public void initialize() { protected void activate() { bsqBalanceUtil.activate(); - stateService.addBlockListener(this); + daoFacade.addBlockListener(this); priceFeedService.updateCounterProperty().addListener(priceChangeListener); - hyperlinkWithIcon.setOnAction(event -> GUIUtil.openWebPage(preferences.getBsqBlockChainExplorer().txUrl + stateService.getGenesisTxId())); + hyperlinkWithIcon.setOnAction(event -> GUIUtil.openWebPage(preferences.getBsqBlockChainExplorer().txUrl + daoFacade.getGenesisTxId())); updateWithBsqBlockChainData(); updatePrice(); @@ -141,7 +142,7 @@ protected void activate() { @Override protected void deactivate() { bsqBalanceUtil.deactivate(); - stateService.addBlockListener(this); + daoFacade.removeBlockListener(this); priceFeedService.updateCounterProperty().removeListener(priceChangeListener); hyperlinkWithIcon.setOnAction(null); } @@ -157,25 +158,25 @@ public void onBlockAdded(Block block) { } private void updateWithBsqBlockChainData() { - final Coin issuedAmountFromGenesis = stateService.getGenesisTotalSupply(); + final Coin issuedAmountFromGenesis = daoFacade.getGenesisTotalSupply(); genesisIssueAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(issuedAmountFromGenesis)); - final Coin issuedAmountFromCompRequests = Coin.valueOf(stateService.getTotalIssuedAmountFromCompRequests()); + final Coin issuedAmountFromCompRequests = Coin.valueOf(daoFacade.getTotalIssuedAmountFromCompRequests()); compRequestIssueAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(issuedAmountFromCompRequests)); - final Coin burntFee = Coin.valueOf(stateService.getTotalBurntFee()); + final Coin burntFee = Coin.valueOf(daoFacade.getTotalBurntFee()); final Coin availableAmount = issuedAmountFromGenesis.add(issuedAmountFromCompRequests).subtract(burntFee); availableAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(availableAmount)); burntAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(burntFee)); - allTxTextField.setText(String.valueOf(stateService.getTxs().size())); - utxoTextField.setText(String.valueOf(stateService.getUnspentTxOutputs().size())); + allTxTextField.setText(String.valueOf(daoFacade.getTxs().size())); + utxoTextField.setText(String.valueOf(daoFacade.getUnspentTxOutputs().size())); //spentTxTextField.setText(String.valueOf(stateService.getSpentTxOutputs().size())); - burntTxTextField.setText(String.valueOf(stateService.getFeeTxs().size())); + burntTxTextField.setText(String.valueOf(daoFacade.getFeeTxs().size())); } private void updatePrice() { - final Coin issuedAmount = stateService.getGenesisTotalSupply(); + final Coin issuedAmount = daoFacade.getGenesisTotalSupply(); final MarketPrice bsqMarketPrice = priceFeedService.getMarketPrice("BSQ"); if (bsqMarketPrice != null) { long bsqPrice = MathUtils.roundDoubleToLong(MathUtils.scaleUpByPowerOf10(bsqMarketPrice.getPrice(), Altcoin.SMALLEST_UNIT_EXPONENT)); diff --git a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java index ea3079cc0ee..5066cfd8c83 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java @@ -25,8 +25,7 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; import bisq.core.btc.wallet.WalletService; -import bisq.core.dao.state.StateService; -import bisq.core.dao.state.blockchain.Tx; +import bisq.core.dao.DaoFacade; import bisq.core.dao.state.blockchain.TxType; import bisq.core.locale.Res; @@ -38,7 +37,6 @@ import javafx.scene.control.Tooltip; import java.util.Date; -import java.util.Optional; import lombok.Data; @@ -48,39 +46,35 @@ @Data class BsqTxListItem { private final Transaction transaction; - private final Optional optionalTx; private final BsqWalletService bsqWalletService; private final BtcWalletService btcWalletService; - private final StateService stateService; + private final DaoFacade daoFacade; private final BsqFormatter bsqFormatter; private final Date date; private final String txId; + private final boolean isBurnedBsqTx; private int confirmations = 0; private final String address; private final String direction; private Coin amount; private boolean received; - private boolean isBurnedBsqTx; private TxConfidenceIndicator txConfidenceIndicator; private TxConfidenceListener txConfidenceListener; private boolean issuanceTx; BsqTxListItem(Transaction transaction, - Optional optionalTx, BsqWalletService bsqWalletService, BtcWalletService btcWalletService, - StateService stateService, - boolean isBurnedBsqTx, + DaoFacade daoFacade, Date date, BsqFormatter bsqFormatter) { this.transaction = transaction; - this.optionalTx = optionalTx; this.bsqWalletService = bsqWalletService; this.btcWalletService = btcWalletService; - this.stateService = stateService; - this.isBurnedBsqTx = isBurnedBsqTx; + this.daoFacade = daoFacade; + this.isBurnedBsqTx = daoFacade.hasTxBurntFee(transaction.getHashAsString()); this.date = date; this.bsqFormatter = bsqFormatter; @@ -165,13 +159,9 @@ public void cleanup() { } public TxType getTxType() { - if (optionalTx.isPresent()) { - Optional optionalTxType = stateService.getTxType(optionalTx.get().getId()); - if (optionalTxType.isPresent()) - return optionalTxType.get(); - } - - return confirmations == 0 ? TxType.UNVERIFIED : TxType.UNDEFINED_TX_TYPE; + return daoFacade.getTx(txId) + .flatMap(tx -> daoFacade.getTxType(tx.getId())) + .orElse(confirmations == 0 ? TxType.UNVERIFIED : TxType.UNDEFINED_TX_TYPE); } public void setAmount(Coin amount) { diff --git a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java index ea2adc42b94..45908f549b0 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java @@ -32,10 +32,9 @@ import bisq.core.btc.wallet.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; +import bisq.core.dao.DaoFacade; import bisq.core.dao.state.Block; import bisq.core.dao.state.BlockListener; -import bisq.core.dao.state.StateService; -import bisq.core.dao.state.blockchain.Tx; import bisq.core.dao.state.blockchain.TxType; import bisq.core.locale.Res; import bisq.core.user.Preferences; @@ -77,7 +76,6 @@ import java.util.Comparator; import java.util.Date; import java.util.List; -import java.util.Optional; import java.util.stream.Collectors; @FxmlView @@ -86,12 +84,13 @@ public class BsqTxView extends ActivatableView implements BsqBal private TableView tableView; private Pane rootParent; + private final DaoFacade daoFacade; private final BsqFormatter bsqFormatter; private final BsqWalletService bsqWalletService; - private final StateService stateService; private final BtcWalletService btcWalletService; private final BsqBalanceUtil bsqBalanceUtil; private final Preferences preferences; + private final ObservableList observableList = FXCollections.observableArrayList(); // Need to be DoubleProperty as we pass it as reference private final DoubleProperty initialOccupiedHeight = new SimpleDoubleProperty(-1); @@ -109,16 +108,16 @@ public class BsqTxView extends ActivatableView implements BsqBal /////////////////////////////////////////////////////////////////////////////////////////// @Inject - private BsqTxView(BsqFormatter bsqFormatter, + private BsqTxView(DaoFacade daoFacade, BsqWalletService bsqWalletService, Preferences preferences, - StateService stateService, BtcWalletService btcWalletService, - BsqBalanceUtil bsqBalanceUtil) { + BsqBalanceUtil bsqBalanceUtil, + BsqFormatter bsqFormatter) { + this.daoFacade = daoFacade; this.bsqFormatter = bsqFormatter; this.bsqWalletService = bsqWalletService; this.preferences = preferences; - this.stateService = stateService; this.btcWalletService = btcWalletService; this.bsqBalanceUtil = bsqBalanceUtil; } @@ -177,7 +176,7 @@ protected void activate() { sortedList.comparatorProperty().bind(tableView.comparatorProperty()); tableView.setItems(sortedList); - stateService.addBlockListener(this); + daoFacade.addBlockListener(this); if (root.getParent() instanceof Pane) { rootParent = (Pane) root.getParent(); @@ -196,7 +195,7 @@ protected void deactivate() { bsqWalletService.getWalletTransactions().removeListener(walletBsqTransactionsListener); bsqWalletService.removeBsqBalanceListener(this); btcWalletService.getChainHeightProperty().removeListener(walletChainHeightListener); - stateService.removeBlockListener(this); + daoFacade.removeBlockListener(this); observableList.forEach(BsqTxListItem::cleanup); @@ -225,7 +224,7 @@ public void onBlockAdded(Block block) { // If chain height from wallet of from the BSQ blockchain parsing changed we update our state. private void onUpdateAnyChainHeight() { - final int bsqBlockChainHeight = stateService.getChainHeight(); + final int bsqBlockChainHeight = daoFacade.getChainHeight(); final int bsqWalletChainHeight = bsqWalletService.getBestChainHeight(); if (bsqWalletChainHeight > 0) { final boolean synced = bsqWalletChainHeight == bsqBlockChainHeight; @@ -258,13 +257,10 @@ private void updateList() { final List walletTransactions = new ArrayList<>(bsqWalletService.getWalletTransactions()); List items = walletTransactions.stream() .map(transaction -> { - final Optional optionalTx = stateService.getTx(transaction.getHashAsString()); return new BsqTxListItem(transaction, - optionalTx, bsqWalletService, btcWalletService, - stateService, - stateService.hasTxBurntFee(transaction.getHashAsString()), + daoFacade, transaction.getUpdateTime(), bsqFormatter); }) @@ -370,11 +366,8 @@ public void updateItem(final BsqTxListItem item, boolean empty) { String labelString = Res.get("dao.tx.type.enum." + txType.name()); Label label; if (item.getConfirmations() > 0 && txType.ordinal() > TxType.INVALID.ordinal()) { - final Optional optionalTx = item.getOptionalTx(); - if (txType == TxType.COMPENSATION_REQUEST && - optionalTx.isPresent() && - stateService.isIssuanceTx(optionalTx.get().getId())) { + daoFacade.isIssuanceTx(item.getTxId())) { if (field != null) field.setOnAction(null); @@ -535,12 +528,12 @@ public void updateItem(final BsqTxListItem item, boolean empty) { break; case PROPOSAL: case COMPENSATION_REQUEST: - final String txId = item.getOptionalTx().get().getId(); - if (item.getOptionalTx().isPresent() && stateService.isIssuanceTx(txId)) { + final String txId = item.getTxId(); + if (daoFacade.isIssuanceTx(txId)) { awesomeIcon = AwesomeIcon.MONEY; style = "dao-tx-type-issuance-icon"; - final int issuanceBlockHeight = stateService.getIssuanceBlockHeight(txId); - long blockTimeInSec = stateService.getBlockTime(issuanceBlockHeight); + final int issuanceBlockHeight = daoFacade.getIssuanceBlockHeight(txId); + long blockTimeInSec = daoFacade.getBlockTime(issuanceBlockHeight); final String formattedDate = bsqFormatter.formatDateTime(new Date(blockTimeInSec * 1000)); toolTipText = Res.get("dao.tx.issuance.tooltip", formattedDate); } else { diff --git a/src/main/java/bisq/desktop/main/funds/transactions/TransactionListItemFactory.java b/src/main/java/bisq/desktop/main/funds/transactions/TransactionListItemFactory.java index 7fc5b61ff1a..6be0a7c5c82 100644 --- a/src/main/java/bisq/desktop/main/funds/transactions/TransactionListItemFactory.java +++ b/src/main/java/bisq/desktop/main/funds/transactions/TransactionListItemFactory.java @@ -21,7 +21,7 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; -import bisq.core.dao.state.StateService; +import bisq.core.dao.DaoFacade; import bisq.core.trade.Tradable; import org.bitcoinj.core.Transaction; @@ -35,15 +35,15 @@ public class TransactionListItemFactory { private final BtcWalletService btcWalletService; private final BsqWalletService bsqWalletService; - private final StateService stateService; + private final DaoFacade daoFacade; private final BSFormatter formatter; @Inject TransactionListItemFactory(BtcWalletService btcWalletService, BsqWalletService bsqWalletService, - StateService stateService, BSFormatter formatter) { + DaoFacade daoFacade, BSFormatter formatter) { this.btcWalletService = btcWalletService; this.bsqWalletService = bsqWalletService; - this.stateService = stateService; + this.daoFacade = daoFacade; this.formatter = formatter; } @@ -51,6 +51,6 @@ TransactionsListItem create(Transaction transaction, @Nullable TransactionAwareT Optional maybeTradable = Optional.ofNullable(tradable) .map(TransactionAwareTradable::asTradable); - return new TransactionsListItem(transaction, btcWalletService, bsqWalletService, maybeTradable, stateService, formatter); + return new TransactionsListItem(transaction, btcWalletService, bsqWalletService, maybeTradable, daoFacade, formatter); } } diff --git a/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java b/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java index f1bdd17577f..3280fbd2501 100644 --- a/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java +++ b/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java @@ -26,7 +26,7 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; import bisq.core.btc.wallet.WalletService; -import bisq.core.dao.state.StateService; +import bisq.core.dao.DaoFacade; import bisq.core.dao.state.blockchain.TxType; import bisq.core.locale.Res; import bisq.core.offer.Offer; @@ -50,10 +50,11 @@ @Slf4j class TransactionsListItem { + private final BtcWalletService btcWalletService; + private final BSFormatter formatter; private String dateString; private final Date date; private final String txId; - private final BtcWalletService btcWalletService; private final TxConfidenceIndicator txConfidenceIndicator; private final Tooltip tooltip; @Nullable @@ -65,26 +66,28 @@ class TransactionsListItem { private boolean received; private boolean detailsAvailable; private Coin amountAsCoin = Coin.ZERO; - private BSFormatter formatter; private int confirmations = 0; - public TransactionsListItem() { + // used at exportCSV + TransactionsListItem() { date = null; btcWalletService = null; txConfidenceIndicator = null; tooltip = null; txId = null; + formatter = null; } - public TransactionsListItem(Transaction transaction, - BtcWalletService btcWalletService, - BsqWalletService bsqWalletService, - Optional tradableOptional, - StateService stateService, - BSFormatter formatter) { + TransactionsListItem(Transaction transaction, + BtcWalletService btcWalletService, + BsqWalletService bsqWalletService, + Optional tradableOptional, + DaoFacade daoFacade, + BSFormatter formatter) { + this.btcWalletService = btcWalletService; this.formatter = formatter; + txId = transaction.getHashAsString(); - this.btcWalletService = btcWalletService; Coin valueSentToMe = btcWalletService.getValueSentToMeForTransaction(transaction); Coin valueSentFromMe = btcWalletService.getValueSentFromMeForTransaction(transaction); @@ -130,7 +133,7 @@ public TransactionsListItem(Transaction transaction, txFeeForBsqPayment = true; // - final Optional txTypeOptional = stateService.getTxType(txId); + final Optional txTypeOptional = daoFacade.getTxType(txId); if (txTypeOptional.isPresent() && txTypeOptional.get().equals(TxType.COMPENSATION_REQUEST)) details = Res.get("funds.tx.proposal"); } else { From 6ed700589ddd66bb2fa72d73efc9715409796a2f Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Mon, 23 Apr 2018 00:16:34 -0500 Subject: [PATCH 068/197] Move ValidationException to bisq.core.dao.exceptions --- .../bisq/desktop/main/dao/proposal/make/MakeProposalView.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index ca93bac3556..bf2bdf5228e 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -32,9 +32,9 @@ import bisq.core.btc.wallet.InsufficientBsqException; import bisq.core.btc.wallet.WalletsSetup; import bisq.core.dao.DaoFacade; -import bisq.core.dao.ValidationException; import bisq.core.dao.ballot.Ballot; import bisq.core.dao.ballot.BallotWithTransaction; +import bisq.core.dao.exceptions.ValidationException; import bisq.core.dao.proposal.ProposalConsensus; import bisq.core.dao.proposal.ProposalType; import bisq.core.locale.Res; From 15ff5fadab60cfe85382eefe20180fd48dc662f1 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Mon, 23 Apr 2018 19:20:00 -0500 Subject: [PATCH 069/197] Move voting related classes to voting package --- .../desktop/main/dao/proposal/BaseProposalView.java | 4 ++-- .../main/dao/proposal/ProposalDetailsWindow.java | 2 +- .../desktop/main/dao/proposal/ProposalDisplay.java | 10 +++++----- .../desktop/main/dao/proposal/ProposalListItem.java | 6 +++--- .../main/dao/proposal/active/ActiveProposalsView.java | 4 ++-- .../main/dao/proposal/make/MakeProposalView.java | 8 ++++---- .../desktop/main/dao/proposal/myvotes/MyVotesView.java | 6 +++--- .../main/dao/proposal/myvotes/VoteListItem.java | 2 +- 8 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java index 89554ee7cff..33297ad49a3 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java @@ -28,9 +28,9 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; -import bisq.core.dao.ballot.Ballot; import bisq.core.dao.period.Phase; -import bisq.core.dao.proposal.Proposal; +import bisq.core.dao.voting.ballot.Ballot; +import bisq.core.dao.voting.proposal.Proposal; import bisq.core.locale.Res; import javax.inject.Inject; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java index bb7fe536899..263ccc36728 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java @@ -22,7 +22,7 @@ import bisq.desktop.util.Layout; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.proposal.Proposal; +import bisq.core.dao.voting.proposal.Proposal; import bisq.core.locale.Res; import javafx.geometry.Insets; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java index 9d954b67d9a..4073ffed1c6 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java @@ -28,11 +28,11 @@ import bisq.desktop.util.validation.BsqValidator; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.proposal.Proposal; -import bisq.core.dao.proposal.ProposalConsensus; -import bisq.core.dao.proposal.ProposalType; -import bisq.core.dao.proposal.compensation.CompensationConsensus; -import bisq.core.dao.proposal.compensation.CompensationProposal; +import bisq.core.dao.voting.proposal.Proposal; +import bisq.core.dao.voting.proposal.ProposalConsensus; +import bisq.core.dao.voting.proposal.ProposalType; +import bisq.core.dao.voting.proposal.compensation.CompensationConsensus; +import bisq.core.dao.voting.proposal.compensation.CompensationProposal; import bisq.core.locale.Res; import bisq.core.provider.fee.FeeService; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index d754444c9e9..4873bc6d72f 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -24,13 +24,13 @@ import bisq.core.btc.listeners.TxConfidenceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; -import bisq.core.dao.ballot.Ballot; import bisq.core.dao.period.Phase; import bisq.core.dao.state.Block; import bisq.core.dao.state.BlockListener; import bisq.core.dao.state.blockchain.Tx; -import bisq.core.dao.vote.BooleanVote; -import bisq.core.dao.vote.Vote; +import bisq.core.dao.voting.ballot.Ballot; +import bisq.core.dao.voting.vote.BooleanVote; +import bisq.core.dao.voting.vote.Vote; import bisq.core.locale.Res; import org.bitcoinj.core.Transaction; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index 7ce69c2d9b2..efc4545584b 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -34,9 +34,9 @@ import bisq.core.btc.wallet.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; -import bisq.core.dao.ballot.Ballot; import bisq.core.dao.period.Phase; -import bisq.core.dao.vote.BooleanVote; +import bisq.core.dao.voting.ballot.Ballot; +import bisq.core.dao.voting.vote.BooleanVote; import bisq.core.locale.Res; import bisq.common.util.Tuple2; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index bf2bdf5228e..869f3e2e5d6 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -32,11 +32,11 @@ import bisq.core.btc.wallet.InsufficientBsqException; import bisq.core.btc.wallet.WalletsSetup; import bisq.core.dao.DaoFacade; -import bisq.core.dao.ballot.Ballot; -import bisq.core.dao.ballot.BallotWithTransaction; import bisq.core.dao.exceptions.ValidationException; -import bisq.core.dao.proposal.ProposalConsensus; -import bisq.core.dao.proposal.ProposalType; +import bisq.core.dao.voting.ballot.Ballot; +import bisq.core.dao.voting.ballot.BallotWithTransaction; +import bisq.core.dao.voting.proposal.ProposalConsensus; +import bisq.core.dao.voting.proposal.ProposalType; import bisq.core.locale.Res; import bisq.core.provider.fee.FeeService; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java index 466bfd6d737..560604930fc 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java @@ -31,9 +31,9 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; -import bisq.core.dao.ballot.BallotList; -import bisq.core.dao.vote.BooleanVote; -import bisq.core.dao.vote.Vote; +import bisq.core.dao.voting.ballot.BallotList; +import bisq.core.dao.voting.vote.BooleanVote; +import bisq.core.dao.voting.vote.Vote; import bisq.core.locale.Res; import bisq.core.user.Preferences; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java index 460361e199d..a3b8ceb271c 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java @@ -23,11 +23,11 @@ import bisq.core.btc.listeners.TxConfidenceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; -import bisq.core.dao.myvote.MyVote; import bisq.core.dao.state.Block; import bisq.core.dao.state.BlockListener; import bisq.core.dao.state.blockchain.Tx; import bisq.core.dao.state.blockchain.TxOutput; +import bisq.core.dao.voting.myvote.MyVote; import bisq.core.locale.Res; import org.bitcoinj.core.Coin; From bf8629d23ea91cbdf28f49ae57023ac992b4ba7b Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Mon, 23 Apr 2018 22:59:34 -0500 Subject: [PATCH 070/197] Refactor handling of cycles - Remove PeriodState - Add cycles to state - Use stateService for getting chainHeight instead of periodService - Let parser call stateService methods on start parsing and on new block - Rename PeriodStateChangeListener to ChainHeightListener - Rename PeriodStateUpdater to CycleService - Use StartParsingListener to decouple CycleService with StateService - Remove StateChangeEventsProvider interface from CycleService - Let CycleService write to StateService not PeriodService --- .../dao/proposal/dashboard/ProposalDashboardView.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java index 1f41ba2084d..e1428a0c970 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java @@ -23,8 +23,8 @@ import bisq.desktop.util.Layout; import bisq.core.dao.DaoFacade; -import bisq.core.dao.period.PeriodStateChangeListener; import bisq.core.dao.period.Phase; +import bisq.core.dao.state.ChainHeightListener; import bisq.core.locale.Res; import bisq.common.UserThread; @@ -44,11 +44,11 @@ import static bisq.desktop.util.FormBuilder.addTitledGroupBg; -// We use here PeriodStateChangeListener because we are interested in period changes not in the result of a completed -// block. The event from the PeriodStateChangeListener is sent before parsing starts. +// We use here ChainHeightListener because we are interested in period changes not in the result of a completed +// block. The event from the ChainHeightListener is sent before parsing starts. // The event from the StateService.Listener would notify after parsing a new block. @FxmlView -public class ProposalDashboardView extends ActivatableView implements PeriodStateChangeListener { +public class ProposalDashboardView extends ActivatableView implements ChainHeightListener { private final DaoFacade daoFacade; private List phaseBarsItems; From 81c57cf2d582adc1869f230b6c5f879a78a7fba9 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Tue, 24 Apr 2018 09:28:19 -0500 Subject: [PATCH 071/197] Remove chainHeightListeners from PeriodService - Rename addPeriodStateChangeListener to addChainHeightListener --- .../main/dao/proposal/dashboard/ProposalDashboardView.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java index e1428a0c970..63cff02a811 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java @@ -124,7 +124,7 @@ protected void activate() { }); }); - daoFacade.addPeriodStateChangeListener(this); + daoFacade.addChainHeightListener(this); // We need to delay as otherwise the periodService has not been updated yet. UserThread.execute(() -> onChainHeightChanged(daoFacade.getChainHeight())); @@ -133,10 +133,11 @@ protected void activate() { @Override protected void deactivate() { super.deactivate(); - daoFacade.removePeriodStateChangeListener(this); + daoFacade.removeChainHeightListener(this); phaseSubscription.unsubscribe(); } + // ChainHeightListener @Override public void onChainHeightChanged(int height) { if (height > 0) { From 55ee4a15b82211c83aa07da093a107ccc4294140 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Tue, 24 Apr 2018 11:00:26 -0500 Subject: [PATCH 072/197] Remove Meta data from block. - Remove Block - Rename TxBlock to Block - Rename classes, methods with *TxBlock* to *Block* - Remove stateChangeEventsProviders --- doc/rpc.md | 5 ++++- .../bisq/desktop/main/dao/proposal/ProposalListItem.java | 2 +- .../bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java | 2 +- .../desktop/main/dao/wallet/dashboard/BsqDashboardView.java | 2 +- src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java | 2 +- 5 files changed, 8 insertions(+), 5 deletions(-) diff --git a/doc/rpc.md b/doc/rpc.md index f4f2b208be6..79ed3f91780 100644 --- a/doc/rpc.md +++ b/doc/rpc.md @@ -32,5 +32,8 @@ If you use RegTest in development environment you need to create the genesis tra Create one Bitcoin transaction from Bitcoin Core to one or 2 Bisq instances using the BSQ receive addresses from those apps (1 tx with 2 or more outputs to the Bisq app). If you copy the BSQ address and use that in Bitcoin Core you need to remove the "B" at the beginning. This is only for protection to mix up BTC and BSQ addresses but without the B it is a native Bitcoin address. Create one block with the debug commandline inside Bitcoin Core (generate 1). Look up the block height in the info screen in the debug window. -Set the block height and transaction ID at BsqBlockChain.BTC_REG_TEST_GENESIS_TX_ID and BsqBlockChain.BTC_REG_TEST_GENESIS_BLOCK_HEIGHT. +Set the block height and transaction ID at with options genesisBlockHeight and genesisTxId. Restart the Bisq apps. After that the app will recognize the received Bitcoin as BSQ. + +Here are example options for regtest mode: +--daoActivated=true --genesisBlockHeight=111 --genesisTxId=aa92a8d56be3aaafc6b1a8d248ae67c221d78a31de8867a9564e7ae24340b495 --useDevPrivilegeKeys=true --useDevMode=true--baseCurrencyNetwork=BTC_REGTEST --useLocalhostForP2P=true --nodePort=3612 --appName=bisq-BTC_REGTEST_Bob_dao --fullDaoNode=true --rpcUser=bisq --rpcPassword=bisqPW --rpcPort=18332 --rpcBlockNotificationPort=5159 diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index 4873bc6d72f..dec1f0118da 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -25,8 +25,8 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; import bisq.core.dao.period.Phase; -import bisq.core.dao.state.Block; import bisq.core.dao.state.BlockListener; +import bisq.core.dao.state.blockchain.Block; import bisq.core.dao.state.blockchain.Tx; import bisq.core.dao.voting.ballot.Ballot; import bisq.core.dao.voting.vote.BooleanVote; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java index a3b8ceb271c..252ba82f75e 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java @@ -23,8 +23,8 @@ import bisq.core.btc.listeners.TxConfidenceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; -import bisq.core.dao.state.Block; import bisq.core.dao.state.BlockListener; +import bisq.core.dao.state.blockchain.Block; import bisq.core.dao.state.blockchain.Tx; import bisq.core.dao.state.blockchain.TxOutput; import bisq.core.dao.voting.myvote.MyVote; diff --git a/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java b/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java index 1a6f5db668c..6d4581c2858 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java @@ -27,8 +27,8 @@ import bisq.desktop.util.Layout; import bisq.core.dao.DaoFacade; -import bisq.core.dao.state.Block; import bisq.core.dao.state.BlockListener; +import bisq.core.dao.state.blockchain.Block; import bisq.core.locale.Res; import bisq.core.monetary.Altcoin; import bisq.core.monetary.Price; diff --git a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java index 45908f549b0..aeeb018a753 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java @@ -33,8 +33,8 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; import bisq.core.dao.DaoFacade; -import bisq.core.dao.state.Block; import bisq.core.dao.state.BlockListener; +import bisq.core.dao.state.blockchain.Block; import bisq.core.dao.state.blockchain.TxType; import bisq.core.locale.Res; import bisq.core.user.Preferences; From 62da432790c109ff0b2f4ab9903fffa360ae0cf5 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Tue, 24 Apr 2018 16:35:18 -0500 Subject: [PATCH 073/197] Refactor ParamChange domain --- .../components/SeparatedPhaseBars.java | 6 +++--- .../main/dao/proposal/BaseProposalView.java | 8 ++++---- .../main/dao/proposal/ProposalListItem.java | 7 +++---- .../proposal/active/ActiveProposalsView.java | 6 +++--- .../dashboard/ProposalDashboardView.java | 20 +++++++++---------- .../dao/proposal/myvotes/VoteListItem.java | 1 - 6 files changed, 23 insertions(+), 25 deletions(-) diff --git a/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java b/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java index b714f626142..795e27437f0 100644 --- a/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java +++ b/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java @@ -17,7 +17,7 @@ package bisq.desktop.components; -import bisq.core.dao.period.Phase; +import bisq.core.dao.period.DaoPhase; import bisq.core.locale.Res; import bisq.common.UserThread; @@ -143,7 +143,7 @@ private void updateWidth(double availableWidth) { @Getter public static class SeparatedPhaseBarsItem { - private final Phase phase; + private final DaoPhase.Phase phase; private final boolean showBlocks; private final IntegerProperty startBlockProperty = new SimpleIntegerProperty(); private final IntegerProperty lastBlockProperty = new SimpleIntegerProperty(); @@ -154,7 +154,7 @@ public static class SeparatedPhaseBarsItem { @Setter private Label titleLabel; - public SeparatedPhaseBarsItem(Phase phase, boolean showBlocks) { + public SeparatedPhaseBarsItem(DaoPhase.Phase phase, boolean showBlocks) { this.phase = phase; this.showBlocks = showBlocks; } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java index 33297ad49a3..e7e73b625c4 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java @@ -28,7 +28,7 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; -import bisq.core.dao.period.Phase; +import bisq.core.dao.period.DaoPhase; import bisq.core.dao.voting.ballot.Ballot; import bisq.core.dao.voting.proposal.Proposal; import bisq.core.locale.Res; @@ -82,8 +82,8 @@ public abstract class BaseProposalView extends ActivatableView { protected GridPane detailsGridPane, gridPane; protected ProposalListItem selectedProposalListItem; protected ListChangeListener proposalListChangeListener; - protected ChangeListener phaseChangeListener; - protected Phase currentPhase; + protected ChangeListener phaseChangeListener; + protected DaoPhase.Phase currentPhase; protected Subscription phaseSubscription; private ScrollPane proposalDisplayView; @@ -214,7 +214,7 @@ protected void onSelectProposal(ProposalListItem item) { hideProposalDisplay(); } - protected void onPhaseChanged(Phase phase) { + protected void onPhaseChanged(DaoPhase.Phase phase) { if (phase != null && !phase.equals(currentPhase)) { currentPhase = phase; onSelectProposal(selectedProposalListItem); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index dec1f0118da..ec466488458 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -24,7 +24,7 @@ import bisq.core.btc.listeners.TxConfidenceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; -import bisq.core.dao.period.Phase; +import bisq.core.dao.period.DaoPhase; import bisq.core.dao.state.BlockListener; import bisq.core.dao.state.blockchain.Block; import bisq.core.dao.state.blockchain.Tx; @@ -69,7 +69,7 @@ public class ProposalListItem implements BlockListener { private TxConfidenceListener txConfidenceListener; private Tooltip tooltip = new Tooltip(Res.get("confidence.unknown")); private Transaction walletTransaction; - private ChangeListener phaseChangeListener; + private ChangeListener phaseChangeListener; private AutoTooltipButton actionButton; private ImageView actionButtonIconView; @Setter @@ -115,7 +115,7 @@ public class ProposalListItem implements BlockListener { ballot.getVoteResultProperty().addListener(voteResultChangeListener); } - public void applyState(Phase phase, Vote vote) { + public void applyState(DaoPhase.Phase phase, Vote vote) { if (phase != null) { actionButton.setText(""); actionButton.setVisible(false); @@ -218,7 +218,6 @@ public void onTransactionConfidenceChanged(TransactionConfidence confidence) { int depth = bsqWalletService.getChainHeightProperty().get() - tx.getBlockHeight() + 1; if (depth > 0) updateConfidence(TransactionConfidence.ConfidenceType.BUILDING, depth, -1); - //log.error("name={}, id ={}, depth={}", compensationRequest.getPayload().getName(), compensationRequest.getPayload().getUid(), depth); } final TransactionConfidence confidence = bsqWalletService.getConfidenceForTxId(txId); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index efc4545584b..4645165dfdc 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -34,7 +34,7 @@ import bisq.core.btc.wallet.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; -import bisq.core.dao.period.Phase; +import bisq.core.dao.period.DaoPhase; import bisq.core.dao.voting.ballot.Ballot; import bisq.core.dao.voting.vote.BooleanVote; import bisq.core.locale.Res; @@ -241,11 +241,11 @@ private void onCancelVote() { } @Override - protected void onPhaseChanged(Phase phase) { + protected void onPhaseChanged(DaoPhase.Phase phase) { if (phase != null) { super.onPhaseChanged(phase); - changeVoteViewItemsVisibility(phase == Phase.BLIND_VOTE); + changeVoteViewItemsVisibility(phase == DaoPhase.Phase.BLIND_VOTE); if (removeButton != null) { removeButton.setManaged(false); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java index 63cff02a811..afd557287f9 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java @@ -23,7 +23,7 @@ import bisq.desktop.util.Layout; import bisq.core.dao.DaoFacade; -import bisq.core.dao.period.Phase; +import bisq.core.dao.period.DaoPhase; import bisq.core.dao.state.ChainHeightListener; import bisq.core.locale.Res; @@ -52,7 +52,7 @@ public class ProposalDashboardView extends ActivatableView imple private final DaoFacade daoFacade; private List phaseBarsItems; - private Phase currentPhase; + private DaoPhase.Phase currentPhase; private Subscription phaseSubscription; private GridPane gridPane; private int gridRow = 0; @@ -96,14 +96,14 @@ public void initialize() { private SeparatedPhaseBars createSeparatedPhaseBars() { phaseBarsItems = Arrays.asList( - new SeparatedPhaseBars.SeparatedPhaseBarsItem(Phase.PROPOSAL, true), - new SeparatedPhaseBars.SeparatedPhaseBarsItem(Phase.BREAK1, false), - new SeparatedPhaseBars.SeparatedPhaseBarsItem(Phase.BLIND_VOTE, true), - new SeparatedPhaseBars.SeparatedPhaseBarsItem(Phase.BREAK2, false), - new SeparatedPhaseBars.SeparatedPhaseBarsItem(Phase.VOTE_REVEAL, true), - new SeparatedPhaseBars.SeparatedPhaseBarsItem(Phase.BREAK3, false), - new SeparatedPhaseBars.SeparatedPhaseBarsItem(Phase.VOTE_RESULT, false), - new SeparatedPhaseBars.SeparatedPhaseBarsItem(Phase.BREAK4, false)); + new SeparatedPhaseBars.SeparatedPhaseBarsItem(DaoPhase.Phase.PROPOSAL, true), + new SeparatedPhaseBars.SeparatedPhaseBarsItem(DaoPhase.Phase.BREAK1, false), + new SeparatedPhaseBars.SeparatedPhaseBarsItem(DaoPhase.Phase.BLIND_VOTE, true), + new SeparatedPhaseBars.SeparatedPhaseBarsItem(DaoPhase.Phase.BREAK2, false), + new SeparatedPhaseBars.SeparatedPhaseBarsItem(DaoPhase.Phase.VOTE_REVEAL, true), + new SeparatedPhaseBars.SeparatedPhaseBarsItem(DaoPhase.Phase.BREAK3, false), + new SeparatedPhaseBars.SeparatedPhaseBarsItem(DaoPhase.Phase.VOTE_RESULT, false), + new SeparatedPhaseBars.SeparatedPhaseBarsItem(DaoPhase.Phase.BREAK4, false)); return new SeparatedPhaseBars(phaseBarsItems); } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java index 252ba82f75e..7e014d7a9d6 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java @@ -136,7 +136,6 @@ public void onTransactionConfidenceChanged(TransactionConfidence confidence) { int depth = bsqWalletService.getChainHeightProperty().get() - tx.getBlockHeight() + 1; if (depth > 0) updateConfidence(TransactionConfidence.ConfidenceType.BUILDING, depth, -1); - //log.error("name={}, id ={}, depth={}", compensationRequest.getPayload().getName(), compensationRequest.getPayload().getUid(), depth); } final TransactionConfidence confidence = bsqWalletService.getConfidenceForTxId(txId); From 8381ce6f9ecb8a9227c56e5e12f61e0f40a3439c Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Tue, 24 Apr 2018 18:18:26 -0500 Subject: [PATCH 074/197] Rename VOTE_RESULT to RESULT --- .../java/bisq/desktop/main/dao/proposal/ProposalListItem.java | 2 +- .../desktop/main/dao/proposal/active/ActiveProposalsView.java | 2 +- .../main/dao/proposal/dashboard/ProposalDashboardView.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index ec466488458..50dfa63599d 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -163,7 +163,7 @@ public void applyState(DaoPhase.Phase phase, Vote vote) { break; case BREAK3: break; - case VOTE_RESULT: + case RESULT: break; case BREAK4: break; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index 4645165dfdc..eeb04920dfd 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -297,7 +297,7 @@ protected void onPhaseChanged(DaoPhase.Phase phase) { break; case BREAK3: break; - case VOTE_RESULT: + case RESULT: break; case BREAK4: break; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java index afd557287f9..e3a1634ef87 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java @@ -102,7 +102,7 @@ private SeparatedPhaseBars createSeparatedPhaseBars() { new SeparatedPhaseBars.SeparatedPhaseBarsItem(DaoPhase.Phase.BREAK2, false), new SeparatedPhaseBars.SeparatedPhaseBarsItem(DaoPhase.Phase.VOTE_REVEAL, true), new SeparatedPhaseBars.SeparatedPhaseBarsItem(DaoPhase.Phase.BREAK3, false), - new SeparatedPhaseBars.SeparatedPhaseBarsItem(DaoPhase.Phase.VOTE_RESULT, false), + new SeparatedPhaseBars.SeparatedPhaseBarsItem(DaoPhase.Phase.RESULT, false), new SeparatedPhaseBars.SeparatedPhaseBarsItem(DaoPhase.Phase.BREAK4, false)); return new SeparatedPhaseBars(phaseBarsItems); } From a66b62ef288d8061346386ff4517b59e84a87e3c Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Tue, 24 Apr 2018 21:01:04 -0500 Subject: [PATCH 075/197] Move ValidationException to voting package --- .../bisq/desktop/main/dao/proposal/make/MakeProposalView.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index 869f3e2e5d6..21851bd0e12 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -32,7 +32,7 @@ import bisq.core.btc.wallet.InsufficientBsqException; import bisq.core.btc.wallet.WalletsSetup; import bisq.core.dao.DaoFacade; -import bisq.core.dao.exceptions.ValidationException; +import bisq.core.dao.voting.ValidationException; import bisq.core.dao.voting.ballot.Ballot; import bisq.core.dao.voting.ballot.BallotWithTransaction; import bisq.core.dao.voting.proposal.ProposalConsensus; From 99e9943eb2bc5c26f35dc48b1c5f1d3a0620839a Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Tue, 24 Apr 2018 21:04:06 -0500 Subject: [PATCH 076/197] Move proposal and vote package into ballot package --- .../desktop/main/dao/proposal/BaseProposalView.java | 2 +- .../main/dao/proposal/ProposalDetailsWindow.java | 2 +- .../desktop/main/dao/proposal/ProposalDisplay.java | 10 +++++----- .../desktop/main/dao/proposal/ProposalListItem.java | 4 ++-- .../main/dao/proposal/active/ActiveProposalsView.java | 2 +- .../main/dao/proposal/make/MakeProposalView.java | 4 ++-- .../desktop/main/dao/proposal/myvotes/MyVotesView.java | 4 ++-- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java index e7e73b625c4..5b9c10fab4a 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java @@ -30,7 +30,7 @@ import bisq.core.dao.DaoFacade; import bisq.core.dao.period.DaoPhase; import bisq.core.dao.voting.ballot.Ballot; -import bisq.core.dao.voting.proposal.Proposal; +import bisq.core.dao.voting.ballot.proposal.Proposal; import bisq.core.locale.Res; import javax.inject.Inject; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java index 263ccc36728..abfb178359f 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java @@ -22,7 +22,7 @@ import bisq.desktop.util.Layout; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.voting.proposal.Proposal; +import bisq.core.dao.voting.ballot.proposal.Proposal; import bisq.core.locale.Res; import javafx.geometry.Insets; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java index 4073ffed1c6..b521a6cea7f 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java @@ -28,11 +28,11 @@ import bisq.desktop.util.validation.BsqValidator; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.voting.proposal.Proposal; -import bisq.core.dao.voting.proposal.ProposalConsensus; -import bisq.core.dao.voting.proposal.ProposalType; -import bisq.core.dao.voting.proposal.compensation.CompensationConsensus; -import bisq.core.dao.voting.proposal.compensation.CompensationProposal; +import bisq.core.dao.voting.ballot.proposal.Proposal; +import bisq.core.dao.voting.ballot.proposal.ProposalConsensus; +import bisq.core.dao.voting.ballot.proposal.ProposalType; +import bisq.core.dao.voting.ballot.proposal.compensation.CompensationConsensus; +import bisq.core.dao.voting.ballot.proposal.compensation.CompensationProposal; import bisq.core.locale.Res; import bisq.core.provider.fee.FeeService; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index 50dfa63599d..da8576264b4 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -29,8 +29,8 @@ import bisq.core.dao.state.blockchain.Block; import bisq.core.dao.state.blockchain.Tx; import bisq.core.dao.voting.ballot.Ballot; -import bisq.core.dao.voting.vote.BooleanVote; -import bisq.core.dao.voting.vote.Vote; +import bisq.core.dao.voting.ballot.vote.BooleanVote; +import bisq.core.dao.voting.ballot.vote.Vote; import bisq.core.locale.Res; import org.bitcoinj.core.Transaction; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index eeb04920dfd..567749c4db9 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -36,7 +36,7 @@ import bisq.core.dao.DaoFacade; import bisq.core.dao.period.DaoPhase; import bisq.core.dao.voting.ballot.Ballot; -import bisq.core.dao.voting.vote.BooleanVote; +import bisq.core.dao.voting.ballot.vote.BooleanVote; import bisq.core.locale.Res; import bisq.common.util.Tuple2; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index 21851bd0e12..bc049e5d395 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -35,8 +35,8 @@ import bisq.core.dao.voting.ValidationException; import bisq.core.dao.voting.ballot.Ballot; import bisq.core.dao.voting.ballot.BallotWithTransaction; -import bisq.core.dao.voting.proposal.ProposalConsensus; -import bisq.core.dao.voting.proposal.ProposalType; +import bisq.core.dao.voting.ballot.proposal.ProposalConsensus; +import bisq.core.dao.voting.ballot.proposal.ProposalType; import bisq.core.locale.Res; import bisq.core.provider.fee.FeeService; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java index 560604930fc..32178270bc5 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java @@ -32,8 +32,8 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; import bisq.core.dao.voting.ballot.BallotList; -import bisq.core.dao.voting.vote.BooleanVote; -import bisq.core.dao.voting.vote.Vote; +import bisq.core.dao.voting.ballot.vote.BooleanVote; +import bisq.core.dao.voting.ballot.vote.Vote; import bisq.core.locale.Res; import bisq.core.user.Preferences; From 85328e4db80a2e3244749f911c7a7c8c53fa4c95 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Tue, 24 Apr 2018 21:08:29 -0500 Subject: [PATCH 077/197] Move period package into state package --- src/main/java/bisq/desktop/components/SeparatedPhaseBars.java | 2 +- .../java/bisq/desktop/main/dao/proposal/BaseProposalView.java | 2 +- .../java/bisq/desktop/main/dao/proposal/ProposalListItem.java | 2 +- .../desktop/main/dao/proposal/active/ActiveProposalsView.java | 2 +- .../main/dao/proposal/dashboard/ProposalDashboardView.java | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java b/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java index 795e27437f0..6a32059fd62 100644 --- a/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java +++ b/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java @@ -17,7 +17,7 @@ package bisq.desktop.components; -import bisq.core.dao.period.DaoPhase; +import bisq.core.dao.state.period.DaoPhase; import bisq.core.locale.Res; import bisq.common.UserThread; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java index 5b9c10fab4a..0975ad7aaec 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java @@ -28,7 +28,7 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; -import bisq.core.dao.period.DaoPhase; +import bisq.core.dao.state.period.DaoPhase; import bisq.core.dao.voting.ballot.Ballot; import bisq.core.dao.voting.ballot.proposal.Proposal; import bisq.core.locale.Res; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index da8576264b4..06cdf2cafb2 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -24,7 +24,7 @@ import bisq.core.btc.listeners.TxConfidenceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; -import bisq.core.dao.period.DaoPhase; +import bisq.core.dao.state.period.DaoPhase; import bisq.core.dao.state.BlockListener; import bisq.core.dao.state.blockchain.Block; import bisq.core.dao.state.blockchain.Tx; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index 567749c4db9..51dc19d9065 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -34,7 +34,7 @@ import bisq.core.btc.wallet.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; -import bisq.core.dao.period.DaoPhase; +import bisq.core.dao.state.period.DaoPhase; import bisq.core.dao.voting.ballot.Ballot; import bisq.core.dao.voting.ballot.vote.BooleanVote; import bisq.core.locale.Res; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java index e3a1634ef87..6db609451fe 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java @@ -23,7 +23,7 @@ import bisq.desktop.util.Layout; import bisq.core.dao.DaoFacade; -import bisq.core.dao.period.DaoPhase; +import bisq.core.dao.state.period.DaoPhase; import bisq.core.dao.state.ChainHeightListener; import bisq.core.locale.Res; From b996e948a218520a88377394a6192ed8adf7f79a Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Wed, 25 Apr 2018 12:42:26 -0500 Subject: [PATCH 078/197] Store only proposal TxId + vote instead of whole ballot in BlindVote - Add BallotFactory - Change encryptedBallotList to encryptedVotes --- src/main/java/bisq/desktop/main/dao/DaoView.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/bisq/desktop/main/dao/DaoView.java b/src/main/java/bisq/desktop/main/dao/DaoView.java index e86494d8c70..975fd42b846 100644 --- a/src/main/java/bisq/desktop/main/dao/DaoView.java +++ b/src/main/java/bisq/desktop/main/dao/DaoView.java @@ -71,7 +71,8 @@ public void initialize() { votingTab = new Tab(Res.get("dao.tab.voting")); compensationTab.setClosable(false); votingTab.setClosable(false); - root.getTabs().addAll(compensationTab, votingTab); + //TODO + root.getTabs().addAll(compensationTab/*, votingTab*/); if (!BisqEnvironment.isDAOActivatedAndBaseCurrencySupportingBsq() || !DevEnv.isDaoPhase2Activated()) { votingTab.setDisable(true); From 2705e68dc8b57763e1af00cad01bc677655c11c3 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Mon, 30 Apr 2018 12:28:22 -0500 Subject: [PATCH 079/197] Let proposal domain handle all its relevant use cases - Previously we wrapped by default a proposal into a ballot and used that in the UI. We changed that so in the proposal phase there is only the proposal used. Once we enter the blind vote phase we move to ballot representation. - We also changed that the proposals for the append-only data store gets filled by the proposal domain once entering the blind vote phase. - We moved also the publishing, removal and republishing to the myProposalListService. --- .../main/dao/proposal/BaseProposalView.java | 29 ++++++++-------- .../main/dao/proposal/ProposalListItem.java | 33 +++++++++++-------- .../proposal/active/ActiveProposalsView.java | 26 ++++++++------- .../proposal/closed/ClosedProposalsView.java | 2 +- .../dao/proposal/make/MakeProposalView.java | 22 ++++++------- .../dao/proposal/myvotes/MyVotesView.java | 12 +++---- 6 files changed, 67 insertions(+), 57 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java index 0975ad7aaec..73d43767b12 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java @@ -191,14 +191,14 @@ protected void hideProposalDisplay() { proposalDisplayView.setManaged(false); } - protected void showProposalDisplay(Ballot ballot) { + protected void showProposalDisplay(Proposal proposal) { proposalDisplayView.setVisible(true); proposalDisplayView.setManaged(true); - proposalDisplay.createAllFields(Res.get("dao.proposal.selectedProposal"), 0, 0, ballot.getType(), + proposalDisplay.createAllFields(Res.get("dao.proposal.selectedProposal"), 0, 0, proposal.getType(), false, false); proposalDisplay.setEditable(false); - proposalDisplay.applyProposalPayload(ballot.getProposal()); + proposalDisplay.applyProposalPayload(proposal); } @@ -209,7 +209,7 @@ protected void showProposalDisplay(Ballot ballot) { protected void onSelectProposal(ProposalListItem item) { selectedProposalListItem = item; if (item != null) - showProposalDisplay(item.getBallot()); + showProposalDisplay(item.getProposal()); else hideProposalDisplay(); } @@ -228,11 +228,11 @@ protected void onPhaseChanged(DaoPhase.Phase phase) { abstract protected void updateProposalList(); - protected void doUpdateProposalList(List list) { + protected void doUpdateProposalList(List list) { proposalListItems.forEach(ProposalListItem::cleanup); proposalListItems.clear(); proposalListItems.setAll(list.stream() - .map(ballot -> new ProposalListItem(ballot, + .map(proposal -> new ProposalListItem(proposal, daoFacade, bsqWalletService, bsqFormatter)) @@ -273,14 +273,14 @@ public TableCell call( public void updateItem(final ProposalListItem item, boolean empty) { super.updateItem(item, empty); if (item != null) - setText(bsqFormatter.formatDateTime(item.getBallot().getProposal().getCreationDate())); + setText(bsqFormatter.formatDateTime(item.getProposal().getCreationDate())); else setText(""); } }; } }); - dateColumn.setComparator(Comparator.comparing(o3 -> o3.getBallot().getProposal().getCreationDate())); + dateColumn.setComparator(Comparator.comparing(o3 -> o3.getProposal().getCreationDate())); dateColumn.setSortType(TableColumn.SortType.DESCENDING); tableView.getColumns().add(dateColumn); tableView.getSortOrder().add(dateColumn); @@ -298,14 +298,14 @@ public TableCell call( public void updateItem(final ProposalListItem item, boolean empty) { super.updateItem(item, empty); if (item != null) - setText(item.getBallot().getProposal().getName()); + setText(item.getProposal().getName()); else setText(""); } }; } }); - nameColumn.setComparator(Comparator.comparing(o2 -> o2.getBallot().getProposal().getName())); + nameColumn.setComparator(Comparator.comparing(o2 -> o2.getProposal().getName())); tableView.getColumns().add(nameColumn); TableColumn titleColumn = new AutoTooltipTableColumn<>(Res.get("dao.proposal.title")); @@ -322,14 +322,14 @@ public TableCell call( public void updateItem(final ProposalListItem item, boolean empty) { super.updateItem(item, empty); if (item != null) - setText(item.getBallot().getProposal().getTitle()); + setText(item.getProposal().getTitle()); else setText(""); } }; } }); - titleColumn.setComparator(Comparator.comparing(o2 -> o2.getBallot().getProposal().getTitle())); + titleColumn.setComparator(Comparator.comparing(o2 -> o2.getProposal().getTitle())); tableView.getColumns().add(titleColumn); TableColumn uidColumn = new AutoTooltipTableColumn<>(Res.get("shared.id")); @@ -348,8 +348,7 @@ public TableCell call(TableColumn { new ProposalDetailsWindow(bsqFormatter, bsqWalletService, proposal).show(); @@ -365,7 +364,7 @@ public void updateItem(final ProposalListItem item, boolean empty) { }; } }); - uidColumn.setComparator(Comparator.comparing(o -> o.getBallot().getUid())); + uidColumn.setComparator(Comparator.comparing(o -> o.getProposal().getUid())); tableView.getColumns().add(uidColumn); } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index 06cdf2cafb2..233075211b2 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -24,12 +24,11 @@ import bisq.core.btc.listeners.TxConfidenceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; -import bisq.core.dao.state.period.DaoPhase; import bisq.core.dao.state.BlockListener; import bisq.core.dao.state.blockchain.Block; import bisq.core.dao.state.blockchain.Tx; -import bisq.core.dao.voting.ballot.Ballot; -import bisq.core.dao.voting.ballot.vote.BooleanVote; +import bisq.core.dao.state.period.DaoPhase; +import bisq.core.dao.voting.ballot.proposal.Proposal; import bisq.core.dao.voting.ballot.vote.Vote; import bisq.core.locale.Res; @@ -55,7 +54,7 @@ @EqualsAndHashCode public class ProposalListItem implements BlockListener { @Getter - private final Ballot ballot; + private final Proposal proposal; private final DaoFacade daoFacade; private final BsqWalletService bsqWalletService; private final BsqFormatter bsqFormatter; @@ -76,11 +75,11 @@ public class ProposalListItem implements BlockListener { private Runnable onRemoveHandler; private Node actionNode; - ProposalListItem(Ballot ballot, + ProposalListItem(Proposal proposal, DaoFacade daoFacade, BsqWalletService bsqWalletService, BsqFormatter bsqFormatter) { - this.ballot = ballot; + this.proposal = proposal; this.daoFacade = daoFacade; this.bsqWalletService = bsqWalletService; this.bsqFormatter = bsqFormatter; @@ -104,7 +103,8 @@ public class ProposalListItem implements BlockListener { daoFacade.addBlockListener(this); phaseChangeListener = (observable, oldValue, newValue) -> { - applyState(newValue, ballot.getVote()); + //TODO + //applyState(newValue, proposal.getVote()); }; voteResultChangeListener = (observable, oldValue, newValue) -> { @@ -112,7 +112,9 @@ public class ProposalListItem implements BlockListener { }; daoFacade.phaseProperty().addListener(phaseChangeListener); - ballot.getVoteResultProperty().addListener(voteResultChangeListener); + + //TODO + //proposal.getVoteResultProperty().addListener(voteResultChangeListener); } public void applyState(DaoPhase.Phase phase, Vote vote) { @@ -125,7 +127,7 @@ public void applyState(DaoPhase.Phase phase, Vote vote) { log.error("invalid state UNDEFINED"); break; case PROPOSAL: - if (daoFacade.isMyProposal(ballot.getProposal())) { + if (daoFacade.isMyProposal(proposal)) { actionButtonIconView.setVisible(actionButton.isVisible()); actionButton.setText(Res.get("shared.remove")); actionButton.setGraphic(actionButtonIconView); @@ -142,7 +144,9 @@ public void applyState(DaoPhase.Phase phase, Vote vote) { case BLIND_VOTE: actionNode = actionButtonIconView; actionButton.setVisible(false); - if (ballot.getVote() != null) { + + //TODO + /*if (proposal.getVote() != null) { actionButtonIconView.setVisible(true); if (vote instanceof BooleanVote) { if (((BooleanVote) vote).isAccepted()) { @@ -155,7 +159,8 @@ public void applyState(DaoPhase.Phase phase, Vote vote) { } } else { actionButtonIconView.setVisible(false); - } + }*/ + break; case BREAK2: break; @@ -191,7 +196,7 @@ public void onBlockAdded(Block block) { // TODO reuse from other item private void setupConfidence() { - final String txId = ballot.getProposal().getTxId(); + final String txId = proposal.getTxId(); Optional optionalTx = daoFacade.getTx(txId); if (optionalTx.isPresent()) { Tx tx = optionalTx.get(); @@ -240,7 +245,9 @@ public void cleanup() { bsqWalletService.removeTxConfidenceListener(txConfidenceListener); daoFacade.phaseProperty().removeListener(phaseChangeListener); - ballot.getVoteResultProperty().removeListener(voteResultChangeListener); + + //TODO + // proposal.getVoteResultProperty().removeListener(voteResultChangeListener); } private void updateConfidence(TransactionConfidence.ConfidenceType confidenceType, int depthInBlocks, int numBroadcastPeers) { diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index 51dc19d9065..6788cf50766 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -35,8 +35,7 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; import bisq.core.dao.state.period.DaoPhase; -import bisq.core.dao.voting.ballot.Ballot; -import bisq.core.dao.voting.ballot.vote.BooleanVote; +import bisq.core.dao.voting.ballot.proposal.Proposal; import bisq.core.locale.Res; import bisq.common.util.Tuple2; @@ -226,17 +225,21 @@ protected void onSelectProposal(ProposalListItem item) { } private void onAccept() { - daoFacade.setVote(selectedProposalListItem.getBallot(), new BooleanVote(true)); + //TODO + // daoFacade.setVote(selectedProposalListItem.getProposal(), new BooleanVote(true)); updateStateAfterVote(); } + private void onReject() { - daoFacade.setVote(selectedProposalListItem.getBallot(), new BooleanVote(false)); + //TODO + // daoFacade.setVote(selectedProposalListItem.getProposal(), new BooleanVote(false)); updateStateAfterVote(); } private void onCancelVote() { - daoFacade.setVote(selectedProposalListItem.getBallot(), null); + //TODO + // daoFacade.setVote(selectedProposalListItem.getProposal(), null); updateStateAfterVote(); } @@ -253,10 +256,10 @@ protected void onPhaseChanged(DaoPhase.Phase phase) { removeButton = null; } if (selectedProposalListItem != null && proposalDisplay != null) { - final Ballot ballot = selectedProposalListItem.getBallot(); + final Proposal proposal = selectedProposalListItem.getProposal(); switch (phase) { case PROPOSAL: - if (daoFacade.isMyProposal(ballot.getProposal())) { + if (daoFacade.isMyProposal(proposal)) { if (removeButton == null) { removeButton = addButtonAfterGroup(detailsGridPane, proposalDisplay.incrementAndGetGridRow(), Res.get("dao.proposal.active.remove")); removeButton.setOnAction(event -> onRemove()); @@ -316,7 +319,7 @@ protected void onPhaseChanged(DaoPhase.Phase phase) { @Override protected void updateProposalList() { - doUpdateProposalList(daoFacade.getActiveOrMyUnconfirmedBallots()); + doUpdateProposalList(daoFacade.getActiveOrMyUnconfirmedProposals()); } private void updateStateAfterVote() { @@ -332,8 +335,8 @@ private void changeVoteViewItemsVisibility(boolean value) { } private void onRemove() { - final Ballot ballot = selectedProposalListItem.getBallot(); - if (daoFacade.removeBallot(ballot)) { + final Proposal proposal = selectedProposalListItem.getProposal(); + if (daoFacade.removeMyProposal(proposal)) { hideProposalDisplay(); } else { new Popup<>().warning(Res.get("dao.proposal.active.remove.failed")).show(); @@ -378,7 +381,8 @@ public void updateItem(final ProposalListItem item, boolean empty) { ActiveProposalsView.this.selectedProposalListItem = item; ActiveProposalsView.this.onRemove(); }); - item.applyState(currentPhase, item.getBallot().getVoteResultProperty().get()); + //TODO + // item.applyState(currentPhase, item.getProposal().getVoteResultProperty().get()); } } else { setGraphic(null); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java index dd2f0486a5c..98f2d14b372 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java @@ -65,7 +65,7 @@ protected void deactivate() { @Override protected void updateProposalList() { - doUpdateProposalList(daoFacade.getClosedBallots()); + doUpdateProposalList(daoFacade.getClosedProposals()); } } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index bc049e5d395..2a2eb6514bc 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -33,10 +33,10 @@ import bisq.core.btc.wallet.WalletsSetup; import bisq.core.dao.DaoFacade; import bisq.core.dao.voting.ValidationException; -import bisq.core.dao.voting.ballot.Ballot; -import bisq.core.dao.voting.ballot.BallotWithTransaction; +import bisq.core.dao.voting.ballot.proposal.Proposal; import bisq.core.dao.voting.ballot.proposal.ProposalConsensus; import bisq.core.dao.voting.ballot.proposal.ProposalType; +import bisq.core.dao.voting.ballot.proposal.ProposalWithTransaction; import bisq.core.locale.Res; import bisq.core.provider.fee.FeeService; @@ -147,16 +147,16 @@ protected void deactivate() { createButton.setOnAction(null); } - private void publishProposalAndStoreBallot(ProposalType type) { + private void publishMyProposal(ProposalType type) { try { - final BallotWithTransaction ballotWithTransaction = getBallotWithTransaction(type); - Ballot ballot = ballotWithTransaction.getBallot(); + final ProposalWithTransaction ballotWithTransaction = getBallotWithTransaction(type); + Proposal proposal = ballotWithTransaction.getProposal(); Transaction transaction = ballotWithTransaction.getTransaction(); Coin miningFee = transaction.getFee(); int txSize = transaction.bitcoinSerialize().length; final Coin fee = daoFacade.getProposalFee(); GUIUtil.showBsqFeeInfoPopup(fee, miningFee, txSize, bsqFormatter, btcFormatter, - Res.get("dao.proposal"), () -> publishProposalAndStoreBallot(ballot, transaction)); + Res.get("dao.proposal"), () -> doPublishMyProposal(proposal, transaction)); } catch (InsufficientMoneyException e) { BSFormatter formatter = e instanceof InsufficientBsqException ? bsqFormatter : btcFormatter; @@ -178,8 +178,8 @@ private void publishProposalAndStoreBallot(ProposalType type) { } } - private void publishProposalAndStoreBallot(Ballot ballot, Transaction transaction) { - daoFacade.publishBallot(ballot, + private void doPublishMyProposal(Proposal proposal, Transaction transaction) { + daoFacade.publishMyProposal(proposal, transaction, () -> { proposalDisplay.clearForm(); @@ -189,7 +189,7 @@ private void publishProposalAndStoreBallot(Ballot ballot, Transaction transactio errorMessage -> new Popup<>().warning(errorMessage).show()); } - private BallotWithTransaction getBallotWithTransaction(ProposalType type) + private ProposalWithTransaction getBallotWithTransaction(ProposalType type) throws InsufficientMoneyException, TransactionVerificationException, ValidationException, WalletException, IOException { @@ -197,7 +197,7 @@ private BallotWithTransaction getBallotWithTransaction(ProposalType type) switch (type) { case COMPENSATION_REQUEST: - return daoFacade.getCompensationBallotWithTransaction(proposalDisplay.nameTextField.getText(), + return daoFacade.getCompensationProposalWithTransaction(proposalDisplay.nameTextField.getText(), proposalDisplay.titleTextField.getText(), proposalDisplay.descriptionTextArea.getText(), proposalDisplay.linkInputTextField.getText(), @@ -246,7 +246,7 @@ private void setCreateButtonHandler() { createButton.setOnAction(event -> { // TODO break up in methods if (GUIUtil.isReadyForTxBroadcast(p2PService, walletsSetup)) { - publishProposalAndStoreBallot(selectedProposalType); + publishMyProposal(selectedProposalType); } else { GUIUtil.showNotReadyForTxBroadcastPopups(p2PService, walletsSetup); } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java index 32178270bc5..f51cb863fc4 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java @@ -32,8 +32,6 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; import bisq.core.dao.voting.ballot.BallotList; -import bisq.core.dao.voting.ballot.vote.BooleanVote; -import bisq.core.dao.voting.ballot.vote.Vote; import bisq.core.locale.Res; import bisq.core.user.Preferences; @@ -178,8 +176,9 @@ private void onShowProposalList(BallotList ballotList) { @Override protected void updateProposalList() { - if (selectedVoteListItem != null) - doUpdateProposalList(selectedVoteListItem.getMyVote().getBallotList().getList()); + //TODO + //if (selectedVoteListItem != null) + // doUpdateProposalList(selectedVoteListItem.getMyVote().getBallotList().getList()); } @@ -363,7 +362,8 @@ public void updateItem(final ProposalListItem item, boolean empty) { if (item != null && !empty) { actionButtonIconView = new ImageView(); - Vote vote = item.getBallot().getVote(); + //TODO + /* Vote vote = item.getProposal().getVote(); if (vote instanceof BooleanVote) { if (((BooleanVote) vote).isAccepted()) { actionButtonIconView.setId("accepted"); @@ -372,7 +372,7 @@ public void updateItem(final ProposalListItem item, boolean empty) { } } else { //TODO - } + }*/ setGraphic(actionButtonIconView); } else { From 7b6a8fd59a9d65174293a16e5fd346e198ff167d Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Mon, 30 Apr 2018 12:37:13 -0500 Subject: [PATCH 080/197] Move propsal package one level up --- .../desktop/main/dao/proposal/BaseProposalView.java | 2 +- .../main/dao/proposal/ProposalDetailsWindow.java | 2 +- .../desktop/main/dao/proposal/ProposalDisplay.java | 10 +++++----- .../desktop/main/dao/proposal/ProposalListItem.java | 2 +- .../main/dao/proposal/active/ActiveProposalsView.java | 2 +- .../main/dao/proposal/make/MakeProposalView.java | 8 ++++---- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java index 73d43767b12..0650943e28a 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java @@ -30,7 +30,7 @@ import bisq.core.dao.DaoFacade; import bisq.core.dao.state.period.DaoPhase; import bisq.core.dao.voting.ballot.Ballot; -import bisq.core.dao.voting.ballot.proposal.Proposal; +import bisq.core.dao.voting.proposal.Proposal; import bisq.core.locale.Res; import javax.inject.Inject; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java index abfb178359f..263ccc36728 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java @@ -22,7 +22,7 @@ import bisq.desktop.util.Layout; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.voting.ballot.proposal.Proposal; +import bisq.core.dao.voting.proposal.Proposal; import bisq.core.locale.Res; import javafx.geometry.Insets; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java index b521a6cea7f..4073ffed1c6 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java @@ -28,11 +28,11 @@ import bisq.desktop.util.validation.BsqValidator; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.voting.ballot.proposal.Proposal; -import bisq.core.dao.voting.ballot.proposal.ProposalConsensus; -import bisq.core.dao.voting.ballot.proposal.ProposalType; -import bisq.core.dao.voting.ballot.proposal.compensation.CompensationConsensus; -import bisq.core.dao.voting.ballot.proposal.compensation.CompensationProposal; +import bisq.core.dao.voting.proposal.Proposal; +import bisq.core.dao.voting.proposal.ProposalConsensus; +import bisq.core.dao.voting.proposal.ProposalType; +import bisq.core.dao.voting.proposal.compensation.CompensationConsensus; +import bisq.core.dao.voting.proposal.compensation.CompensationProposal; import bisq.core.locale.Res; import bisq.core.provider.fee.FeeService; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index 233075211b2..de6c0d6f126 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -28,7 +28,7 @@ import bisq.core.dao.state.blockchain.Block; import bisq.core.dao.state.blockchain.Tx; import bisq.core.dao.state.period.DaoPhase; -import bisq.core.dao.voting.ballot.proposal.Proposal; +import bisq.core.dao.voting.proposal.Proposal; import bisq.core.dao.voting.ballot.vote.Vote; import bisq.core.locale.Res; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index 6788cf50766..c2b869c4847 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -35,7 +35,7 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; import bisq.core.dao.state.period.DaoPhase; -import bisq.core.dao.voting.ballot.proposal.Proposal; +import bisq.core.dao.voting.proposal.Proposal; import bisq.core.locale.Res; import bisq.common.util.Tuple2; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index 2a2eb6514bc..1dbd9482cdf 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -33,10 +33,10 @@ import bisq.core.btc.wallet.WalletsSetup; import bisq.core.dao.DaoFacade; import bisq.core.dao.voting.ValidationException; -import bisq.core.dao.voting.ballot.proposal.Proposal; -import bisq.core.dao.voting.ballot.proposal.ProposalConsensus; -import bisq.core.dao.voting.ballot.proposal.ProposalType; -import bisq.core.dao.voting.ballot.proposal.ProposalWithTransaction; +import bisq.core.dao.voting.proposal.Proposal; +import bisq.core.dao.voting.proposal.ProposalConsensus; +import bisq.core.dao.voting.proposal.ProposalType; +import bisq.core.dao.voting.proposal.ProposalWithTransaction; import bisq.core.locale.Res; import bisq.core.provider.fee.FeeService; From 390d7999c8cd44c48fac34d7cb17f1600f3cca05 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Mon, 30 Apr 2018 12:47:45 -0500 Subject: [PATCH 081/197] Use Proposal instead of Ballot. Cleanup --- .../java/bisq/desktop/main/dao/proposal/BaseProposalView.java | 3 +-- .../desktop/main/dao/proposal/active/ActiveProposalsView.java | 4 ++-- .../desktop/main/dao/proposal/closed/ClosedProposalsView.java | 4 ++-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java index 0650943e28a..307e248e7cc 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java @@ -29,7 +29,6 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; import bisq.core.dao.state.period.DaoPhase; -import bisq.core.dao.voting.ballot.Ballot; import bisq.core.dao.voting.proposal.Proposal; import bisq.core.locale.Res; @@ -81,7 +80,7 @@ public abstract class BaseProposalView extends ActivatableView { protected int gridRow = 0; protected GridPane detailsGridPane, gridPane; protected ProposalListItem selectedProposalListItem; - protected ListChangeListener proposalListChangeListener; + protected ListChangeListener proposalListChangeListener; protected ChangeListener phaseChangeListener; protected DaoPhase.Phase currentPhase; protected Subscription phaseSubscription; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index c2b869c4847..21a724ff4ef 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -101,7 +101,7 @@ public void initialize() { protected void activate() { super.activate(); - daoFacade.getActiveOrMyUnconfirmedBallots().addListener(proposalListChangeListener); + daoFacade.getActiveOrMyUnconfirmedProposals().addListener(proposalListChangeListener); bsqWalletService.addBsqBalanceListener(this); onUpdateBalances(bsqWalletService.getAvailableBalance(), @@ -152,7 +152,7 @@ private void publishBlindVote(Coin stake) { protected void deactivate() { super.deactivate(); - daoFacade.getActiveOrMyUnconfirmedBallots().removeListener(proposalListChangeListener); + daoFacade.getActiveOrMyUnconfirmedProposals().removeListener(proposalListChangeListener); bsqWalletService.removeBsqBalanceListener(this); } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java index 98f2d14b372..7a7d94d226e 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java @@ -54,13 +54,13 @@ public void initialize() { @Override protected void activate() { super.activate(); - daoFacade.getClosedBallots().addListener(proposalListChangeListener); + daoFacade.getClosedProposals().addListener(proposalListChangeListener); } @Override protected void deactivate() { super.deactivate(); - daoFacade.getClosedBallots().removeListener(proposalListChangeListener); + daoFacade.getClosedProposals().removeListener(proposalListChangeListener); } @Override From 554c11fbd6084b48ad7b2d7bc2f14d1ac4592cf8 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Mon, 30 Apr 2018 13:43:47 -0500 Subject: [PATCH 082/197] Fix missing txId at proposal creation - Add check for empty txIf in proposalValidator - Disable create proposal combobox if in last block of phase or outside phase - Improve UI code --- .../main/dao/proposal/BaseProposalView.java | 13 +- .../proposal/active/ActiveProposalsView.java | 123 +++++++++--------- .../proposal/closed/ClosedProposalsView.java | 7 +- .../dao/proposal/make/MakeProposalView.java | 26 +++- .../dao/proposal/myvotes/MyVotesView.java | 15 ++- 5 files changed, 105 insertions(+), 79 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java index 307e248e7cc..fc78da033ec 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java @@ -109,7 +109,7 @@ public void initialize() { detailsGridPane = new GridPane(); - proposalListChangeListener = c -> updateProposalList(); + proposalListChangeListener = c -> updateProposalListItems(); phaseChangeListener = (observable, oldValue, newValue) -> onPhaseChanged(newValue); } @@ -124,7 +124,7 @@ protected void activate() { sortedList.comparatorProperty().bind(proposalTableView.comparatorProperty()); - updateProposalList(); + updateProposalListItems(); } @Override @@ -207,8 +207,8 @@ protected void showProposalDisplay(Proposal proposal) { protected void onSelectProposal(ProposalListItem item) { selectedProposalListItem = item; - if (item != null) - showProposalDisplay(item.getProposal()); + if (selectedProposalListItem != null) + showProposalDisplay(selectedProposalListItem.getProposal()); else hideProposalDisplay(); } @@ -225,9 +225,10 @@ protected void onPhaseChanged(DaoPhase.Phase phase) { // Protected /////////////////////////////////////////////////////////////////////////////////////////// - abstract protected void updateProposalList(); + abstract protected List getProposalList(); - protected void doUpdateProposalList(List list) { + protected void updateProposalListItems() { + List list = getProposalList(); proposalListItems.forEach(ProposalListItem::cleanup); proposalListItems.clear(); proposalListItems.setAll(list.stream() diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index 21a724ff4ef..58b96baa841 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -96,7 +96,6 @@ public void initialize() { createProposalDisplay(); } - @Override protected void activate() { super.activate(); @@ -245,70 +244,68 @@ private void onCancelVote() { @Override protected void onPhaseChanged(DaoPhase.Phase phase) { - if (phase != null) { - super.onPhaseChanged(phase); + super.onPhaseChanged(phase); - changeVoteViewItemsVisibility(phase == DaoPhase.Phase.BLIND_VOTE); + changeVoteViewItemsVisibility(phase == DaoPhase.Phase.BLIND_VOTE); - if (removeButton != null) { - removeButton.setManaged(false); - removeButton.setVisible(false); - removeButton = null; - } - if (selectedProposalListItem != null && proposalDisplay != null) { - final Proposal proposal = selectedProposalListItem.getProposal(); - switch (phase) { - case PROPOSAL: - if (daoFacade.isMyProposal(proposal)) { - if (removeButton == null) { - removeButton = addButtonAfterGroup(detailsGridPane, proposalDisplay.incrementAndGetGridRow(), Res.get("dao.proposal.active.remove")); - removeButton.setOnAction(event -> onRemove()); - } else { - removeButton.setManaged(true); - removeButton.setVisible(true); - } - } - break; - case BREAK1: - break; - case BLIND_VOTE: - if (acceptButton == null) { - Tuple3 tuple = add3ButtonsAfterGroup(detailsGridPane, proposalDisplay - .incrementAndGetGridRow(), - Res.get("dao.proposal.myVote.accept"), - Res.get("dao.proposal.myVote.reject"), - Res.get("dao.proposal.myVote.cancelVote")); - acceptButton = tuple.first; - acceptButton.setDefaultButton(false); - rejectButton = tuple.second; - cancelVoteButton = tuple.third; - acceptButton.setOnAction(event -> onAccept()); - rejectButton.setOnAction(event -> onReject()); - cancelVoteButton.setOnAction(event -> onCancelVote()); + if (removeButton != null) { + removeButton.setManaged(false); + removeButton.setVisible(false); + removeButton = null; + } + if (selectedProposalListItem != null && proposalDisplay != null) { + final Proposal proposal = selectedProposalListItem.getProposal(); + switch (phase) { + case PROPOSAL: + if (daoFacade.isMyProposal(proposal)) { + if (removeButton == null) { + removeButton = addButtonAfterGroup(detailsGridPane, proposalDisplay.incrementAndGetGridRow(), Res.get("dao.proposal.active.remove")); + removeButton.setOnAction(event -> onRemove()); } else { - acceptButton.setManaged(true); - acceptButton.setVisible(true); - rejectButton.setManaged(true); - rejectButton.setVisible(true); - cancelVoteButton.setManaged(true); - cancelVoteButton.setVisible(true); + removeButton.setManaged(true); + removeButton.setVisible(true); } - break; - case BREAK2: - break; - case VOTE_REVEAL: - break; - case BREAK3: - break; - case RESULT: - break; - case BREAK4: - break; - case UNDEFINED: - default: - log.error("Undefined phase: " + phase); - break; - } + } + break; + case BREAK1: + break; + case BLIND_VOTE: + if (acceptButton == null) { + Tuple3 tuple = add3ButtonsAfterGroup(detailsGridPane, proposalDisplay + .incrementAndGetGridRow(), + Res.get("dao.proposal.myVote.accept"), + Res.get("dao.proposal.myVote.reject"), + Res.get("dao.proposal.myVote.cancelVote")); + acceptButton = tuple.first; + acceptButton.setDefaultButton(false); + rejectButton = tuple.second; + cancelVoteButton = tuple.third; + acceptButton.setOnAction(event -> onAccept()); + rejectButton.setOnAction(event -> onReject()); + cancelVoteButton.setOnAction(event -> onCancelVote()); + } else { + acceptButton.setManaged(true); + acceptButton.setVisible(true); + rejectButton.setManaged(true); + rejectButton.setVisible(true); + cancelVoteButton.setManaged(true); + cancelVoteButton.setVisible(true); + } + break; + case BREAK2: + break; + case VOTE_REVEAL: + break; + case BREAK3: + break; + case RESULT: + break; + case BREAK4: + break; + case UNDEFINED: + default: + log.error("Undefined phase: " + phase); + break; } } } @@ -318,8 +315,8 @@ protected void onPhaseChanged(DaoPhase.Phase phase) { /////////////////////////////////////////////////////////////////////////////////////////// @Override - protected void updateProposalList() { - doUpdateProposalList(daoFacade.getActiveOrMyUnconfirmedProposals()); + protected List getProposalList() { + return daoFacade.getActiveOrMyUnconfirmedProposals(); } private void updateStateAfterVote() { diff --git a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java index 7a7d94d226e..3048f7b7ba6 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java @@ -24,9 +24,12 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; +import bisq.core.dao.voting.proposal.Proposal; import javax.inject.Inject; +import java.util.List; + @FxmlView public class ClosedProposalsView extends BaseProposalView { @@ -64,8 +67,8 @@ protected void deactivate() { } @Override - protected void updateProposalList() { - doUpdateProposalList(daoFacade.getClosedProposals()); + protected List getProposalList() { + return daoFacade.getClosedProposals(); } } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index 1dbd9482cdf..139fc9d2d10 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -32,6 +32,8 @@ import bisq.core.btc.wallet.InsufficientBsqException; import bisq.core.btc.wallet.WalletsSetup; import bisq.core.dao.DaoFacade; +import bisq.core.dao.state.ChainHeightListener; +import bisq.core.dao.state.period.DaoPhase; import bisq.core.dao.voting.ValidationException; import bisq.core.dao.voting.proposal.Proposal; import bisq.core.dao.voting.proposal.ProposalConsensus; @@ -69,7 +71,7 @@ import static com.google.common.base.Preconditions.checkArgument; @FxmlView -public class MakeProposalView extends ActivatableView { +public class MakeProposalView extends ActivatableView implements ChainHeightListener { private final DaoFacade daoFacade; private final BsqWalletService bsqWalletService; private final WalletsSetup walletsSetup; @@ -134,6 +136,9 @@ public ProposalType fromString(String string) { @Override protected void activate() { + daoFacade.addChainHeightListener(this); + onChainHeightChanged(daoFacade.getChainHeight()); + proposalTypeComboBox.getSelectionModel().selectedItemProperty().addListener(proposalTypeChangeListener); if (createButton != null) @@ -142,11 +147,27 @@ protected void activate() { @Override protected void deactivate() { + daoFacade.removeChainHeightListener(this); proposalTypeComboBox.getSelectionModel().selectedItemProperty().removeListener(proposalTypeChangeListener); if (createButton != null) createButton.setOnAction(null); } + + /////////////////////////////////////////////////////////////////////////////////////////// + // ChainHeightListener + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public void onChainHeightChanged(int blockHeight) { + proposalTypeComboBox.setDisable(!daoFacade.isInPhaseButNotLastBlock(DaoPhase.Phase.PROPOSAL)); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Private + /////////////////////////////////////////////////////////////////////////////////////////// + private void publishMyProposal(ProposalType type) { try { final ProposalWithTransaction ballotWithTransaction = getBallotWithTransaction(type); @@ -257,10 +278,9 @@ private void validateInputs() { // We check in proposalDisplay that no invalid input as allowed checkArgument(ProposalConsensus.isDescriptionSizeValid(proposalDisplay.descriptionTextArea.getText()), "descriptionText must not be longer than " + - ProposalConsensus.getMaxLengthDescriptionText() + " chars"); + ProposalConsensus.getMaxLengthDescriptionText() + " chars"); // TODO add more checks for all input fields } - } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java index f51cb863fc4..4da808d3c82 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java @@ -32,6 +32,7 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; import bisq.core.dao.voting.ballot.BallotList; +import bisq.core.dao.voting.proposal.Proposal; import bisq.core.locale.Res; import bisq.core.user.Preferences; @@ -121,7 +122,7 @@ protected void activate() { private void onSelectVote(VoteListItem voteListItem) { selectedVoteListItem = voteListItem; changeProposalViewItemsVisibility(selectedVoteListItem != null); - updateProposalList(); + updateProposalListItems(); } @Override @@ -174,14 +175,18 @@ private void onShowProposalList(BallotList ballotList) { // Protected /////////////////////////////////////////////////////////////////////////////////////////// + /* @Override + protected void updateProposalList() { + //TODO + //if (selectedVoteListItem != null) + // doUpdateProposalList(selectedVoteListItem.getMyVote().getBallotList().getList()); + }*/ @Override - protected void updateProposalList() { + protected List getProposalList() { //TODO - //if (selectedVoteListItem != null) - // doUpdateProposalList(selectedVoteListItem.getMyVote().getBallotList().getList()); + return null;// daoFacade.getActiveOrMyUnconfirmedProposals(); } - /////////////////////////////////////////////////////////////////////////////////////////// // TableColumns /////////////////////////////////////////////////////////////////////////////////////////// From 040fec61d17cbf886071d935a0f2ea74f877c5b8 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Mon, 30 Apr 2018 17:15:03 -0500 Subject: [PATCH 083/197] Rename "Cancel vote" to "Remove my vote" --- .../java/bisq/desktop/main/dao/DaoView.java | 18 +++++------ .../main/dao/proposal/ProposalListItem.java | 19 ++---------- .../main/dao/proposal/ProposalView.fxml | 1 - .../proposal/active/ActiveProposalsView.java | 30 +++++++++++-------- 4 files changed, 30 insertions(+), 38 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/DaoView.java b/src/main/java/bisq/desktop/main/dao/DaoView.java index 975fd42b846..1ffdde19fc7 100644 --- a/src/main/java/bisq/desktop/main/dao/DaoView.java +++ b/src/main/java/bisq/desktop/main/dao/DaoView.java @@ -48,7 +48,7 @@ public class DaoView extends ActivatableViewAndModel { @FXML - Tab bsqWalletTab, compensationTab, votingTab; + Tab bsqWalletTab, proposalsTab, votingTab; private Navigation.Listener navigationListener; private ChangeListener tabChangeListener; @@ -67,23 +67,23 @@ private DaoView(CachingViewLoader viewLoader, Navigation navigation) { @Override public void initialize() { - compensationTab = new Tab(Res.get("dao.tab.proposals")); + proposalsTab = new Tab(Res.get("dao.tab.proposals")); votingTab = new Tab(Res.get("dao.tab.voting")); - compensationTab.setClosable(false); + proposalsTab.setClosable(false); votingTab.setClosable(false); //TODO - root.getTabs().addAll(compensationTab/*, votingTab*/); + root.getTabs().addAll(proposalsTab/*, votingTab*/); if (!BisqEnvironment.isDAOActivatedAndBaseCurrencySupportingBsq() || !DevEnv.isDaoPhase2Activated()) { votingTab.setDisable(true); - compensationTab.setDisable(true); + proposalsTab.setDisable(true); } bsqWalletTab.setText(Res.get("dao.tab.bsqWallet")); navigationListener = viewPath -> { if (viewPath.size() == 3 && viewPath.indexOf(DaoView.class) == 1) { - if (compensationTab == null && viewPath.get(2).equals(BsqWalletView.class)) + if (proposalsTab == null && viewPath.get(2).equals(BsqWalletView.class)) //noinspection unchecked navigation.navigateTo(MainView.class, DaoView.class, BsqWalletView.class); else @@ -100,7 +100,7 @@ public void initialize() { else //noinspection unchecked navigation.navigateTo(MainView.class, DaoView.class, BsqWalletView.class, selectedViewClass); - } else if (newValue == compensationTab) { + } else if (newValue == proposalsTab) { //noinspection unchecked navigation.navigateTo(MainView.class, DaoView.class, ProposalView.class); } else if (newValue == votingTab) { @@ -120,7 +120,7 @@ protected void activate() { if (selectedItem == bsqWalletTab) //noinspection unchecked navigation.navigateTo(MainView.class, DaoView.class, BsqWalletView.class); - else if (selectedItem == compensationTab) + else if (selectedItem == proposalsTab) //noinspection unchecked navigation.navigateTo(MainView.class, DaoView.class, ProposalView.class); else if (selectedItem == votingTab) @@ -141,7 +141,7 @@ private void loadView(Class viewClass) { selectedTab = bsqWalletTab; bsqWalletView = (BsqWalletView) view; } else if (view instanceof ProposalView) { - selectedTab = compensationTab; + selectedTab = proposalsTab; } else if (view instanceof VotingView) { selectedTab = votingTab; } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index de6c0d6f126..a7a86c24e72 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -29,7 +29,6 @@ import bisq.core.dao.state.blockchain.Tx; import bisq.core.dao.state.period.DaoPhase; import bisq.core.dao.voting.proposal.Proposal; -import bisq.core.dao.voting.ballot.vote.Vote; import bisq.core.locale.Res; import org.bitcoinj.core.Transaction; @@ -59,7 +58,6 @@ public class ProposalListItem implements BlockListener { private final BsqWalletService bsqWalletService; private final BsqFormatter bsqFormatter; private final ChangeListener chainHeightListener; - private final ChangeListener voteResultChangeListener; @Getter private TxConfidenceIndicator txConfidenceIndicator; @Getter @@ -103,21 +101,13 @@ public class ProposalListItem implements BlockListener { daoFacade.addBlockListener(this); phaseChangeListener = (observable, oldValue, newValue) -> { - //TODO - //applyState(newValue, proposal.getVote()); - }; - - voteResultChangeListener = (observable, oldValue, newValue) -> { - applyState(daoFacade.phaseProperty().get(), newValue); + applyState(newValue); }; daoFacade.phaseProperty().addListener(phaseChangeListener); - - //TODO - //proposal.getVoteResultProperty().addListener(voteResultChangeListener); } - public void applyState(DaoPhase.Phase phase, Vote vote) { + public void applyState(DaoPhase.Phase phase) { if (phase != null) { actionButton.setText(""); actionButton.setVisible(false); @@ -146,7 +136,7 @@ public void applyState(DaoPhase.Phase phase, Vote vote) { actionButton.setVisible(false); //TODO - /*if (proposal.getVote() != null) { + /* if (vote != null) { actionButtonIconView.setVisible(true); if (vote instanceof BooleanVote) { if (((BooleanVote) vote).isAccepted()) { @@ -245,9 +235,6 @@ public void cleanup() { bsqWalletService.removeTxConfidenceListener(txConfidenceListener); daoFacade.phaseProperty().removeListener(phaseChangeListener); - - //TODO - // proposal.getVoteResultProperty().removeListener(voteResultChangeListener); } private void updateConfidence(TransactionConfidence.ConfidenceType confidenceType, int depthInBlocks, int numBroadcastPeers) { diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalView.fxml b/src/main/java/bisq/desktop/main/dao/proposal/ProposalView.fxml index 35c7261a5ae..7209d295000 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalView.fxml +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalView.fxml @@ -17,7 +17,6 @@ ~ along with Bisq. If not, see . --> - voteViewItems = new ArrayList<>(); private BusyAnimation voteButtonBusyAnimation; @@ -213,10 +213,10 @@ protected void onSelectProposal(ProposalListItem item) { rejectButton.setVisible(false); rejectButton = null; } - if (cancelVoteButton != null) { - cancelVoteButton.setManaged(false); - cancelVoteButton.setVisible(false); - cancelVoteButton = null; + if (removeMyVoteButton != null) { + removeMyVoteButton.setManaged(false); + removeMyVoteButton.setVisible(false); + removeMyVoteButton = null; } onPhaseChanged(daoFacade.phaseProperty().get()); @@ -242,6 +242,12 @@ private void onCancelVote() { updateStateAfterVote(); } + + /////////////////////////////////////////////////////////////////////////////////////////// + // ChainHeightListener + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override protected void onPhaseChanged(DaoPhase.Phase phase) { super.onPhaseChanged(phase); @@ -275,21 +281,22 @@ protected void onPhaseChanged(DaoPhase.Phase phase) { .incrementAndGetGridRow(), Res.get("dao.proposal.myVote.accept"), Res.get("dao.proposal.myVote.reject"), - Res.get("dao.proposal.myVote.cancelVote")); + Res.get("dao.proposal.myVote.removeMyVote")); acceptButton = tuple.first; acceptButton.setDefaultButton(false); rejectButton = tuple.second; - cancelVoteButton = tuple.third; + removeMyVoteButton = tuple.third; acceptButton.setOnAction(event -> onAccept()); rejectButton.setOnAction(event -> onReject()); - cancelVoteButton.setOnAction(event -> onCancelVote()); + removeMyVoteButton.setOnAction(event -> onCancelVote()); } else { + //TODO prob. not possible code path acceptButton.setManaged(true); acceptButton.setVisible(true); rejectButton.setManaged(true); rejectButton.setVisible(true); - cancelVoteButton.setManaged(true); - cancelVoteButton.setVisible(true); + removeMyVoteButton.setManaged(true); + removeMyVoteButton.setVisible(true); } break; case BREAK2: @@ -378,8 +385,7 @@ public void updateItem(final ProposalListItem item, boolean empty) { ActiveProposalsView.this.selectedProposalListItem = item; ActiveProposalsView.this.onRemove(); }); - //TODO - // item.applyState(currentPhase, item.getProposal().getVoteResultProperty().get()); + item.applyState(currentPhase); } } else { setGraphic(null); From 57f612958b5fdd003a7a07247a3fa9a63920a173 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Mon, 30 Apr 2018 18:21:37 -0500 Subject: [PATCH 084/197] Add voting tab --- .../bisq/desktop/components/MenuItem.java | 28 +- .../java/bisq/desktop/main/dao/DaoView.java | 2 +- .../main/dao/proposal/ProposalView.java | 17 +- .../dashboard/ProposalDashboardView.java | 5 +- .../desktop/main/dao/voting/VotingView.java | 102 +---- .../dao/voting/active/ActiveVotingView.fxml | 33 ++ .../dao/voting/active/ActiveVotingView.java | 406 ++++++++++++++++++ .../voting/dashboard/VotingDashboardView.java | 14 +- 8 files changed, 500 insertions(+), 107 deletions(-) create mode 100644 src/main/java/bisq/desktop/main/dao/voting/active/ActiveVotingView.fxml create mode 100644 src/main/java/bisq/desktop/main/dao/voting/active/ActiveVotingView.java diff --git a/src/main/java/bisq/desktop/components/MenuItem.java b/src/main/java/bisq/desktop/components/MenuItem.java index ef860e6e04b..7a48cb40a27 100644 --- a/src/main/java/bisq/desktop/components/MenuItem.java +++ b/src/main/java/bisq/desktop/components/MenuItem.java @@ -19,9 +19,6 @@ import bisq.desktop.Navigation; import bisq.desktop.common.view.View; -import bisq.desktop.main.MainView; -import bisq.desktop.main.dao.DaoView; -import bisq.desktop.main.dao.proposal.ProposalView; import bisq.desktop.util.Colors; import de.jensd.fx.fontawesome.AwesomeDude; @@ -36,16 +33,28 @@ import javafx.beans.value.ChangeListener; +import java.util.ArrayList; +import java.util.List; + +import org.jetbrains.annotations.NotNull; + public class MenuItem extends AutoTooltipToggleButton { private final ChangeListener selectedPropertyChangeListener; private final ChangeListener disablePropertyChangeListener; private final Navigation navigation; private final Class viewClass; + private final List> baseNavPath; - public MenuItem(Navigation navigation, ToggleGroup toggleGroup, String title, Class viewClass, AwesomeIcon awesomeIcon) { + public MenuItem(Navigation navigation, + ToggleGroup toggleGroup, + String title, + Class viewClass, + AwesomeIcon awesomeIcon, + List> baseNavPath) { this.navigation = navigation; this.viewClass = viewClass; + this.baseNavPath = baseNavPath; setToggleGroup(toggleGroup); setText(title); @@ -86,11 +95,20 @@ public MenuItem(Navigation navigation, ToggleGroup toggleGroup, String title, Cl public void activate() { //noinspection unchecked - setOnAction((event) -> navigation.navigateTo(MainView.class, DaoView.class, ProposalView.class, viewClass)); + setOnAction((event) -> navigation.navigateTo(getNavPathClasses())); selectedProperty().addListener(selectedPropertyChangeListener); disableProperty().addListener(disablePropertyChangeListener); } + + @NotNull + private Class[] getNavPathClasses() { + List> list = new ArrayList<>(baseNavPath); + list.add(viewClass); + Class[] array = new Class[list.size()]; + list.toArray(array); + return array; + } public void deactivate() { setOnAction(null); selectedProperty().removeListener(selectedPropertyChangeListener); diff --git a/src/main/java/bisq/desktop/main/dao/DaoView.java b/src/main/java/bisq/desktop/main/dao/DaoView.java index 1ffdde19fc7..ac70e01937b 100644 --- a/src/main/java/bisq/desktop/main/dao/DaoView.java +++ b/src/main/java/bisq/desktop/main/dao/DaoView.java @@ -72,7 +72,7 @@ public void initialize() { proposalsTab.setClosable(false); votingTab.setClosable(false); //TODO - root.getTabs().addAll(proposalsTab/*, votingTab*/); + root.getTabs().addAll(proposalsTab, votingTab); if (!BisqEnvironment.isDAOActivatedAndBaseCurrencySupportingBsq() || !DevEnv.isDaoPhase2Activated()) { votingTab.setDisable(true); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalView.java index ffd087f0073..9c3a4a67a7e 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalView.java @@ -25,6 +25,7 @@ import bisq.desktop.common.view.ViewLoader; import bisq.desktop.common.view.ViewPath; import bisq.desktop.components.MenuItem; +import bisq.desktop.main.MainView; import bisq.desktop.main.dao.DaoView; import bisq.desktop.main.dao.proposal.active.ActiveProposalsView; import bisq.desktop.main.dao.proposal.closed.ClosedProposalsView; @@ -45,6 +46,9 @@ import javafx.scene.layout.AnchorPane; import javafx.scene.layout.VBox; +import java.util.Arrays; +import java.util.List; + @FxmlView public class ProposalView extends ActivatableViewAndModel { @@ -78,18 +82,19 @@ public void initialize() { }; ToggleGroup toggleGroup = new ToggleGroup(); + final List> baseNavPath = Arrays.asList(MainView.class, DaoView.class, ProposalView.class); dashboard = new MenuItem(navigation, toggleGroup, Res.get("shared.dashboard"), - ProposalDashboardView.class, AwesomeIcon.DASHBOARD); + ProposalDashboardView.class, AwesomeIcon.DASHBOARD, baseNavPath); make = new MenuItem(navigation, toggleGroup, Res.get("dao.proposal.menuItem.make"), - MakeProposalView.class, AwesomeIcon.EDIT); + MakeProposalView.class, AwesomeIcon.EDIT, baseNavPath); active = new MenuItem(navigation, toggleGroup, Res.get("dao.proposal.menuItem.active"), - ActiveProposalsView.class, AwesomeIcon.LIST_UL); + ActiveProposalsView.class, AwesomeIcon.LIST_UL, baseNavPath); myVotes = new MenuItem(navigation, toggleGroup, Res.get("dao.proposal.menuItem.myVotes"), - MyVotesView.class, AwesomeIcon.THUMBS_UP); + MyVotesView.class, AwesomeIcon.THUMBS_UP, baseNavPath); votes = new MenuItem(navigation, toggleGroup, Res.get("dao.proposal.menuItem.votes"), - VotesView.class, AwesomeIcon.THUMBS_UP_ALT); + VotesView.class, AwesomeIcon.THUMBS_UP_ALT, baseNavPath); closed = new MenuItem(navigation, toggleGroup, Res.get("dao.proposal.menuItem.closed"), - ClosedProposalsView.class, AwesomeIcon.LIST_ALT); + ClosedProposalsView.class, AwesomeIcon.LIST_ALT, baseNavPath); leftVBox.getChildren().addAll(dashboard, make, active, myVotes, votes, closed); } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java index 6db609451fe..e305584d572 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java @@ -23,8 +23,8 @@ import bisq.desktop.util.Layout; import bisq.core.dao.DaoFacade; -import bisq.core.dao.state.period.DaoPhase; import bisq.core.dao.state.ChainHeightListener; +import bisq.core.dao.state.period.DaoPhase; import bisq.core.locale.Res; import bisq.common.UserThread; @@ -64,7 +64,7 @@ public class ProposalDashboardView extends ActivatableView imple /////////////////////////////////////////////////////////////////////////////////////////// @Inject - private ProposalDashboardView(DaoFacade daoFacade) { + public ProposalDashboardView(DaoFacade daoFacade) { this.daoFacade = daoFacade; } @@ -159,5 +159,4 @@ public void onChainHeightChanged(int height) { }); } } - } diff --git a/src/main/java/bisq/desktop/main/dao/voting/VotingView.java b/src/main/java/bisq/desktop/main/dao/voting/VotingView.java index bcb3d96cf61..0eedb29faab 100644 --- a/src/main/java/bisq/desktop/main/dao/voting/VotingView.java +++ b/src/main/java/bisq/desktop/main/dao/voting/VotingView.java @@ -24,33 +24,26 @@ import bisq.desktop.common.view.View; import bisq.desktop.common.view.ViewLoader; import bisq.desktop.common.view.ViewPath; -import bisq.desktop.components.AutoTooltipToggleButton; +import bisq.desktop.components.MenuItem; import bisq.desktop.main.MainView; import bisq.desktop.main.dao.DaoView; +import bisq.desktop.main.dao.voting.active.ActiveVotingView; import bisq.desktop.main.dao.voting.dashboard.VotingDashboardView; -import bisq.desktop.main.dao.voting.history.VotingHistoryView; -import bisq.desktop.main.dao.voting.vote.VoteView; -import bisq.desktop.util.Colors; import bisq.core.locale.Res; import javax.inject.Inject; -import de.jensd.fx.fontawesome.AwesomeDude; import de.jensd.fx.fontawesome.AwesomeIcon; import javafx.fxml.FXML; -import javafx.scene.control.Label; import javafx.scene.control.ToggleGroup; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.VBox; -import javafx.scene.paint.Paint; -import javafx.geometry.Insets; -import javafx.geometry.Pos; - -import javafx.beans.value.ChangeListener; +import java.util.Arrays; +import java.util.List; @FxmlView public class VotingView extends ActivatableViewAndModel { @@ -58,7 +51,7 @@ public class VotingView extends ActivatableViewAndModel { private final ViewLoader viewLoader; private final Navigation navigation; - private MenuItem dashboard, vote, history; + private MenuItem dashboard, active; private Navigation.Listener listener; @FXML @@ -85,24 +78,25 @@ public void initialize() { }; ToggleGroup toggleGroup = new ToggleGroup(); - dashboard = new MenuItem(navigation, toggleGroup, Res.get("shared.dashboard"), VotingDashboardView.class, AwesomeIcon.DASHBOARD); - vote = new MenuItem(navigation, toggleGroup, Res.get("share.vote"), VoteView.class, AwesomeIcon.EDIT); - history = new MenuItem(navigation, toggleGroup, Res.get("share.history"), VotingHistoryView.class, AwesomeIcon.TABLE); - leftVBox.getChildren().addAll(dashboard, vote, history); + final List> baseNavPath = Arrays.asList(MainView.class, DaoView.class, VotingView.class); + dashboard = new MenuItem(navigation, toggleGroup, Res.get("shared.dashboard"), + VotingDashboardView.class, AwesomeIcon.DASHBOARD, baseNavPath); + active = new MenuItem(navigation, toggleGroup, Res.get("dao.proposal.menuItem.active"), + ActiveVotingView.class, AwesomeIcon.LIST_UL, baseNavPath); + leftVBox.getChildren().addAll(dashboard, active); } @Override protected void activate() { dashboard.activate(); - vote.activate(); - history.activate(); + active.activate(); navigation.addListener(listener); ViewPath viewPath = navigation.getCurrentPath(); if (viewPath.size() == 3 && viewPath.indexOf(VotingView.class) == 2 || viewPath.size() == 2 && viewPath.indexOf(DaoView.class) == 1) { if (selectedViewClass == null) - selectedViewClass = VotingDashboardView.class; + selectedViewClass = ActiveVotingView.class; loadView(selectedViewClass); @@ -117,8 +111,7 @@ protected void deactivate() { navigation.removeListener(listener); dashboard.deactivate(); - vote.deactivate(); - history.deactivate(); + active.deactivate(); } private void loadView(Class viewClass) { @@ -126,75 +119,10 @@ private void loadView(Class viewClass) { content.getChildren().setAll(view.getRoot()); if (view instanceof VotingDashboardView) dashboard.setSelected(true); - else if (view instanceof VoteView) vote.setSelected(true); - else if (view instanceof VotingHistoryView) history.setSelected(true); + else if (view instanceof ActiveVotingView) active.setSelected(true); } public Class getSelectedViewClass() { return selectedViewClass; } } - - -class MenuItem extends AutoTooltipToggleButton { - - private final ChangeListener selectedPropertyChangeListener; - private final ChangeListener disablePropertyChangeListener; - private final Navigation navigation; - private final Class viewClass; - - MenuItem(Navigation navigation, ToggleGroup toggleGroup, String title, Class viewClass, AwesomeIcon awesomeIcon) { - this.navigation = navigation; - this.viewClass = viewClass; - - setToggleGroup(toggleGroup); - setText(title); - setId("account-settings-item-background-active"); - setPrefHeight(40); - setPrefWidth(240); - setAlignment(Pos.CENTER_LEFT); - - Label icon = new Label(); - AwesomeDude.setIcon(icon, awesomeIcon); - icon.setTextFill(Paint.valueOf("#333")); - icon.setPadding(new Insets(0, 5, 0, 0)); - icon.setAlignment(Pos.CENTER); - icon.setMinWidth(25); - icon.setMaxWidth(25); - setGraphic(icon); - - selectedPropertyChangeListener = (ov, oldValue, newValue) -> { - if (newValue) { - setId("account-settings-item-background-selected"); - icon.setTextFill(Colors.BLUE); - } else { - setId("account-settings-item-background-active"); - icon.setTextFill(Paint.valueOf("#333")); - } - }; - - disablePropertyChangeListener = (ov, oldValue, newValue) -> { - if (newValue) { - setId("account-settings-item-background-disabled"); - icon.setTextFill(Paint.valueOf("#ccc")); - } else { - setId("account-settings-item-background-active"); - icon.setTextFill(Paint.valueOf("#333")); - } - }; - } - - public void activate() { - //noinspection unchecked - setOnAction((event) -> navigation.navigateTo(MainView.class, DaoView.class, VotingView.class, viewClass)); - selectedProperty().addListener(selectedPropertyChangeListener); - disableProperty().addListener(disablePropertyChangeListener); - } - - public void deactivate() { - setOnAction(null); - selectedProperty().removeListener(selectedPropertyChangeListener); - disableProperty().removeListener(disablePropertyChangeListener); - } -} - diff --git a/src/main/java/bisq/desktop/main/dao/voting/active/ActiveVotingView.fxml b/src/main/java/bisq/desktop/main/dao/voting/active/ActiveVotingView.fxml new file mode 100644 index 00000000000..7bca40f1184 --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/voting/active/ActiveVotingView.fxml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + diff --git a/src/main/java/bisq/desktop/main/dao/voting/active/ActiveVotingView.java b/src/main/java/bisq/desktop/main/dao/voting/active/ActiveVotingView.java new file mode 100644 index 00000000000..b806c02e096 --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/voting/active/ActiveVotingView.java @@ -0,0 +1,406 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.desktop.main.dao.voting.active; + +import bisq.desktop.common.view.FxmlView; +import bisq.desktop.components.BusyAnimation; +import bisq.desktop.components.InputTextField; +import bisq.desktop.components.TitledGroupBg; +import bisq.desktop.main.dao.proposal.BaseProposalView; +import bisq.desktop.main.dao.proposal.ProposalListItem; +import bisq.desktop.main.overlays.popups.Popup; +import bisq.desktop.util.BSFormatter; +import bisq.desktop.util.BsqFormatter; +import bisq.desktop.util.GUIUtil; +import bisq.desktop.util.Layout; + +import bisq.core.btc.exceptions.TransactionVerificationException; +import bisq.core.btc.exceptions.WalletException; +import bisq.core.btc.wallet.BsqBalanceListener; +import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.dao.DaoFacade; +import bisq.core.dao.state.period.DaoPhase; +import bisq.core.dao.voting.proposal.Proposal; +import bisq.core.locale.Res; + +import bisq.common.util.Tuple2; +import bisq.common.util.Tuple3; + +import org.bitcoinj.core.Coin; +import org.bitcoinj.core.InsufficientMoneyException; +import org.bitcoinj.core.Transaction; + +import javax.inject.Inject; + +import javafx.scene.Node; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.control.TableCell; +import javafx.scene.control.TableColumn; +import javafx.scene.control.TableView; + +import javafx.beans.property.ReadOnlyObjectWrapper; + +import javafx.util.Callback; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; + +import static bisq.desktop.util.FormBuilder.*; + +@FxmlView +public class ActiveVotingView extends BaseProposalView implements BsqBalanceListener { + + private Button removeButton, acceptButton, rejectButton, removeMyVoteButton, voteButton; + private InputTextField stakeInputTextField; + private List voteViewItems = new ArrayList<>(); + private BusyAnimation voteButtonBusyAnimation; + private Label voteButtonInfoLabel; + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Constructor, lifecycle + /////////////////////////////////////////////////////////////////////////////////////////// + + @Inject + private ActiveVotingView(DaoFacade daoFacade, + BsqWalletService bsqWalletService, + BsqFormatter bsqFormatter, + BSFormatter btcFormatter) { + + super(daoFacade, bsqWalletService, bsqFormatter, btcFormatter); + } + + @Override + public void initialize() { + super.initialize(); + + createProposalsTableView(); + createVoteView(); + createProposalDisplay(); + } + + @Override + protected void activate() { + super.activate(); + + daoFacade.getActiveOrMyUnconfirmedProposals().addListener(proposalListChangeListener); + bsqWalletService.addBsqBalanceListener(this); + + onUpdateBalances(bsqWalletService.getAvailableBalance(), + bsqWalletService.getPendingBalance(), + bsqWalletService.getLockedForVotingBalance(), + bsqWalletService.getLockedInBondsBalance()); + + if (voteButton != null) { + voteButton.setOnAction(e -> { + // TODO verify stake + Coin stake = bsqFormatter.parseToCoin(stakeInputTextField.getText()); + final Coin blindVoteFee = daoFacade.getBlindVoteFeeForCycle(); + Transaction dummyTx = null; + try { + // We create a dummy tx to get the mining blindVoteFee for confirmation popup + dummyTx = daoFacade.getDummyBlindVoteTx(stake, blindVoteFee); + } catch (InsufficientMoneyException | WalletException | TransactionVerificationException exception) { + new Popup<>().warning(exception.toString()).show(); + } + + if (dummyTx != null) { + Coin miningFee = dummyTx.getFee(); + int txSize = dummyTx.bitcoinSerialize().length; + GUIUtil.showBsqFeeInfoPopup(blindVoteFee, miningFee, txSize, bsqFormatter, btcFormatter, + Res.get("dao.blindVote"), () -> publishBlindVote(stake)); + } + }); + } + } + + private void publishBlindVote(Coin stake) { + voteButtonBusyAnimation.play(); + voteButtonInfoLabel.setText(Res.get("dao.blindVote.startPublishing")); + daoFacade.publishBlindVote(stake, + () -> { + voteButtonBusyAnimation.stop(); + voteButtonInfoLabel.setText(""); + new Popup().feedback(Res.get("dao.blindVote.success")) + .show(); + }, exception -> { + voteButtonBusyAnimation.stop(); + voteButtonInfoLabel.setText(""); + new Popup<>().warning(exception.toString()).show(); + }); + } + + @Override + protected void deactivate() { + super.deactivate(); + + daoFacade.getActiveOrMyUnconfirmedProposals().removeListener(proposalListChangeListener); + bsqWalletService.removeBsqBalanceListener(this); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Create views + /////////////////////////////////////////////////////////////////////////////////////////// + + + private void createVoteView() { + TitledGroupBg titledGroupBg = addTitledGroupBg(root, ++gridRow, 1, Res.get("dao.proposal.votes.header"), + Layout.GROUP_DISTANCE - 20); + final Tuple2 tuple2 = addLabelInputTextField(root, gridRow, + Res.getWithCol("dao.proposal.myVote.stake"), Layout + .FIRST_ROW_AND_GROUP_DISTANCE - 20); + stakeInputTextField = tuple2.second; + Tuple3 tuple = addButtonBusyAnimationLabelAfterGroup(root, ++gridRow, Res.get("dao.proposal.myVote.button")); + voteButton = tuple.first; + voteButtonBusyAnimation = tuple.second; + voteButtonInfoLabel = tuple.third; + + voteViewItems.add(titledGroupBg); + voteViewItems.add(tuple2.first); + voteViewItems.add(stakeInputTextField); + voteViewItems.add(voteButton); + + changeVoteViewItemsVisibility(false); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Handlers + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public void onUpdateBalances(Coin confirmedBalance, + Coin pendingBalance, + Coin lockedForVotingBalance, + Coin lockedInBondsBalance) { + stakeInputTextField.setPromptText(Res.get("dao.proposal.myVote.stake.prompt", + bsqFormatter.formatCoinWithCode(confirmedBalance))); + } + + protected void onSelectProposal(ProposalListItem item) { + super.onSelectProposal(item); + if (item != null) { + if (removeButton != null) { + removeButton.setManaged(false); + removeButton.setVisible(false); + removeButton = null; + } + if (acceptButton != null) { + acceptButton.setManaged(false); + acceptButton.setVisible(false); + acceptButton = null; + } + if (rejectButton != null) { + rejectButton.setManaged(false); + rejectButton.setVisible(false); + rejectButton = null; + } + if (removeMyVoteButton != null) { + removeMyVoteButton.setManaged(false); + removeMyVoteButton.setVisible(false); + removeMyVoteButton = null; + } + + onPhaseChanged(daoFacade.phaseProperty().get()); + } + } + + private void onAccept() { + //TODO + // daoFacade.setVote(selectedProposalListItem.getProposal(), new BooleanVote(true)); + updateStateAfterVote(); + } + + + private void onReject() { + //TODO + // daoFacade.setVote(selectedProposalListItem.getProposal(), new BooleanVote(false)); + updateStateAfterVote(); + } + + private void onCancelVote() { + //TODO + // daoFacade.setVote(selectedProposalListItem.getProposal(), null); + updateStateAfterVote(); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // ChainHeightListener + /////////////////////////////////////////////////////////////////////////////////////////// + + + @Override + protected void onPhaseChanged(DaoPhase.Phase phase) { + super.onPhaseChanged(phase); + + changeVoteViewItemsVisibility(phase == DaoPhase.Phase.BLIND_VOTE); + + if (removeButton != null) { + removeButton.setManaged(false); + removeButton.setVisible(false); + removeButton = null; + } + if (selectedProposalListItem != null && proposalDisplay != null) { + final Proposal proposal = selectedProposalListItem.getProposal(); + switch (phase) { + case PROPOSAL: + if (daoFacade.isMyProposal(proposal)) { + if (removeButton == null) { + removeButton = addButtonAfterGroup(detailsGridPane, proposalDisplay.incrementAndGetGridRow(), Res.get("dao.proposal.active.remove")); + removeButton.setOnAction(event -> onRemove()); + } else { + removeButton.setManaged(true); + removeButton.setVisible(true); + } + } + break; + case BREAK1: + break; + case BLIND_VOTE: + if (acceptButton == null) { + Tuple3 tuple = add3ButtonsAfterGroup(detailsGridPane, proposalDisplay + .incrementAndGetGridRow(), + Res.get("dao.proposal.myVote.accept"), + Res.get("dao.proposal.myVote.reject"), + Res.get("dao.proposal.myVote.removeMyVote")); + acceptButton = tuple.first; + acceptButton.setDefaultButton(false); + rejectButton = tuple.second; + removeMyVoteButton = tuple.third; + acceptButton.setOnAction(event -> onAccept()); + rejectButton.setOnAction(event -> onReject()); + removeMyVoteButton.setOnAction(event -> onCancelVote()); + } else { + //TODO prob. not possible code path + acceptButton.setManaged(true); + acceptButton.setVisible(true); + rejectButton.setManaged(true); + rejectButton.setVisible(true); + removeMyVoteButton.setManaged(true); + removeMyVoteButton.setVisible(true); + } + break; + case BREAK2: + break; + case VOTE_REVEAL: + break; + case BREAK3: + break; + case RESULT: + break; + case BREAK4: + break; + case UNDEFINED: + default: + log.error("Undefined phase: " + phase); + break; + } + } + } + + /////////////////////////////////////////////////////////////////////////////////////////// + // Protected + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + protected List getProposalList() { + return daoFacade.getActiveOrMyUnconfirmedProposals(); + } + + private void updateStateAfterVote() { + hideProposalDisplay(); + proposalTableView.getSelectionModel().clearSelection(); + } + + private void changeVoteViewItemsVisibility(boolean value) { + voteViewItems.forEach(node -> { + node.setVisible(value); + node.setManaged(value); + }); + } + + private void onRemove() { + final Proposal proposal = selectedProposalListItem.getProposal(); + if (daoFacade.removeMyProposal(proposal)) { + hideProposalDisplay(); + } else { + new Popup<>().warning(Res.get("dao.proposal.active.remove.failed")).show(); + } + proposalTableView.getSelectionModel().clearSelection(); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // TableColumns + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + protected void createProposalColumns(TableView tableView) { + super.createProposalColumns(tableView); + createConfidenceColumn(tableView); + + TableColumn actionColumn = new TableColumn<>(); + actionColumn.setMinWidth(130); + actionColumn.setMaxWidth(actionColumn.getMinWidth()); + + actionColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + + actionColumn.setCellFactory(new Callback, + TableCell>() { + + @Override + public TableCell call(TableColumn column) { + return new TableCell() { + Node node; + + @Override + public void updateItem(final ProposalListItem item, boolean empty) { + super.updateItem(item, empty); + + if (item != null && !empty) { + if (node == null) { + node = item.getActionNode(); + setGraphic(node); + item.setOnRemoveHandler(() -> { + ActiveVotingView.this.selectedProposalListItem = item; + ActiveVotingView.this.onRemove(); + }); + item.applyState(currentPhase); + } + } else { + setGraphic(null); + if (node != null) { + if (node instanceof Button) + ((Button) node).setOnAction(null); + node = null; + } + } + } + }; + } + }); + actionColumn.setComparator(Comparator.comparing(ProposalListItem::getConfirmations)); + tableView.getColumns().add(actionColumn); + } +} + diff --git a/src/main/java/bisq/desktop/main/dao/voting/dashboard/VotingDashboardView.java b/src/main/java/bisq/desktop/main/dao/voting/dashboard/VotingDashboardView.java index 034979eaa23..111f20ff386 100644 --- a/src/main/java/bisq/desktop/main/dao/voting/dashboard/VotingDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/voting/dashboard/VotingDashboardView.java @@ -17,15 +17,15 @@ package bisq.desktop.main.dao.voting.dashboard; -import bisq.desktop.common.view.ActivatableView; import bisq.desktop.common.view.FxmlView; +import bisq.desktop.main.dao.proposal.dashboard.ProposalDashboardView; -import javax.inject.Inject; +import bisq.core.dao.DaoFacade; -import javafx.scene.layout.GridPane; +import javax.inject.Inject; @FxmlView -public class VotingDashboardView extends ActivatableView { +public class VotingDashboardView extends ProposalDashboardView { /////////////////////////////////////////////////////////////////////////////////////////// @@ -33,19 +33,23 @@ public class VotingDashboardView extends ActivatableView { /////////////////////////////////////////////////////////////////////////////////////////// @Inject - private VotingDashboardView() { + private VotingDashboardView(DaoFacade daoFacade) { + super(daoFacade); } @Override public void initialize() { + super.initialize(); } @Override protected void activate() { + super.activate(); } @Override protected void deactivate() { + super.deactivate(); } } From b274a4a3cd66ec9322878819ca27c66848f24d2c Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Mon, 30 Apr 2018 18:34:04 -0500 Subject: [PATCH 085/197] Add superclasses for ProposalListItem and ActiveProposalView --- .../bisq/desktop/main/dao/ActiveView.java | 399 ++++++++++++++++++ .../dao/{proposal => }/BaseProposalView.java | 109 ++--- .../java/bisq/desktop/main/dao/ListItem.java | 268 ++++++++++++ .../main/dao/proposal/ProposalListItem.java | 241 +---------- .../proposal/active/ActiveProposalsView.java | 350 +-------------- .../proposal/closed/ClosedProposalsView.java | 9 +- .../dao/proposal/myvotes/MyVotesView.java | 26 +- .../dao/voting/active/ActiveVotingView.java | 350 +-------------- 8 files changed, 773 insertions(+), 979 deletions(-) create mode 100644 src/main/java/bisq/desktop/main/dao/ActiveView.java rename src/main/java/bisq/desktop/main/dao/{proposal => }/BaseProposalView.java (77%) create mode 100644 src/main/java/bisq/desktop/main/dao/ListItem.java diff --git a/src/main/java/bisq/desktop/main/dao/ActiveView.java b/src/main/java/bisq/desktop/main/dao/ActiveView.java new file mode 100644 index 00000000000..8869db46b7f --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/ActiveView.java @@ -0,0 +1,399 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.desktop.main.dao; + +import bisq.desktop.common.view.FxmlView; +import bisq.desktop.components.BusyAnimation; +import bisq.desktop.components.InputTextField; +import bisq.desktop.components.TitledGroupBg; +import bisq.desktop.main.overlays.popups.Popup; +import bisq.desktop.util.BSFormatter; +import bisq.desktop.util.BsqFormatter; +import bisq.desktop.util.GUIUtil; +import bisq.desktop.util.Layout; + +import bisq.core.btc.exceptions.TransactionVerificationException; +import bisq.core.btc.exceptions.WalletException; +import bisq.core.btc.wallet.BsqBalanceListener; +import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.dao.DaoFacade; +import bisq.core.dao.state.period.DaoPhase; +import bisq.core.dao.voting.proposal.Proposal; +import bisq.core.locale.Res; + +import bisq.common.util.Tuple2; +import bisq.common.util.Tuple3; + +import org.bitcoinj.core.Coin; +import org.bitcoinj.core.InsufficientMoneyException; +import org.bitcoinj.core.Transaction; + +import javax.inject.Inject; + +import javafx.scene.Node; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.control.TableCell; +import javafx.scene.control.TableColumn; +import javafx.scene.control.TableView; + +import javafx.beans.property.ReadOnlyObjectWrapper; + +import javafx.util.Callback; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; + +import static bisq.desktop.util.FormBuilder.*; + +@FxmlView +public abstract class ActiveView extends BaseProposalView implements BsqBalanceListener { + + protected Button removeButton, acceptButton, rejectButton, removeMyVoteButton, voteButton; + protected InputTextField stakeInputTextField; + protected List voteViewItems = new ArrayList<>(); + protected BusyAnimation voteButtonBusyAnimation; + protected Label voteButtonInfoLabel; + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Constructor, lifecycle + /////////////////////////////////////////////////////////////////////////////////////////// + + @Inject + protected ActiveView(DaoFacade daoFacade, + BsqWalletService bsqWalletService, + BsqFormatter bsqFormatter, + BSFormatter btcFormatter) { + + super(daoFacade, bsqWalletService, bsqFormatter, btcFormatter); + } + + @Override + public void initialize() { + super.initialize(); + + createProposalsTableView(); + createVoteView(); + createProposalDisplay(); + } + + @Override + protected void activate() { + super.activate(); + + daoFacade.getActiveOrMyUnconfirmedProposals().addListener(proposalListChangeListener); + bsqWalletService.addBsqBalanceListener(this); + + onUpdateBalances(bsqWalletService.getAvailableBalance(), + bsqWalletService.getPendingBalance(), + bsqWalletService.getLockedForVotingBalance(), + bsqWalletService.getLockedInBondsBalance()); + + if (voteButton != null) { + voteButton.setOnAction(e -> { + // TODO verify stake + Coin stake = bsqFormatter.parseToCoin(stakeInputTextField.getText()); + final Coin blindVoteFee = daoFacade.getBlindVoteFeeForCycle(); + Transaction dummyTx = null; + try { + // We create a dummy tx to get the mining blindVoteFee for confirmation popup + dummyTx = daoFacade.getDummyBlindVoteTx(stake, blindVoteFee); + } catch (InsufficientMoneyException | WalletException | TransactionVerificationException exception) { + new Popup<>().warning(exception.toString()).show(); + } + + if (dummyTx != null) { + Coin miningFee = dummyTx.getFee(); + int txSize = dummyTx.bitcoinSerialize().length; + GUIUtil.showBsqFeeInfoPopup(blindVoteFee, miningFee, txSize, bsqFormatter, btcFormatter, + Res.get("dao.blindVote"), () -> publishBlindVote(stake)); + } + }); + } + } + + protected void publishBlindVote(Coin stake) { + voteButtonBusyAnimation.play(); + voteButtonInfoLabel.setText(Res.get("dao.blindVote.startPublishing")); + daoFacade.publishBlindVote(stake, + () -> { + voteButtonBusyAnimation.stop(); + voteButtonInfoLabel.setText(""); + new Popup().feedback(Res.get("dao.blindVote.success")) + .show(); + }, exception -> { + voteButtonBusyAnimation.stop(); + voteButtonInfoLabel.setText(""); + new Popup<>().warning(exception.toString()).show(); + }); + } + + @Override + protected void deactivate() { + super.deactivate(); + + daoFacade.getActiveOrMyUnconfirmedProposals().removeListener(proposalListChangeListener); + bsqWalletService.removeBsqBalanceListener(this); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Create views + /////////////////////////////////////////////////////////////////////////////////////////// + + + protected void createVoteView() { + TitledGroupBg titledGroupBg = addTitledGroupBg(root, ++gridRow, 1, Res.get("dao.proposal.votes.header"), + Layout.GROUP_DISTANCE - 20); + final Tuple2 tuple2 = addLabelInputTextField(root, gridRow, + Res.getWithCol("dao.proposal.myVote.stake"), Layout + .FIRST_ROW_AND_GROUP_DISTANCE - 20); + stakeInputTextField = tuple2.second; + Tuple3 tuple = addButtonBusyAnimationLabelAfterGroup(root, ++gridRow, Res.get("dao.proposal.myVote.button")); + voteButton = tuple.first; + voteButtonBusyAnimation = tuple.second; + voteButtonInfoLabel = tuple.third; + + voteViewItems.add(titledGroupBg); + voteViewItems.add(tuple2.first); + voteViewItems.add(stakeInputTextField); + voteViewItems.add(voteButton); + + changeVoteViewItemsVisibility(false); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Handlers + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public void onUpdateBalances(Coin confirmedBalance, + Coin pendingBalance, + Coin lockedForVotingBalance, + Coin lockedInBondsBalance) { + stakeInputTextField.setPromptText(Res.get("dao.proposal.myVote.stake.prompt", + bsqFormatter.formatCoinWithCode(confirmedBalance))); + } + + protected void onSelectProposal(ListItem item) { + super.onSelectProposal(item); + if (item != null) { + if (removeButton != null) { + removeButton.setManaged(false); + removeButton.setVisible(false); + removeButton = null; + } + if (acceptButton != null) { + acceptButton.setManaged(false); + acceptButton.setVisible(false); + acceptButton = null; + } + if (rejectButton != null) { + rejectButton.setManaged(false); + rejectButton.setVisible(false); + rejectButton = null; + } + if (removeMyVoteButton != null) { + removeMyVoteButton.setManaged(false); + removeMyVoteButton.setVisible(false); + removeMyVoteButton = null; + } + + onPhaseChanged(daoFacade.phaseProperty().get()); + } + } + + protected void onAccept() { + //TODO + // daoFacade.setVote(selectedProposalListItem.getProposal(), new BooleanVote(true)); + updateStateAfterVote(); + } + + + protected void onReject() { + //TODO + // daoFacade.setVote(selectedProposalListItem.getProposal(), new BooleanVote(false)); + updateStateAfterVote(); + } + + protected void onCancelVote() { + //TODO + // daoFacade.setVote(selectedProposalListItem.getProposal(), null); + updateStateAfterVote(); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // ChainHeightListener + /////////////////////////////////////////////////////////////////////////////////////////// + + + @Override + protected void onPhaseChanged(DaoPhase.Phase phase) { + super.onPhaseChanged(phase); + + changeVoteViewItemsVisibility(phase == DaoPhase.Phase.BLIND_VOTE); + + if (removeButton != null) { + removeButton.setManaged(false); + removeButton.setVisible(false); + removeButton = null; + } + if (selectedProposalListItem != null && proposalDisplay != null) { + final Proposal proposal = selectedProposalListItem.getProposal(); + switch (phase) { + case PROPOSAL: + if (daoFacade.isMyProposal(proposal)) { + if (removeButton == null) { + removeButton = addButtonAfterGroup(detailsGridPane, proposalDisplay.incrementAndGetGridRow(), Res.get("dao.proposal.active.remove")); + removeButton.setOnAction(event -> onRemove()); + } else { + removeButton.setManaged(true); + removeButton.setVisible(true); + } + } + break; + case BREAK1: + break; + case BLIND_VOTE: + if (acceptButton == null) { + Tuple3 tuple = add3ButtonsAfterGroup(detailsGridPane, proposalDisplay + .incrementAndGetGridRow(), + Res.get("dao.proposal.myVote.accept"), + Res.get("dao.proposal.myVote.reject"), + Res.get("dao.proposal.myVote.removeMyVote")); + acceptButton = tuple.first; + acceptButton.setDefaultButton(false); + rejectButton = tuple.second; + removeMyVoteButton = tuple.third; + acceptButton.setOnAction(event -> onAccept()); + rejectButton.setOnAction(event -> onReject()); + removeMyVoteButton.setOnAction(event -> onCancelVote()); + } else { + //TODO prob. not possible code path + acceptButton.setManaged(true); + acceptButton.setVisible(true); + rejectButton.setManaged(true); + rejectButton.setVisible(true); + removeMyVoteButton.setManaged(true); + removeMyVoteButton.setVisible(true); + } + break; + case BREAK2: + break; + case VOTE_REVEAL: + break; + case BREAK3: + break; + case RESULT: + break; + case BREAK4: + break; + case UNDEFINED: + default: + log.error("Undefined phase: " + phase); + break; + } + } + } + + /////////////////////////////////////////////////////////////////////////////////////////// + // Protected + /////////////////////////////////////////////////////////////////////////////////////////// + + protected void updateStateAfterVote() { + hideProposalDisplay(); + proposalTableView.getSelectionModel().clearSelection(); + } + + protected void changeVoteViewItemsVisibility(boolean value) { + voteViewItems.forEach(node -> { + node.setVisible(value); + node.setManaged(value); + }); + } + + protected void onRemove() { + final Proposal proposal = selectedProposalListItem.getProposal(); + if (daoFacade.removeMyProposal(proposal)) { + hideProposalDisplay(); + } else { + new Popup<>().warning(Res.get("dao.proposal.active.remove.failed")).show(); + } + proposalTableView.getSelectionModel().clearSelection(); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // TableColumns + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + protected void createProposalColumns(TableView tableView) { + super.createProposalColumns(tableView); + createConfidenceColumn(tableView); + + TableColumn actionColumn = new TableColumn<>(); + actionColumn.setMinWidth(130); + actionColumn.setMaxWidth(actionColumn.getMinWidth()); + + actionColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + + actionColumn.setCellFactory(new Callback, + TableCell>() { + + @Override + public TableCell call(TableColumn column) { + return new TableCell() { + Node node; + + @Override + public void updateItem(final ListItem item, boolean empty) { + super.updateItem(item, empty); + + if (item != null && !empty) { + if (node == null) { + node = item.getActionNode(); + setGraphic(node); + item.setOnRemoveHandler(() -> { + ActiveView.this.selectedProposalListItem = item; + ActiveView.this.onRemove(); + }); + item.applyState(currentPhase); + } + } else { + setGraphic(null); + if (node != null) { + if (node instanceof Button) + ((Button) node).setOnAction(null); + node = null; + } + } + } + }; + } + }); + actionColumn.setComparator(Comparator.comparing(ListItem::getConfirmations)); + tableView.getColumns().add(actionColumn); + } +} + diff --git a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/BaseProposalView.java similarity index 77% rename from src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java rename to src/main/java/bisq/desktop/main/dao/BaseProposalView.java index fc78da033ec..2f187d02a88 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/BaseProposalView.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.desktop.main.dao.proposal; +package bisq.desktop.main.dao; import bisq.desktop.common.view.ActivatableView; import bisq.desktop.common.view.FxmlView; @@ -23,6 +23,8 @@ import bisq.desktop.components.AutoTooltipTableColumn; import bisq.desktop.components.HyperlinkWithIcon; import bisq.desktop.components.TableGroupHeadline; +import bisq.desktop.main.dao.proposal.ProposalDetailsWindow; +import bisq.desktop.main.dao.proposal.ProposalDisplay; import bisq.desktop.util.BSFormatter; import bisq.desktop.util.BsqFormatter; @@ -71,15 +73,15 @@ public abstract class BaseProposalView extends ActivatableView { protected final BsqFormatter bsqFormatter; protected final BSFormatter btcFormatter; - protected final ObservableList proposalListItems = FXCollections.observableArrayList(); - protected final SortedList sortedList = new SortedList<>(proposalListItems); + protected final ObservableList proposalListItems = FXCollections.observableArrayList(); + protected final SortedList sortedList = new SortedList<>(proposalListItems); protected final List proposalViewItems = new ArrayList<>(); - protected TableView proposalTableView; + protected TableView proposalTableView; protected Subscription selectedProposalSubscription; protected ProposalDisplay proposalDisplay; protected int gridRow = 0; protected GridPane detailsGridPane, gridPane; - protected ProposalListItem selectedProposalListItem; + protected ListItem selectedProposalListItem; protected ListChangeListener proposalListChangeListener; protected ChangeListener phaseChangeListener; protected DaoPhase.Phase currentPhase; @@ -136,7 +138,7 @@ protected void deactivate() { sortedList.comparatorProperty().unbind(); - proposalListItems.forEach(ProposalListItem::cleanup); + proposalListItems.forEach(ListItem::cleanup); proposalTableView.getSelectionModel().clearSelection(); selectedProposalListItem = null; } @@ -205,7 +207,7 @@ protected void showProposalDisplay(Proposal proposal) { // Handlers /////////////////////////////////////////////////////////////////////////////////////////// - protected void onSelectProposal(ProposalListItem item) { + protected void onSelectProposal(ListItem item) { selectedProposalListItem = item; if (selectedProposalListItem != null) showProposalDisplay(selectedProposalListItem.getProposal()); @@ -229,19 +231,26 @@ protected void onPhaseChanged(DaoPhase.Phase phase) { protected void updateProposalListItems() { List list = getProposalList(); - proposalListItems.forEach(ProposalListItem::cleanup); + proposalListItems.forEach(ListItem::cleanup); proposalListItems.clear(); proposalListItems.setAll(list.stream() - .map(proposal -> new ProposalListItem(proposal, - daoFacade, - bsqWalletService, - bsqFormatter)) + .map(proposal -> getListItem(proposal)) .collect(Collectors.toSet())); if (list.isEmpty()) hideProposalDisplay(); } + protected abstract ListItem getListItem(Proposal proposal); + + /* @NotNull + private ListItem getListItem(Proposal proposal) { + return new ListItem(proposal, + daoFacade, + bsqWalletService, + bsqFormatter); + }*/ + protected void changeProposalViewItemsVisibility(boolean value) { proposalViewItems.forEach(node -> { node.setVisible(value); @@ -254,8 +263,8 @@ protected void changeProposalViewItemsVisibility(boolean value) { // TableColumns /////////////////////////////////////////////////////////////////////////////////////////// - protected void createProposalColumns(TableView tableView) { - TableColumn dateColumn = new AutoTooltipTableColumn(Res.get("shared.dateTime")) { + protected void createProposalColumns(TableView tableView) { + TableColumn dateColumn = new AutoTooltipTableColumn(Res.get("shared.dateTime")) { { setMinWidth(190); setMaxWidth(190); @@ -263,14 +272,14 @@ protected void createProposalColumns(TableView tableView) { }; dateColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); dateColumn.setCellFactory( - new Callback, TableCell>() { + new Callback, TableCell>() { @Override - public TableCell call( - TableColumn column) { - return new TableCell() { + public TableCell call( + TableColumn column) { + return new TableCell() { @Override - public void updateItem(final ProposalListItem item, boolean empty) { + public void updateItem(final ListItem item, boolean empty) { super.updateItem(item, empty); if (item != null) setText(bsqFormatter.formatDateTime(item.getProposal().getCreationDate())); @@ -285,17 +294,17 @@ public void updateItem(final ProposalListItem item, boolean empty) { tableView.getColumns().add(dateColumn); tableView.getSortOrder().add(dateColumn); - TableColumn nameColumn = new AutoTooltipTableColumn<>(Res.get("shared.name")); + TableColumn nameColumn = new AutoTooltipTableColumn<>(Res.get("shared.name")); nameColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); nameColumn.setCellFactory( - new Callback, TableCell>() { + new Callback, TableCell>() { @Override - public TableCell call( - TableColumn column) { - return new TableCell() { + public TableCell call( + TableColumn column) { + return new TableCell() { @Override - public void updateItem(final ProposalListItem item, boolean empty) { + public void updateItem(final ListItem item, boolean empty) { super.updateItem(item, empty); if (item != null) setText(item.getProposal().getName()); @@ -308,18 +317,18 @@ public void updateItem(final ProposalListItem item, boolean empty) { nameColumn.setComparator(Comparator.comparing(o2 -> o2.getProposal().getName())); tableView.getColumns().add(nameColumn); - TableColumn titleColumn = new AutoTooltipTableColumn<>(Res.get("dao.proposal.title")); + TableColumn titleColumn = new AutoTooltipTableColumn<>(Res.get("dao.proposal.title")); titleColumn.setPrefWidth(100); titleColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); titleColumn.setCellFactory( - new Callback, TableCell>() { + new Callback, TableCell>() { @Override - public TableCell call( - TableColumn column) { - return new TableCell() { + public TableCell call( + TableColumn column) { + return new TableCell() { @Override - public void updateItem(final ProposalListItem item, boolean empty) { + public void updateItem(final ListItem item, boolean empty) { super.updateItem(item, empty); if (item != null) setText(item.getProposal().getTitle()); @@ -332,20 +341,20 @@ public void updateItem(final ProposalListItem item, boolean empty) { titleColumn.setComparator(Comparator.comparing(o2 -> o2.getProposal().getTitle())); tableView.getColumns().add(titleColumn); - TableColumn uidColumn = new AutoTooltipTableColumn<>(Res.get("shared.id")); + TableColumn uidColumn = new AutoTooltipTableColumn<>(Res.get("shared.id")); uidColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); uidColumn.setCellFactory( - new Callback, TableCell>() { + new Callback, TableCell>() { @Override - public TableCell call(TableColumn column) { - return new TableCell() { + public TableCell call(TableColumn column) { + return new TableCell() { private HyperlinkWithIcon field; @Override - public void updateItem(final ProposalListItem item, boolean empty) { + public void updateItem(final ListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { final Proposal proposal = item.getProposal(); @@ -368,23 +377,23 @@ public void updateItem(final ProposalListItem item, boolean empty) { tableView.getColumns().add(uidColumn); } - protected void createConfidenceColumn(TableView tableView) { - TableColumn confidenceColumn = new TableColumn<>(Res.get("shared.confirmations")); + protected void createConfidenceColumn(TableView tableView) { + TableColumn confidenceColumn = new TableColumn<>(Res.get("shared.confirmations")); confidenceColumn.setMinWidth(130); confidenceColumn.setMaxWidth(confidenceColumn.getMinWidth()); confidenceColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - confidenceColumn.setCellFactory(new Callback, - TableCell>() { + confidenceColumn.setCellFactory(new Callback, + TableCell>() { @Override - public TableCell call(TableColumn column) { - return new TableCell() { + public TableCell call(TableColumn column) { + return new TableCell() { @Override - public void updateItem(final ProposalListItem item, boolean empty) { + public void updateItem(final ListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { @@ -396,7 +405,7 @@ public void updateItem(final ProposalListItem item, boolean empty) { }; } }); - confidenceColumn.setComparator(Comparator.comparing(ProposalListItem::getConfirmations)); + confidenceColumn.setComparator(Comparator.comparing(ListItem::getConfirmations)); tableView.getColumns().add(confidenceColumn); } } diff --git a/src/main/java/bisq/desktop/main/dao/ListItem.java b/src/main/java/bisq/desktop/main/dao/ListItem.java new file mode 100644 index 00000000000..966530160a6 --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/ListItem.java @@ -0,0 +1,268 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.desktop.main.dao; + +import bisq.desktop.components.AutoTooltipButton; +import bisq.desktop.components.indicator.TxConfidenceIndicator; +import bisq.desktop.util.BsqFormatter; + +import bisq.core.btc.listeners.TxConfidenceListener; +import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.dao.DaoFacade; +import bisq.core.dao.state.BlockListener; +import bisq.core.dao.state.blockchain.Block; +import bisq.core.dao.state.blockchain.Tx; +import bisq.core.dao.state.period.DaoPhase; +import bisq.core.dao.voting.proposal.Proposal; +import bisq.core.locale.Res; + +import org.bitcoinj.core.Transaction; +import org.bitcoinj.core.TransactionConfidence; + +import javafx.scene.Node; +import javafx.scene.control.Tooltip; +import javafx.scene.image.ImageView; + +import javafx.beans.value.ChangeListener; + +import java.util.Optional; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import lombok.extern.slf4j.Slf4j; + +@ToString +@Slf4j +@EqualsAndHashCode +public abstract class ListItem implements BlockListener { + @Getter + private final DaoFacade daoFacade; + private final BsqWalletService bsqWalletService; + private final BsqFormatter bsqFormatter; + + private ChangeListener chainHeightListener; + @Getter + private TxConfidenceIndicator txConfidenceIndicator; + @Getter + private Integer confirmations = 0; + + private TxConfidenceListener txConfidenceListener; + private Tooltip tooltip = new Tooltip(Res.get("confidence.unknown")); + private Transaction walletTransaction; + private ChangeListener phaseChangeListener; + private AutoTooltipButton actionButton; + private ImageView actionButtonIconView; + @Setter + private Runnable onRemoveHandler; + private Node actionNode; + + protected ListItem(DaoFacade daoFacade, + BsqWalletService bsqWalletService, + BsqFormatter bsqFormatter) { + this.daoFacade = daoFacade; + this.bsqWalletService = bsqWalletService; + this.bsqFormatter = bsqFormatter; + } + + protected abstract Proposal getProposal(); + + protected void init() { + txConfidenceIndicator = new TxConfidenceIndicator(); + txConfidenceIndicator.setId("funds-confidence"); + + txConfidenceIndicator.setProgress(-1); + txConfidenceIndicator.setPrefSize(24, 24); + txConfidenceIndicator.setTooltip(tooltip); + + actionButton = new AutoTooltipButton(); + actionButton.setMinWidth(70); + actionButtonIconView = new ImageView(); + + chainHeightListener = (observable, oldValue, newValue) -> setupConfidence(); + bsqWalletService.getChainHeightProperty().addListener(chainHeightListener); + setupConfidence(); + + daoFacade.addBlockListener(this); + + phaseChangeListener = (observable, oldValue, newValue) -> { + applyState(newValue); + }; + + daoFacade.phaseProperty().addListener(phaseChangeListener); + } + + public void applyState(DaoPhase.Phase phase) { + if (phase != null) { + actionButton.setText(""); + actionButton.setVisible(false); + actionButton.setOnAction(null); + switch (phase) { + case UNDEFINED: + log.error("invalid state UNDEFINED"); + break; + case PROPOSAL: + if (daoFacade.isMyProposal(getProposal())) { + actionButtonIconView.setVisible(actionButton.isVisible()); + actionButton.setText(Res.get("shared.remove")); + actionButton.setGraphic(actionButtonIconView); + actionButtonIconView.setId("image-remove"); + actionButton.setOnAction(e -> { + if (onRemoveHandler != null) + onRemoveHandler.run(); + }); + actionNode = actionButton; + } + break; + case BREAK1: + break; + case BLIND_VOTE: + actionNode = actionButtonIconView; + actionButton.setVisible(false); + + //TODO + /* if (vote != null) { + actionButtonIconView.setVisible(true); + if (vote instanceof BooleanVote) { + if (((BooleanVote) vote).isAccepted()) { + actionButtonIconView.setId("accepted"); + } else { + actionButtonIconView.setId("rejected"); + } + } else { + //TODO + } + } else { + actionButtonIconView.setVisible(false); + }*/ + + break; + case BREAK2: + break; + case VOTE_REVEAL: + break; + case BREAK3: + break; + case RESULT: + break; + case BREAK4: + break; + default: + log.error("invalid state " + phase); + } + actionButton.setManaged(actionButton.isVisible()); + + // Don't set managed as otherwise the update does not work (not sure why but probably table + // cell item issue) + //actionButtonIconView.setManaged(actionButtonIconView.isVisible()); + } + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Listener + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public void onBlockAdded(Block block) { + //TODO do we want that here??? + setupConfidence(); + } + + // TODO reuse from other item + private void setupConfidence() { + final String txId = getProposal().getTxId(); + Optional optionalTx = daoFacade.getTx(txId); + if (optionalTx.isPresent()) { + Tx tx = optionalTx.get(); + // We cache the walletTransaction once found + if (walletTransaction == null) { + final Optional transactionOptional = bsqWalletService.isWalletTransaction(txId); + transactionOptional.ifPresent(transaction -> walletTransaction = transaction); + } + + if (walletTransaction != null) { + // It is our tx so we get confidence updates + if (txConfidenceListener == null) { + txConfidenceListener = new TxConfidenceListener(txId) { + @Override + public void onTransactionConfidenceChanged(TransactionConfidence confidence) { + updateConfidence(confidence.getConfidenceType(), confidence.getDepthInBlocks(), confidence.numBroadcastPeers()); + } + }; + bsqWalletService.addTxConfidenceListener(txConfidenceListener); + } + } else { + // tx from other users, we dont get confidence updates but as we have the bsq tx we can calculate it + // we get setupConfidence called at each new block from above listener so no need to register a new listener + int depth = bsqWalletService.getChainHeightProperty().get() - tx.getBlockHeight() + 1; + if (depth > 0) + updateConfidence(TransactionConfidence.ConfidenceType.BUILDING, depth, -1); + } + + final TransactionConfidence confidence = bsqWalletService.getConfidenceForTxId(txId); + if (confidence != null) + updateConfidence(confidence, confidence.getDepthInBlocks()); + } + } + + private void updateConfidence(TransactionConfidence confidence, int depthInBlocks) { + if (confidence != null) { + updateConfidence(confidence.getConfidenceType(), confidence.getDepthInBlocks(), confidence.numBroadcastPeers()); + confirmations = depthInBlocks; + } + } + + public void cleanup() { + daoFacade.removeBlockListener(this); + bsqWalletService.getChainHeightProperty().removeListener(chainHeightListener); + if (txConfidenceListener != null) + bsqWalletService.removeTxConfidenceListener(txConfidenceListener); + + daoFacade.phaseProperty().removeListener(phaseChangeListener); + } + + private void updateConfidence(TransactionConfidence.ConfidenceType confidenceType, int depthInBlocks, int numBroadcastPeers) { + switch (confidenceType) { + case UNKNOWN: + tooltip.setText(Res.get("confidence.unknown")); + txConfidenceIndicator.setProgress(0); + break; + case PENDING: + tooltip.setText(Res.get("confidence.seen", numBroadcastPeers > -1 ? numBroadcastPeers : Res.get("shared.na"))); + txConfidenceIndicator.setProgress(-1.0); + break; + case BUILDING: + tooltip.setText(Res.get("confidence.confirmed", depthInBlocks)); + txConfidenceIndicator.setProgress(Math.min(1, (double) depthInBlocks / 6.0)); + break; + case DEAD: + tooltip.setText(Res.get("confidence.invalid")); + txConfidenceIndicator.setProgress(0); + break; + } + + txConfidenceIndicator.setPrefSize(24, 24); + } + + public Node getActionNode() { + return actionNode; + } +} + diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index a7a86c24e72..905174e0474 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -17,251 +17,36 @@ package bisq.desktop.main.dao.proposal; -import bisq.desktop.components.AutoTooltipButton; -import bisq.desktop.components.indicator.TxConfidenceIndicator; +import bisq.desktop.main.dao.ListItem; import bisq.desktop.util.BsqFormatter; -import bisq.core.btc.listeners.TxConfidenceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; -import bisq.core.dao.state.BlockListener; -import bisq.core.dao.state.blockchain.Block; -import bisq.core.dao.state.blockchain.Tx; -import bisq.core.dao.state.period.DaoPhase; import bisq.core.dao.voting.proposal.Proposal; -import bisq.core.locale.Res; - -import org.bitcoinj.core.Transaction; -import org.bitcoinj.core.TransactionConfidence; - -import javafx.scene.Node; -import javafx.scene.control.Tooltip; -import javafx.scene.image.ImageView; - -import javafx.beans.value.ChangeListener; - -import java.util.Optional; import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; import lombok.ToString; import lombok.extern.slf4j.Slf4j; @ToString @Slf4j -@EqualsAndHashCode -public class ProposalListItem implements BlockListener { - @Getter +@EqualsAndHashCode(callSuper = true) +public class ProposalListItem extends ListItem { private final Proposal proposal; - private final DaoFacade daoFacade; - private final BsqWalletService bsqWalletService; - private final BsqFormatter bsqFormatter; - private final ChangeListener chainHeightListener; - @Getter - private TxConfidenceIndicator txConfidenceIndicator; - @Getter - private Integer confirmations = 0; - - private TxConfidenceListener txConfidenceListener; - private Tooltip tooltip = new Tooltip(Res.get("confidence.unknown")); - private Transaction walletTransaction; - private ChangeListener phaseChangeListener; - private AutoTooltipButton actionButton; - private ImageView actionButtonIconView; - @Setter - private Runnable onRemoveHandler; - private Node actionNode; - ProposalListItem(Proposal proposal, - DaoFacade daoFacade, - BsqWalletService bsqWalletService, - BsqFormatter bsqFormatter) { + public ProposalListItem(Proposal proposal, + DaoFacade daoFacade, + BsqWalletService bsqWalletService, + BsqFormatter bsqFormatter) { + super(daoFacade, + bsqWalletService, + bsqFormatter); this.proposal = proposal; - this.daoFacade = daoFacade; - this.bsqWalletService = bsqWalletService; - this.bsqFormatter = bsqFormatter; - - - txConfidenceIndicator = new TxConfidenceIndicator(); - txConfidenceIndicator.setId("funds-confidence"); - - txConfidenceIndicator.setProgress(-1); - txConfidenceIndicator.setPrefSize(24, 24); - txConfidenceIndicator.setTooltip(tooltip); - - actionButton = new AutoTooltipButton(); - actionButton.setMinWidth(70); - actionButtonIconView = new ImageView(); - - chainHeightListener = (observable, oldValue, newValue) -> setupConfidence(); - bsqWalletService.getChainHeightProperty().addListener(chainHeightListener); - setupConfidence(); - - daoFacade.addBlockListener(this); - - phaseChangeListener = (observable, oldValue, newValue) -> { - applyState(newValue); - }; - - daoFacade.phaseProperty().addListener(phaseChangeListener); - } - - public void applyState(DaoPhase.Phase phase) { - if (phase != null) { - actionButton.setText(""); - actionButton.setVisible(false); - actionButton.setOnAction(null); - switch (phase) { - case UNDEFINED: - log.error("invalid state UNDEFINED"); - break; - case PROPOSAL: - if (daoFacade.isMyProposal(proposal)) { - actionButtonIconView.setVisible(actionButton.isVisible()); - actionButton.setText(Res.get("shared.remove")); - actionButton.setGraphic(actionButtonIconView); - actionButtonIconView.setId("image-remove"); - actionButton.setOnAction(e -> { - if (onRemoveHandler != null) - onRemoveHandler.run(); - }); - actionNode = actionButton; - } - break; - case BREAK1: - break; - case BLIND_VOTE: - actionNode = actionButtonIconView; - actionButton.setVisible(false); - - //TODO - /* if (vote != null) { - actionButtonIconView.setVisible(true); - if (vote instanceof BooleanVote) { - if (((BooleanVote) vote).isAccepted()) { - actionButtonIconView.setId("accepted"); - } else { - actionButtonIconView.setId("rejected"); - } - } else { - //TODO - } - } else { - actionButtonIconView.setVisible(false); - }*/ - - break; - case BREAK2: - break; - case VOTE_REVEAL: - break; - case BREAK3: - break; - case RESULT: - break; - case BREAK4: - break; - default: - log.error("invalid state " + phase); - } - actionButton.setManaged(actionButton.isVisible()); - - // Don't set managed as otherwise the update does not work (not sure why but probably table - // cell item issue) - //actionButtonIconView.setManaged(actionButtonIconView.isVisible()); - } + init(); } - - /////////////////////////////////////////////////////////////////////////////////////////// - // Listener - /////////////////////////////////////////////////////////////////////////////////////////// - @Override - public void onBlockAdded(Block block) { - //TODO do we want that here??? - setupConfidence(); - } - - // TODO reuse from other item - private void setupConfidence() { - final String txId = proposal.getTxId(); - Optional optionalTx = daoFacade.getTx(txId); - if (optionalTx.isPresent()) { - Tx tx = optionalTx.get(); - // We cache the walletTransaction once found - if (walletTransaction == null) { - final Optional transactionOptional = bsqWalletService.isWalletTransaction(txId); - transactionOptional.ifPresent(transaction -> walletTransaction = transaction); - } - - if (walletTransaction != null) { - // It is our tx so we get confidence updates - if (txConfidenceListener == null) { - txConfidenceListener = new TxConfidenceListener(txId) { - @Override - public void onTransactionConfidenceChanged(TransactionConfidence confidence) { - updateConfidence(confidence.getConfidenceType(), confidence.getDepthInBlocks(), confidence.numBroadcastPeers()); - } - }; - bsqWalletService.addTxConfidenceListener(txConfidenceListener); - } - } else { - // tx from other users, we dont get confidence updates but as we have the bsq tx we can calculate it - // we get setupConfidence called at each new block from above listener so no need to register a new listener - int depth = bsqWalletService.getChainHeightProperty().get() - tx.getBlockHeight() + 1; - if (depth > 0) - updateConfidence(TransactionConfidence.ConfidenceType.BUILDING, depth, -1); - } - - final TransactionConfidence confidence = bsqWalletService.getConfidenceForTxId(txId); - if (confidence != null) - updateConfidence(confidence, confidence.getDepthInBlocks()); - } - } - - private void updateConfidence(TransactionConfidence confidence, int depthInBlocks) { - if (confidence != null) { - updateConfidence(confidence.getConfidenceType(), confidence.getDepthInBlocks(), confidence.numBroadcastPeers()); - confirmations = depthInBlocks; - } - } - - public void cleanup() { - daoFacade.removeBlockListener(this); - bsqWalletService.getChainHeightProperty().removeListener(chainHeightListener); - if (txConfidenceListener != null) - bsqWalletService.removeTxConfidenceListener(txConfidenceListener); - - daoFacade.phaseProperty().removeListener(phaseChangeListener); - } - - private void updateConfidence(TransactionConfidence.ConfidenceType confidenceType, int depthInBlocks, int numBroadcastPeers) { - switch (confidenceType) { - case UNKNOWN: - tooltip.setText(Res.get("confidence.unknown")); - txConfidenceIndicator.setProgress(0); - break; - case PENDING: - tooltip.setText(Res.get("confidence.seen", numBroadcastPeers > -1 ? numBroadcastPeers : Res.get("shared.na"))); - txConfidenceIndicator.setProgress(-1.0); - break; - case BUILDING: - tooltip.setText(Res.get("confidence.confirmed", depthInBlocks)); - txConfidenceIndicator.setProgress(Math.min(1, (double) depthInBlocks / 6.0)); - break; - case DEAD: - tooltip.setText(Res.get("confidence.invalid")); - txConfidenceIndicator.setProgress(0); - break; - } - - txConfidenceIndicator.setPrefSize(24, 24); - } - - public Node getActionNode() { - return actionNode; + protected Proposal getProposal() { + return proposal; } } - diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index ab93eda22c0..a1f528780cf 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -18,61 +18,22 @@ package bisq.desktop.main.dao.proposal.active; import bisq.desktop.common.view.FxmlView; -import bisq.desktop.components.BusyAnimation; -import bisq.desktop.components.InputTextField; -import bisq.desktop.components.TitledGroupBg; -import bisq.desktop.main.dao.proposal.BaseProposalView; +import bisq.desktop.main.dao.ActiveView; +import bisq.desktop.main.dao.ListItem; import bisq.desktop.main.dao.proposal.ProposalListItem; -import bisq.desktop.main.overlays.popups.Popup; import bisq.desktop.util.BSFormatter; import bisq.desktop.util.BsqFormatter; -import bisq.desktop.util.GUIUtil; -import bisq.desktop.util.Layout; -import bisq.core.btc.exceptions.TransactionVerificationException; -import bisq.core.btc.exceptions.WalletException; -import bisq.core.btc.wallet.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; -import bisq.core.dao.state.period.DaoPhase; import bisq.core.dao.voting.proposal.Proposal; -import bisq.core.locale.Res; - -import bisq.common.util.Tuple2; -import bisq.common.util.Tuple3; - -import org.bitcoinj.core.Coin; -import org.bitcoinj.core.InsufficientMoneyException; -import org.bitcoinj.core.Transaction; import javax.inject.Inject; -import javafx.scene.Node; -import javafx.scene.control.Button; -import javafx.scene.control.Label; -import javafx.scene.control.TableCell; -import javafx.scene.control.TableColumn; -import javafx.scene.control.TableView; - -import javafx.beans.property.ReadOnlyObjectWrapper; - -import javafx.util.Callback; - -import java.util.ArrayList; -import java.util.Comparator; import java.util.List; -import static bisq.desktop.util.FormBuilder.*; - @FxmlView -public class ActiveProposalsView extends BaseProposalView implements BsqBalanceListener { - - private Button removeButton, acceptButton, rejectButton, removeMyVoteButton, voteButton; - private InputTextField stakeInputTextField; - private List voteViewItems = new ArrayList<>(); - private BusyAnimation voteButtonBusyAnimation; - private Label voteButtonInfoLabel; - +public class ActiveProposalsView extends ActiveView { /////////////////////////////////////////////////////////////////////////////////////////// // Constructor, lifecycle @@ -87,235 +48,6 @@ private ActiveProposalsView(DaoFacade daoFacade, super(daoFacade, bsqWalletService, bsqFormatter, btcFormatter); } - @Override - public void initialize() { - super.initialize(); - - createProposalsTableView(); - createVoteView(); - createProposalDisplay(); - } - - @Override - protected void activate() { - super.activate(); - - daoFacade.getActiveOrMyUnconfirmedProposals().addListener(proposalListChangeListener); - bsqWalletService.addBsqBalanceListener(this); - - onUpdateBalances(bsqWalletService.getAvailableBalance(), - bsqWalletService.getPendingBalance(), - bsqWalletService.getLockedForVotingBalance(), - bsqWalletService.getLockedInBondsBalance()); - - if (voteButton != null) { - voteButton.setOnAction(e -> { - // TODO verify stake - Coin stake = bsqFormatter.parseToCoin(stakeInputTextField.getText()); - final Coin blindVoteFee = daoFacade.getBlindVoteFeeForCycle(); - Transaction dummyTx = null; - try { - // We create a dummy tx to get the mining blindVoteFee for confirmation popup - dummyTx = daoFacade.getDummyBlindVoteTx(stake, blindVoteFee); - } catch (InsufficientMoneyException | WalletException | TransactionVerificationException exception) { - new Popup<>().warning(exception.toString()).show(); - } - - if (dummyTx != null) { - Coin miningFee = dummyTx.getFee(); - int txSize = dummyTx.bitcoinSerialize().length; - GUIUtil.showBsqFeeInfoPopup(blindVoteFee, miningFee, txSize, bsqFormatter, btcFormatter, - Res.get("dao.blindVote"), () -> publishBlindVote(stake)); - } - }); - } - } - - private void publishBlindVote(Coin stake) { - voteButtonBusyAnimation.play(); - voteButtonInfoLabel.setText(Res.get("dao.blindVote.startPublishing")); - daoFacade.publishBlindVote(stake, - () -> { - voteButtonBusyAnimation.stop(); - voteButtonInfoLabel.setText(""); - new Popup().feedback(Res.get("dao.blindVote.success")) - .show(); - }, exception -> { - voteButtonBusyAnimation.stop(); - voteButtonInfoLabel.setText(""); - new Popup<>().warning(exception.toString()).show(); - }); - } - - @Override - protected void deactivate() { - super.deactivate(); - - daoFacade.getActiveOrMyUnconfirmedProposals().removeListener(proposalListChangeListener); - bsqWalletService.removeBsqBalanceListener(this); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Create views - /////////////////////////////////////////////////////////////////////////////////////////// - - - private void createVoteView() { - TitledGroupBg titledGroupBg = addTitledGroupBg(root, ++gridRow, 1, Res.get("dao.proposal.votes.header"), - Layout.GROUP_DISTANCE - 20); - final Tuple2 tuple2 = addLabelInputTextField(root, gridRow, - Res.getWithCol("dao.proposal.myVote.stake"), Layout - .FIRST_ROW_AND_GROUP_DISTANCE - 20); - stakeInputTextField = tuple2.second; - Tuple3 tuple = addButtonBusyAnimationLabelAfterGroup(root, ++gridRow, Res.get("dao.proposal.myVote.button")); - voteButton = tuple.first; - voteButtonBusyAnimation = tuple.second; - voteButtonInfoLabel = tuple.third; - - voteViewItems.add(titledGroupBg); - voteViewItems.add(tuple2.first); - voteViewItems.add(stakeInputTextField); - voteViewItems.add(voteButton); - - changeVoteViewItemsVisibility(false); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Handlers - /////////////////////////////////////////////////////////////////////////////////////////// - - @Override - public void onUpdateBalances(Coin confirmedBalance, - Coin pendingBalance, - Coin lockedForVotingBalance, - Coin lockedInBondsBalance) { - stakeInputTextField.setPromptText(Res.get("dao.proposal.myVote.stake.prompt", - bsqFormatter.formatCoinWithCode(confirmedBalance))); - } - - protected void onSelectProposal(ProposalListItem item) { - super.onSelectProposal(item); - if (item != null) { - if (removeButton != null) { - removeButton.setManaged(false); - removeButton.setVisible(false); - removeButton = null; - } - if (acceptButton != null) { - acceptButton.setManaged(false); - acceptButton.setVisible(false); - acceptButton = null; - } - if (rejectButton != null) { - rejectButton.setManaged(false); - rejectButton.setVisible(false); - rejectButton = null; - } - if (removeMyVoteButton != null) { - removeMyVoteButton.setManaged(false); - removeMyVoteButton.setVisible(false); - removeMyVoteButton = null; - } - - onPhaseChanged(daoFacade.phaseProperty().get()); - } - } - - private void onAccept() { - //TODO - // daoFacade.setVote(selectedProposalListItem.getProposal(), new BooleanVote(true)); - updateStateAfterVote(); - } - - - private void onReject() { - //TODO - // daoFacade.setVote(selectedProposalListItem.getProposal(), new BooleanVote(false)); - updateStateAfterVote(); - } - - private void onCancelVote() { - //TODO - // daoFacade.setVote(selectedProposalListItem.getProposal(), null); - updateStateAfterVote(); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // ChainHeightListener - /////////////////////////////////////////////////////////////////////////////////////////// - - - @Override - protected void onPhaseChanged(DaoPhase.Phase phase) { - super.onPhaseChanged(phase); - - changeVoteViewItemsVisibility(phase == DaoPhase.Phase.BLIND_VOTE); - - if (removeButton != null) { - removeButton.setManaged(false); - removeButton.setVisible(false); - removeButton = null; - } - if (selectedProposalListItem != null && proposalDisplay != null) { - final Proposal proposal = selectedProposalListItem.getProposal(); - switch (phase) { - case PROPOSAL: - if (daoFacade.isMyProposal(proposal)) { - if (removeButton == null) { - removeButton = addButtonAfterGroup(detailsGridPane, proposalDisplay.incrementAndGetGridRow(), Res.get("dao.proposal.active.remove")); - removeButton.setOnAction(event -> onRemove()); - } else { - removeButton.setManaged(true); - removeButton.setVisible(true); - } - } - break; - case BREAK1: - break; - case BLIND_VOTE: - if (acceptButton == null) { - Tuple3 tuple = add3ButtonsAfterGroup(detailsGridPane, proposalDisplay - .incrementAndGetGridRow(), - Res.get("dao.proposal.myVote.accept"), - Res.get("dao.proposal.myVote.reject"), - Res.get("dao.proposal.myVote.removeMyVote")); - acceptButton = tuple.first; - acceptButton.setDefaultButton(false); - rejectButton = tuple.second; - removeMyVoteButton = tuple.third; - acceptButton.setOnAction(event -> onAccept()); - rejectButton.setOnAction(event -> onReject()); - removeMyVoteButton.setOnAction(event -> onCancelVote()); - } else { - //TODO prob. not possible code path - acceptButton.setManaged(true); - acceptButton.setVisible(true); - rejectButton.setManaged(true); - rejectButton.setVisible(true); - removeMyVoteButton.setManaged(true); - removeMyVoteButton.setVisible(true); - } - break; - case BREAK2: - break; - case VOTE_REVEAL: - break; - case BREAK3: - break; - case RESULT: - break; - case BREAK4: - break; - case UNDEFINED: - default: - log.error("Undefined phase: " + phase); - break; - } - } - } /////////////////////////////////////////////////////////////////////////////////////////// // Protected @@ -326,81 +58,9 @@ protected List getProposalList() { return daoFacade.getActiveOrMyUnconfirmedProposals(); } - private void updateStateAfterVote() { - hideProposalDisplay(); - proposalTableView.getSelectionModel().clearSelection(); - } - - private void changeVoteViewItemsVisibility(boolean value) { - voteViewItems.forEach(node -> { - node.setVisible(value); - node.setManaged(value); - }); - } - - private void onRemove() { - final Proposal proposal = selectedProposalListItem.getProposal(); - if (daoFacade.removeMyProposal(proposal)) { - hideProposalDisplay(); - } else { - new Popup<>().warning(Res.get("dao.proposal.active.remove.failed")).show(); - } - proposalTableView.getSelectionModel().clearSelection(); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // TableColumns - /////////////////////////////////////////////////////////////////////////////////////////// - @Override - protected void createProposalColumns(TableView tableView) { - super.createProposalColumns(tableView); - createConfidenceColumn(tableView); - - TableColumn actionColumn = new TableColumn<>(); - actionColumn.setMinWidth(130); - actionColumn.setMaxWidth(actionColumn.getMinWidth()); - - actionColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - - actionColumn.setCellFactory(new Callback, - TableCell>() { - - @Override - public TableCell call(TableColumn column) { - return new TableCell() { - Node node; - - @Override - public void updateItem(final ProposalListItem item, boolean empty) { - super.updateItem(item, empty); - - if (item != null && !empty) { - if (node == null) { - node = item.getActionNode(); - setGraphic(node); - item.setOnRemoveHandler(() -> { - ActiveProposalsView.this.selectedProposalListItem = item; - ActiveProposalsView.this.onRemove(); - }); - item.applyState(currentPhase); - } - } else { - setGraphic(null); - if (node != null) { - if (node instanceof Button) - ((Button) node).setOnAction(null); - node = null; - } - } - } - }; - } - }); - actionColumn.setComparator(Comparator.comparing(ProposalListItem::getConfirmations)); - tableView.getColumns().add(actionColumn); + protected ListItem getListItem(Proposal proposal) { + return new ProposalListItem(proposal, daoFacade, bsqWalletService, bsqFormatter); } } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java index 3048f7b7ba6..e1106330e07 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java @@ -18,7 +18,9 @@ package bisq.desktop.main.dao.proposal.closed; import bisq.desktop.common.view.FxmlView; -import bisq.desktop.main.dao.proposal.BaseProposalView; +import bisq.desktop.main.dao.BaseProposalView; +import bisq.desktop.main.dao.ListItem; +import bisq.desktop.main.dao.proposal.ProposalListItem; import bisq.desktop.util.BSFormatter; import bisq.desktop.util.BsqFormatter; @@ -70,5 +72,10 @@ protected void deactivate() { protected List getProposalList() { return daoFacade.getClosedProposals(); } + + @Override + protected ListItem getListItem(Proposal proposal) { + return new ProposalListItem(proposal, daoFacade, bsqWalletService, bsqFormatter); + } } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java index 4da808d3c82..a6a8fdfb614 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java @@ -22,7 +22,8 @@ import bisq.desktop.components.AutoTooltipTableColumn; import bisq.desktop.components.HyperlinkWithIcon; import bisq.desktop.components.TableGroupHeadline; -import bisq.desktop.main.dao.proposal.BaseProposalView; +import bisq.desktop.main.dao.BaseProposalView; +import bisq.desktop.main.dao.ListItem; import bisq.desktop.main.dao.proposal.ProposalListItem; import bisq.desktop.util.BSFormatter; import bisq.desktop.util.BsqFormatter; @@ -187,6 +188,11 @@ protected List getProposalList() { return null;// daoFacade.getActiveOrMyUnconfirmedProposals(); } + @Override + protected ListItem getListItem(Proposal proposal) { + return new ProposalListItem(proposal, daoFacade, bsqWalletService, bsqFormatter); + } + /////////////////////////////////////////////////////////////////////////////////////////// // TableColumns /////////////////////////////////////////////////////////////////////////////////////////// @@ -343,26 +349,26 @@ public void updateItem(final VoteListItem item, boolean empty) { @Override - protected void createProposalColumns(TableView tableView) { + protected void createProposalColumns(TableView tableView) { super.createProposalColumns(tableView); - TableColumn actionColumn = new TableColumn<>(Res.get("dao.proposal.votes.header")); + TableColumn actionColumn = new TableColumn<>(Res.get("dao.proposal.votes.header")); actionColumn.setMinWidth(50); actionColumn.setMaxWidth(actionColumn.getMinWidth()); actionColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - actionColumn.setCellFactory(new Callback, - TableCell>() { + actionColumn.setCellFactory(new Callback, + TableCell>() { @Override - public TableCell call(TableColumn column) { - return new TableCell() { + public TableCell call(TableColumn column) { + return new TableCell() { ImageView actionButtonIconView; @Override - public void updateItem(final ProposalListItem item, boolean empty) { + public void updateItem(final ListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { @@ -387,7 +393,7 @@ public void updateItem(final ProposalListItem item, boolean empty) { }; } }); - actionColumn.setComparator(Comparator.comparing(ProposalListItem::getConfirmations)); + actionColumn.setComparator(Comparator.comparing(ListItem::getConfirmations)); tableView.getColumns().add(actionColumn); } } diff --git a/src/main/java/bisq/desktop/main/dao/voting/active/ActiveVotingView.java b/src/main/java/bisq/desktop/main/dao/voting/active/ActiveVotingView.java index b806c02e096..8b6d536bf3d 100644 --- a/src/main/java/bisq/desktop/main/dao/voting/active/ActiveVotingView.java +++ b/src/main/java/bisq/desktop/main/dao/voting/active/ActiveVotingView.java @@ -18,61 +18,22 @@ package bisq.desktop.main.dao.voting.active; import bisq.desktop.common.view.FxmlView; -import bisq.desktop.components.BusyAnimation; -import bisq.desktop.components.InputTextField; -import bisq.desktop.components.TitledGroupBg; -import bisq.desktop.main.dao.proposal.BaseProposalView; +import bisq.desktop.main.dao.ActiveView; +import bisq.desktop.main.dao.ListItem; import bisq.desktop.main.dao.proposal.ProposalListItem; -import bisq.desktop.main.overlays.popups.Popup; import bisq.desktop.util.BSFormatter; import bisq.desktop.util.BsqFormatter; -import bisq.desktop.util.GUIUtil; -import bisq.desktop.util.Layout; -import bisq.core.btc.exceptions.TransactionVerificationException; -import bisq.core.btc.exceptions.WalletException; -import bisq.core.btc.wallet.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; -import bisq.core.dao.state.period.DaoPhase; import bisq.core.dao.voting.proposal.Proposal; -import bisq.core.locale.Res; - -import bisq.common.util.Tuple2; -import bisq.common.util.Tuple3; - -import org.bitcoinj.core.Coin; -import org.bitcoinj.core.InsufficientMoneyException; -import org.bitcoinj.core.Transaction; import javax.inject.Inject; -import javafx.scene.Node; -import javafx.scene.control.Button; -import javafx.scene.control.Label; -import javafx.scene.control.TableCell; -import javafx.scene.control.TableColumn; -import javafx.scene.control.TableView; - -import javafx.beans.property.ReadOnlyObjectWrapper; - -import javafx.util.Callback; - -import java.util.ArrayList; -import java.util.Comparator; import java.util.List; -import static bisq.desktop.util.FormBuilder.*; - @FxmlView -public class ActiveVotingView extends BaseProposalView implements BsqBalanceListener { - - private Button removeButton, acceptButton, rejectButton, removeMyVoteButton, voteButton; - private InputTextField stakeInputTextField; - private List voteViewItems = new ArrayList<>(); - private BusyAnimation voteButtonBusyAnimation; - private Label voteButtonInfoLabel; - +public class ActiveVotingView extends ActiveView { /////////////////////////////////////////////////////////////////////////////////////////// // Constructor, lifecycle @@ -87,235 +48,6 @@ private ActiveVotingView(DaoFacade daoFacade, super(daoFacade, bsqWalletService, bsqFormatter, btcFormatter); } - @Override - public void initialize() { - super.initialize(); - - createProposalsTableView(); - createVoteView(); - createProposalDisplay(); - } - - @Override - protected void activate() { - super.activate(); - - daoFacade.getActiveOrMyUnconfirmedProposals().addListener(proposalListChangeListener); - bsqWalletService.addBsqBalanceListener(this); - - onUpdateBalances(bsqWalletService.getAvailableBalance(), - bsqWalletService.getPendingBalance(), - bsqWalletService.getLockedForVotingBalance(), - bsqWalletService.getLockedInBondsBalance()); - - if (voteButton != null) { - voteButton.setOnAction(e -> { - // TODO verify stake - Coin stake = bsqFormatter.parseToCoin(stakeInputTextField.getText()); - final Coin blindVoteFee = daoFacade.getBlindVoteFeeForCycle(); - Transaction dummyTx = null; - try { - // We create a dummy tx to get the mining blindVoteFee for confirmation popup - dummyTx = daoFacade.getDummyBlindVoteTx(stake, blindVoteFee); - } catch (InsufficientMoneyException | WalletException | TransactionVerificationException exception) { - new Popup<>().warning(exception.toString()).show(); - } - - if (dummyTx != null) { - Coin miningFee = dummyTx.getFee(); - int txSize = dummyTx.bitcoinSerialize().length; - GUIUtil.showBsqFeeInfoPopup(blindVoteFee, miningFee, txSize, bsqFormatter, btcFormatter, - Res.get("dao.blindVote"), () -> publishBlindVote(stake)); - } - }); - } - } - - private void publishBlindVote(Coin stake) { - voteButtonBusyAnimation.play(); - voteButtonInfoLabel.setText(Res.get("dao.blindVote.startPublishing")); - daoFacade.publishBlindVote(stake, - () -> { - voteButtonBusyAnimation.stop(); - voteButtonInfoLabel.setText(""); - new Popup().feedback(Res.get("dao.blindVote.success")) - .show(); - }, exception -> { - voteButtonBusyAnimation.stop(); - voteButtonInfoLabel.setText(""); - new Popup<>().warning(exception.toString()).show(); - }); - } - - @Override - protected void deactivate() { - super.deactivate(); - - daoFacade.getActiveOrMyUnconfirmedProposals().removeListener(proposalListChangeListener); - bsqWalletService.removeBsqBalanceListener(this); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Create views - /////////////////////////////////////////////////////////////////////////////////////////// - - - private void createVoteView() { - TitledGroupBg titledGroupBg = addTitledGroupBg(root, ++gridRow, 1, Res.get("dao.proposal.votes.header"), - Layout.GROUP_DISTANCE - 20); - final Tuple2 tuple2 = addLabelInputTextField(root, gridRow, - Res.getWithCol("dao.proposal.myVote.stake"), Layout - .FIRST_ROW_AND_GROUP_DISTANCE - 20); - stakeInputTextField = tuple2.second; - Tuple3 tuple = addButtonBusyAnimationLabelAfterGroup(root, ++gridRow, Res.get("dao.proposal.myVote.button")); - voteButton = tuple.first; - voteButtonBusyAnimation = tuple.second; - voteButtonInfoLabel = tuple.third; - - voteViewItems.add(titledGroupBg); - voteViewItems.add(tuple2.first); - voteViewItems.add(stakeInputTextField); - voteViewItems.add(voteButton); - - changeVoteViewItemsVisibility(false); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Handlers - /////////////////////////////////////////////////////////////////////////////////////////// - - @Override - public void onUpdateBalances(Coin confirmedBalance, - Coin pendingBalance, - Coin lockedForVotingBalance, - Coin lockedInBondsBalance) { - stakeInputTextField.setPromptText(Res.get("dao.proposal.myVote.stake.prompt", - bsqFormatter.formatCoinWithCode(confirmedBalance))); - } - - protected void onSelectProposal(ProposalListItem item) { - super.onSelectProposal(item); - if (item != null) { - if (removeButton != null) { - removeButton.setManaged(false); - removeButton.setVisible(false); - removeButton = null; - } - if (acceptButton != null) { - acceptButton.setManaged(false); - acceptButton.setVisible(false); - acceptButton = null; - } - if (rejectButton != null) { - rejectButton.setManaged(false); - rejectButton.setVisible(false); - rejectButton = null; - } - if (removeMyVoteButton != null) { - removeMyVoteButton.setManaged(false); - removeMyVoteButton.setVisible(false); - removeMyVoteButton = null; - } - - onPhaseChanged(daoFacade.phaseProperty().get()); - } - } - - private void onAccept() { - //TODO - // daoFacade.setVote(selectedProposalListItem.getProposal(), new BooleanVote(true)); - updateStateAfterVote(); - } - - - private void onReject() { - //TODO - // daoFacade.setVote(selectedProposalListItem.getProposal(), new BooleanVote(false)); - updateStateAfterVote(); - } - - private void onCancelVote() { - //TODO - // daoFacade.setVote(selectedProposalListItem.getProposal(), null); - updateStateAfterVote(); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // ChainHeightListener - /////////////////////////////////////////////////////////////////////////////////////////// - - - @Override - protected void onPhaseChanged(DaoPhase.Phase phase) { - super.onPhaseChanged(phase); - - changeVoteViewItemsVisibility(phase == DaoPhase.Phase.BLIND_VOTE); - - if (removeButton != null) { - removeButton.setManaged(false); - removeButton.setVisible(false); - removeButton = null; - } - if (selectedProposalListItem != null && proposalDisplay != null) { - final Proposal proposal = selectedProposalListItem.getProposal(); - switch (phase) { - case PROPOSAL: - if (daoFacade.isMyProposal(proposal)) { - if (removeButton == null) { - removeButton = addButtonAfterGroup(detailsGridPane, proposalDisplay.incrementAndGetGridRow(), Res.get("dao.proposal.active.remove")); - removeButton.setOnAction(event -> onRemove()); - } else { - removeButton.setManaged(true); - removeButton.setVisible(true); - } - } - break; - case BREAK1: - break; - case BLIND_VOTE: - if (acceptButton == null) { - Tuple3 tuple = add3ButtonsAfterGroup(detailsGridPane, proposalDisplay - .incrementAndGetGridRow(), - Res.get("dao.proposal.myVote.accept"), - Res.get("dao.proposal.myVote.reject"), - Res.get("dao.proposal.myVote.removeMyVote")); - acceptButton = tuple.first; - acceptButton.setDefaultButton(false); - rejectButton = tuple.second; - removeMyVoteButton = tuple.third; - acceptButton.setOnAction(event -> onAccept()); - rejectButton.setOnAction(event -> onReject()); - removeMyVoteButton.setOnAction(event -> onCancelVote()); - } else { - //TODO prob. not possible code path - acceptButton.setManaged(true); - acceptButton.setVisible(true); - rejectButton.setManaged(true); - rejectButton.setVisible(true); - removeMyVoteButton.setManaged(true); - removeMyVoteButton.setVisible(true); - } - break; - case BREAK2: - break; - case VOTE_REVEAL: - break; - case BREAK3: - break; - case RESULT: - break; - case BREAK4: - break; - case UNDEFINED: - default: - log.error("Undefined phase: " + phase); - break; - } - } - } /////////////////////////////////////////////////////////////////////////////////////////// // Protected @@ -326,81 +58,9 @@ protected List getProposalList() { return daoFacade.getActiveOrMyUnconfirmedProposals(); } - private void updateStateAfterVote() { - hideProposalDisplay(); - proposalTableView.getSelectionModel().clearSelection(); - } - - private void changeVoteViewItemsVisibility(boolean value) { - voteViewItems.forEach(node -> { - node.setVisible(value); - node.setManaged(value); - }); - } - - private void onRemove() { - final Proposal proposal = selectedProposalListItem.getProposal(); - if (daoFacade.removeMyProposal(proposal)) { - hideProposalDisplay(); - } else { - new Popup<>().warning(Res.get("dao.proposal.active.remove.failed")).show(); - } - proposalTableView.getSelectionModel().clearSelection(); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // TableColumns - /////////////////////////////////////////////////////////////////////////////////////////// - @Override - protected void createProposalColumns(TableView tableView) { - super.createProposalColumns(tableView); - createConfidenceColumn(tableView); - - TableColumn actionColumn = new TableColumn<>(); - actionColumn.setMinWidth(130); - actionColumn.setMaxWidth(actionColumn.getMinWidth()); - - actionColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - - actionColumn.setCellFactory(new Callback, - TableCell>() { - - @Override - public TableCell call(TableColumn column) { - return new TableCell() { - Node node; - - @Override - public void updateItem(final ProposalListItem item, boolean empty) { - super.updateItem(item, empty); - - if (item != null && !empty) { - if (node == null) { - node = item.getActionNode(); - setGraphic(node); - item.setOnRemoveHandler(() -> { - ActiveVotingView.this.selectedProposalListItem = item; - ActiveVotingView.this.onRemove(); - }); - item.applyState(currentPhase); - } - } else { - setGraphic(null); - if (node != null) { - if (node instanceof Button) - ((Button) node).setOnAction(null); - node = null; - } - } - } - }; - } - }); - actionColumn.setComparator(Comparator.comparing(ProposalListItem::getConfirmations)); - tableView.getColumns().add(actionColumn); + protected ListItem getListItem(Proposal proposal) { + return new ProposalListItem(proposal, daoFacade, bsqWalletService, bsqFormatter); } } From df9af404dab442f29dc5520e6a24f2d60203cd14 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Mon, 30 Apr 2018 18:42:51 -0500 Subject: [PATCH 086/197] Add support for BallotListItem --- .../desktop/main/dao/BaseProposalView.java | 26 ++------ .../proposal/active/ActiveProposalsView.java | 14 ++--- .../proposal/closed/ClosedProposalsView.java | 14 ++--- .../dao/proposal/myvotes/MyVotesView.java | 60 ++++--------------- .../main/dao/voting/BallotListItem.java | 53 ++++++++++++++++ .../desktop/main/dao/voting/VotingView.java | 18 +++--- .../BallotsView.fxml} | 2 +- .../BallotsView.java} | 29 +++++---- 8 files changed, 107 insertions(+), 109 deletions(-) create mode 100644 src/main/java/bisq/desktop/main/dao/voting/BallotListItem.java rename src/main/java/bisq/desktop/main/dao/voting/{active/ActiveVotingView.fxml => ballots/BallotsView.fxml} (97%) rename src/main/java/bisq/desktop/main/dao/voting/{active/ActiveVotingView.java => ballots/BallotsView.java} (67%) diff --git a/src/main/java/bisq/desktop/main/dao/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/BaseProposalView.java index 2f187d02a88..e0edb1b56b7 100644 --- a/src/main/java/bisq/desktop/main/dao/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/BaseProposalView.java @@ -63,7 +63,6 @@ import java.util.ArrayList; import java.util.Comparator; import java.util.List; -import java.util.stream.Collectors; @FxmlView public abstract class BaseProposalView extends ActivatableView { @@ -111,7 +110,7 @@ public void initialize() { detailsGridPane = new GridPane(); - proposalListChangeListener = c -> updateProposalListItems(); + proposalListChangeListener = c -> updateListItems(); phaseChangeListener = (observable, oldValue, newValue) -> onPhaseChanged(newValue); } @@ -126,7 +125,7 @@ protected void activate() { sortedList.comparatorProperty().bind(proposalTableView.comparatorProperty()); - updateProposalListItems(); + updateListItems(); } @Override @@ -227,29 +226,16 @@ protected void onPhaseChanged(DaoPhase.Phase phase) { // Protected /////////////////////////////////////////////////////////////////////////////////////////// - abstract protected List getProposalList(); - - protected void updateProposalListItems() { - List list = getProposalList(); + protected void updateListItems() { proposalListItems.forEach(ListItem::cleanup); proposalListItems.clear(); - proposalListItems.setAll(list.stream() - .map(proposal -> getListItem(proposal)) - .collect(Collectors.toSet())); + fillListItems(); - if (list.isEmpty()) + if (proposalListItems.isEmpty()) hideProposalDisplay(); } - protected abstract ListItem getListItem(Proposal proposal); - - /* @NotNull - private ListItem getListItem(Proposal proposal) { - return new ListItem(proposal, - daoFacade, - bsqWalletService, - bsqFormatter); - }*/ + abstract protected void fillListItems(); protected void changeProposalViewItemsVisibility(boolean value) { proposalViewItems.forEach(node -> { diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index a1f528780cf..a8aab693199 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -19,7 +19,6 @@ import bisq.desktop.common.view.FxmlView; import bisq.desktop.main.dao.ActiveView; -import bisq.desktop.main.dao.ListItem; import bisq.desktop.main.dao.proposal.ProposalListItem; import bisq.desktop.util.BSFormatter; import bisq.desktop.util.BsqFormatter; @@ -31,6 +30,7 @@ import javax.inject.Inject; import java.util.List; +import java.util.stream.Collectors; @FxmlView public class ActiveProposalsView extends ActiveView { @@ -54,13 +54,11 @@ private ActiveProposalsView(DaoFacade daoFacade, /////////////////////////////////////////////////////////////////////////////////////////// @Override - protected List getProposalList() { - return daoFacade.getActiveOrMyUnconfirmedProposals(); - } - - @Override - protected ListItem getListItem(Proposal proposal) { - return new ProposalListItem(proposal, daoFacade, bsqWalletService, bsqFormatter); + protected void fillListItems() { + List list = daoFacade.getActiveOrMyUnconfirmedProposals(); + proposalListItems.setAll(list.stream() + .map(proposal -> new ProposalListItem(proposal, daoFacade, bsqWalletService, bsqFormatter)) + .collect(Collectors.toSet())); } } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java index e1106330e07..5c8b17a0cc0 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java @@ -19,7 +19,6 @@ import bisq.desktop.common.view.FxmlView; import bisq.desktop.main.dao.BaseProposalView; -import bisq.desktop.main.dao.ListItem; import bisq.desktop.main.dao.proposal.ProposalListItem; import bisq.desktop.util.BSFormatter; import bisq.desktop.util.BsqFormatter; @@ -31,6 +30,7 @@ import javax.inject.Inject; import java.util.List; +import java.util.stream.Collectors; @FxmlView public class ClosedProposalsView extends BaseProposalView { @@ -69,13 +69,11 @@ protected void deactivate() { } @Override - protected List getProposalList() { - return daoFacade.getClosedProposals(); - } - - @Override - protected ListItem getListItem(Proposal proposal) { - return new ProposalListItem(proposal, daoFacade, bsqWalletService, bsqFormatter); + protected void fillListItems() { + List list = daoFacade.getClosedProposals(); + proposalListItems.setAll(list.stream() + .map(proposal -> new ProposalListItem(proposal, daoFacade, bsqWalletService, bsqFormatter)) + .collect(Collectors.toSet())); } } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java index a6a8fdfb614..d3c4255a258 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java @@ -17,66 +17,30 @@ package bisq.desktop.main.dao.proposal.myvotes; +import bisq.desktop.common.view.ActivatableView; import bisq.desktop.common.view.FxmlView; -import bisq.desktop.components.AutoTooltipLabel; -import bisq.desktop.components.AutoTooltipTableColumn; -import bisq.desktop.components.HyperlinkWithIcon; -import bisq.desktop.components.TableGroupHeadline; -import bisq.desktop.main.dao.BaseProposalView; -import bisq.desktop.main.dao.ListItem; -import bisq.desktop.main.dao.proposal.ProposalListItem; import bisq.desktop.util.BSFormatter; import bisq.desktop.util.BsqFormatter; -import bisq.desktop.util.GUIUtil; -import bisq.desktop.util.Layout; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; -import bisq.core.dao.voting.ballot.BallotList; -import bisq.core.dao.voting.proposal.Proposal; -import bisq.core.locale.Res; import bisq.core.user.Preferences; import javax.inject.Inject; -import de.jensd.fx.fontawesome.AwesomeIcon; - -import javafx.scene.control.TableCell; -import javafx.scene.control.TableColumn; -import javafx.scene.control.TableView; -import javafx.scene.control.Tooltip; -import javafx.scene.image.ImageView; import javafx.scene.layout.GridPane; -import javafx.scene.layout.Priority; - -import javafx.geometry.Insets; - -import org.fxmisc.easybind.EasyBind; -import org.fxmisc.easybind.Subscription; - -import javafx.beans.property.ReadOnlyObjectWrapper; - -import javafx.collections.FXCollections; -import javafx.collections.ObservableList; -import javafx.collections.transformation.SortedList; - -import javafx.util.Callback; - -import java.util.Comparator; -import java.util.Date; -import java.util.List; -import java.util.stream.Collectors; @FxmlView -public class MyVotesView extends BaseProposalView { +public class MyVotesView extends ActivatableView /*extends BaseProposalView*/ { private final Preferences preferences; + /* private final ObservableList voteListItems = FXCollections.observableArrayList(); private SortedList sortedList = new SortedList<>(voteListItems); private TableView votesTableView; private VoteListItem selectedVoteListItem; private Subscription selectedVoteSubscription; - +*/ /////////////////////////////////////////////////////////////////////////////////////////// // Constructor, lifecycle @@ -89,11 +53,11 @@ private MyVotesView(DaoFacade daoFacade, BSFormatter btcFormatter, Preferences preferences) { - super(daoFacade, bsqWalletService, bsqFormatter, btcFormatter); + // super(daoFacade, bsqWalletService, bsqFormatter, btcFormatter); this.preferences = preferences; } - @Override + /* @Override public void initialize() { super.initialize(); @@ -123,7 +87,7 @@ protected void activate() { private void onSelectVote(VoteListItem voteListItem) { selectedVoteListItem = voteListItem; changeProposalViewItemsVisibility(selectedVoteListItem != null); - updateProposalListItems(); + updateListItems(); } @Override @@ -176,12 +140,12 @@ private void onShowProposalList(BallotList ballotList) { // Protected /////////////////////////////////////////////////////////////////////////////////////////// - /* @Override + *//* @Override protected void updateProposalList() { //TODO //if (selectedVoteListItem != null) // doUpdateProposalList(selectedVoteListItem.getMyVote().getBallotList().getList()); - }*/ + }*//* @Override protected List getProposalList() { //TODO @@ -374,7 +338,7 @@ public void updateItem(final ListItem item, boolean empty) { if (item != null && !empty) { actionButtonIconView = new ImageView(); //TODO - /* Vote vote = item.getProposal().getVote(); + *//* Vote vote = item.getProposal().getVote(); if (vote instanceof BooleanVote) { if (((BooleanVote) vote).isAccepted()) { actionButtonIconView.setId("accepted"); @@ -383,7 +347,7 @@ public void updateItem(final ListItem item, boolean empty) { } } else { //TODO - }*/ + }*//* setGraphic(actionButtonIconView); } else { @@ -395,5 +359,5 @@ public void updateItem(final ListItem item, boolean empty) { }); actionColumn.setComparator(Comparator.comparing(ListItem::getConfirmations)); tableView.getColumns().add(actionColumn); - } + }*/ } diff --git a/src/main/java/bisq/desktop/main/dao/voting/BallotListItem.java b/src/main/java/bisq/desktop/main/dao/voting/BallotListItem.java new file mode 100644 index 00000000000..9b929e3daca --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/voting/BallotListItem.java @@ -0,0 +1,53 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.desktop.main.dao.voting; + +import bisq.desktop.main.dao.ListItem; +import bisq.desktop.util.BsqFormatter; + +import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.dao.DaoFacade; +import bisq.core.dao.voting.ballot.Ballot; +import bisq.core.dao.voting.proposal.Proposal; + +import lombok.EqualsAndHashCode; +import lombok.ToString; +import lombok.extern.slf4j.Slf4j; + +@ToString +@Slf4j +@EqualsAndHashCode(callSuper = true) +public class BallotListItem extends ListItem { + private final Ballot ballot; + + public BallotListItem(Ballot ballot, + DaoFacade daoFacade, + BsqWalletService bsqWalletService, + BsqFormatter bsqFormatter) { + super(daoFacade, + bsqWalletService, + bsqFormatter); + this.ballot = ballot; + init(); + } + + @Override + protected Proposal getProposal() { + return ballot.getProposal(); + } +} diff --git a/src/main/java/bisq/desktop/main/dao/voting/VotingView.java b/src/main/java/bisq/desktop/main/dao/voting/VotingView.java index 0eedb29faab..a3cbad879c1 100644 --- a/src/main/java/bisq/desktop/main/dao/voting/VotingView.java +++ b/src/main/java/bisq/desktop/main/dao/voting/VotingView.java @@ -27,7 +27,7 @@ import bisq.desktop.components.MenuItem; import bisq.desktop.main.MainView; import bisq.desktop.main.dao.DaoView; -import bisq.desktop.main.dao.voting.active.ActiveVotingView; +import bisq.desktop.main.dao.voting.ballots.BallotsView; import bisq.desktop.main.dao.voting.dashboard.VotingDashboardView; import bisq.core.locale.Res; @@ -51,7 +51,7 @@ public class VotingView extends ActivatableViewAndModel { private final ViewLoader viewLoader; private final Navigation navigation; - private MenuItem dashboard, active; + private MenuItem dashboard, ballots; private Navigation.Listener listener; @FXML @@ -81,22 +81,22 @@ public void initialize() { final List> baseNavPath = Arrays.asList(MainView.class, DaoView.class, VotingView.class); dashboard = new MenuItem(navigation, toggleGroup, Res.get("shared.dashboard"), VotingDashboardView.class, AwesomeIcon.DASHBOARD, baseNavPath); - active = new MenuItem(navigation, toggleGroup, Res.get("dao.proposal.menuItem.active"), - ActiveVotingView.class, AwesomeIcon.LIST_UL, baseNavPath); - leftVBox.getChildren().addAll(dashboard, active); + ballots = new MenuItem(navigation, toggleGroup, Res.get("dao.voting.menuItem.ballots"), + BallotsView.class, AwesomeIcon.LIST_UL, baseNavPath); + leftVBox.getChildren().addAll(dashboard, ballots); } @Override protected void activate() { dashboard.activate(); - active.activate(); + ballots.activate(); navigation.addListener(listener); ViewPath viewPath = navigation.getCurrentPath(); if (viewPath.size() == 3 && viewPath.indexOf(VotingView.class) == 2 || viewPath.size() == 2 && viewPath.indexOf(DaoView.class) == 1) { if (selectedViewClass == null) - selectedViewClass = ActiveVotingView.class; + selectedViewClass = BallotsView.class; loadView(selectedViewClass); @@ -111,7 +111,7 @@ protected void deactivate() { navigation.removeListener(listener); dashboard.deactivate(); - active.deactivate(); + ballots.deactivate(); } private void loadView(Class viewClass) { @@ -119,7 +119,7 @@ private void loadView(Class viewClass) { content.getChildren().setAll(view.getRoot()); if (view instanceof VotingDashboardView) dashboard.setSelected(true); - else if (view instanceof ActiveVotingView) active.setSelected(true); + else if (view instanceof BallotsView) ballots.setSelected(true); } public Class getSelectedViewClass() { diff --git a/src/main/java/bisq/desktop/main/dao/voting/active/ActiveVotingView.fxml b/src/main/java/bisq/desktop/main/dao/voting/ballots/BallotsView.fxml similarity index 97% rename from src/main/java/bisq/desktop/main/dao/voting/active/ActiveVotingView.fxml rename to src/main/java/bisq/desktop/main/dao/voting/ballots/BallotsView.fxml index 7bca40f1184..76cd4c69bc1 100644 --- a/src/main/java/bisq/desktop/main/dao/voting/active/ActiveVotingView.fxml +++ b/src/main/java/bisq/desktop/main/dao/voting/ballots/BallotsView.fxml @@ -21,7 +21,7 @@ - diff --git a/src/main/java/bisq/desktop/main/dao/voting/active/ActiveVotingView.java b/src/main/java/bisq/desktop/main/dao/voting/ballots/BallotsView.java similarity index 67% rename from src/main/java/bisq/desktop/main/dao/voting/active/ActiveVotingView.java rename to src/main/java/bisq/desktop/main/dao/voting/ballots/BallotsView.java index 8b6d536bf3d..dd7fb5637a8 100644 --- a/src/main/java/bisq/desktop/main/dao/voting/active/ActiveVotingView.java +++ b/src/main/java/bisq/desktop/main/dao/voting/ballots/BallotsView.java @@ -15,35 +15,35 @@ * along with Bisq. If not, see . */ -package bisq.desktop.main.dao.voting.active; +package bisq.desktop.main.dao.voting.ballots; import bisq.desktop.common.view.FxmlView; import bisq.desktop.main.dao.ActiveView; -import bisq.desktop.main.dao.ListItem; -import bisq.desktop.main.dao.proposal.ProposalListItem; +import bisq.desktop.main.dao.voting.BallotListItem; import bisq.desktop.util.BSFormatter; import bisq.desktop.util.BsqFormatter; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; -import bisq.core.dao.voting.proposal.Proposal; +import bisq.core.dao.voting.ballot.Ballot; import javax.inject.Inject; import java.util.List; +import java.util.stream.Collectors; @FxmlView -public class ActiveVotingView extends ActiveView { +public class BallotsView extends ActiveView { /////////////////////////////////////////////////////////////////////////////////////////// // Constructor, lifecycle /////////////////////////////////////////////////////////////////////////////////////////// @Inject - private ActiveVotingView(DaoFacade daoFacade, - BsqWalletService bsqWalletService, - BsqFormatter bsqFormatter, - BSFormatter btcFormatter) { + private BallotsView(DaoFacade daoFacade, + BsqWalletService bsqWalletService, + BsqFormatter bsqFormatter, + BSFormatter btcFormatter) { super(daoFacade, bsqWalletService, bsqFormatter, btcFormatter); } @@ -53,14 +53,13 @@ private ActiveVotingView(DaoFacade daoFacade, // Protected /////////////////////////////////////////////////////////////////////////////////////////// - @Override - protected List getProposalList() { - return daoFacade.getActiveOrMyUnconfirmedProposals(); - } @Override - protected ListItem getListItem(Proposal proposal) { - return new ProposalListItem(proposal, daoFacade, bsqWalletService, bsqFormatter); + protected void fillListItems() { + List list = daoFacade.getActiveOrMyUnconfirmedBallots(); + proposalListItems.setAll(list.stream() + .map(ballot -> new BallotListItem(ballot, daoFacade, bsqWalletService, bsqFormatter)) + .collect(Collectors.toSet())); } } From a4ad4d36652d568232ac556310c3b6331207f2ff Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Mon, 30 Apr 2018 20:33:15 -0500 Subject: [PATCH 087/197] Further refactoring of Views --- .../bisq/desktop/main/dao/ActiveView.java | 399 ------------------ .../{BaseProposalView.java => ItemsView.java} | 67 ++- .../java/bisq/desktop/main/dao/ListItem.java | 110 +---- .../main/dao/proposal/ProposalDisplay.java | 25 +- .../main/dao/proposal/ProposalItemsView.java | 89 ++++ .../main/dao/proposal/ProposalListItem.java | 33 +- .../proposal/active/ActiveProposalsView.java | 121 +++++- .../proposal/closed/ClosedProposalsView.java | 35 +- .../dao/proposal/myvotes/MyVotesView.java | 2 +- .../main/dao/voting/BallotListItem.java | 2 +- .../main/dao/voting/ballots/BallotsView.java | 219 +++++++++- 11 files changed, 508 insertions(+), 594 deletions(-) delete mode 100644 src/main/java/bisq/desktop/main/dao/ActiveView.java rename src/main/java/bisq/desktop/main/dao/{BaseProposalView.java => ItemsView.java} (89%) create mode 100644 src/main/java/bisq/desktop/main/dao/proposal/ProposalItemsView.java diff --git a/src/main/java/bisq/desktop/main/dao/ActiveView.java b/src/main/java/bisq/desktop/main/dao/ActiveView.java deleted file mode 100644 index 8869db46b7f..00000000000 --- a/src/main/java/bisq/desktop/main/dao/ActiveView.java +++ /dev/null @@ -1,399 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.desktop.main.dao; - -import bisq.desktop.common.view.FxmlView; -import bisq.desktop.components.BusyAnimation; -import bisq.desktop.components.InputTextField; -import bisq.desktop.components.TitledGroupBg; -import bisq.desktop.main.overlays.popups.Popup; -import bisq.desktop.util.BSFormatter; -import bisq.desktop.util.BsqFormatter; -import bisq.desktop.util.GUIUtil; -import bisq.desktop.util.Layout; - -import bisq.core.btc.exceptions.TransactionVerificationException; -import bisq.core.btc.exceptions.WalletException; -import bisq.core.btc.wallet.BsqBalanceListener; -import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.DaoFacade; -import bisq.core.dao.state.period.DaoPhase; -import bisq.core.dao.voting.proposal.Proposal; -import bisq.core.locale.Res; - -import bisq.common.util.Tuple2; -import bisq.common.util.Tuple3; - -import org.bitcoinj.core.Coin; -import org.bitcoinj.core.InsufficientMoneyException; -import org.bitcoinj.core.Transaction; - -import javax.inject.Inject; - -import javafx.scene.Node; -import javafx.scene.control.Button; -import javafx.scene.control.Label; -import javafx.scene.control.TableCell; -import javafx.scene.control.TableColumn; -import javafx.scene.control.TableView; - -import javafx.beans.property.ReadOnlyObjectWrapper; - -import javafx.util.Callback; - -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; - -import static bisq.desktop.util.FormBuilder.*; - -@FxmlView -public abstract class ActiveView extends BaseProposalView implements BsqBalanceListener { - - protected Button removeButton, acceptButton, rejectButton, removeMyVoteButton, voteButton; - protected InputTextField stakeInputTextField; - protected List voteViewItems = new ArrayList<>(); - protected BusyAnimation voteButtonBusyAnimation; - protected Label voteButtonInfoLabel; - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Constructor, lifecycle - /////////////////////////////////////////////////////////////////////////////////////////// - - @Inject - protected ActiveView(DaoFacade daoFacade, - BsqWalletService bsqWalletService, - BsqFormatter bsqFormatter, - BSFormatter btcFormatter) { - - super(daoFacade, bsqWalletService, bsqFormatter, btcFormatter); - } - - @Override - public void initialize() { - super.initialize(); - - createProposalsTableView(); - createVoteView(); - createProposalDisplay(); - } - - @Override - protected void activate() { - super.activate(); - - daoFacade.getActiveOrMyUnconfirmedProposals().addListener(proposalListChangeListener); - bsqWalletService.addBsqBalanceListener(this); - - onUpdateBalances(bsqWalletService.getAvailableBalance(), - bsqWalletService.getPendingBalance(), - bsqWalletService.getLockedForVotingBalance(), - bsqWalletService.getLockedInBondsBalance()); - - if (voteButton != null) { - voteButton.setOnAction(e -> { - // TODO verify stake - Coin stake = bsqFormatter.parseToCoin(stakeInputTextField.getText()); - final Coin blindVoteFee = daoFacade.getBlindVoteFeeForCycle(); - Transaction dummyTx = null; - try { - // We create a dummy tx to get the mining blindVoteFee for confirmation popup - dummyTx = daoFacade.getDummyBlindVoteTx(stake, blindVoteFee); - } catch (InsufficientMoneyException | WalletException | TransactionVerificationException exception) { - new Popup<>().warning(exception.toString()).show(); - } - - if (dummyTx != null) { - Coin miningFee = dummyTx.getFee(); - int txSize = dummyTx.bitcoinSerialize().length; - GUIUtil.showBsqFeeInfoPopup(blindVoteFee, miningFee, txSize, bsqFormatter, btcFormatter, - Res.get("dao.blindVote"), () -> publishBlindVote(stake)); - } - }); - } - } - - protected void publishBlindVote(Coin stake) { - voteButtonBusyAnimation.play(); - voteButtonInfoLabel.setText(Res.get("dao.blindVote.startPublishing")); - daoFacade.publishBlindVote(stake, - () -> { - voteButtonBusyAnimation.stop(); - voteButtonInfoLabel.setText(""); - new Popup().feedback(Res.get("dao.blindVote.success")) - .show(); - }, exception -> { - voteButtonBusyAnimation.stop(); - voteButtonInfoLabel.setText(""); - new Popup<>().warning(exception.toString()).show(); - }); - } - - @Override - protected void deactivate() { - super.deactivate(); - - daoFacade.getActiveOrMyUnconfirmedProposals().removeListener(proposalListChangeListener); - bsqWalletService.removeBsqBalanceListener(this); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Create views - /////////////////////////////////////////////////////////////////////////////////////////// - - - protected void createVoteView() { - TitledGroupBg titledGroupBg = addTitledGroupBg(root, ++gridRow, 1, Res.get("dao.proposal.votes.header"), - Layout.GROUP_DISTANCE - 20); - final Tuple2 tuple2 = addLabelInputTextField(root, gridRow, - Res.getWithCol("dao.proposal.myVote.stake"), Layout - .FIRST_ROW_AND_GROUP_DISTANCE - 20); - stakeInputTextField = tuple2.second; - Tuple3 tuple = addButtonBusyAnimationLabelAfterGroup(root, ++gridRow, Res.get("dao.proposal.myVote.button")); - voteButton = tuple.first; - voteButtonBusyAnimation = tuple.second; - voteButtonInfoLabel = tuple.third; - - voteViewItems.add(titledGroupBg); - voteViewItems.add(tuple2.first); - voteViewItems.add(stakeInputTextField); - voteViewItems.add(voteButton); - - changeVoteViewItemsVisibility(false); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Handlers - /////////////////////////////////////////////////////////////////////////////////////////// - - @Override - public void onUpdateBalances(Coin confirmedBalance, - Coin pendingBalance, - Coin lockedForVotingBalance, - Coin lockedInBondsBalance) { - stakeInputTextField.setPromptText(Res.get("dao.proposal.myVote.stake.prompt", - bsqFormatter.formatCoinWithCode(confirmedBalance))); - } - - protected void onSelectProposal(ListItem item) { - super.onSelectProposal(item); - if (item != null) { - if (removeButton != null) { - removeButton.setManaged(false); - removeButton.setVisible(false); - removeButton = null; - } - if (acceptButton != null) { - acceptButton.setManaged(false); - acceptButton.setVisible(false); - acceptButton = null; - } - if (rejectButton != null) { - rejectButton.setManaged(false); - rejectButton.setVisible(false); - rejectButton = null; - } - if (removeMyVoteButton != null) { - removeMyVoteButton.setManaged(false); - removeMyVoteButton.setVisible(false); - removeMyVoteButton = null; - } - - onPhaseChanged(daoFacade.phaseProperty().get()); - } - } - - protected void onAccept() { - //TODO - // daoFacade.setVote(selectedProposalListItem.getProposal(), new BooleanVote(true)); - updateStateAfterVote(); - } - - - protected void onReject() { - //TODO - // daoFacade.setVote(selectedProposalListItem.getProposal(), new BooleanVote(false)); - updateStateAfterVote(); - } - - protected void onCancelVote() { - //TODO - // daoFacade.setVote(selectedProposalListItem.getProposal(), null); - updateStateAfterVote(); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // ChainHeightListener - /////////////////////////////////////////////////////////////////////////////////////////// - - - @Override - protected void onPhaseChanged(DaoPhase.Phase phase) { - super.onPhaseChanged(phase); - - changeVoteViewItemsVisibility(phase == DaoPhase.Phase.BLIND_VOTE); - - if (removeButton != null) { - removeButton.setManaged(false); - removeButton.setVisible(false); - removeButton = null; - } - if (selectedProposalListItem != null && proposalDisplay != null) { - final Proposal proposal = selectedProposalListItem.getProposal(); - switch (phase) { - case PROPOSAL: - if (daoFacade.isMyProposal(proposal)) { - if (removeButton == null) { - removeButton = addButtonAfterGroup(detailsGridPane, proposalDisplay.incrementAndGetGridRow(), Res.get("dao.proposal.active.remove")); - removeButton.setOnAction(event -> onRemove()); - } else { - removeButton.setManaged(true); - removeButton.setVisible(true); - } - } - break; - case BREAK1: - break; - case BLIND_VOTE: - if (acceptButton == null) { - Tuple3 tuple = add3ButtonsAfterGroup(detailsGridPane, proposalDisplay - .incrementAndGetGridRow(), - Res.get("dao.proposal.myVote.accept"), - Res.get("dao.proposal.myVote.reject"), - Res.get("dao.proposal.myVote.removeMyVote")); - acceptButton = tuple.first; - acceptButton.setDefaultButton(false); - rejectButton = tuple.second; - removeMyVoteButton = tuple.third; - acceptButton.setOnAction(event -> onAccept()); - rejectButton.setOnAction(event -> onReject()); - removeMyVoteButton.setOnAction(event -> onCancelVote()); - } else { - //TODO prob. not possible code path - acceptButton.setManaged(true); - acceptButton.setVisible(true); - rejectButton.setManaged(true); - rejectButton.setVisible(true); - removeMyVoteButton.setManaged(true); - removeMyVoteButton.setVisible(true); - } - break; - case BREAK2: - break; - case VOTE_REVEAL: - break; - case BREAK3: - break; - case RESULT: - break; - case BREAK4: - break; - case UNDEFINED: - default: - log.error("Undefined phase: " + phase); - break; - } - } - } - - /////////////////////////////////////////////////////////////////////////////////////////// - // Protected - /////////////////////////////////////////////////////////////////////////////////////////// - - protected void updateStateAfterVote() { - hideProposalDisplay(); - proposalTableView.getSelectionModel().clearSelection(); - } - - protected void changeVoteViewItemsVisibility(boolean value) { - voteViewItems.forEach(node -> { - node.setVisible(value); - node.setManaged(value); - }); - } - - protected void onRemove() { - final Proposal proposal = selectedProposalListItem.getProposal(); - if (daoFacade.removeMyProposal(proposal)) { - hideProposalDisplay(); - } else { - new Popup<>().warning(Res.get("dao.proposal.active.remove.failed")).show(); - } - proposalTableView.getSelectionModel().clearSelection(); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // TableColumns - /////////////////////////////////////////////////////////////////////////////////////////// - - @Override - protected void createProposalColumns(TableView tableView) { - super.createProposalColumns(tableView); - createConfidenceColumn(tableView); - - TableColumn actionColumn = new TableColumn<>(); - actionColumn.setMinWidth(130); - actionColumn.setMaxWidth(actionColumn.getMinWidth()); - - actionColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - - actionColumn.setCellFactory(new Callback, - TableCell>() { - - @Override - public TableCell call(TableColumn column) { - return new TableCell() { - Node node; - - @Override - public void updateItem(final ListItem item, boolean empty) { - super.updateItem(item, empty); - - if (item != null && !empty) { - if (node == null) { - node = item.getActionNode(); - setGraphic(node); - item.setOnRemoveHandler(() -> { - ActiveView.this.selectedProposalListItem = item; - ActiveView.this.onRemove(); - }); - item.applyState(currentPhase); - } - } else { - setGraphic(null); - if (node != null) { - if (node instanceof Button) - ((Button) node).setOnAction(null); - node = null; - } - } - } - }; - } - }); - actionColumn.setComparator(Comparator.comparing(ListItem::getConfirmations)); - tableView.getColumns().add(actionColumn); - } -} - diff --git a/src/main/java/bisq/desktop/main/dao/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/ItemsView.java similarity index 89% rename from src/main/java/bisq/desktop/main/dao/BaseProposalView.java rename to src/main/java/bisq/desktop/main/dao/ItemsView.java index e0edb1b56b7..9e932c50188 100644 --- a/src/main/java/bisq/desktop/main/dao/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/ItemsView.java @@ -36,7 +36,6 @@ import javax.inject.Inject; -import javafx.scene.Node; import javafx.scene.control.ScrollPane; import javafx.scene.control.TableCell; import javafx.scene.control.TableColumn; @@ -51,21 +50,17 @@ import org.fxmisc.easybind.Subscription; import javafx.beans.property.ReadOnlyObjectWrapper; -import javafx.beans.value.ChangeListener; import javafx.collections.FXCollections; -import javafx.collections.ListChangeListener; import javafx.collections.ObservableList; import javafx.collections.transformation.SortedList; import javafx.util.Callback; -import java.util.ArrayList; import java.util.Comparator; -import java.util.List; @FxmlView -public abstract class BaseProposalView extends ActivatableView { +public abstract class ItemsView extends ActivatableView { protected final DaoFacade daoFacade; protected final BsqWalletService bsqWalletService; @@ -74,18 +69,17 @@ public abstract class BaseProposalView extends ActivatableView { protected final ObservableList proposalListItems = FXCollections.observableArrayList(); protected final SortedList sortedList = new SortedList<>(proposalListItems); - protected final List proposalViewItems = new ArrayList<>(); protected TableView proposalTableView; protected Subscription selectedProposalSubscription; protected ProposalDisplay proposalDisplay; protected int gridRow = 0; protected GridPane detailsGridPane, gridPane; - protected ListItem selectedProposalListItem; - protected ListChangeListener proposalListChangeListener; - protected ChangeListener phaseChangeListener; + protected ListItem selectedListItem; + protected DaoPhase.Phase currentPhase; protected Subscription phaseSubscription; private ScrollPane proposalDisplayView; + private boolean proposalDisplayInitialized; /////////////////////////////////////////////////////////////////////////////////////////// @@ -93,10 +87,10 @@ public abstract class BaseProposalView extends ActivatableView { /////////////////////////////////////////////////////////////////////////////////////////// @Inject - protected BaseProposalView(DaoFacade daoFacade, - BsqWalletService bsqWalletService, - BsqFormatter bsqFormatter, - BSFormatter btcFormatter) { + protected ItemsView(DaoFacade daoFacade, + BsqWalletService bsqWalletService, + BsqFormatter bsqFormatter, + BSFormatter btcFormatter) { this.daoFacade = daoFacade; this.bsqWalletService = bsqWalletService; this.bsqFormatter = bsqFormatter; @@ -109,9 +103,6 @@ public void initialize() { root.getStyleClass().add("vote-root"); detailsGridPane = new GridPane(); - - proposalListChangeListener = c -> updateListItems(); - phaseChangeListener = (observable, oldValue, newValue) -> onPhaseChanged(newValue); } @Override @@ -119,10 +110,6 @@ protected void activate() { phaseSubscription = EasyBind.subscribe(daoFacade.phaseProperty(), this::onPhaseChanged); selectedProposalSubscription = EasyBind.subscribe(proposalTableView.getSelectionModel().selectedItemProperty(), this::onSelectProposal); - daoFacade.phaseProperty().addListener(phaseChangeListener); - - onPhaseChanged(daoFacade.phaseProperty().get()); - sortedList.comparatorProperty().bind(proposalTableView.comparatorProperty()); updateListItems(); @@ -133,13 +120,11 @@ protected void deactivate() { phaseSubscription.unsubscribe(); selectedProposalSubscription.unsubscribe(); - daoFacade.phaseProperty().removeListener(phaseChangeListener); - sortedList.comparatorProperty().unbind(); proposalListItems.forEach(ListItem::cleanup); proposalTableView.getSelectionModel().clearSelection(); - selectedProposalListItem = null; + selectedListItem = null; } @@ -171,12 +156,9 @@ protected void createProposalsTableView(String header, double top) { root.getChildren().add(proposalTableView); proposalTableView.setItems(sortedList); - - proposalViewItems.add(proposalsHeadline); - proposalViewItems.add(proposalTableView); } - protected void createProposalDisplay() { + protected void createEmptyProposalDisplay() { proposalDisplay = new ProposalDisplay(detailsGridPane, bsqFormatter, bsqWalletService, null); proposalDisplayView = proposalDisplay.getView(); GridPane.setMargin(proposalDisplayView, new Insets(10, -10, 0, -10)); @@ -186,12 +168,14 @@ protected void createProposalDisplay() { } protected void hideProposalDisplay() { - proposalDisplay.removeAllFields(); - proposalDisplayView.setVisible(false); - proposalDisplayView.setManaged(false); + if (proposalDisplayInitialized) { + proposalDisplay.removeAllFields(); + proposalDisplayView.setVisible(false); + proposalDisplayView.setManaged(false); + } } - protected void showProposalDisplay(Proposal proposal) { + protected void createAllFieldsOnProposalDisplay(Proposal proposal) { proposalDisplayView.setVisible(true); proposalDisplayView.setManaged(true); @@ -199,6 +183,7 @@ protected void showProposalDisplay(Proposal proposal) { false, false); proposalDisplay.setEditable(false); proposalDisplay.applyProposalPayload(proposal); + proposalDisplayInitialized = true; } @@ -207,17 +192,19 @@ protected void showProposalDisplay(Proposal proposal) { /////////////////////////////////////////////////////////////////////////////////////////// protected void onSelectProposal(ListItem item) { - selectedProposalListItem = item; - if (selectedProposalListItem != null) - showProposalDisplay(selectedProposalListItem.getProposal()); + selectedListItem = item; + if (selectedListItem != null) + createAllFieldsOnProposalDisplay(selectedListItem.getProposal()); else hideProposalDisplay(); + + onPhaseChanged(daoFacade.phaseProperty().get()); } protected void onPhaseChanged(DaoPhase.Phase phase) { if (phase != null && !phase.equals(currentPhase)) { currentPhase = phase; - onSelectProposal(selectedProposalListItem); + onSelectProposal(selectedListItem); } } @@ -229,6 +216,7 @@ protected void onPhaseChanged(DaoPhase.Phase phase) { protected void updateListItems() { proposalListItems.forEach(ListItem::cleanup); proposalListItems.clear(); + fillListItems(); if (proposalListItems.isEmpty()) @@ -237,13 +225,6 @@ protected void updateListItems() { abstract protected void fillListItems(); - protected void changeProposalViewItemsVisibility(boolean value) { - proposalViewItems.forEach(node -> { - node.setVisible(value); - node.setManaged(value); - }); - } - /////////////////////////////////////////////////////////////////////////////////////////// // TableColumns diff --git a/src/main/java/bisq/desktop/main/dao/ListItem.java b/src/main/java/bisq/desktop/main/dao/ListItem.java index 966530160a6..03bfe611814 100644 --- a/src/main/java/bisq/desktop/main/dao/ListItem.java +++ b/src/main/java/bisq/desktop/main/dao/ListItem.java @@ -17,7 +17,6 @@ package bisq.desktop.main.dao; -import bisq.desktop.components.AutoTooltipButton; import bisq.desktop.components.indicator.TxConfidenceIndicator; import bisq.desktop.util.BsqFormatter; @@ -34,7 +33,6 @@ import org.bitcoinj.core.Transaction; import org.bitcoinj.core.TransactionConfidence; -import javafx.scene.Node; import javafx.scene.control.Tooltip; import javafx.scene.image.ImageView; @@ -44,7 +42,6 @@ import lombok.EqualsAndHashCode; import lombok.Getter; -import lombok.Setter; import lombok.ToString; import lombok.extern.slf4j.Slf4j; @@ -53,25 +50,22 @@ @EqualsAndHashCode public abstract class ListItem implements BlockListener { @Getter - private final DaoFacade daoFacade; - private final BsqWalletService bsqWalletService; - private final BsqFormatter bsqFormatter; + protected final DaoFacade daoFacade; + protected final BsqWalletService bsqWalletService; + protected final BsqFormatter bsqFormatter; - private ChangeListener chainHeightListener; + protected ChangeListener chainHeightListener; @Getter - private TxConfidenceIndicator txConfidenceIndicator; + protected TxConfidenceIndicator txConfidenceIndicator; @Getter - private Integer confirmations = 0; - - private TxConfidenceListener txConfidenceListener; - private Tooltip tooltip = new Tooltip(Res.get("confidence.unknown")); - private Transaction walletTransaction; - private ChangeListener phaseChangeListener; - private AutoTooltipButton actionButton; - private ImageView actionButtonIconView; - @Setter - private Runnable onRemoveHandler; - private Node actionNode; + protected Integer confirmations = 0; + + protected TxConfidenceListener txConfidenceListener; + protected Tooltip tooltip = new Tooltip(Res.get("confidence.unknown")); + protected Transaction walletTransaction; + protected ChangeListener phaseChangeListener; + protected ImageView actionButtonIconView; + // protected Node actionNode; protected ListItem(DaoFacade daoFacade, BsqWalletService bsqWalletService, @@ -81,7 +75,7 @@ protected ListItem(DaoFacade daoFacade, this.bsqFormatter = bsqFormatter; } - protected abstract Proposal getProposal(); + public abstract Proposal getProposal(); protected void init() { txConfidenceIndicator = new TxConfidenceIndicator(); @@ -91,8 +85,7 @@ protected void init() { txConfidenceIndicator.setPrefSize(24, 24); txConfidenceIndicator.setTooltip(tooltip); - actionButton = new AutoTooltipButton(); - actionButton.setMinWidth(70); + actionButtonIconView = new ImageView(); chainHeightListener = (observable, oldValue, newValue) -> setupConfidence(); @@ -109,69 +102,6 @@ protected void init() { } public void applyState(DaoPhase.Phase phase) { - if (phase != null) { - actionButton.setText(""); - actionButton.setVisible(false); - actionButton.setOnAction(null); - switch (phase) { - case UNDEFINED: - log.error("invalid state UNDEFINED"); - break; - case PROPOSAL: - if (daoFacade.isMyProposal(getProposal())) { - actionButtonIconView.setVisible(actionButton.isVisible()); - actionButton.setText(Res.get("shared.remove")); - actionButton.setGraphic(actionButtonIconView); - actionButtonIconView.setId("image-remove"); - actionButton.setOnAction(e -> { - if (onRemoveHandler != null) - onRemoveHandler.run(); - }); - actionNode = actionButton; - } - break; - case BREAK1: - break; - case BLIND_VOTE: - actionNode = actionButtonIconView; - actionButton.setVisible(false); - - //TODO - /* if (vote != null) { - actionButtonIconView.setVisible(true); - if (vote instanceof BooleanVote) { - if (((BooleanVote) vote).isAccepted()) { - actionButtonIconView.setId("accepted"); - } else { - actionButtonIconView.setId("rejected"); - } - } else { - //TODO - } - } else { - actionButtonIconView.setVisible(false); - }*/ - - break; - case BREAK2: - break; - case VOTE_REVEAL: - break; - case BREAK3: - break; - case RESULT: - break; - case BREAK4: - break; - default: - log.error("invalid state " + phase); - } - actionButton.setManaged(actionButton.isVisible()); - - // Don't set managed as otherwise the update does not work (not sure why but probably table - // cell item issue) - //actionButtonIconView.setManaged(actionButtonIconView.isVisible()); - } } @@ -186,7 +116,7 @@ public void onBlockAdded(Block block) { } // TODO reuse from other item - private void setupConfidence() { + protected void setupConfidence() { final String txId = getProposal().getTxId(); Optional optionalTx = daoFacade.getTx(txId); if (optionalTx.isPresent()) { @@ -222,7 +152,7 @@ public void onTransactionConfidenceChanged(TransactionConfidence confidence) { } } - private void updateConfidence(TransactionConfidence confidence, int depthInBlocks) { + protected void updateConfidence(TransactionConfidence confidence, int depthInBlocks) { if (confidence != null) { updateConfidence(confidence.getConfidenceType(), confidence.getDepthInBlocks(), confidence.numBroadcastPeers()); confirmations = depthInBlocks; @@ -238,7 +168,7 @@ public void cleanup() { daoFacade.phaseProperty().removeListener(phaseChangeListener); } - private void updateConfidence(TransactionConfidence.ConfidenceType confidenceType, int depthInBlocks, int numBroadcastPeers) { + protected void updateConfidence(TransactionConfidence.ConfidenceType confidenceType, int depthInBlocks, int numBroadcastPeers) { switch (confidenceType) { case UNKNOWN: tooltip.setText(Res.get("confidence.unknown")); @@ -260,9 +190,5 @@ private void updateConfidence(TransactionConfidence.ConfidenceType confidenceTyp txConfidenceIndicator.setPrefSize(24, 24); } - - public Node getActionNode() { - return actionNode; - } } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java index 4073ffed1c6..ea19d99c81b 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java @@ -176,21 +176,16 @@ public void applyProposalPayload(Proposal proposal) { } public void clearForm() { - if (uidTextField != null) - uidTextField.clear(); - nameTextField.clear(); - titleTextField.clear(); - descriptionTextArea.clear(); - linkInputTextField.clear(); - linkHyperlinkWithIcon.clear(); - if (requestedBsqTextField != null) - requestedBsqTextField.clear(); - if (bsqAddressTextField != null) - bsqAddressTextField.clear(); - if (txIdTextField != null) - txIdTextField.cleanup(); - - descriptionTextArea.textProperty().removeListener(descriptionTextAreaListener); + if (uidTextField != null) uidTextField.clear(); + if (nameTextField != null) nameTextField.clear(); + if (titleTextField != null) titleTextField.clear(); + if (descriptionTextArea != null) descriptionTextArea.clear(); + if (linkInputTextField != null) linkInputTextField.clear(); + if (linkHyperlinkWithIcon != null) linkHyperlinkWithIcon.clear(); + if (requestedBsqTextField != null) requestedBsqTextField.clear(); + if (bsqAddressTextField != null) bsqAddressTextField.clear(); + if (txIdTextField != null) txIdTextField.cleanup(); + if (descriptionTextArea != null) descriptionTextArea.textProperty().removeListener(descriptionTextAreaListener); } public void fillWithMock() { diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalItemsView.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalItemsView.java new file mode 100644 index 00000000000..bba47a3595b --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalItemsView.java @@ -0,0 +1,89 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.desktop.main.dao.proposal; + +import bisq.desktop.common.view.FxmlView; +import bisq.desktop.main.dao.ItemsView; +import bisq.desktop.util.BSFormatter; +import bisq.desktop.util.BsqFormatter; + +import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.dao.DaoFacade; +import bisq.core.dao.voting.proposal.Proposal; + +import javax.inject.Inject; + +import javafx.collections.ListChangeListener; +import javafx.collections.ObservableList; + +import java.util.List; +import java.util.stream.Collectors; + +@FxmlView +public abstract class ProposalItemsView extends ItemsView { + protected ListChangeListener listChangeListener; + + /////////////////////////////////////////////////////////////////////////////////////////// + // Constructor, lifecycle + /////////////////////////////////////////////////////////////////////////////////////////// + + @Inject + protected ProposalItemsView(DaoFacade daoFacade, + BsqWalletService bsqWalletService, + BsqFormatter bsqFormatter, + BSFormatter btcFormatter) { + + super(daoFacade, bsqWalletService, bsqFormatter, btcFormatter); + } + + @Override + public void initialize() { + super.initialize(); + + createProposalsTableView(); + createEmptyProposalDisplay(); + + listChangeListener = c -> updateListItems(); + } + + @Override + protected void activate() { + super.activate(); + + getProposals().addListener(listChangeListener); + } + + @Override + protected void deactivate() { + super.deactivate(); + + getProposals().removeListener(listChangeListener); + } + + @Override + protected void fillListItems() { + List list = getProposals(); + proposalListItems.setAll(list.stream() + .map(proposal -> new ProposalListItem(proposal, daoFacade, bsqWalletService, bsqFormatter)) + .collect(Collectors.toSet())); + } + + abstract protected ObservableList getProposals(); + +} + diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index 905174e0474..fb3b8dfc76d 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -17,14 +17,18 @@ package bisq.desktop.main.dao.proposal; +import bisq.desktop.components.AutoTooltipButton; import bisq.desktop.main.dao.ListItem; import bisq.desktop.util.BsqFormatter; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; +import bisq.core.dao.state.period.DaoPhase; import bisq.core.dao.voting.proposal.Proposal; +import bisq.core.locale.Res; import lombok.EqualsAndHashCode; +import lombok.Getter; import lombok.ToString; import lombok.extern.slf4j.Slf4j; @@ -33,6 +37,8 @@ @EqualsAndHashCode(callSuper = true) public class ProposalListItem extends ListItem { private final Proposal proposal; + @Getter + private AutoTooltipButton actionButton; public ProposalListItem(Proposal proposal, DaoFacade daoFacade, @@ -41,12 +47,37 @@ public ProposalListItem(Proposal proposal, super(daoFacade, bsqWalletService, bsqFormatter); + this.proposal = proposal; + init(); } @Override - protected Proposal getProposal() { + protected void init() { + super.init(); + + actionButtonIconView.setId("image-remove"); + + actionButton = new AutoTooltipButton(); + actionButton.setMinWidth(70); + actionButton.setText(Res.get("shared.remove")); + actionButton.setGraphic(actionButtonIconView); + } + + @Override + public void applyState(DaoPhase.Phase phase) { + super.applyState(phase); + + actionButton.setDisable(phase != DaoPhase.Phase.PROPOSAL); + + final boolean myProposal = daoFacade.isMyProposal(proposal); + // actionButton.setVisible(myProposal); + // actionButton.setManaged(myProposal); + } + + @Override + public Proposal getProposal() { return proposal; } } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index a8aab693199..abb3322c389 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -18,22 +18,41 @@ package bisq.desktop.main.dao.proposal.active; import bisq.desktop.common.view.FxmlView; -import bisq.desktop.main.dao.ActiveView; +import bisq.desktop.main.dao.ListItem; +import bisq.desktop.main.dao.proposal.ProposalItemsView; import bisq.desktop.main.dao.proposal.ProposalListItem; +import bisq.desktop.main.overlays.popups.Popup; import bisq.desktop.util.BSFormatter; import bisq.desktop.util.BsqFormatter; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; +import bisq.core.dao.state.period.DaoPhase; import bisq.core.dao.voting.proposal.Proposal; +import bisq.core.locale.Res; import javax.inject.Inject; -import java.util.List; -import java.util.stream.Collectors; +import javafx.scene.control.Button; +import javafx.scene.control.TableCell; +import javafx.scene.control.TableColumn; +import javafx.scene.control.TableView; + +import javafx.beans.property.ReadOnlyObjectWrapper; + +import javafx.collections.ObservableList; + +import javafx.util.Callback; + +import java.util.Comparator; + +import static bisq.desktop.util.FormBuilder.addButtonAfterGroup; @FxmlView -public class ActiveProposalsView extends ActiveView { +public class ActiveProposalsView extends ProposalItemsView { + + private Button removeButton; + /////////////////////////////////////////////////////////////////////////////////////////// // Constructor, lifecycle @@ -54,11 +73,95 @@ private ActiveProposalsView(DaoFacade daoFacade, /////////////////////////////////////////////////////////////////////////////////////////// @Override - protected void fillListItems() { - List list = daoFacade.getActiveOrMyUnconfirmedProposals(); - proposalListItems.setAll(list.stream() - .map(proposal -> new ProposalListItem(proposal, daoFacade, bsqWalletService, bsqFormatter)) - .collect(Collectors.toSet())); + protected ObservableList getProposals() { + return daoFacade.getActiveOrMyUnconfirmedProposals(); + } + + + @Override + protected void createAllFieldsOnProposalDisplay(Proposal proposal) { + super.createAllFieldsOnProposalDisplay(proposal); + + removeButton = addButtonAfterGroup(detailsGridPane, proposalDisplay.incrementAndGetGridRow(), Res.get("dao.proposal.active.remove")); + removeButton.setOnAction(event -> onRemove()); + removeButton.setDisable(daoFacade.phaseProperty().get() != DaoPhase.Phase.PROPOSAL); + + } + + @Override + protected void hideProposalDisplay() { + super.hideProposalDisplay(); + + if (removeButton != null) { + removeButton.setManaged(false); + removeButton.setVisible(false); + } + } + + protected void onRemove() { + final Proposal proposal = selectedListItem.getProposal(); + if (daoFacade.removeMyProposal(proposal)) { + hideProposalDisplay(); + } else { + new Popup<>().warning(Res.get("dao.proposal.active.remove.failed")).show(); + } + proposalTableView.getSelectionModel().clearSelection(); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // TableColumns + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + protected void createProposalColumns(TableView tableView) { + super.createProposalColumns(tableView); + createConfidenceColumn(tableView); + + TableColumn actionColumn = new TableColumn<>(); + actionColumn.setMinWidth(130); + actionColumn.setMaxWidth(actionColumn.getMinWidth()); + + actionColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + + actionColumn.setCellFactory(new Callback, + TableCell>() { + + @Override + public TableCell call(TableColumn column) { + return new TableCell() { + Button button; + + @Override + public void updateItem(final ListItem item, boolean empty) { + super.updateItem(item, empty); + + if (item != null && !empty) { + ProposalListItem proposalListItem = (ProposalListItem) item; + + proposalListItem.applyState(currentPhase); + if (button == null) { + button = proposalListItem.getActionButton(); + setGraphic(button); + button.setOnAction(e -> { + ActiveProposalsView.this.selectedListItem = item; + ActiveProposalsView.this.onRemove(); + }); + } + } else { + setGraphic(null); + if (button != null) { + button.setOnAction(null); + button = null; + } + } + } + }; + } + }); + actionColumn.setComparator(Comparator.comparing(ListItem::getConfirmations)); + tableView.getColumns().add(actionColumn); } } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java index 5c8b17a0cc0..03f49ee70d6 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java @@ -18,8 +18,7 @@ package bisq.desktop.main.dao.proposal.closed; import bisq.desktop.common.view.FxmlView; -import bisq.desktop.main.dao.BaseProposalView; -import bisq.desktop.main.dao.proposal.ProposalListItem; +import bisq.desktop.main.dao.proposal.ProposalItemsView; import bisq.desktop.util.BSFormatter; import bisq.desktop.util.BsqFormatter; @@ -29,11 +28,10 @@ import javax.inject.Inject; -import java.util.List; -import java.util.stream.Collectors; +import javafx.collections.ObservableList; @FxmlView -public class ClosedProposalsView extends BaseProposalView { +public class ClosedProposalsView extends ProposalItemsView { /////////////////////////////////////////////////////////////////////////////////////////// // Constructor, lifecycle @@ -49,31 +47,8 @@ private ClosedProposalsView(DaoFacade daoFacade, } @Override - public void initialize() { - super.initialize(); - - createProposalsTableView(); - createProposalDisplay(); - } - - @Override - protected void activate() { - super.activate(); - daoFacade.getClosedProposals().addListener(proposalListChangeListener); - } - - @Override - protected void deactivate() { - super.deactivate(); - daoFacade.getClosedProposals().removeListener(proposalListChangeListener); - } - - @Override - protected void fillListItems() { - List list = daoFacade.getClosedProposals(); - proposalListItems.setAll(list.stream() - .map(proposal -> new ProposalListItem(proposal, daoFacade, bsqWalletService, bsqFormatter)) - .collect(Collectors.toSet())); + protected ObservableList getProposals() { + return daoFacade.getClosedProposals(); } } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java index d3c4255a258..8fe43f3070f 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java @@ -31,7 +31,7 @@ import javafx.scene.layout.GridPane; @FxmlView -public class MyVotesView extends ActivatableView /*extends BaseProposalView*/ { +public class MyVotesView extends ActivatableView /*extends ItemsView*/ { private final Preferences preferences; /* diff --git a/src/main/java/bisq/desktop/main/dao/voting/BallotListItem.java b/src/main/java/bisq/desktop/main/dao/voting/BallotListItem.java index 9b929e3daca..04623d7b853 100644 --- a/src/main/java/bisq/desktop/main/dao/voting/BallotListItem.java +++ b/src/main/java/bisq/desktop/main/dao/voting/BallotListItem.java @@ -47,7 +47,7 @@ public BallotListItem(Ballot ballot, } @Override - protected Proposal getProposal() { + public Proposal getProposal() { return ballot.getProposal(); } } diff --git a/src/main/java/bisq/desktop/main/dao/voting/ballots/BallotsView.java b/src/main/java/bisq/desktop/main/dao/voting/ballots/BallotsView.java index dd7fb5637a8..267f22b37b4 100644 --- a/src/main/java/bisq/desktop/main/dao/voting/ballots/BallotsView.java +++ b/src/main/java/bisq/desktop/main/dao/voting/ballots/BallotsView.java @@ -18,22 +18,56 @@ package bisq.desktop.main.dao.voting.ballots; import bisq.desktop.common.view.FxmlView; -import bisq.desktop.main.dao.ActiveView; +import bisq.desktop.components.BusyAnimation; +import bisq.desktop.components.InputTextField; +import bisq.desktop.components.TitledGroupBg; +import bisq.desktop.main.dao.ItemsView; +import bisq.desktop.main.dao.ListItem; import bisq.desktop.main.dao.voting.BallotListItem; +import bisq.desktop.main.overlays.popups.Popup; import bisq.desktop.util.BSFormatter; import bisq.desktop.util.BsqFormatter; +import bisq.desktop.util.GUIUtil; +import bisq.desktop.util.Layout; +import bisq.core.btc.exceptions.TransactionVerificationException; +import bisq.core.btc.exceptions.WalletException; +import bisq.core.btc.wallet.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; +import bisq.core.dao.state.period.DaoPhase; import bisq.core.dao.voting.ballot.Ballot; +import bisq.core.locale.Res; + +import bisq.common.util.Tuple2; +import bisq.common.util.Tuple3; + +import org.bitcoinj.core.Coin; +import org.bitcoinj.core.InsufficientMoneyException; +import org.bitcoinj.core.Transaction; import javax.inject.Inject; +import javafx.scene.control.Button; +import javafx.scene.control.Label; + +import javafx.collections.ListChangeListener; + import java.util.List; import java.util.stream.Collectors; +import static bisq.desktop.util.FormBuilder.add3ButtonsAfterGroup; +import static bisq.desktop.util.FormBuilder.addButtonBusyAnimationLabelAfterGroup; +import static bisq.desktop.util.FormBuilder.addLabelInputTextField; +import static bisq.desktop.util.FormBuilder.addTitledGroupBg; + @FxmlView -public class BallotsView extends ActiveView { +public class BallotsView extends ItemsView implements BsqBalanceListener { + protected Button acceptButton, rejectButton, removeMyVoteButton, voteButton; + protected InputTextField stakeInputTextField; + protected BusyAnimation voteButtonBusyAnimation; + protected Label voteButtonInfoLabel; + protected ListChangeListener listChangeListener; /////////////////////////////////////////////////////////////////////////////////////////// // Constructor, lifecycle @@ -48,11 +82,130 @@ private BallotsView(DaoFacade daoFacade, super(daoFacade, bsqWalletService, bsqFormatter, btcFormatter); } + @Override + public void initialize() { + super.initialize(); + + createProposalsTableView(); + createVoteView(); + createEmptyProposalDisplay(); + + listChangeListener = c -> updateListItems(); + } + + @Override + protected void activate() { + super.activate(); + bsqWalletService.addBsqBalanceListener(this); + + daoFacade.getActiveOrMyUnconfirmedBallots().addListener(listChangeListener); + + onUpdateBalances(bsqWalletService.getAvailableBalance(), + bsqWalletService.getPendingBalance(), + bsqWalletService.getLockedForVotingBalance(), + bsqWalletService.getLockedInBondsBalance()); + + voteButton.setOnAction(e -> onVote()); + } + + + @Override + protected void deactivate() { + super.deactivate(); + + daoFacade.getActiveOrMyUnconfirmedBallots().removeListener(listChangeListener); + bsqWalletService.removeBsqBalanceListener(this); + } + /////////////////////////////////////////////////////////////////////////////////////////// // Protected /////////////////////////////////////////////////////////////////////////////////////////// + @Override + public void onUpdateBalances(Coin confirmedBalance, + Coin pendingBalance, + Coin lockedForVotingBalance, + Coin lockedInBondsBalance) { + stakeInputTextField.setPromptText(Res.get("dao.proposal.myVote.stake.prompt", + bsqFormatter.formatCoinWithCode(confirmedBalance))); + } + + + @Override + protected void onPhaseChanged(DaoPhase.Phase phase) { + super.onPhaseChanged(phase); + + if (selectedListItem != null && proposalDisplay != null) { + if (phase == DaoPhase.Phase.BLIND_VOTE) { + if (acceptButton == null) { + Tuple3 tuple = add3ButtonsAfterGroup(detailsGridPane, proposalDisplay + .incrementAndGetGridRow(), + Res.get("dao.proposal.myVote.accept"), + Res.get("dao.proposal.myVote.reject"), + Res.get("dao.proposal.myVote.removeMyVote")); + acceptButton = tuple.first; + acceptButton.setDefaultButton(false); + rejectButton = tuple.second; + removeMyVoteButton = tuple.third; + acceptButton.setOnAction(event -> onAccept()); + rejectButton.setOnAction(event -> onReject()); + removeMyVoteButton.setOnAction(event -> onCancelVote()); + } else { + //TODO prob. not possible code path + acceptButton.setManaged(true); + acceptButton.setVisible(true); + rejectButton.setManaged(true); + rejectButton.setVisible(true); + removeMyVoteButton.setManaged(true); + removeMyVoteButton.setVisible(true); + } + } + } + } + + /////////////////////////////////////////////////////////////////////////////////////////// + // Handlers + /////////////////////////////////////////////////////////////////////////////////////////// + + protected void onAccept() { + //TODO + // daoFacade.setVote(selectedProposalListItem.getProposal(), new BooleanVote(true)); + updateStateAfterVote(); + } + + + protected void onReject() { + //TODO + // daoFacade.setVote(selectedProposalListItem.getProposal(), new BooleanVote(false)); + updateStateAfterVote(); + } + + protected void onCancelVote() { + //TODO + // daoFacade.setVote(selectedProposalListItem.getProposal(), null); + updateStateAfterVote(); + } + + private void onVote() { + // TODO verify stake + Coin stake = bsqFormatter.parseToCoin(stakeInputTextField.getText()); + final Coin blindVoteFee = daoFacade.getBlindVoteFeeForCycle(); + Transaction dummyTx = null; + try { + // We create a dummy tx to get the mining blindVoteFee for confirmation popup + dummyTx = daoFacade.getDummyBlindVoteTx(stake, blindVoteFee); + } catch (InsufficientMoneyException | WalletException | TransactionVerificationException exception) { + new Popup<>().warning(exception.toString()).show(); + } + + if (dummyTx != null) { + Coin miningFee = dummyTx.getFee(); + int txSize = dummyTx.bitcoinSerialize().length; + GUIUtil.showBsqFeeInfoPopup(blindVoteFee, miningFee, txSize, bsqFormatter, btcFormatter, + Res.get("dao.blindVote"), () -> publishBlindVote(stake)); + } + } @Override protected void fillListItems() { @@ -61,5 +214,65 @@ protected void fillListItems() { .map(ballot -> new BallotListItem(ballot, daoFacade, bsqWalletService, bsqFormatter)) .collect(Collectors.toSet())); } -} + protected void publishBlindVote(Coin stake) { + voteButtonBusyAnimation.play(); + voteButtonInfoLabel.setText(Res.get("dao.blindVote.startPublishing")); + daoFacade.publishBlindVote(stake, + () -> { + voteButtonBusyAnimation.stop(); + voteButtonInfoLabel.setText(""); + new Popup().feedback(Res.get("dao.blindVote.success")) + .show(); + }, exception -> { + voteButtonBusyAnimation.stop(); + voteButtonInfoLabel.setText(""); + new Popup<>().warning(exception.toString()).show(); + }); + } + + protected void onSelectProposal(ListItem item) { + super.onSelectProposal(item); + if (item != null) { + if (acceptButton != null) { + acceptButton.setManaged(false); + acceptButton.setVisible(false); + acceptButton = null; + } + if (rejectButton != null) { + rejectButton.setManaged(false); + rejectButton.setVisible(false); + rejectButton = null; + } + if (removeMyVoteButton != null) { + removeMyVoteButton.setManaged(false); + removeMyVoteButton.setVisible(false); + removeMyVoteButton = null; + } + + onPhaseChanged(daoFacade.phaseProperty().get()); + } + } + + protected void updateStateAfterVote() { + hideProposalDisplay(); + proposalTableView.getSelectionModel().clearSelection(); + } + + /////////////////////////////////////////////////////////////////////////////////////////// + // Create views + /////////////////////////////////////////////////////////////////////////////////////////// + + protected void createVoteView() { + TitledGroupBg titledGroupBg = addTitledGroupBg(root, ++gridRow, 1, Res.get("dao.proposal.votes.header"), + Layout.GROUP_DISTANCE - 20); + final Tuple2 tuple2 = addLabelInputTextField(root, gridRow, + Res.getWithCol("dao.proposal.myVote.stake"), Layout + .FIRST_ROW_AND_GROUP_DISTANCE - 20); + stakeInputTextField = tuple2.second; + Tuple3 tuple = addButtonBusyAnimationLabelAfterGroup(root, ++gridRow, Res.get("dao.proposal.myVote.button")); + voteButton = tuple.first; + voteButtonBusyAnimation = tuple.second; + voteButtonInfoLabel = tuple.third; + } +} From c3f2ff29d8f141b03d1d76bcfc7985278a876832 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Mon, 30 Apr 2018 21:33:10 -0500 Subject: [PATCH 088/197] Separated voting view from proposals view by activeBallotsView --- ...istItem.java => BaseProposalListItem.java} | 81 +++--- .../{ItemsView.java => BaseProposalView.java} | 114 ++++---- .../main/dao/proposal/ProposalItemsView.java | 16 +- .../main/dao/proposal/ProposalListItem.java | 49 +--- .../active/ActiveProposalListItem.java | 84 ++++++ .../proposal/active/ActiveProposalsView.java | 50 ++-- .../closed/ClosedProposalListItem.java} | 30 +- .../proposal/closed/ClosedProposalsView.java | 11 + .../dao/proposal/myvotes/MyVotesView.java | 24 +- .../desktop/main/dao/voting/VotingView.java | 8 +- .../voting/active/ActiveBallotListItem.java | 96 +++++++ .../ActiveBallotsView.fxml} | 2 +- .../ActiveBallotsView.java} | 257 ++++++++++++------ 13 files changed, 543 insertions(+), 279 deletions(-) rename src/main/java/bisq/desktop/main/dao/{ListItem.java => BaseProposalListItem.java} (81%) rename src/main/java/bisq/desktop/main/dao/{ItemsView.java => BaseProposalView.java} (71%) create mode 100644 src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalListItem.java rename src/main/java/bisq/desktop/main/dao/{voting/BallotListItem.java => proposal/closed/ClosedProposalListItem.java} (62%) create mode 100644 src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotListItem.java rename src/main/java/bisq/desktop/main/dao/voting/{ballots/BallotsView.fxml => active/ActiveBallotsView.fxml} (97%) rename src/main/java/bisq/desktop/main/dao/voting/{ballots/BallotsView.java => active/ActiveBallotsView.java} (51%) diff --git a/src/main/java/bisq/desktop/main/dao/ListItem.java b/src/main/java/bisq/desktop/main/dao/BaseProposalListItem.java similarity index 81% rename from src/main/java/bisq/desktop/main/dao/ListItem.java rename to src/main/java/bisq/desktop/main/dao/BaseProposalListItem.java index 03bfe611814..9c1d3bb8f9a 100644 --- a/src/main/java/bisq/desktop/main/dao/ListItem.java +++ b/src/main/java/bisq/desktop/main/dao/BaseProposalListItem.java @@ -48,7 +48,7 @@ @ToString @Slf4j @EqualsAndHashCode -public abstract class ListItem implements BlockListener { +public abstract class BaseProposalListItem implements BlockListener { @Getter protected final DaoFacade daoFacade; protected final BsqWalletService bsqWalletService; @@ -64,19 +64,56 @@ public abstract class ListItem implements BlockListener { protected Tooltip tooltip = new Tooltip(Res.get("confidence.unknown")); protected Transaction walletTransaction; protected ChangeListener phaseChangeListener; - protected ImageView actionButtonIconView; - // protected Node actionNode; + @Getter + protected ImageView imageView; + - protected ListItem(DaoFacade daoFacade, - BsqWalletService bsqWalletService, - BsqFormatter bsqFormatter) { + /////////////////////////////////////////////////////////////////////////////////////////// + // Constructor, lifecycle + /////////////////////////////////////////////////////////////////////////////////////////// + + protected BaseProposalListItem(DaoFacade daoFacade, + BsqWalletService bsqWalletService, + BsqFormatter bsqFormatter) { this.daoFacade = daoFacade; this.bsqWalletService = bsqWalletService; this.bsqFormatter = bsqFormatter; } + + /////////////////////////////////////////////////////////////////////////////////////////// + // BlockListener + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public void onBlockAdded(Block block) { + setupConfidence(); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Public + /////////////////////////////////////////////////////////////////////////////////////////// + + public void onPhase(DaoPhase.Phase phase) { + } + + public void cleanup() { + daoFacade.removeBlockListener(this); + bsqWalletService.getChainHeightProperty().removeListener(chainHeightListener); + if (txConfidenceListener != null) + bsqWalletService.removeTxConfidenceListener(txConfidenceListener); + + daoFacade.phaseProperty().removeListener(phaseChangeListener); + } + public abstract Proposal getProposal(); + + /////////////////////////////////////////////////////////////////////////////////////////// + // Protected + /////////////////////////////////////////////////////////////////////////////////////////// + protected void init() { txConfidenceIndicator = new TxConfidenceIndicator(); txConfidenceIndicator.setId("funds-confidence"); @@ -86,7 +123,7 @@ protected void init() { txConfidenceIndicator.setTooltip(tooltip); - actionButtonIconView = new ImageView(); + imageView = new ImageView(); chainHeightListener = (observable, oldValue, newValue) -> setupConfidence(); bsqWalletService.getChainHeightProperty().addListener(chainHeightListener); @@ -94,29 +131,18 @@ protected void init() { daoFacade.addBlockListener(this); - phaseChangeListener = (observable, oldValue, newValue) -> { - applyState(newValue); - }; + phaseChangeListener = (observable, oldValue, newValue) -> onPhase(newValue); daoFacade.phaseProperty().addListener(phaseChangeListener); } - public void applyState(DaoPhase.Phase phase) { - } - /////////////////////////////////////////////////////////////////////////////////////////// - // Listener + // Private /////////////////////////////////////////////////////////////////////////////////////////// - @Override - public void onBlockAdded(Block block) { - //TODO do we want that here??? - setupConfidence(); - } - // TODO reuse from other item - protected void setupConfidence() { + private void setupConfidence() { final String txId = getProposal().getTxId(); Optional optionalTx = daoFacade.getTx(txId); if (optionalTx.isPresent()) { @@ -152,23 +178,14 @@ public void onTransactionConfidenceChanged(TransactionConfidence confidence) { } } - protected void updateConfidence(TransactionConfidence confidence, int depthInBlocks) { + private void updateConfidence(TransactionConfidence confidence, int depthInBlocks) { if (confidence != null) { updateConfidence(confidence.getConfidenceType(), confidence.getDepthInBlocks(), confidence.numBroadcastPeers()); confirmations = depthInBlocks; } } - public void cleanup() { - daoFacade.removeBlockListener(this); - bsqWalletService.getChainHeightProperty().removeListener(chainHeightListener); - if (txConfidenceListener != null) - bsqWalletService.removeTxConfidenceListener(txConfidenceListener); - - daoFacade.phaseProperty().removeListener(phaseChangeListener); - } - - protected void updateConfidence(TransactionConfidence.ConfidenceType confidenceType, int depthInBlocks, int numBroadcastPeers) { + private void updateConfidence(TransactionConfidence.ConfidenceType confidenceType, int depthInBlocks, int numBroadcastPeers) { switch (confidenceType) { case UNKNOWN: tooltip.setText(Res.get("confidence.unknown")); diff --git a/src/main/java/bisq/desktop/main/dao/ItemsView.java b/src/main/java/bisq/desktop/main/dao/BaseProposalView.java similarity index 71% rename from src/main/java/bisq/desktop/main/dao/ItemsView.java rename to src/main/java/bisq/desktop/main/dao/BaseProposalView.java index 9e932c50188..f16fe2bb4e1 100644 --- a/src/main/java/bisq/desktop/main/dao/ItemsView.java +++ b/src/main/java/bisq/desktop/main/dao/BaseProposalView.java @@ -60,21 +60,21 @@ import java.util.Comparator; @FxmlView -public abstract class ItemsView extends ActivatableView { +public abstract class BaseProposalView extends ActivatableView { protected final DaoFacade daoFacade; protected final BsqWalletService bsqWalletService; protected final BsqFormatter bsqFormatter; protected final BSFormatter btcFormatter; - protected final ObservableList proposalListItems = FXCollections.observableArrayList(); - protected final SortedList sortedList = new SortedList<>(proposalListItems); - protected TableView proposalTableView; + protected final ObservableList proposalBaseProposalListItems = FXCollections.observableArrayList(); + protected final SortedList sortedList = new SortedList<>(proposalBaseProposalListItems); + protected TableView proposalTableView; protected Subscription selectedProposalSubscription; protected ProposalDisplay proposalDisplay; protected int gridRow = 0; protected GridPane detailsGridPane, gridPane; - protected ListItem selectedListItem; + protected BaseProposalListItem selectedBaseProposalListItem; protected DaoPhase.Phase currentPhase; protected Subscription phaseSubscription; @@ -87,10 +87,10 @@ public abstract class ItemsView extends ActivatableView { /////////////////////////////////////////////////////////////////////////////////////////// @Inject - protected ItemsView(DaoFacade daoFacade, - BsqWalletService bsqWalletService, - BsqFormatter bsqFormatter, - BSFormatter btcFormatter) { + protected BaseProposalView(DaoFacade daoFacade, + BsqWalletService bsqWalletService, + BsqFormatter bsqFormatter, + BSFormatter btcFormatter) { this.daoFacade = daoFacade; this.bsqWalletService = bsqWalletService; this.bsqFormatter = bsqFormatter; @@ -122,9 +122,9 @@ protected void deactivate() { sortedList.comparatorProperty().unbind(); - proposalListItems.forEach(ListItem::cleanup); + proposalBaseProposalListItems.forEach(BaseProposalListItem::cleanup); proposalTableView.getSelectionModel().clearSelection(); - selectedListItem = null; + selectedBaseProposalListItem = null; } @@ -191,10 +191,10 @@ protected void createAllFieldsOnProposalDisplay(Proposal proposal) { // Handlers /////////////////////////////////////////////////////////////////////////////////////////// - protected void onSelectProposal(ListItem item) { - selectedListItem = item; - if (selectedListItem != null) - createAllFieldsOnProposalDisplay(selectedListItem.getProposal()); + protected void onSelectProposal(BaseProposalListItem item) { + selectedBaseProposalListItem = item; + if (selectedBaseProposalListItem != null) + createAllFieldsOnProposalDisplay(selectedBaseProposalListItem.getProposal()); else hideProposalDisplay(); @@ -204,7 +204,7 @@ protected void onSelectProposal(ListItem item) { protected void onPhaseChanged(DaoPhase.Phase phase) { if (phase != null && !phase.equals(currentPhase)) { currentPhase = phase; - onSelectProposal(selectedListItem); + onSelectProposal(selectedBaseProposalListItem); } } @@ -214,12 +214,12 @@ protected void onPhaseChanged(DaoPhase.Phase phase) { /////////////////////////////////////////////////////////////////////////////////////////// protected void updateListItems() { - proposalListItems.forEach(ListItem::cleanup); - proposalListItems.clear(); + proposalBaseProposalListItems.forEach(BaseProposalListItem::cleanup); + proposalBaseProposalListItems.clear(); fillListItems(); - if (proposalListItems.isEmpty()) + if (proposalBaseProposalListItems.isEmpty()) hideProposalDisplay(); } @@ -230,8 +230,8 @@ protected void updateListItems() { // TableColumns /////////////////////////////////////////////////////////////////////////////////////////// - protected void createProposalColumns(TableView tableView) { - TableColumn dateColumn = new AutoTooltipTableColumn(Res.get("shared.dateTime")) { + protected void createProposalColumns(TableView tableView) { + TableColumn dateColumn = new AutoTooltipTableColumn(Res.get("shared.dateTime")) { { setMinWidth(190); setMaxWidth(190); @@ -239,14 +239,14 @@ protected void createProposalColumns(TableView tableView) { }; dateColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); dateColumn.setCellFactory( - new Callback, TableCell>() { + new Callback, TableCell>() { @Override - public TableCell call( - TableColumn column) { - return new TableCell() { + public TableCell call( + TableColumn column) { + return new TableCell() { @Override - public void updateItem(final ListItem item, boolean empty) { + public void updateItem(final BaseProposalListItem item, boolean empty) { super.updateItem(item, empty); if (item != null) setText(bsqFormatter.formatDateTime(item.getProposal().getCreationDate())); @@ -261,17 +261,17 @@ public void updateItem(final ListItem item, boolean empty) { tableView.getColumns().add(dateColumn); tableView.getSortOrder().add(dateColumn); - TableColumn nameColumn = new AutoTooltipTableColumn<>(Res.get("shared.name")); + TableColumn nameColumn = new AutoTooltipTableColumn<>(Res.get("shared.name")); nameColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); nameColumn.setCellFactory( - new Callback, TableCell>() { + new Callback, TableCell>() { @Override - public TableCell call( - TableColumn column) { - return new TableCell() { + public TableCell call( + TableColumn column) { + return new TableCell() { @Override - public void updateItem(final ListItem item, boolean empty) { + public void updateItem(final BaseProposalListItem item, boolean empty) { super.updateItem(item, empty); if (item != null) setText(item.getProposal().getName()); @@ -284,18 +284,18 @@ public void updateItem(final ListItem item, boolean empty) { nameColumn.setComparator(Comparator.comparing(o2 -> o2.getProposal().getName())); tableView.getColumns().add(nameColumn); - TableColumn titleColumn = new AutoTooltipTableColumn<>(Res.get("dao.proposal.title")); + TableColumn titleColumn = new AutoTooltipTableColumn<>(Res.get("dao.proposal.title")); titleColumn.setPrefWidth(100); titleColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); titleColumn.setCellFactory( - new Callback, TableCell>() { + new Callback, TableCell>() { @Override - public TableCell call( - TableColumn column) { - return new TableCell() { + public TableCell call( + TableColumn column) { + return new TableCell() { @Override - public void updateItem(final ListItem item, boolean empty) { + public void updateItem(final BaseProposalListItem item, boolean empty) { super.updateItem(item, empty); if (item != null) setText(item.getProposal().getTitle()); @@ -308,20 +308,20 @@ public void updateItem(final ListItem item, boolean empty) { titleColumn.setComparator(Comparator.comparing(o2 -> o2.getProposal().getTitle())); tableView.getColumns().add(titleColumn); - TableColumn uidColumn = new AutoTooltipTableColumn<>(Res.get("shared.id")); + TableColumn uidColumn = new AutoTooltipTableColumn<>(Res.get("shared.id")); uidColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); uidColumn.setCellFactory( - new Callback, TableCell>() { + new Callback, TableCell>() { @Override - public TableCell call(TableColumn column) { - return new TableCell() { + public TableCell call(TableColumn column) { + return new TableCell() { private HyperlinkWithIcon field; @Override - public void updateItem(final ListItem item, boolean empty) { + public void updateItem(final BaseProposalListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { final Proposal proposal = item.getProposal(); @@ -344,23 +344,23 @@ public void updateItem(final ListItem item, boolean empty) { tableView.getColumns().add(uidColumn); } - protected void createConfidenceColumn(TableView tableView) { - TableColumn confidenceColumn = new TableColumn<>(Res.get("shared.confirmations")); + protected void createConfidenceColumn(TableView tableView) { + TableColumn confidenceColumn = new TableColumn<>(Res.get("shared.confirmations")); confidenceColumn.setMinWidth(130); confidenceColumn.setMaxWidth(confidenceColumn.getMinWidth()); confidenceColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - confidenceColumn.setCellFactory(new Callback, - TableCell>() { + confidenceColumn.setCellFactory(new Callback, + TableCell>() { @Override - public TableCell call(TableColumn column) { - return new TableCell() { + public TableCell call(TableColumn column) { + return new TableCell() { @Override - public void updateItem(final ListItem item, boolean empty) { + public void updateItem(final BaseProposalListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { @@ -372,7 +372,7 @@ public void updateItem(final ListItem item, boolean empty) { }; } }); - confidenceColumn.setComparator(Comparator.comparing(ListItem::getConfirmations)); + confidenceColumn.setComparator(Comparator.comparing(BaseProposalListItem::getConfirmations)); tableView.getColumns().add(confidenceColumn); } } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalItemsView.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalItemsView.java index bba47a3595b..5c84bf97261 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalItemsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalItemsView.java @@ -18,7 +18,7 @@ package bisq.desktop.main.dao.proposal; import bisq.desktop.common.view.FxmlView; -import bisq.desktop.main.dao.ItemsView; +import bisq.desktop.main.dao.BaseProposalView; import bisq.desktop.util.BSFormatter; import bisq.desktop.util.BsqFormatter; @@ -31,11 +31,8 @@ import javafx.collections.ListChangeListener; import javafx.collections.ObservableList; -import java.util.List; -import java.util.stream.Collectors; - @FxmlView -public abstract class ProposalItemsView extends ItemsView { +public abstract class ProposalItemsView extends BaseProposalView { protected ListChangeListener listChangeListener; /////////////////////////////////////////////////////////////////////////////////////////// @@ -75,15 +72,6 @@ protected void deactivate() { getProposals().removeListener(listChangeListener); } - @Override - protected void fillListItems() { - List list = getProposals(); - proposalListItems.setAll(list.stream() - .map(proposal -> new ProposalListItem(proposal, daoFacade, bsqWalletService, bsqFormatter)) - .collect(Collectors.toSet())); - } - abstract protected ObservableList getProposals(); - } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index fb3b8dfc76d..772dd72c484 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -17,33 +17,32 @@ package bisq.desktop.main.dao.proposal; -import bisq.desktop.components.AutoTooltipButton; -import bisq.desktop.main.dao.ListItem; +import bisq.desktop.main.dao.BaseProposalListItem; import bisq.desktop.util.BsqFormatter; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; -import bisq.core.dao.state.period.DaoPhase; import bisq.core.dao.voting.proposal.Proposal; -import bisq.core.locale.Res; import lombok.EqualsAndHashCode; -import lombok.Getter; import lombok.ToString; import lombok.extern.slf4j.Slf4j; @ToString @Slf4j @EqualsAndHashCode(callSuper = true) -public class ProposalListItem extends ListItem { - private final Proposal proposal; - @Getter - private AutoTooltipButton actionButton; +public abstract class ProposalListItem extends BaseProposalListItem { + protected final Proposal proposal; - public ProposalListItem(Proposal proposal, - DaoFacade daoFacade, - BsqWalletService bsqWalletService, - BsqFormatter bsqFormatter) { + + /////////////////////////////////////////////////////////////////////////////////////////// + // Constructor, lifecycle + /////////////////////////////////////////////////////////////////////////////////////////// + + protected ProposalListItem(Proposal proposal, + DaoFacade daoFacade, + BsqWalletService bsqWalletService, + BsqFormatter bsqFormatter) { super(daoFacade, bsqWalletService, bsqFormatter); @@ -53,28 +52,10 @@ public ProposalListItem(Proposal proposal, init(); } - @Override - protected void init() { - super.init(); - - actionButtonIconView.setId("image-remove"); - - actionButton = new AutoTooltipButton(); - actionButton.setMinWidth(70); - actionButton.setText(Res.get("shared.remove")); - actionButton.setGraphic(actionButtonIconView); - } - - @Override - public void applyState(DaoPhase.Phase phase) { - super.applyState(phase); - actionButton.setDisable(phase != DaoPhase.Phase.PROPOSAL); - - final boolean myProposal = daoFacade.isMyProposal(proposal); - // actionButton.setVisible(myProposal); - // actionButton.setManaged(myProposal); - } + /////////////////////////////////////////////////////////////////////////////////////////// + // Protected + /////////////////////////////////////////////////////////////////////////////////////////// @Override public Proposal getProposal() { diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalListItem.java new file mode 100644 index 00000000000..dc23f1cdc3e --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalListItem.java @@ -0,0 +1,84 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.desktop.main.dao.proposal.active; + +import bisq.desktop.components.AutoTooltipButton; +import bisq.desktop.main.dao.proposal.ProposalListItem; +import bisq.desktop.util.BsqFormatter; + +import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.dao.DaoFacade; +import bisq.core.dao.state.period.DaoPhase; +import bisq.core.dao.voting.proposal.Proposal; +import bisq.core.locale.Res; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.ToString; +import lombok.extern.slf4j.Slf4j; + +@ToString +@Slf4j +@EqualsAndHashCode(callSuper = true) +public class ActiveProposalListItem extends ProposalListItem { + @Getter + private AutoTooltipButton actionButton; + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Constructor, lifecycle + /////////////////////////////////////////////////////////////////////////////////////////// + + ActiveProposalListItem(Proposal proposal, + DaoFacade daoFacade, + BsqWalletService bsqWalletService, + BsqFormatter bsqFormatter) { + super(proposal, + daoFacade, + bsqWalletService, + bsqFormatter); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Protected + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + protected void init() { + super.init(); + + imageView.setId("image-remove"); + + actionButton = new AutoTooltipButton(); + actionButton.setMinWidth(70); + actionButton.setText(Res.get("shared.remove")); + actionButton.setGraphic(imageView); + } + + @Override + public void onPhase(DaoPhase.Phase phase) { + super.onPhase(phase); + + actionButton.setDisable(phase != DaoPhase.Phase.PROPOSAL); + + final boolean myProposal = daoFacade.isMyProposal(proposal); + actionButton.setVisible(myProposal); + actionButton.setManaged(myProposal); + } +} diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index abb3322c389..bdf3e81488e 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -18,9 +18,8 @@ package bisq.desktop.main.dao.proposal.active; import bisq.desktop.common.view.FxmlView; -import bisq.desktop.main.dao.ListItem; +import bisq.desktop.main.dao.BaseProposalListItem; import bisq.desktop.main.dao.proposal.ProposalItemsView; -import bisq.desktop.main.dao.proposal.ProposalListItem; import bisq.desktop.main.overlays.popups.Popup; import bisq.desktop.util.BSFormatter; import bisq.desktop.util.BsqFormatter; @@ -45,6 +44,8 @@ import javafx.util.Callback; import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; import static bisq.desktop.util.FormBuilder.addButtonAfterGroup; @@ -98,8 +99,20 @@ protected void hideProposalDisplay() { } } - protected void onRemove() { - final Proposal proposal = selectedListItem.getProposal(); + @Override + protected void fillListItems() { + List list = getProposals(); + proposalBaseProposalListItems.setAll(list.stream() + .map(proposal -> new ActiveProposalListItem(proposal, daoFacade, bsqWalletService, bsqFormatter)) + .collect(Collectors.toSet())); + } + + /////////////////////////////////////////////////////////////////////////////////////////// + // Handlers + /////////////////////////////////////////////////////////////////////////////////////////// + + private void onRemove() { + final Proposal proposal = selectedBaseProposalListItem.getProposal(); if (daoFacade.removeMyProposal(proposal)) { hideProposalDisplay(); } else { @@ -114,41 +127,40 @@ protected void onRemove() { /////////////////////////////////////////////////////////////////////////////////////////// @Override - protected void createProposalColumns(TableView tableView) { + protected void createProposalColumns(TableView tableView) { super.createProposalColumns(tableView); createConfidenceColumn(tableView); - TableColumn actionColumn = new TableColumn<>(); + TableColumn actionColumn = new TableColumn<>(); actionColumn.setMinWidth(130); actionColumn.setMaxWidth(actionColumn.getMinWidth()); actionColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - actionColumn.setCellFactory(new Callback, - TableCell>() { + actionColumn.setCellFactory(new Callback, + TableCell>() { @Override - public TableCell call(TableColumn column) { - return new TableCell() { + public TableCell call(TableColumn column) { + return new TableCell() { Button button; @Override - public void updateItem(final ListItem item, boolean empty) { + public void updateItem(final BaseProposalListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { - ProposalListItem proposalListItem = (ProposalListItem) item; - - proposalListItem.applyState(currentPhase); + ActiveProposalListItem activeProposalListItem = (ActiveProposalListItem) item; if (button == null) { - button = proposalListItem.getActionButton(); - setGraphic(button); + button = activeProposalListItem.getActionButton(); button.setOnAction(e -> { - ActiveProposalsView.this.selectedListItem = item; + ActiveProposalsView.this.selectedBaseProposalListItem = item; ActiveProposalsView.this.onRemove(); }); + setGraphic(button); } + activeProposalListItem.onPhase(currentPhase); } else { setGraphic(null); if (button != null) { @@ -160,7 +172,7 @@ public void updateItem(final ListItem item, boolean empty) { }; } }); - actionColumn.setComparator(Comparator.comparing(ListItem::getConfirmations)); + actionColumn.setComparator(Comparator.comparing(BaseProposalListItem::getConfirmations)); tableView.getColumns().add(actionColumn); } } diff --git a/src/main/java/bisq/desktop/main/dao/voting/BallotListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalListItem.java similarity index 62% rename from src/main/java/bisq/desktop/main/dao/voting/BallotListItem.java rename to src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalListItem.java index 04623d7b853..4334fbb0f21 100644 --- a/src/main/java/bisq/desktop/main/dao/voting/BallotListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalListItem.java @@ -15,14 +15,13 @@ * along with Bisq. If not, see . */ -package bisq.desktop.main.dao.voting; +package bisq.desktop.main.dao.proposal.closed; -import bisq.desktop.main.dao.ListItem; +import bisq.desktop.main.dao.proposal.ProposalListItem; import bisq.desktop.util.BsqFormatter; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; -import bisq.core.dao.voting.ballot.Ballot; import bisq.core.dao.voting.proposal.Proposal; import lombok.EqualsAndHashCode; @@ -32,22 +31,19 @@ @ToString @Slf4j @EqualsAndHashCode(callSuper = true) -public class BallotListItem extends ListItem { - private final Ballot ballot; +public class ClosedProposalListItem extends ProposalListItem { - public BallotListItem(Ballot ballot, - DaoFacade daoFacade, - BsqWalletService bsqWalletService, - BsqFormatter bsqFormatter) { - super(daoFacade, + /////////////////////////////////////////////////////////////////////////////////////////// + // Constructor, lifecycle + /////////////////////////////////////////////////////////////////////////////////////////// + + ClosedProposalListItem(Proposal proposal, + DaoFacade daoFacade, + BsqWalletService bsqWalletService, + BsqFormatter bsqFormatter) { + super(proposal, + daoFacade, bsqWalletService, bsqFormatter); - this.ballot = ballot; - init(); - } - - @Override - public Proposal getProposal() { - return ballot.getProposal(); } } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java index 03f49ee70d6..5beadb6fa81 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java @@ -30,6 +30,9 @@ import javafx.collections.ObservableList; +import java.util.List; +import java.util.stream.Collectors; + @FxmlView public class ClosedProposalsView extends ProposalItemsView { @@ -50,5 +53,13 @@ private ClosedProposalsView(DaoFacade daoFacade, protected ObservableList getProposals() { return daoFacade.getClosedProposals(); } + + @Override + protected void fillListItems() { + List list = getProposals(); + proposalBaseProposalListItems.setAll(list.stream() + .map(proposal -> new ClosedProposalListItem(proposal, daoFacade, bsqWalletService, bsqFormatter)) + .collect(Collectors.toSet())); + } } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java index 8fe43f3070f..b98e12b9433 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java @@ -31,7 +31,7 @@ import javafx.scene.layout.GridPane; @FxmlView -public class MyVotesView extends ActivatableView /*extends ItemsView*/ { +public class MyVotesView extends ActivatableView /*extends BaseProposalView*/ { private final Preferences preferences; /* @@ -153,8 +153,8 @@ protected List getProposalList() { } @Override - protected ListItem getListItem(Proposal proposal) { - return new ProposalListItem(proposal, daoFacade, bsqWalletService, bsqFormatter); + protected BaseProposalListItem getListItem(Proposal proposal) { + return new ActiveProposalListItem(proposal, daoFacade, bsqWalletService, bsqFormatter); } /////////////////////////////////////////////////////////////////////////////////////////// @@ -313,26 +313,26 @@ public void updateItem(final VoteListItem item, boolean empty) { @Override - protected void createProposalColumns(TableView tableView) { + protected void createProposalColumns(TableView tableView) { super.createProposalColumns(tableView); - TableColumn actionColumn = new TableColumn<>(Res.get("dao.proposal.votes.header")); + TableColumn actionColumn = new TableColumn<>(Res.get("dao.proposal.votes.header")); actionColumn.setMinWidth(50); actionColumn.setMaxWidth(actionColumn.getMinWidth()); actionColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - actionColumn.setCellFactory(new Callback, - TableCell>() { + actionColumn.setCellFactory(new Callback, + TableCell>() { @Override - public TableCell call(TableColumn column) { - return new TableCell() { + public TableCell call(TableColumn column) { + return new TableCell() { ImageView actionButtonIconView; @Override - public void updateItem(final ListItem item, boolean empty) { + public void updateItem(final BaseProposalListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { @@ -357,7 +357,7 @@ public void updateItem(final ListItem item, boolean empty) { }; } }); - actionColumn.setComparator(Comparator.comparing(ListItem::getConfirmations)); + actionColumn.setComparator(Comparator.comparing(BaseProposalListItem::getConfirmations)); tableView.getColumns().add(actionColumn); }*/ } diff --git a/src/main/java/bisq/desktop/main/dao/voting/VotingView.java b/src/main/java/bisq/desktop/main/dao/voting/VotingView.java index a3cbad879c1..b1da86a9056 100644 --- a/src/main/java/bisq/desktop/main/dao/voting/VotingView.java +++ b/src/main/java/bisq/desktop/main/dao/voting/VotingView.java @@ -27,7 +27,7 @@ import bisq.desktop.components.MenuItem; import bisq.desktop.main.MainView; import bisq.desktop.main.dao.DaoView; -import bisq.desktop.main.dao.voting.ballots.BallotsView; +import bisq.desktop.main.dao.voting.active.ActiveBallotsView; import bisq.desktop.main.dao.voting.dashboard.VotingDashboardView; import bisq.core.locale.Res; @@ -82,7 +82,7 @@ public void initialize() { dashboard = new MenuItem(navigation, toggleGroup, Res.get("shared.dashboard"), VotingDashboardView.class, AwesomeIcon.DASHBOARD, baseNavPath); ballots = new MenuItem(navigation, toggleGroup, Res.get("dao.voting.menuItem.ballots"), - BallotsView.class, AwesomeIcon.LIST_UL, baseNavPath); + ActiveBallotsView.class, AwesomeIcon.LIST_UL, baseNavPath); leftVBox.getChildren().addAll(dashboard, ballots); } @@ -96,7 +96,7 @@ protected void activate() { if (viewPath.size() == 3 && viewPath.indexOf(VotingView.class) == 2 || viewPath.size() == 2 && viewPath.indexOf(DaoView.class) == 1) { if (selectedViewClass == null) - selectedViewClass = BallotsView.class; + selectedViewClass = ActiveBallotsView.class; loadView(selectedViewClass); @@ -119,7 +119,7 @@ private void loadView(Class viewClass) { content.getChildren().setAll(view.getRoot()); if (view instanceof VotingDashboardView) dashboard.setSelected(true); - else if (view instanceof BallotsView) ballots.setSelected(true); + else if (view instanceof ActiveBallotsView) ballots.setSelected(true); } public Class getSelectedViewClass() { diff --git a/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotListItem.java b/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotListItem.java new file mode 100644 index 00000000000..b73fe41c7b0 --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotListItem.java @@ -0,0 +1,96 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.desktop.main.dao.voting.active; + +import bisq.desktop.main.dao.BaseProposalListItem; +import bisq.desktop.util.BsqFormatter; + +import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.dao.DaoFacade; +import bisq.core.dao.state.period.DaoPhase; +import bisq.core.dao.voting.ballot.Ballot; +import bisq.core.dao.voting.ballot.vote.BooleanVote; +import bisq.core.dao.voting.ballot.vote.Vote; +import bisq.core.dao.voting.proposal.Proposal; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.ToString; +import lombok.extern.slf4j.Slf4j; + +@ToString +@Slf4j +@EqualsAndHashCode(callSuper = true) +public class ActiveBallotListItem extends BaseProposalListItem { + @Getter + private final Ballot ballot; + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Constructor, lifecycle + /////////////////////////////////////////////////////////////////////////////////////////// + + public ActiveBallotListItem(Ballot ballot, + DaoFacade daoFacade, + BsqWalletService bsqWalletService, + BsqFormatter bsqFormatter) { + super(daoFacade, + bsqWalletService, + bsqFormatter); + + this.ballot = ballot; + + init(); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Protected + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + protected void init() { + super.init(); + } + + @Override + public void onPhase(DaoPhase.Phase phase) { + super.onPhase(phase); + + final Vote vote = ballot.getVote(); + if (vote != null) { + imageView.setVisible(true); + if (vote instanceof BooleanVote) { + if (((BooleanVote) vote).isAccepted()) { + imageView.setId("accepted"); + } else { + imageView.setId("rejected"); + } + } else { + //TODO + } + } else { + imageView.setVisible(false); + } + } + + @Override + public Proposal getProposal() { + return ballot.getProposal(); + } +} diff --git a/src/main/java/bisq/desktop/main/dao/voting/ballots/BallotsView.fxml b/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.fxml similarity index 97% rename from src/main/java/bisq/desktop/main/dao/voting/ballots/BallotsView.fxml rename to src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.fxml index 76cd4c69bc1..833129da2b1 100644 --- a/src/main/java/bisq/desktop/main/dao/voting/ballots/BallotsView.fxml +++ b/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.fxml @@ -21,7 +21,7 @@ - diff --git a/src/main/java/bisq/desktop/main/dao/voting/ballots/BallotsView.java b/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.java similarity index 51% rename from src/main/java/bisq/desktop/main/dao/voting/ballots/BallotsView.java rename to src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.java index 267f22b37b4..8aa2aabd710 100644 --- a/src/main/java/bisq/desktop/main/dao/voting/ballots/BallotsView.java +++ b/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.java @@ -15,15 +15,14 @@ * along with Bisq. If not, see . */ -package bisq.desktop.main.dao.voting.ballots; +package bisq.desktop.main.dao.voting.active; import bisq.desktop.common.view.FxmlView; import bisq.desktop.components.BusyAnimation; import bisq.desktop.components.InputTextField; import bisq.desktop.components.TitledGroupBg; -import bisq.desktop.main.dao.ItemsView; -import bisq.desktop.main.dao.ListItem; -import bisq.desktop.main.dao.voting.BallotListItem; +import bisq.desktop.main.dao.BaseProposalListItem; +import bisq.desktop.main.dao.BaseProposalView; import bisq.desktop.main.overlays.popups.Popup; import bisq.desktop.util.BSFormatter; import bisq.desktop.util.BsqFormatter; @@ -37,6 +36,8 @@ import bisq.core.dao.DaoFacade; import bisq.core.dao.state.period.DaoPhase; import bisq.core.dao.voting.ballot.Ballot; +import bisq.core.dao.voting.ballot.vote.BooleanVote; +import bisq.core.dao.voting.proposal.Proposal; import bisq.core.locale.Res; import bisq.common.util.Tuple2; @@ -50,9 +51,18 @@ import javafx.scene.control.Button; import javafx.scene.control.Label; +import javafx.scene.control.TableCell; +import javafx.scene.control.TableColumn; +import javafx.scene.control.TableView; +import javafx.scene.image.ImageView; + +import javafx.beans.property.ReadOnlyObjectWrapper; import javafx.collections.ListChangeListener; +import javafx.util.Callback; + +import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; @@ -62,22 +72,22 @@ import static bisq.desktop.util.FormBuilder.addTitledGroupBg; @FxmlView -public class BallotsView extends ItemsView implements BsqBalanceListener { - protected Button acceptButton, rejectButton, removeMyVoteButton, voteButton; - protected InputTextField stakeInputTextField; - protected BusyAnimation voteButtonBusyAnimation; - protected Label voteButtonInfoLabel; - protected ListChangeListener listChangeListener; +public class ActiveBallotsView extends BaseProposalView implements BsqBalanceListener { + private Button acceptButton, rejectButton, removeMyVoteButton, voteButton; + private InputTextField stakeInputTextField; + private BusyAnimation voteButtonBusyAnimation; + private Label voteButtonInfoLabel; + private ListChangeListener listChangeListener; /////////////////////////////////////////////////////////////////////////////////////////// // Constructor, lifecycle /////////////////////////////////////////////////////////////////////////////////////////// @Inject - private BallotsView(DaoFacade daoFacade, - BsqWalletService bsqWalletService, - BsqFormatter bsqFormatter, - BSFormatter btcFormatter) { + private ActiveBallotsView(DaoFacade daoFacade, + BsqWalletService bsqWalletService, + BsqFormatter bsqFormatter, + BSFormatter btcFormatter) { super(daoFacade, bsqWalletService, bsqFormatter, btcFormatter); } @@ -96,8 +106,8 @@ public void initialize() { @Override protected void activate() { super.activate(); - bsqWalletService.addBsqBalanceListener(this); + bsqWalletService.addBsqBalanceListener(this); daoFacade.getActiveOrMyUnconfirmedBallots().addListener(listChangeListener); onUpdateBalances(bsqWalletService.getAvailableBalance(), @@ -119,7 +129,7 @@ protected void deactivate() { /////////////////////////////////////////////////////////////////////////////////////////// - // Protected + // BsqBalanceListener /////////////////////////////////////////////////////////////////////////////////////////// @Override @@ -132,58 +142,85 @@ public void onUpdateBalances(Coin confirmedBalance, } + /////////////////////////////////////////////////////////////////////////////////////////// + // Protected + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + protected void fillListItems() { + List list = daoFacade.getActiveOrMyUnconfirmedBallots(); + proposalBaseProposalListItems.setAll(list.stream() + .map(ballot -> new ActiveBallotListItem(ballot, daoFacade, bsqWalletService, bsqFormatter)) + .collect(Collectors.toSet())); + } + + @Override + protected void createAllFieldsOnProposalDisplay(Proposal proposal) { + super.createAllFieldsOnProposalDisplay(proposal); + + Tuple3 tuple = add3ButtonsAfterGroup(detailsGridPane, + proposalDisplay.incrementAndGetGridRow(), + Res.get("dao.proposal.myVote.accept"), + Res.get("dao.proposal.myVote.reject"), + Res.get("dao.proposal.myVote.removeMyVote")); + acceptButton = tuple.first; + acceptButton.setDefaultButton(false); + rejectButton = tuple.second; + removeMyVoteButton = tuple.third; + acceptButton.setOnAction(event -> onAccept()); + rejectButton.setOnAction(event -> onReject()); + removeMyVoteButton.setOnAction(event -> onCancelVote()); + } + + @Override + protected void hideProposalDisplay() { + super.hideProposalDisplay(); + + if (acceptButton != null) { + acceptButton.setManaged(false); + acceptButton.setVisible(false); + } + if (rejectButton != null) { + rejectButton.setManaged(false); + rejectButton.setVisible(false); + } + if (removeMyVoteButton != null) { + removeMyVoteButton.setManaged(false); + removeMyVoteButton.setVisible(false); + } + } + @Override protected void onPhaseChanged(DaoPhase.Phase phase) { super.onPhaseChanged(phase); - if (selectedListItem != null && proposalDisplay != null) { - if (phase == DaoPhase.Phase.BLIND_VOTE) { - if (acceptButton == null) { - Tuple3 tuple = add3ButtonsAfterGroup(detailsGridPane, proposalDisplay - .incrementAndGetGridRow(), - Res.get("dao.proposal.myVote.accept"), - Res.get("dao.proposal.myVote.reject"), - Res.get("dao.proposal.myVote.removeMyVote")); - acceptButton = tuple.first; - acceptButton.setDefaultButton(false); - rejectButton = tuple.second; - removeMyVoteButton = tuple.third; - acceptButton.setOnAction(event -> onAccept()); - rejectButton.setOnAction(event -> onReject()); - removeMyVoteButton.setOnAction(event -> onCancelVote()); - } else { - //TODO prob. not possible code path - acceptButton.setManaged(true); - acceptButton.setVisible(true); - rejectButton.setManaged(true); - rejectButton.setVisible(true); - removeMyVoteButton.setManaged(true); - removeMyVoteButton.setVisible(true); - } - } - } + updateButtons(); + } + + @Override + protected void onSelectProposal(BaseProposalListItem item) { + super.onSelectProposal(item); + + updateButtons(); } + /////////////////////////////////////////////////////////////////////////////////////////// // Handlers /////////////////////////////////////////////////////////////////////////////////////////// - protected void onAccept() { - //TODO - // daoFacade.setVote(selectedProposalListItem.getProposal(), new BooleanVote(true)); + private void onAccept() { + daoFacade.setVote(getBallotListItem().getBallot(), new BooleanVote(true)); updateStateAfterVote(); } - - protected void onReject() { - //TODO - // daoFacade.setVote(selectedProposalListItem.getProposal(), new BooleanVote(false)); + private void onReject() { + daoFacade.setVote(getBallotListItem().getBallot(), new BooleanVote(false)); updateStateAfterVote(); } - protected void onCancelVote() { - //TODO - // daoFacade.setVote(selectedProposalListItem.getProposal(), null); + private void onCancelVote() { + daoFacade.setVote(getBallotListItem().getBallot(), null); updateStateAfterVote(); } @@ -207,15 +244,12 @@ private void onVote() { } } - @Override - protected void fillListItems() { - List list = daoFacade.getActiveOrMyUnconfirmedBallots(); - proposalListItems.setAll(list.stream() - .map(ballot -> new BallotListItem(ballot, daoFacade, bsqWalletService, bsqFormatter)) - .collect(Collectors.toSet())); - } - protected void publishBlindVote(Coin stake) { + /////////////////////////////////////////////////////////////////////////////////////////// + // Private + /////////////////////////////////////////////////////////////////////////////////////////// + + private void publishBlindVote(Coin stake) { voteButtonBusyAnimation.play(); voteButtonInfoLabel.setText(Res.get("dao.blindVote.startPublishing")); daoFacade.publishBlindVote(stake, @@ -231,48 +265,93 @@ protected void publishBlindVote(Coin stake) { }); } - protected void onSelectProposal(ListItem item) { - super.onSelectProposal(item); - if (item != null) { - if (acceptButton != null) { - acceptButton.setManaged(false); - acceptButton.setVisible(false); - acceptButton = null; - } - if (rejectButton != null) { - rejectButton.setManaged(false); - rejectButton.setVisible(false); - rejectButton = null; - } - if (removeMyVoteButton != null) { - removeMyVoteButton.setManaged(false); - removeMyVoteButton.setVisible(false); - removeMyVoteButton = null; - } - - onPhaseChanged(daoFacade.phaseProperty().get()); - } - } - protected void updateStateAfterVote() { + private void updateStateAfterVote() { hideProposalDisplay(); proposalTableView.getSelectionModel().clearSelection(); + proposalTableView.refresh(); + } + + private ActiveBallotListItem getBallotListItem() { + return (ActiveBallotListItem) selectedBaseProposalListItem; + } + + private void updateButtons() { + if (selectedBaseProposalListItem != null && proposalDisplay != null) { + final boolean isBlindVotePhase = daoFacade.phaseProperty().get() == DaoPhase.Phase.BLIND_VOTE; + stakeInputTextField.setDisable(!isBlindVotePhase); + voteButton.setDisable(!isBlindVotePhase); + + acceptButton.setDisable(!isBlindVotePhase); + rejectButton.setDisable(!isBlindVotePhase); + removeMyVoteButton.setDisable(!isBlindVotePhase); + } } + /////////////////////////////////////////////////////////////////////////////////////////// // Create views /////////////////////////////////////////////////////////////////////////////////////////// - protected void createVoteView() { - TitledGroupBg titledGroupBg = addTitledGroupBg(root, ++gridRow, 1, Res.get("dao.proposal.votes.header"), - Layout.GROUP_DISTANCE - 20); + private void createVoteView() { + TitledGroupBg titledGroupBg = addTitledGroupBg(root, ++gridRow, 1, + Res.get("dao.proposal.votes.header"), Layout.GROUP_DISTANCE - 20); final Tuple2 tuple2 = addLabelInputTextField(root, gridRow, - Res.getWithCol("dao.proposal.myVote.stake"), Layout - .FIRST_ROW_AND_GROUP_DISTANCE - 20); + Res.getWithCol("dao.proposal.myVote.stake"), Layout.FIRST_ROW_AND_GROUP_DISTANCE - 20); stakeInputTextField = tuple2.second; - Tuple3 tuple = addButtonBusyAnimationLabelAfterGroup(root, ++gridRow, Res.get("dao.proposal.myVote.button")); + Tuple3 tuple = addButtonBusyAnimationLabelAfterGroup(root, ++gridRow, + Res.get("dao.proposal.myVote.button")); voteButton = tuple.first; voteButtonBusyAnimation = tuple.second; voteButtonInfoLabel = tuple.third; } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // TableColumns + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + protected void createProposalColumns(TableView tableView) { + super.createProposalColumns(tableView); + createConfidenceColumn(tableView); + + TableColumn actionColumn = new TableColumn<>(); + actionColumn.setMinWidth(130); + actionColumn.setMaxWidth(actionColumn.getMinWidth()); + + actionColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + + actionColumn.setCellFactory(new Callback, + TableCell>() { + + @Override + public TableCell call(TableColumn column) { + return new TableCell() { + ImageView imageView; + + @Override + public void updateItem(final BaseProposalListItem item, boolean empty) { + super.updateItem(item, empty); + + if (item != null && !empty) { + ActiveBallotListItem activeBallotListItem = (ActiveBallotListItem) item; + if (imageView == null) { + imageView = activeBallotListItem.getImageView(); + setGraphic(imageView); + } + activeBallotListItem.onPhase(currentPhase); + } else { + setGraphic(null); + if (imageView != null) + imageView = null; + } + } + }; + } + }); + actionColumn.setComparator(Comparator.comparing(BaseProposalListItem::getConfirmations)); + tableView.getColumns().add(actionColumn); + } } From ab1bcd3aa022f91d3cfeef4c09f2c8a5c6865efd Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Mon, 30 Apr 2018 22:23:22 -0500 Subject: [PATCH 089/197] Add MyProposalListService to CorePers.DataHost --- .../main/dao/BaseProposalListItem.java | 4 ++-- .../active/ActiveProposalListItem.java | 20 +++++++++---------- .../proposal/active/ActiveProposalsView.java | 19 ++++++++++++++++-- .../voting/active/ActiveBallotListItem.java | 4 ++-- .../dao/voting/active/ActiveBallotsView.java | 5 ++--- 5 files changed, 33 insertions(+), 19 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/BaseProposalListItem.java b/src/main/java/bisq/desktop/main/dao/BaseProposalListItem.java index 9c1d3bb8f9a..064a7497806 100644 --- a/src/main/java/bisq/desktop/main/dao/BaseProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/BaseProposalListItem.java @@ -95,7 +95,7 @@ public void onBlockAdded(Block block) { // Public /////////////////////////////////////////////////////////////////////////////////////////// - public void onPhase(DaoPhase.Phase phase) { + public void onPhaseChanged(DaoPhase.Phase phase) { } public void cleanup() { @@ -131,7 +131,7 @@ protected void init() { daoFacade.addBlockListener(this); - phaseChangeListener = (observable, oldValue, newValue) -> onPhase(newValue); + phaseChangeListener = (observable, oldValue, newValue) -> onPhaseChanged(newValue); daoFacade.phaseProperty().addListener(phaseChangeListener); } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalListItem.java index dc23f1cdc3e..4b253f16a8b 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalListItem.java @@ -37,7 +37,7 @@ @EqualsAndHashCode(callSuper = true) public class ActiveProposalListItem extends ProposalListItem { @Getter - private AutoTooltipButton actionButton; + private AutoTooltipButton removeButton; /////////////////////////////////////////////////////////////////////////////////////////// @@ -65,20 +65,20 @@ protected void init() { imageView.setId("image-remove"); - actionButton = new AutoTooltipButton(); - actionButton.setMinWidth(70); - actionButton.setText(Res.get("shared.remove")); - actionButton.setGraphic(imageView); + removeButton = new AutoTooltipButton(); + removeButton.setMinWidth(70); + removeButton.setText(Res.get("shared.remove")); + removeButton.setGraphic(imageView); } @Override - public void onPhase(DaoPhase.Phase phase) { - super.onPhase(phase); + public void onPhaseChanged(DaoPhase.Phase phase) { + super.onPhaseChanged(phase); - actionButton.setDisable(phase != DaoPhase.Phase.PROPOSAL); + removeButton.setDisable(phase != DaoPhase.Phase.PROPOSAL); final boolean myProposal = daoFacade.isMyProposal(proposal); - actionButton.setVisible(myProposal); - actionButton.setManaged(myProposal); + removeButton.setVisible(myProposal); + removeButton.setManaged(myProposal); } } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index bdf3e81488e..8293c1d2158 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -107,6 +107,21 @@ protected void fillListItems() { .collect(Collectors.toSet())); } + + @Override + public void onPhaseChanged(DaoPhase.Phase phase) { + super.onPhaseChanged(phase); + + if (removeButton != null) { + removeButton.setDisable(phase != DaoPhase.Phase.PROPOSAL); + if (selectedBaseProposalListItem != null && selectedBaseProposalListItem.getProposal() != null) { + final boolean myProposal = daoFacade.isMyProposal(selectedBaseProposalListItem.getProposal()); + removeButton.setVisible(myProposal); + removeButton.setManaged(myProposal); + } + } + } + /////////////////////////////////////////////////////////////////////////////////////////// // Handlers /////////////////////////////////////////////////////////////////////////////////////////// @@ -153,14 +168,14 @@ public void updateItem(final BaseProposalListItem item, boolean empty) { if (item != null && !empty) { ActiveProposalListItem activeProposalListItem = (ActiveProposalListItem) item; if (button == null) { - button = activeProposalListItem.getActionButton(); + button = activeProposalListItem.getRemoveButton(); button.setOnAction(e -> { ActiveProposalsView.this.selectedBaseProposalListItem = item; ActiveProposalsView.this.onRemove(); }); setGraphic(button); } - activeProposalListItem.onPhase(currentPhase); + activeProposalListItem.onPhaseChanged(currentPhase); } else { setGraphic(null); if (button != null) { diff --git a/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotListItem.java b/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotListItem.java index b73fe41c7b0..327896885ee 100644 --- a/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotListItem.java +++ b/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotListItem.java @@ -69,8 +69,8 @@ protected void init() { } @Override - public void onPhase(DaoPhase.Phase phase) { - super.onPhase(phase); + public void onPhaseChanged(DaoPhase.Phase phase) { + super.onPhaseChanged(phase); final Vote vote = ballot.getVote(); if (vote != null) { diff --git a/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.java b/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.java index 8aa2aabd710..18e86eeb38f 100644 --- a/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.java +++ b/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.java @@ -20,7 +20,6 @@ import bisq.desktop.common.view.FxmlView; import bisq.desktop.components.BusyAnimation; import bisq.desktop.components.InputTextField; -import bisq.desktop.components.TitledGroupBg; import bisq.desktop.main.dao.BaseProposalListItem; import bisq.desktop.main.dao.BaseProposalView; import bisq.desktop.main.overlays.popups.Popup; @@ -294,7 +293,7 @@ private void updateButtons() { /////////////////////////////////////////////////////////////////////////////////////////// private void createVoteView() { - TitledGroupBg titledGroupBg = addTitledGroupBg(root, ++gridRow, 1, + addTitledGroupBg(root, ++gridRow, 1, Res.get("dao.proposal.votes.header"), Layout.GROUP_DISTANCE - 20); final Tuple2 tuple2 = addLabelInputTextField(root, gridRow, Res.getWithCol("dao.proposal.myVote.stake"), Layout.FIRST_ROW_AND_GROUP_DISTANCE - 20); @@ -341,7 +340,7 @@ public void updateItem(final BaseProposalListItem item, boolean empty) { imageView = activeBallotListItem.getImageView(); setGraphic(imageView); } - activeBallotListItem.onPhase(currentPhase); + activeBallotListItem.onPhaseChanged(currentPhase); } else { setGraphic(null); if (imageView != null) From 90e310263b132a47b7fc4d71e6c529ee49ef4a1a Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sat, 5 May 2018 20:08:27 -0500 Subject: [PATCH 090/197] Use BlockHash and data for append-only store We add the blockHash of the 10th block in the break before the relevant phase as part of the hash in the appen-only data. Together with the date tolerance we get control over the time when the data has been added. This protects agains various attacks (data withhold and publish late attack). - Implement DateTolerantPayload at BlindVoteAppendOnlyPayload and ProposalAppendOnlyPayload - Implement ExpirablePayload at ProposalPayload and BlindVotePayload - Add blockHash and data at BlindVoteAppendOnlyPayload and ProposalAppendOnlyPayload - Add ClosedBallotsView --- .../desktop/main/dao/voting/VotingView.java | 18 +- .../dao/voting/active/ActiveBallotsView.java | 34 ++-- .../voting/closed/ClosedBallotListItem.java | 96 +++++++++++ .../dao/voting/closed/ClosedBallotsView.fxml | 33 ++++ .../dao/voting/closed/ClosedBallotsView.java | 160 ++++++++++++++++++ .../VotingHistoryView.fxml | 2 +- .../VotingHistoryView.java | 2 +- 7 files changed, 327 insertions(+), 18 deletions(-) create mode 100644 src/main/java/bisq/desktop/main/dao/voting/closed/ClosedBallotListItem.java create mode 100644 src/main/java/bisq/desktop/main/dao/voting/closed/ClosedBallotsView.fxml create mode 100644 src/main/java/bisq/desktop/main/dao/voting/closed/ClosedBallotsView.java rename src/main/java/bisq/desktop/main/dao/voting/{history => closed}/VotingHistoryView.fxml (97%) rename src/main/java/bisq/desktop/main/dao/voting/{history => closed}/VotingHistoryView.java (96%) diff --git a/src/main/java/bisq/desktop/main/dao/voting/VotingView.java b/src/main/java/bisq/desktop/main/dao/voting/VotingView.java index b1da86a9056..79aa9d5a507 100644 --- a/src/main/java/bisq/desktop/main/dao/voting/VotingView.java +++ b/src/main/java/bisq/desktop/main/dao/voting/VotingView.java @@ -28,6 +28,7 @@ import bisq.desktop.main.MainView; import bisq.desktop.main.dao.DaoView; import bisq.desktop.main.dao.voting.active.ActiveBallotsView; +import bisq.desktop.main.dao.voting.closed.ClosedBallotsView; import bisq.desktop.main.dao.voting.dashboard.VotingDashboardView; import bisq.core.locale.Res; @@ -51,7 +52,7 @@ public class VotingView extends ActivatableViewAndModel { private final ViewLoader viewLoader; private final Navigation navigation; - private MenuItem dashboard, ballots; + private MenuItem dashboard, activeBallots, closedBallots; private Navigation.Listener listener; @FXML @@ -81,15 +82,18 @@ public void initialize() { final List> baseNavPath = Arrays.asList(MainView.class, DaoView.class, VotingView.class); dashboard = new MenuItem(navigation, toggleGroup, Res.get("shared.dashboard"), VotingDashboardView.class, AwesomeIcon.DASHBOARD, baseNavPath); - ballots = new MenuItem(navigation, toggleGroup, Res.get("dao.voting.menuItem.ballots"), + activeBallots = new MenuItem(navigation, toggleGroup, Res.get("dao.voting.menuItem.activeBallots"), ActiveBallotsView.class, AwesomeIcon.LIST_UL, baseNavPath); - leftVBox.getChildren().addAll(dashboard, ballots); + closedBallots = new MenuItem(navigation, toggleGroup, Res.get("dao.voting.menuItem.closedBallots"), + ClosedBallotsView.class, AwesomeIcon.LIST_UL, baseNavPath); + leftVBox.getChildren().addAll(dashboard, activeBallots, closedBallots); } @Override protected void activate() { dashboard.activate(); - ballots.activate(); + activeBallots.activate(); + closedBallots.activate(); navigation.addListener(listener); ViewPath viewPath = navigation.getCurrentPath(); @@ -111,7 +115,8 @@ protected void deactivate() { navigation.removeListener(listener); dashboard.deactivate(); - ballots.deactivate(); + activeBallots.deactivate(); + closedBallots.deactivate(); } private void loadView(Class viewClass) { @@ -119,7 +124,8 @@ private void loadView(Class viewClass) { content.getChildren().setAll(view.getRoot()); if (view instanceof VotingDashboardView) dashboard.setSelected(true); - else if (view instanceof ActiveBallotsView) ballots.setSelected(true); + else if (view instanceof ActiveBallotsView) activeBallots.setSelected(true); + else if (view instanceof ClosedBallotsView) closedBallots.setSelected(true); } public Class getSelectedViewClass() { diff --git a/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.java b/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.java index 18e86eeb38f..2b81719b858 100644 --- a/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.java +++ b/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.java @@ -33,6 +33,8 @@ import bisq.core.btc.wallet.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; +import bisq.core.dao.state.BlockListener; +import bisq.core.dao.state.blockchain.Block; import bisq.core.dao.state.period.DaoPhase; import bisq.core.dao.voting.ballot.Ballot; import bisq.core.dao.voting.ballot.vote.BooleanVote; @@ -71,7 +73,7 @@ import static bisq.desktop.util.FormBuilder.addTitledGroupBg; @FxmlView -public class ActiveBallotsView extends BaseProposalView implements BsqBalanceListener { +public class ActiveBallotsView extends BaseProposalView implements BsqBalanceListener, BlockListener { private Button acceptButton, rejectButton, removeMyVoteButton, voteButton; private InputTextField stakeInputTextField; private BusyAnimation voteButtonBusyAnimation; @@ -115,6 +117,10 @@ protected void activate() { bsqWalletService.getLockedInBondsBalance()); voteButton.setOnAction(e -> onVote()); + + daoFacade.addBlockListener(this); + + updateButtons(); } @@ -140,6 +146,15 @@ public void onUpdateBalances(Coin confirmedBalance, bsqFormatter.formatCoinWithCode(confirmedBalance))); } + /////////////////////////////////////////////////////////////////////////////////////////// + // BlockListener + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public void onBlockAdded(Block block) { + updateButtons(); + } + /////////////////////////////////////////////////////////////////////////////////////////// // Protected @@ -151,6 +166,7 @@ protected void fillListItems() { proposalBaseProposalListItems.setAll(list.stream() .map(ballot -> new ActiveBallotListItem(ballot, daoFacade, bsqWalletService, bsqFormatter)) .collect(Collectors.toSet())); + updateButtons(); } @Override @@ -276,15 +292,13 @@ private ActiveBallotListItem getBallotListItem() { } private void updateButtons() { - if (selectedBaseProposalListItem != null && proposalDisplay != null) { - final boolean isBlindVotePhase = daoFacade.phaseProperty().get() == DaoPhase.Phase.BLIND_VOTE; - stakeInputTextField.setDisable(!isBlindVotePhase); - voteButton.setDisable(!isBlindVotePhase); - - acceptButton.setDisable(!isBlindVotePhase); - rejectButton.setDisable(!isBlindVotePhase); - removeMyVoteButton.setDisable(!isBlindVotePhase); - } + final boolean isBlindVotePhase = daoFacade.phaseProperty().get() == DaoPhase.Phase.BLIND_VOTE; + stakeInputTextField.setDisable(!isBlindVotePhase); + voteButton.setDisable(!isBlindVotePhase); + + if (acceptButton != null) acceptButton.setDisable(!isBlindVotePhase); + if (rejectButton != null) rejectButton.setDisable(!isBlindVotePhase); + if (removeMyVoteButton != null) removeMyVoteButton.setDisable(!isBlindVotePhase); } diff --git a/src/main/java/bisq/desktop/main/dao/voting/closed/ClosedBallotListItem.java b/src/main/java/bisq/desktop/main/dao/voting/closed/ClosedBallotListItem.java new file mode 100644 index 00000000000..e95000a7a9b --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/voting/closed/ClosedBallotListItem.java @@ -0,0 +1,96 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.desktop.main.dao.voting.closed; + +import bisq.desktop.main.dao.BaseProposalListItem; +import bisq.desktop.util.BsqFormatter; + +import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.dao.DaoFacade; +import bisq.core.dao.state.period.DaoPhase; +import bisq.core.dao.voting.ballot.Ballot; +import bisq.core.dao.voting.ballot.vote.BooleanVote; +import bisq.core.dao.voting.ballot.vote.Vote; +import bisq.core.dao.voting.proposal.Proposal; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.ToString; +import lombok.extern.slf4j.Slf4j; + +@ToString +@Slf4j +@EqualsAndHashCode(callSuper = true) +public class ClosedBallotListItem extends BaseProposalListItem { + @Getter + private final Ballot ballot; + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Constructor, lifecycle + /////////////////////////////////////////////////////////////////////////////////////////// + + public ClosedBallotListItem(Ballot ballot, + DaoFacade daoFacade, + BsqWalletService bsqWalletService, + BsqFormatter bsqFormatter) { + super(daoFacade, + bsqWalletService, + bsqFormatter); + + this.ballot = ballot; + + init(); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Protected + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + protected void init() { + super.init(); + } + + @Override + public void onPhaseChanged(DaoPhase.Phase phase) { + super.onPhaseChanged(phase); + + final Vote vote = ballot.getVote(); + if (vote != null) { + imageView.setVisible(true); + if (vote instanceof BooleanVote) { + if (((BooleanVote) vote).isAccepted()) { + imageView.setId("accepted"); + } else { + imageView.setId("rejected"); + } + } else { + //TODO + } + } else { + imageView.setVisible(false); + } + } + + @Override + public Proposal getProposal() { + return ballot.getProposal(); + } +} diff --git a/src/main/java/bisq/desktop/main/dao/voting/closed/ClosedBallotsView.fxml b/src/main/java/bisq/desktop/main/dao/voting/closed/ClosedBallotsView.fxml new file mode 100644 index 00000000000..77b723ecc0c --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/voting/closed/ClosedBallotsView.fxml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + diff --git a/src/main/java/bisq/desktop/main/dao/voting/closed/ClosedBallotsView.java b/src/main/java/bisq/desktop/main/dao/voting/closed/ClosedBallotsView.java new file mode 100644 index 00000000000..a3f19ad85a5 --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/voting/closed/ClosedBallotsView.java @@ -0,0 +1,160 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.desktop.main.dao.voting.closed; + +import bisq.desktop.common.view.FxmlView; +import bisq.desktop.main.dao.BaseProposalListItem; +import bisq.desktop.main.dao.BaseProposalView; +import bisq.desktop.util.BSFormatter; +import bisq.desktop.util.BsqFormatter; + +import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.dao.DaoFacade; +import bisq.core.dao.voting.ballot.Ballot; + +import javax.inject.Inject; + +import javafx.scene.control.TableCell; +import javafx.scene.control.TableColumn; +import javafx.scene.control.TableView; +import javafx.scene.image.ImageView; + +import javafx.beans.property.ReadOnlyObjectWrapper; + +import javafx.collections.ListChangeListener; + +import javafx.util.Callback; + +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; + +@FxmlView +public class ClosedBallotsView extends BaseProposalView { + private ListChangeListener listChangeListener; + + /////////////////////////////////////////////////////////////////////////////////////////// + // Constructor, lifecycle + /////////////////////////////////////////////////////////////////////////////////////////// + + @Inject + private ClosedBallotsView(DaoFacade daoFacade, + BsqWalletService bsqWalletService, + BsqFormatter bsqFormatter, + BSFormatter btcFormatter) { + + super(daoFacade, bsqWalletService, bsqFormatter, btcFormatter); + } + + @Override + public void initialize() { + super.initialize(); + + createProposalsTableView(); + createEmptyProposalDisplay(); + + listChangeListener = c -> updateListItems(); + } + + @Override + protected void activate() { + super.activate(); + + daoFacade.getClosedBallots().addListener(listChangeListener); + } + + + @Override + protected void deactivate() { + super.deactivate(); + + daoFacade.getClosedBallots().removeListener(listChangeListener); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Protected + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + protected void fillListItems() { + List list = daoFacade.getClosedBallots(); + proposalBaseProposalListItems.setAll(list.stream() + .map(ballot -> new ClosedBallotListItem(ballot, daoFacade, bsqWalletService, bsqFormatter)) + .collect(Collectors.toSet())); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Private + /////////////////////////////////////////////////////////////////////////////////////////// + + + private ClosedBallotListItem getBallotListItem() { + return (ClosedBallotListItem) selectedBaseProposalListItem; + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // TableColumns + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + protected void createProposalColumns(TableView tableView) { + super.createProposalColumns(tableView); + createConfidenceColumn(tableView); + + TableColumn actionColumn = new TableColumn<>(); + actionColumn.setMinWidth(130); + actionColumn.setMaxWidth(actionColumn.getMinWidth()); + + actionColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + + actionColumn.setCellFactory(new Callback, + TableCell>() { + + @Override + public TableCell call(TableColumn column) { + return new TableCell() { + ImageView imageView; + + @Override + public void updateItem(final BaseProposalListItem item, boolean empty) { + super.updateItem(item, empty); + + if (item != null && !empty) { + ClosedBallotListItem closedBallotListItem = (ClosedBallotListItem) item; + if (imageView == null) { + imageView = closedBallotListItem.getImageView(); + setGraphic(imageView); + } + closedBallotListItem.onPhaseChanged(currentPhase); + } else { + setGraphic(null); + if (imageView != null) + imageView = null; + } + } + }; + } + }); + actionColumn.setComparator(Comparator.comparing(BaseProposalListItem::getConfirmations)); + tableView.getColumns().add(actionColumn); + } +} diff --git a/src/main/java/bisq/desktop/main/dao/voting/history/VotingHistoryView.fxml b/src/main/java/bisq/desktop/main/dao/voting/closed/VotingHistoryView.fxml similarity index 97% rename from src/main/java/bisq/desktop/main/dao/voting/history/VotingHistoryView.fxml rename to src/main/java/bisq/desktop/main/dao/voting/closed/VotingHistoryView.fxml index dbae0652b50..0986c567857 100644 --- a/src/main/java/bisq/desktop/main/dao/voting/history/VotingHistoryView.fxml +++ b/src/main/java/bisq/desktop/main/dao/voting/closed/VotingHistoryView.fxml @@ -20,7 +20,7 @@ -. */ -package bisq.desktop.main.dao.voting.history; +package bisq.desktop.main.dao.voting.closed; import bisq.desktop.common.view.ActivatableView; import bisq.desktop.common.view.FxmlView; From 0139d54bd4737e5eb9f072a5f1613e7c1e5261fd Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Mon, 7 May 2018 14:20:57 -0500 Subject: [PATCH 091/197] Add vote button to proposal view --- .../active/ActiveProposalListItem.java | 32 +++++---- .../proposal/active/ActiveProposalsView.java | 69 ++++++++++++------- 2 files changed, 65 insertions(+), 36 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalListItem.java index 4b253f16a8b..e12dbb376d0 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalListItem.java @@ -37,7 +37,7 @@ @EqualsAndHashCode(callSuper = true) public class ActiveProposalListItem extends ProposalListItem { @Getter - private AutoTooltipButton removeButton; + private AutoTooltipButton button; /////////////////////////////////////////////////////////////////////////////////////////// @@ -63,22 +63,30 @@ public class ActiveProposalListItem extends ProposalListItem { protected void init() { super.init(); - imageView.setId("image-remove"); - - removeButton = new AutoTooltipButton(); - removeButton.setMinWidth(70); - removeButton.setText(Res.get("shared.remove")); - removeButton.setGraphic(imageView); + button = new AutoTooltipButton(); + button.setMinWidth(70); + onPhaseChanged(daoFacade.phaseProperty().get()); } @Override public void onPhaseChanged(DaoPhase.Phase phase) { super.onPhaseChanged(phase); - removeButton.setDisable(phase != DaoPhase.Phase.PROPOSAL); - - final boolean myProposal = daoFacade.isMyProposal(proposal); - removeButton.setVisible(myProposal); - removeButton.setManaged(myProposal); + if (phase == DaoPhase.Phase.PROPOSAL) { + imageView.setId("image-remove"); + button.setGraphic(imageView); + button.setText(Res.get("dao.proposal.active.remove")); + final boolean isMyProposal = daoFacade.isMyProposal(proposal); + button.setVisible(isMyProposal); + button.setManaged(isMyProposal); + } else if (phase == DaoPhase.Phase.BLIND_VOTE) { + button.setGraphic(null); + button.setText(Res.get("dao.proposal.active.vote")); + button.setVisible(true); + button.setManaged(true); + } else { + button.setVisible(false); + button.setManaged(false); + } } } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index 8293c1d2158..3c9e915952a 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -17,9 +17,14 @@ package bisq.desktop.main.dao.proposal.active; +import bisq.desktop.Navigation; import bisq.desktop.common.view.FxmlView; +import bisq.desktop.main.MainView; import bisq.desktop.main.dao.BaseProposalListItem; +import bisq.desktop.main.dao.DaoView; import bisq.desktop.main.dao.proposal.ProposalItemsView; +import bisq.desktop.main.dao.voting.VotingView; +import bisq.desktop.main.dao.voting.active.ActiveBallotsView; import bisq.desktop.main.overlays.popups.Popup; import bisq.desktop.util.BSFormatter; import bisq.desktop.util.BsqFormatter; @@ -51,8 +56,9 @@ @FxmlView public class ActiveProposalsView extends ProposalItemsView { + private final Navigation navigation; - private Button removeButton; + private Button button; /////////////////////////////////////////////////////////////////////////////////////////// @@ -63,9 +69,11 @@ public class ActiveProposalsView extends ProposalItemsView { private ActiveProposalsView(DaoFacade daoFacade, BsqWalletService bsqWalletService, BsqFormatter bsqFormatter, - BSFormatter btcFormatter) { + BSFormatter btcFormatter, + Navigation navigation) { super(daoFacade, bsqWalletService, bsqFormatter, btcFormatter); + this.navigation = navigation; } @@ -83,19 +91,18 @@ protected ObservableList getProposals() { protected void createAllFieldsOnProposalDisplay(Proposal proposal) { super.createAllFieldsOnProposalDisplay(proposal); - removeButton = addButtonAfterGroup(detailsGridPane, proposalDisplay.incrementAndGetGridRow(), Res.get("dao.proposal.active.remove")); - removeButton.setOnAction(event -> onRemove()); - removeButton.setDisable(daoFacade.phaseProperty().get() != DaoPhase.Phase.PROPOSAL); - + button = addButtonAfterGroup(detailsGridPane, proposalDisplay.incrementAndGetGridRow(), ""); + button.setOnAction(event -> onButtonClick()); + onPhaseChanged(daoFacade.phaseProperty().get()); } @Override protected void hideProposalDisplay() { super.hideProposalDisplay(); - if (removeButton != null) { - removeButton.setManaged(false); - removeButton.setVisible(false); + if (button != null) { + button.setManaged(false); + button.setVisible(false); } } @@ -112,28 +119,42 @@ protected void fillListItems() { public void onPhaseChanged(DaoPhase.Phase phase) { super.onPhaseChanged(phase); - if (removeButton != null) { - removeButton.setDisable(phase != DaoPhase.Phase.PROPOSAL); - if (selectedBaseProposalListItem != null && selectedBaseProposalListItem.getProposal() != null) { - final boolean myProposal = daoFacade.isMyProposal(selectedBaseProposalListItem.getProposal()); - removeButton.setVisible(myProposal); - removeButton.setManaged(myProposal); + if (button != null) { + if (phase == DaoPhase.Phase.PROPOSAL) { + if (selectedBaseProposalListItem != null && selectedBaseProposalListItem.getProposal() != null) { + button.setText(Res.get("dao.proposal.active.remove")); + final boolean isMyProposal = daoFacade.isMyProposal(selectedBaseProposalListItem.getProposal()); + button.setVisible(isMyProposal); + button.setManaged(isMyProposal); + } + } else if (phase == DaoPhase.Phase.BLIND_VOTE) { + button.setText(Res.get("dao.proposal.active.vote")); + button.setVisible(true); + button.setManaged(true); + } else { + button.setVisible(false); + button.setManaged(false); } } } + /////////////////////////////////////////////////////////////////////////////////////////// // Handlers /////////////////////////////////////////////////////////////////////////////////////////// - private void onRemove() { - final Proposal proposal = selectedBaseProposalListItem.getProposal(); - if (daoFacade.removeMyProposal(proposal)) { - hideProposalDisplay(); - } else { - new Popup<>().warning(Res.get("dao.proposal.active.remove.failed")).show(); + private void onButtonClick() { + if (daoFacade.phaseProperty().get() == DaoPhase.Phase.PROPOSAL) { + final Proposal proposal = selectedBaseProposalListItem.getProposal(); + if (daoFacade.removeMyProposal(proposal)) { + hideProposalDisplay(); + } else { + new Popup<>().warning(Res.get("dao.proposal.active.remove.failed")).show(); + } + proposalTableView.getSelectionModel().clearSelection(); + } else if (daoFacade.phaseProperty().get() == DaoPhase.Phase.BLIND_VOTE) { + navigation.navigateTo(MainView.class, DaoView.class, VotingView.class, ActiveBallotsView.class); } - proposalTableView.getSelectionModel().clearSelection(); } @@ -168,10 +189,10 @@ public void updateItem(final BaseProposalListItem item, boolean empty) { if (item != null && !empty) { ActiveProposalListItem activeProposalListItem = (ActiveProposalListItem) item; if (button == null) { - button = activeProposalListItem.getRemoveButton(); + button = activeProposalListItem.getButton(); button.setOnAction(e -> { ActiveProposalsView.this.selectedBaseProposalListItem = item; - ActiveProposalsView.this.onRemove(); + ActiveProposalsView.this.onButtonClick(); }); setGraphic(button); } From 214207063031af9d90a2f96efa4c153867efd6c1 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Tue, 8 May 2018 19:38:55 +0200 Subject: [PATCH 092/197] Change DashboardView --- .../components/SeparatedPhaseBars.java | 54 ++++++++----------- .../dashboard/ProposalDashboardView.java | 52 ++++++++++++++++-- .../voting/dashboard/VotingDashboardView.java | 5 +- 3 files changed, 74 insertions(+), 37 deletions(-) diff --git a/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java b/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java index 6a32059fd62..3aed082be1d 100644 --- a/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java +++ b/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java @@ -43,7 +43,7 @@ import lombok.extern.slf4j.Slf4j; @Slf4j -public class SeparatedPhaseBars extends HBox { +public class SeparatedPhaseBars extends VBox { private int totalDuration; private List items; @@ -51,46 +51,33 @@ public class SeparatedPhaseBars extends HBox { public SeparatedPhaseBars(List items) { this.items = items; - setSpacing(0); + setSpacing(10); - addLabels(); + HBox titlesBars = new HBox(); + titlesBars.setSpacing(5); + getChildren().add(titlesBars); + + HBox progressBars = new HBox(); + progressBars.setSpacing(5); + getChildren().add(progressBars); items.forEach(item -> { Label titleLabel = new Label(Res.get("dao.phase.short." + item.phase)); + titleLabel.setMinWidth(10); + titleLabel.setEllipsisString(""); + titleLabel.setAlignment(Pos.CENTER); item.setTitleLabel(titleLabel); - - Label startLabel = new Label(); - item.startBlockProperty.addListener((observable, oldValue, newValue) -> { - startLabel.setText(String.valueOf((int) newValue)); - }); - startLabel.setVisible(item.isShowBlocks()); - AnchorPane startLabelPane = new AnchorPane(); - AnchorPane.setLeftAnchor(startLabel, 0d); - startLabelPane.getChildren().add(startLabel); - - Label endLabel = new Label(); - item.lastBlockProperty.addListener((observable, oldValue, newValue) -> { - endLabel.setText(String.valueOf((int) newValue)); - }); - endLabel.setVisible(item.isShowBlocks()); - AnchorPane endLabelPane = new AnchorPane(); - AnchorPane.setRightAnchor(endLabel, 0d); - endLabelPane.getChildren().add(endLabel); + titlesBars.getChildren().addAll(titleLabel); ProgressBar progressBar = new ProgressBar(); progressBar.setMinHeight(9); progressBar.setMaxHeight(9); - progressBar.setMaxWidth(Double.MAX_VALUE); + progressBar.setMinWidth(10); progressBar.setStyle("-fx-accent: -bs-green;"); progressBar.progressProperty().bind(item.progressProperty); progressBar.setOpacity(item.isShowBlocks() ? 1 : 0.25); - - VBox vBox = new VBox(); - vBox.setSpacing(5); - vBox.getChildren().addAll(titleLabel, progressBar, startLabelPane, endLabelPane); - vBox.setAlignment(Pos.CENTER); - getChildren().add(vBox); - item.setVBox(vBox); + progressBars.getChildren().add(progressBar); + item.setProgressBar(progressBar); }); widthProperty().addListener((observable, oldValue, newValue) -> { @@ -131,12 +118,13 @@ private void addLabels() { private void updateWidth(double availableWidth) { totalDuration = items.stream().mapToInt(SeparatedPhaseBarsItem::getDuration).sum(); - availableWidth -= vBoxLabels.getWidth(); + // availableWidth -= vBoxLabels.getWidth(); if (availableWidth > 0 && totalDuration > 0) { final double finalAvailableWidth = availableWidth; items.forEach(item -> { final double width = (double) item.duration / (double) totalDuration * finalAvailableWidth; - item.getVBox().setPrefWidth(width); + item.getProgressBar().setPrefWidth(width); + item.getTitleLabel().setPrefWidth(width); }); } } @@ -150,9 +138,11 @@ public static class SeparatedPhaseBarsItem { private final DoubleProperty progressProperty = new SimpleDoubleProperty(); private int duration; @Setter - private javafx.scene.layout.VBox VBox; + private javafx.scene.layout.VBox progressVBox; @Setter private Label titleLabel; + @Setter + private ProgressBar progressBar; public SeparatedPhaseBarsItem(DaoPhase.Phase phase, boolean showBlocks) { this.phase = phase; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java index e305584d572..7978f950190 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java @@ -20,6 +20,7 @@ import bisq.desktop.common.view.ActivatableView; import bisq.desktop.common.view.FxmlView; import bisq.desktop.components.SeparatedPhaseBars; +import bisq.desktop.util.BSFormatter; import bisq.desktop.util.Layout; import bisq.core.dao.DaoFacade; @@ -31,17 +32,24 @@ import javax.inject.Inject; +import javafx.scene.control.TextField; import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.ColumnConstraints; import javafx.scene.layout.GridPane; +import javafx.scene.layout.Priority; +import javafx.geometry.HPos; import javafx.geometry.Insets; import org.fxmisc.easybind.EasyBind; import org.fxmisc.easybind.Subscription; import java.util.Arrays; +import java.util.Date; import java.util.List; +import static bisq.desktop.util.FormBuilder.addLabelTextField; +import static bisq.desktop.util.FormBuilder.addMultilineLabel; import static bisq.desktop.util.FormBuilder.addTitledGroupBg; // We use here ChainHeightListener because we are interested in period changes not in the result of a completed @@ -50,6 +58,7 @@ @FxmlView public class ProposalDashboardView extends ActivatableView implements ChainHeightListener { private final DaoFacade daoFacade; + private final BSFormatter formatter; private List phaseBarsItems; private DaoPhase.Phase currentPhase; @@ -57,6 +66,7 @@ public class ProposalDashboardView extends ActivatableView imple private GridPane gridPane; private int gridRow = 0; private SeparatedPhaseBars separatedPhaseBars; + private TextField currentPhaseTextField, currentBlockHeightTextField, proposalTextField, blindVoteTextField, voteRevealTextField, voteResultTextField; /////////////////////////////////////////////////////////////////////////////////////////// @@ -64,8 +74,9 @@ public class ProposalDashboardView extends ActivatableView imple /////////////////////////////////////////////////////////////////////////////////////////// @Inject - public ProposalDashboardView(DaoFacade daoFacade) { + public ProposalDashboardView(DaoFacade daoFacade, BSFormatter formatter) { this.daoFacade = daoFacade; + this.formatter = formatter; } @Override @@ -81,16 +92,35 @@ public void initialize() { AnchorPane.setRightAnchor(gridPane, 10d); AnchorPane.setLeftAnchor(gridPane, 10d); AnchorPane.setTopAnchor(gridPane, 10d); + ColumnConstraints columnConstraints1 = new ColumnConstraints(); + columnConstraints1.setHalignment(HPos.RIGHT); + columnConstraints1.setHgrow(Priority.SOMETIMES); + columnConstraints1.setMinWidth(200); + ColumnConstraints columnConstraints2 = new ColumnConstraints(); + columnConstraints2.setHgrow(Priority.ALWAYS); + gridPane.getColumnConstraints().addAll(columnConstraints1, columnConstraints2); topAnchorPane.getChildren().add(gridPane); - // Add phase info - addTitledGroupBg(gridPane, gridRow, 1, Res.get("dao.proposal.active.phase.header")); + // cycle bar + addTitledGroupBg(gridPane, gridRow, 1, Res.get("dao.cycle.headline")); separatedPhaseBars = createSeparatedPhaseBars(); GridPane.setColumnSpan(separatedPhaseBars, 2); GridPane.setColumnIndex(separatedPhaseBars, 0); GridPane.setMargin(separatedPhaseBars, new Insets(Layout.FIRST_ROW_DISTANCE - 6, 0, 0, 0)); GridPane.setRowIndex(separatedPhaseBars, gridRow); gridPane.getChildren().add(separatedPhaseBars); + + addTitledGroupBg(gridPane, ++gridRow, 6, Res.get("dao.cycle.overview.headline"), Layout.GROUP_DISTANCE); + currentBlockHeightTextField = addLabelTextField(gridPane, gridRow, Res.get("dao.cycle.currentBlockHeight"), + "", Layout.FIRST_ROW_AND_GROUP_DISTANCE).second; + currentPhaseTextField = addLabelTextField(gridPane, ++gridRow, Res.get("dao.cycle.currentPhase"), "").second; + proposalTextField = addLabelTextField(gridPane, ++gridRow, Res.get("dao.cycle.proposal"), "").second; + blindVoteTextField = addLabelTextField(gridPane, ++gridRow, Res.get("dao.cycle.blindVote"), "").second; + voteRevealTextField = addLabelTextField(gridPane, ++gridRow, Res.get("dao.cycle.voteReveal"), "").second; + voteResultTextField = addLabelTextField(gridPane, ++gridRow, Res.get("dao.cycle.voteResult"), "").second; + + addTitledGroupBg(gridPane, ++gridRow, 1, Res.get("dao.cycle.info.headline"), Layout.GROUP_DISTANCE); + addMultilineLabel(gridPane, gridRow, Res.get("dao.cycle.info.details"), Layout.FIRST_ROW_AND_GROUP_DISTANCE); } @@ -158,5 +188,21 @@ public void onChainHeightChanged(int height) { item.getProgressProperty().set(progress); }); } + + currentBlockHeightTextField.setText(String.valueOf(daoFacade.getChainHeight())); + currentPhaseTextField.setText(Res.get("dao.phase." + daoFacade.phaseProperty().get().name())); + proposalTextField.setText(getPhaseDuration(height, DaoPhase.Phase.PROPOSAL)); + blindVoteTextField.setText(getPhaseDuration(height, DaoPhase.Phase.BLIND_VOTE)); + voteRevealTextField.setText(getPhaseDuration(height, DaoPhase.Phase.VOTE_REVEAL)); + voteResultTextField.setText(getPhaseDuration(height, DaoPhase.Phase.RESULT)); + } + + private String getPhaseDuration(int height, DaoPhase.Phase phase) { + final long start = daoFacade.getFirstBlockOfPhase(height, phase); + final long end = daoFacade.getLastBlockOfPhase(height, phase); + long now = new Date().getTime(); + String startDateTime = formatter.formatDateTime(new Date(now + (start - height) * 10 * 60 * 1000L)); + String endDateTime = formatter.formatDateTime(new Date(now + (end - height) * 10 * 60 * 1000L)); + return Res.get("dao.cycle.phaseDuration", start, end, startDateTime, endDateTime); } } diff --git a/src/main/java/bisq/desktop/main/dao/voting/dashboard/VotingDashboardView.java b/src/main/java/bisq/desktop/main/dao/voting/dashboard/VotingDashboardView.java index 111f20ff386..a0f4cf3188c 100644 --- a/src/main/java/bisq/desktop/main/dao/voting/dashboard/VotingDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/voting/dashboard/VotingDashboardView.java @@ -19,6 +19,7 @@ import bisq.desktop.common.view.FxmlView; import bisq.desktop.main.dao.proposal.dashboard.ProposalDashboardView; +import bisq.desktop.util.BSFormatter; import bisq.core.dao.DaoFacade; @@ -33,8 +34,8 @@ public class VotingDashboardView extends ProposalDashboardView { /////////////////////////////////////////////////////////////////////////////////////////// @Inject - private VotingDashboardView(DaoFacade daoFacade) { - super(daoFacade); + private VotingDashboardView(DaoFacade daoFacade, BSFormatter formatter) { + super(daoFacade, formatter); } @Override From 07cf5dbef7ddfb6b24a03e570efbc82d366cbde1 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Thu, 31 May 2018 00:21:30 +0200 Subject: [PATCH 093/197] Update idea files, update gradle --- .../java/bisq/desktop/app/DesktopMain.java | 115 ++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 src/main/java/bisq/desktop/app/DesktopMain.java diff --git a/src/main/java/bisq/desktop/app/DesktopMain.java b/src/main/java/bisq/desktop/app/DesktopMain.java new file mode 100644 index 00000000000..96c1f19df8b --- /dev/null +++ b/src/main/java/bisq/desktop/app/DesktopMain.java @@ -0,0 +1,115 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.desktop.app; + +import bisq.desktop.common.UITimer; +import bisq.desktop.common.view.guice.InjectorViewFactory; +import bisq.desktop.setup.DesktopPersistedDataHost; + +import bisq.core.app.BisqExecutable; + +import bisq.common.UserThread; +import bisq.common.app.AppModule; +import bisq.common.proto.persistable.PersistedDataHost; +import bisq.common.setup.CommonSetup; + +import com.google.inject.Injector; + +import javafx.application.Application; +import javafx.application.Platform; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class DesktopMain extends BisqExecutable { + private BisqApp application; + + public static void main(String[] args) throws Exception { + if (BisqExecutable.setupInitialOptionParser(args)) { + // For some reason the JavaFX launch process results in us losing the thread context class loader: reset it. + // In order to work around a bug in JavaFX 8u25 and below, you must include the following code as the first line of your realMain method: + Thread.currentThread().setContextClassLoader(DesktopMain.class.getClassLoader()); + + new DesktopMain().execute(args); + } + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // First synchronous execution tasks + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + protected void configUserThread() { + UserThread.setExecutor(Platform::runLater); + UserThread.setTimerClass(UITimer.class); + } + + @Override + protected void launchApplication() { + BisqApp.setAppLaunchedHandler(application -> { + DesktopMain.this.application = (BisqApp) application; + // Necessary to do the setup at this point to prevent Bouncy Castle errors + CommonSetup.setup(DesktopMain.this.application); + // Map to user thread! + UserThread.execute(this::onApplicationLaunched); + }); + + Application.launch(BisqApp.class); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // As application is a JavaFX application we need to wait for onApplicationLaunched + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + protected void onApplicationLaunched() { + super.onApplicationLaunched(); + application.setGracefulShutDownHandler(this); + } + + /////////////////////////////////////////////////////////////////////////////////////////// + // We continue with a series of synchronous execution tasks + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + protected AppModule getModule() { + return new BisqAppModule(bisqEnvironment); + } + + @Override + protected void applyInjector() { + super.applyInjector(); + + application.setInjector(injector); + injector.getInstance(InjectorViewFactory.class).setInjector(injector); + } + + @Override + protected void setupPersistedDataHosts(Injector injector) { + super.setupPersistedDataHosts(injector); + PersistedDataHost.apply(DesktopPersistedDataHost.getPersistedDataHosts(injector)); + } + + @Override + protected void startApplication() { + // We need to be in user thread! We mapped at launchApplication already... + application.startApplication(); + } +} From 8ddcd937c29d356f72f0b833e5e0dde91951dba2 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Thu, 31 May 2018 01:13:05 +0200 Subject: [PATCH 094/197] Add support for BisqHttpApi to DesktopMain - Add option keys desktopWithHttpApi and desktopWithGrpcApi - Add BisqDaemon to BisqApp - Fix wrong package of BisqGrpcClient and BisqGrpcServer - Add BisqHttpApi stub - Add http-api and bisq-grpc to Desktop --- build.gradle | 6 ++-- src/main/java/bisq/desktop/app/BisqApp.java | 6 ++++ .../java/bisq/desktop/app/DesktopMain.java | 33 ++++++++++++++++++- 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index e1ce3fc195b..b03d31480e6 100644 --- a/build.gradle +++ b/build.gradle @@ -40,9 +40,11 @@ repositories { } dependencies { + compile 'network.bisq:bisq-common:-SNAPSHOT' compile 'network.bisq:bisq-core:-SNAPSHOT' compile 'network.bisq:bisq-p2p:-SNAPSHOT' - compile 'network.bisq:bisq-common:-SNAPSHOT' + compile 'network.bisq:bisq-http-api:-SNAPSHOT' + compile 'network.bisq:bisq-grpc:-SNAPSHOT' compile 'org.controlsfx:controlsfx:8.0.6_20' compile 'org.reactfx:reactfx:2.0-M3' compile 'net.glxn:qrgen:1.3' @@ -105,7 +107,7 @@ dependencyVerification { 'org.jetbrains:annotations:ace2a10dc8e2d5fd34925ecac03e4988b2c0f851650c94b8cef49ba1bd111478', 'org.bouncycastle:bcpg-jdk15on:de3355b821fc81dd32e1f3f560d5b3eca1c678fd2400011d0bfc69fb91bcde85', 'commons-io:commons-io:cc6a41dc3eaacc9e440a6bd0d2890b20d36b4ee408fe2d67122f328bb6e01581', - 'org.apache.commons:commons-lang3:734c8356420cc8e30c795d64fd1fcd5d44ea9d90342a2cc3262c5158fbc6d98b', + /*'org.apache.commons:commons-lang3:734c8356420cc8e30c795d64fd1fcd5d44ea9d90342a2cc3262c5158fbc6d98b',*/ // seems grpc uses diff. version of org.apache.commons 'org.bouncycastle:bcprov-jdk15on:963e1ee14f808ffb99897d848ddcdb28fa91ddda867eb18d303e82728f878349', 'com.google.zxing:javase:0ec23e2ec12664ddd6347c8920ad647bb3b9da290f897a88516014b56cc77eb9', 'commons-codec:commons-codec:ad19d2601c3abf0b946b5c3a4113e226a8c1e3305e395b90013b78dd94a723ce', diff --git a/src/main/java/bisq/desktop/app/BisqApp.java b/src/main/java/bisq/desktop/app/BisqApp.java index 16b2317e5f2..943e28a0848 100644 --- a/src/main/java/bisq/desktop/app/BisqApp.java +++ b/src/main/java/bisq/desktop/app/BisqApp.java @@ -34,6 +34,7 @@ import bisq.core.alert.AlertManager; import bisq.core.app.AppOptionKeys; +import bisq.core.app.BisqDaemon; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; import bisq.core.btc.wallet.WalletService; @@ -98,6 +99,7 @@ public class BisqApp extends Application implements UncaughtExceptionHandler { private Scene scene; private final List corruptedDatabaseFiles = new ArrayList<>(); private boolean shutDownRequested; + private BisqDaemon daemon; public BisqApp() { shutDownHandler = this::stop; @@ -113,6 +115,10 @@ public BisqApp() { public void init() { } + public void setDaemon(BisqDaemon daemon) { + this.daemon = daemon; + } + @Override public void start(Stage stage) { this.stage = stage; diff --git a/src/main/java/bisq/desktop/app/DesktopMain.java b/src/main/java/bisq/desktop/app/DesktopMain.java index 96c1f19df8b..5b575c48e17 100644 --- a/src/main/java/bisq/desktop/app/DesktopMain.java +++ b/src/main/java/bisq/desktop/app/DesktopMain.java @@ -21,6 +21,7 @@ import bisq.desktop.common.view.guice.InjectorViewFactory; import bisq.desktop.setup.DesktopPersistedDataHost; +import bisq.core.app.BisqDaemon; import bisq.core.app.BisqExecutable; import bisq.common.UserThread; @@ -35,9 +36,18 @@ import lombok.extern.slf4j.Slf4j; +import javax.annotation.Nullable; + + + +import bisq.httpapi.BisqHttpApi; + @Slf4j public class DesktopMain extends BisqExecutable { private BisqApp application; + private BisqDaemon bisqDaemon; + @Nullable + private BisqHttpApi bisqHttpApi; public static void main(String[] args) throws Exception { if (BisqExecutable.setupInitialOptionParser(args)) { @@ -69,8 +79,11 @@ protected void launchApplication() { // Map to user thread! UserThread.execute(this::onApplicationLaunched); }); - + bisqDaemon = new BisqDaemon(); Application.launch(BisqApp.class); + + if (runeWithHttpApi()) + bisqHttpApi = new BisqHttpApi(bisqDaemon); } @@ -82,6 +95,9 @@ protected void launchApplication() { protected void onApplicationLaunched() { super.onApplicationLaunched(); application.setGracefulShutDownHandler(this); + + + application.setDaemon(bisqDaemon); } /////////////////////////////////////////////////////////////////////////////////////////// @@ -97,7 +113,11 @@ protected AppModule getModule() { protected void applyInjector() { super.applyInjector(); + bisqDaemon.setInjector(injector); application.setInjector(injector); + if (runeWithHttpApi()) + bisqHttpApi.setInjector(injector); + injector.getInstance(InjectorViewFactory.class).setInjector(injector); } @@ -110,6 +130,17 @@ protected void setupPersistedDataHosts(Injector injector) { @Override protected void startApplication() { // We need to be in user thread! We mapped at launchApplication already... + bisqDaemon.startApplication(); application.startApplication(); + if (runeWithHttpApi()) + bisqHttpApi.startApplication(); + } + + private boolean runeWithHttpApi() { + return bisqEnvironment.getDesktopWithHttpApi().toLowerCase().equals("true"); + } + + private boolean runeWithGrpcApi() { + return bisqEnvironment.getDesktopWithGrpcApi().toLowerCase().equals("true"); } } From ef58b17d7585406630b7b8f92243b1a49ca5cfd2 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Thu, 31 May 2018 01:50:06 +0200 Subject: [PATCH 095/197] Cleanup --- .../java/bisq/desktop/app/DesktopMain.java | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/main/java/bisq/desktop/app/DesktopMain.java b/src/main/java/bisq/desktop/app/DesktopMain.java index 5b575c48e17..eeae4c3f41e 100644 --- a/src/main/java/bisq/desktop/app/DesktopMain.java +++ b/src/main/java/bisq/desktop/app/DesktopMain.java @@ -72,18 +72,22 @@ protected void configUserThread() { @Override protected void launchApplication() { + bisqDaemon = new BisqDaemon(); + if (runWithHttpApi()) + bisqHttpApi = new BisqHttpApi(bisqDaemon); + BisqApp.setAppLaunchedHandler(application -> { DesktopMain.this.application = (BisqApp) application; + + DesktopMain.this.application.setDaemon(bisqDaemon); + // Necessary to do the setup at this point to prevent Bouncy Castle errors CommonSetup.setup(DesktopMain.this.application); // Map to user thread! UserThread.execute(this::onApplicationLaunched); }); - bisqDaemon = new BisqDaemon(); - Application.launch(BisqApp.class); - if (runeWithHttpApi()) - bisqHttpApi = new BisqHttpApi(bisqDaemon); + Application.launch(BisqApp.class); } @@ -96,8 +100,6 @@ protected void onApplicationLaunched() { super.onApplicationLaunched(); application.setGracefulShutDownHandler(this); - - application.setDaemon(bisqDaemon); } /////////////////////////////////////////////////////////////////////////////////////////// @@ -115,7 +117,7 @@ protected void applyInjector() { bisqDaemon.setInjector(injector); application.setInjector(injector); - if (runeWithHttpApi()) + if (bisqHttpApi != null) bisqHttpApi.setInjector(injector); injector.getInstance(InjectorViewFactory.class).setInjector(injector); @@ -132,15 +134,15 @@ protected void startApplication() { // We need to be in user thread! We mapped at launchApplication already... bisqDaemon.startApplication(); application.startApplication(); - if (runeWithHttpApi()) + if (bisqHttpApi != null) bisqHttpApi.startApplication(); } - private boolean runeWithHttpApi() { + private boolean runWithHttpApi() { return bisqEnvironment.getDesktopWithHttpApi().toLowerCase().equals("true"); } - private boolean runeWithGrpcApi() { + private boolean runWithGrpcApi() { return bisqEnvironment.getDesktopWithGrpcApi().toLowerCase().equals("true"); } } From a22b24b6d52b20c10a098a9a5f106ec3005b053b Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Thu, 31 May 2018 02:28:26 +0200 Subject: [PATCH 096/197] Move BtcAddressValidator to core --- .../java/bisq/desktop/main/funds/withdrawal/WithdrawalView.java | 2 +- .../main/portfolio/pendingtrades/PendingTradesViewModel.java | 2 +- .../portfolio/pendingtrades/steps/buyer/BuyerStep4View.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/bisq/desktop/main/funds/withdrawal/WithdrawalView.java b/src/main/java/bisq/desktop/main/funds/withdrawal/WithdrawalView.java index 4541ede9300..678bb2f8ab4 100644 --- a/src/main/java/bisq/desktop/main/funds/withdrawal/WithdrawalView.java +++ b/src/main/java/bisq/desktop/main/funds/withdrawal/WithdrawalView.java @@ -26,7 +26,6 @@ import bisq.desktop.main.overlays.windows.WalletPasswordWindow; import bisq.desktop.util.BSFormatter; import bisq.desktop.util.GUIUtil; -import bisq.desktop.util.validation.BtcAddressValidator; import bisq.core.btc.AddressEntry; import bisq.core.btc.AddressEntryException; @@ -43,6 +42,7 @@ import bisq.core.trade.failed.FailedTradesManager; import bisq.core.user.Preferences; import bisq.core.util.CoinUtil; +import bisq.core.util.validation.BtcAddressValidator; import bisq.network.p2p.P2PService; diff --git a/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesViewModel.java b/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesViewModel.java index d196e2bc14f..7d3b65f7cfd 100644 --- a/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesViewModel.java +++ b/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesViewModel.java @@ -22,7 +22,6 @@ import bisq.desktop.util.BSFormatter; import bisq.desktop.util.BsqFormatter; import bisq.desktop.util.GUIUtil; -import bisq.desktop.util.validation.BtcAddressValidator; import bisq.core.locale.Res; import bisq.core.offer.Offer; @@ -31,6 +30,7 @@ import bisq.core.trade.Contract; import bisq.core.trade.Trade; import bisq.core.trade.closed.ClosedTradableManager; +import bisq.core.util.validation.BtcAddressValidator; import bisq.network.p2p.P2PService; diff --git a/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/buyer/BuyerStep4View.java b/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/buyer/BuyerStep4View.java index 4a9971c0979..c60cce828df 100644 --- a/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/buyer/BuyerStep4View.java +++ b/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/buyer/BuyerStep4View.java @@ -31,7 +31,6 @@ import bisq.desktop.util.BSFormatter; import bisq.desktop.util.FormBuilder; import bisq.desktop.util.Layout; -import bisq.desktop.util.validation.BtcAddressValidator; import bisq.core.btc.AddressEntry; import bisq.core.btc.AddressEntryException; @@ -41,6 +40,7 @@ import bisq.core.locale.Res; import bisq.core.user.DontShowAgainLookup; import bisq.core.util.CoinUtil; +import bisq.core.util.validation.BtcAddressValidator; import bisq.common.UserThread; import bisq.common.app.DevEnv; From 3602d4eb0f51a8c1c3410be1ddea8ddd87666356 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Thu, 31 May 2018 02:28:53 +0200 Subject: [PATCH 097/197] Add dependencies of http-api --- build.gradle | 62 +--------------------------------------------------- 1 file changed, 1 insertion(+), 61 deletions(-) diff --git a/build.gradle b/build.gradle index b03d31480e6..e95306f6433 100644 --- a/build.gradle +++ b/build.gradle @@ -72,66 +72,6 @@ installDist.destinationDir = file('build/app') // generated with `./gradlew -q calculateChecksums | grep -v network.bisq:bisq-` dependencyVerification { verify = [ - 'org.controlsfx:controlsfx:b98f1c9507c05600f80323674b33d15674926c71b0116f70085b62bdacf1e573', - 'org.reactfx:reactfx:81ec8fe545d65661222735711114c2ce427e2187a65f1722e8ac4e4805beeca3', - 'net.glxn:qrgen:c85d9d8512d91e8ad11fe56259a7825bd50ce0245447e236cf168d1b17591882', - 'de.jensd:fontawesomefx:73bacc991a0a6f5cf0f911767c8db161e0949dbca61e8371eb4342e3da96887b', - 'de.jensd:fontawesomefx-materialdesignfont:8f700556bbfdc4a581224d3bd6ff869b8a03f6670bd7e0fc78884bd2f31fdb64', - 'de.jensd:fontawesomefx-commons:e1505a31433f1b2902478217651afc78dae5ab09670336afc46e582a1dea1e4d', - 'com.googlecode.jcsv:jcsv:73ca7d715e90c8d2c2635cc284543b038245a34f70790660ed590e157b8714a2', - 'net.sf.jopt-simple:jopt-simple:6f45c00908265947c39221035250024f2caec9a15c1c8cf553ebeecee289f342', - 'network.bisq.btcd-cli4j:btcd-cli4j-daemon:300e2fb9500398f4c5cec6ae07d16d07570dbe0eb9944061eb67ab7db18fa72c', - 'network.bisq.btcd-cli4j:btcd-cli4j-core:63baeecea21940670e054bba6b041959e49fa094a496c141b9da55401ee4a8e7', - 'com.fasterxml.jackson.core:jackson-databind:fcf3c2b0c332f5f54604f7e27fa7ee502378a2cc5df6a944bbfae391872c32ff', - 'com.fasterxml.jackson.core:jackson-core:39a74610521d7fb9eb3f437bb8739bbf47f6435be12d17bf954c731a0c6352bb', - 'com.fasterxml.jackson.core:jackson-annotations:2566b3a6662afa3c6af4f5b25006cb46be2efc68f1b5116291d6998a8cdf7ed3', - 'com.github.JesusMcCloud.netlayer:tor.native:de44e782b21838d3426dbff99abbfd1cbb8e5d3f6d5e997441ff4fd8354934fa', - 'org.apache.httpcomponents:httpclient:db3d1b6c2d6a5e5ad47577ad61854e2f0e0936199b8e05eb541ed52349263135', - 'org.fxmisc.easybind:easybind:666af296dda6de68751668a62661571b5238ac6f1c07c8a204fc6f902b222aaf', - 'com.google.protobuf:protobuf-java:b5e2d91812d183c9f053ffeebcbcda034d4de6679521940a19064714966c2cd4', - 'com.google.code.gson:gson:2d43eb5ea9e133d2ee2405cc14f5ee08951b8361302fdd93494a3a997b508d32', - 'com.googlecode.json-simple:json-simple:4e69696892b88b41c55d49ab2fdcc21eead92bf54acc588c0050596c3b75199c', - 'org.springframework:spring-core:c451e8417adb2ffb2445636da5e44a2f59307c4100037a1fe387c3fba4f29b52', - 'ch.qos.logback:logback-classic:e66efc674e94837344bc5b748ff510c37a44eeff86cbfdbf9e714ef2eb374013', - 'org.slf4j:slf4j-api:3a4cd4969015f3beb4b5b4d81dbafc01765fb60b8a439955ca64d8476fef553e', - 'ch.qos.logback:logback-core:4cd46fa17d77057b39160058df2f21ebbc2aded51d0edcc25d2c1cecc042a005', - 'com.google.code.findbugs:jsr305:c885ce34249682bc0236b4a7d56efcc12048e6135a5baf7a9cde8ad8cda13fcd', - 'com.google.guava:guava:36a666e3b71ae7f0f0dca23654b67e086e6c93d192f60ba5dfd5519db6c288c8', - 'com.google.inject:guice:9b9df27a5b8c7864112b4137fd92b36c3f1395bfe57be42fedf2f520ead1a93e', - 'network.bisq.libdohj:libdohj-core:797a65f00e5ddde1b119748a00c6d75bd6e0c60b65b9cfcdb2cff94bfb5c9abc', - 'com.github.JesusMcCloud.netlayer:tor:3896950c56a41985f901ff9475524ac162cba18b2d5a0ed39810b20ddaf5128a', - 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:841b021d62fc007ce2883963ff9440d5393fb1f6a0604ed68cd016afcaf02967', - 'com.github.MicroUtils:kotlin-logging:7dbd501cc210d721f730d480c53ee2a6e3c154ae89b07dc7dee224b9c5aca9eb', - 'org.jetbrains.kotlin:kotlin-stdlib-jdk7:bd8cd4e3ef391cd468434747b7939c49e80f8bf4ae10355a65382bfb54fd633c', - 'org.jetbrains.kotlin:kotlin-stdlib:e1c39d27f23a7fe2d3e4ac65e80a53e98fdcf60e07de9d53b8b841c5944fc810', - 'org.jetbrains:annotations:ace2a10dc8e2d5fd34925ecac03e4988b2c0f851650c94b8cef49ba1bd111478', - 'org.bouncycastle:bcpg-jdk15on:de3355b821fc81dd32e1f3f560d5b3eca1c678fd2400011d0bfc69fb91bcde85', - 'commons-io:commons-io:cc6a41dc3eaacc9e440a6bd0d2890b20d36b4ee408fe2d67122f328bb6e01581', - /*'org.apache.commons:commons-lang3:734c8356420cc8e30c795d64fd1fcd5d44ea9d90342a2cc3262c5158fbc6d98b',*/ // seems grpc uses diff. version of org.apache.commons - 'org.bouncycastle:bcprov-jdk15on:963e1ee14f808ffb99897d848ddcdb28fa91ddda867eb18d303e82728f878349', - 'com.google.zxing:javase:0ec23e2ec12664ddd6347c8920ad647bb3b9da290f897a88516014b56cc77eb9', - 'commons-codec:commons-codec:ad19d2601c3abf0b946b5c3a4113e226a8c1e3305e395b90013b78dd94a723ce', - 'com.cedricwalter:tor-binary-macos:87790e9eade1e44eeadc81f92670f338cd47ef1b39b46a4b022c75d0cf6465fd', - 'com.cedricwalter:tor-binary-linux32:814f6da3b662c96490bcb09781764dd31dfe497ea9c25c73fe61170d2a78086f', - 'com.cedricwalter:tor-binary-linux64:9da7f8a166ad0a767a5373ca67c68971c9c0cac17964eed2e0850bfecc228312', - 'com.cedricwalter:tor-binary-windows:9487a735dadcadc6ede5ffad36a911c2d4a484f996be93d71094f26591b8c29e', - 'com.github.ravn:jsocks:3c71600af027b2b6d4244e4ad14d98ff2352a379410daebefff5d8cd48d742a4', - 'org.apache.httpcomponents:httpcore:d7f853dee87680b07293d30855b39b9eb56c1297bd16ff1cd6f19ddb8fa745fb', - 'commons-logging:commons-logging:daddea1ea0be0f56978ab3006b8ac92834afeefbd9b7e4e6316fca57df0fa636', - 'javax.inject:javax.inject:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff', - 'aopalliance:aopalliance:0addec670fedcd3f113c5c8091d783280d23f75e3acb841b61a9cdb079376a08', - 'com.github.bisq-network.bitcoinj:bitcoinj-core:ad39183983285d00082cb01638428913db976fa8fd7494c7e223fc81c74d578a', - 'com.lambdaworks:scrypt:9a82d218099fb14c10c0e86e7eefeebd8c104de920acdc47b8b4b7a686fb73b4', - 'com.google.zxing:core:11aae8fd974ab25faa8208be50468eb12349cd239e93e7c797377fa13e381729', - 'com.cedricwalter:tor-binary-geoip:7fc7b5ebf80d65ec53d97dd8d3878b8d2c85dc04f3943e5e85e7ba641655492b', - 'com.github.JesusMcCloud:jtorctl:c6ef92e46074d8d26db718ce0fe4b64b8cf7b934b7377d164c5d613b4cd7b847', - 'org.apache.commons:commons-compress:a778bbd659722889245fc52a0ec2873fbbb89ec661bc1ad3dc043c0757c784c4', - 'org.tukaani:xz:a594643d73cc01928cf6ca5ce100e094ea9d73af760a5d4fb6b75fa673ecec96', - 'com.madgag.spongycastle:core:8d6240b974b0aca4d3da9c7dd44d42339d8a374358aca5fc98e50a995764511f', - 'net.jcip:jcip-annotations:be5805392060c71474bf6c9a67a099471274d30b83eef84bfc4e0889a4f1dcc0', - 'org.bitcoinj:orchid:f836325cfa0466a011cb755c9b0fee6368487a2352eb45f4306ad9e4c18de080', - 'com.squareup.okhttp:okhttp:b4c943138fcef2bcc9d2006b2250c4aabbedeafc5947ed7c0af7fd103ceb2707', - 'org.objenesis:objenesis:5e168368fbc250af3c79aa5fef0c3467a2d64e5a7bd74005f25d8399aeb0708d', - 'com.squareup.okio:okio:114bdc1f47338a68bcbc95abf2f5cdc72beeec91812f2fcd7b521c1937876266', + // TODO add excludes to http api dependencies ] } From f5c92097de3ae60ad695cce9783de476ed086995 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Wed, 6 Jun 2018 19:05:49 +0200 Subject: [PATCH 098/197] Complete API refactoring. Supported demo use case: Case 1: Run Desktop + API - Run Bisq Desktop app with gRPC server (pass option key to enable it) - Run gRPC client - Fund Bisq Desktop with some BTC balance - Call getBalance on gRPC client -> get satoshi of available balance Case 2: Run gRPC API headless The HTTP API classes are prepared and should work with the same model, but there is nothing integrated fro the existing API project as that will require bigger refactorings and changes on their side. --- src/main/java/bisq/desktop/app/BisqApp.java | 9 +- .../java/bisq/desktop/app/BisqAppMain.java | 40 ++++- .../java/bisq/desktop/app/BisqAppModule.java | 2 +- .../java/bisq/desktop/app/DesktopMain.java | 148 ---------------- src/main/java/bisq/desktop/main/MainView.java | 5 +- .../java/bisq/desktop/main/MainViewModel.java | 165 +++++++++--------- 6 files changed, 127 insertions(+), 242 deletions(-) delete mode 100644 src/main/java/bisq/desktop/app/DesktopMain.java diff --git a/src/main/java/bisq/desktop/app/BisqApp.java b/src/main/java/bisq/desktop/app/BisqApp.java index 51ae648d1a5..0647e3a8e8c 100644 --- a/src/main/java/bisq/desktop/app/BisqApp.java +++ b/src/main/java/bisq/desktop/app/BisqApp.java @@ -34,7 +34,6 @@ import bisq.core.alert.AlertManager; import bisq.core.app.AppOptionKeys; -import bisq.core.app.BisqDaemon; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; import bisq.core.btc.wallet.WalletService; @@ -96,7 +95,6 @@ public class BisqApp extends Application implements UncaughtExceptionHandler { private boolean popupOpened; private Scene scene; private boolean shutDownRequested; - private BisqDaemon daemon; public BisqApp() { shutDownHandler = this::stop; @@ -112,10 +110,6 @@ public BisqApp() { public void init() { } - public void setDaemon(BisqDaemon daemon) { - this.daemon = daemon; - } - @Override public void start(Stage stage) { this.stage = stage; @@ -123,9 +117,10 @@ public void start(Stage stage) { appLaunchedHandler.accept(this); } - public void startApplication() { + public void startApplication(Runnable onUiReadyHandler) { try { MainView mainView = loadMainView(injector); + mainView.setOnUiReadyHandler(onUiReadyHandler); scene = createAndConfigScene(mainView, injector); setupStage(scene); diff --git a/src/main/java/bisq/desktop/app/BisqAppMain.java b/src/main/java/bisq/desktop/app/BisqAppMain.java index 04770ca5a0f..3e0f95b43d9 100644 --- a/src/main/java/bisq/desktop/app/BisqAppMain.java +++ b/src/main/java/bisq/desktop/app/BisqAppMain.java @@ -22,6 +22,7 @@ import bisq.desktop.setup.DesktopPersistedDataHost; import bisq.core.app.BisqExecutable; +import bisq.core.app.BisqFacade; import bisq.common.UserThread; import bisq.common.app.AppModule; @@ -35,9 +36,20 @@ import lombok.extern.slf4j.Slf4j; +import javax.annotation.Nullable; + + + +import bisq.grpc.BisqGrpcServer; +import bisq.httpapi.BisqHttpApiServer; + @Slf4j public class BisqAppMain extends BisqExecutable { private BisqApp application; + @Nullable + private BisqHttpApiServer bisqHttpApiServer; + @Nullable + private BisqGrpcServer bisqGrpcServer; public static void main(String[] args) throws Exception { if (BisqExecutable.setupInitialOptionParser(args)) { @@ -64,6 +76,7 @@ protected void configUserThread() { protected void launchApplication() { BisqApp.setAppLaunchedHandler(application -> { BisqAppMain.this.application = (BisqApp) application; + // Necessary to do the setup at this point to prevent Bouncy Castle errors CommonSetup.setup(BisqAppMain.this.application); // Map to user thread! @@ -110,6 +123,31 @@ protected void setupPersistedDataHosts(Injector injector) { @Override protected void startApplication() { // We need to be in user thread! We mapped at launchApplication already... - application.startApplication(); + + // Once the UI is ready we get onApplicationStarted called and start the setup there + application.startApplication(this::onApplicationStarted); + } + + @Override + protected void onApplicationStarted() { + super.onApplicationStarted(); + + if (runWithHttpApi()) { + final BisqFacade bisqFacade = injector.getInstance(BisqFacade.class); + bisqHttpApiServer = new BisqHttpApiServer(bisqFacade); + } + + if (runWithGrpcApi()) { + final BisqFacade bisqFacade = injector.getInstance(BisqFacade.class); + bisqGrpcServer = new BisqGrpcServer(bisqFacade); + } + } + + private boolean runWithHttpApi() { + return bisqEnvironment.getDesktopWithHttpApi().toLowerCase().equals("true"); + } + + private boolean runWithGrpcApi() { + return bisqEnvironment.getDesktopWithGrpcApi().toLowerCase().equals("true"); } } diff --git a/src/main/java/bisq/desktop/app/BisqAppModule.java b/src/main/java/bisq/desktop/app/BisqAppModule.java index 942c49a718b..75c389288e3 100644 --- a/src/main/java/bisq/desktop/app/BisqAppModule.java +++ b/src/main/java/bisq/desktop/app/BisqAppModule.java @@ -19,7 +19,7 @@ import bisq.desktop.DesktopModule; -import bisq.core.app.CoreModule; +import bisq.core.CoreModule; import bisq.common.app.AppModule; diff --git a/src/main/java/bisq/desktop/app/DesktopMain.java b/src/main/java/bisq/desktop/app/DesktopMain.java deleted file mode 100644 index eeae4c3f41e..00000000000 --- a/src/main/java/bisq/desktop/app/DesktopMain.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.desktop.app; - -import bisq.desktop.common.UITimer; -import bisq.desktop.common.view.guice.InjectorViewFactory; -import bisq.desktop.setup.DesktopPersistedDataHost; - -import bisq.core.app.BisqDaemon; -import bisq.core.app.BisqExecutable; - -import bisq.common.UserThread; -import bisq.common.app.AppModule; -import bisq.common.proto.persistable.PersistedDataHost; -import bisq.common.setup.CommonSetup; - -import com.google.inject.Injector; - -import javafx.application.Application; -import javafx.application.Platform; - -import lombok.extern.slf4j.Slf4j; - -import javax.annotation.Nullable; - - - -import bisq.httpapi.BisqHttpApi; - -@Slf4j -public class DesktopMain extends BisqExecutable { - private BisqApp application; - private BisqDaemon bisqDaemon; - @Nullable - private BisqHttpApi bisqHttpApi; - - public static void main(String[] args) throws Exception { - if (BisqExecutable.setupInitialOptionParser(args)) { - // For some reason the JavaFX launch process results in us losing the thread context class loader: reset it. - // In order to work around a bug in JavaFX 8u25 and below, you must include the following code as the first line of your realMain method: - Thread.currentThread().setContextClassLoader(DesktopMain.class.getClassLoader()); - - new DesktopMain().execute(args); - } - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // First synchronous execution tasks - /////////////////////////////////////////////////////////////////////////////////////////// - - @Override - protected void configUserThread() { - UserThread.setExecutor(Platform::runLater); - UserThread.setTimerClass(UITimer.class); - } - - @Override - protected void launchApplication() { - bisqDaemon = new BisqDaemon(); - if (runWithHttpApi()) - bisqHttpApi = new BisqHttpApi(bisqDaemon); - - BisqApp.setAppLaunchedHandler(application -> { - DesktopMain.this.application = (BisqApp) application; - - DesktopMain.this.application.setDaemon(bisqDaemon); - - // Necessary to do the setup at this point to prevent Bouncy Castle errors - CommonSetup.setup(DesktopMain.this.application); - // Map to user thread! - UserThread.execute(this::onApplicationLaunched); - }); - - Application.launch(BisqApp.class); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // As application is a JavaFX application we need to wait for onApplicationLaunched - /////////////////////////////////////////////////////////////////////////////////////////// - - @Override - protected void onApplicationLaunched() { - super.onApplicationLaunched(); - application.setGracefulShutDownHandler(this); - - } - - /////////////////////////////////////////////////////////////////////////////////////////// - // We continue with a series of synchronous execution tasks - /////////////////////////////////////////////////////////////////////////////////////////// - - @Override - protected AppModule getModule() { - return new BisqAppModule(bisqEnvironment); - } - - @Override - protected void applyInjector() { - super.applyInjector(); - - bisqDaemon.setInjector(injector); - application.setInjector(injector); - if (bisqHttpApi != null) - bisqHttpApi.setInjector(injector); - - injector.getInstance(InjectorViewFactory.class).setInjector(injector); - } - - @Override - protected void setupPersistedDataHosts(Injector injector) { - super.setupPersistedDataHosts(injector); - PersistedDataHost.apply(DesktopPersistedDataHost.getPersistedDataHosts(injector)); - } - - @Override - protected void startApplication() { - // We need to be in user thread! We mapped at launchApplication already... - bisqDaemon.startApplication(); - application.startApplication(); - if (bisqHttpApi != null) - bisqHttpApi.startApplication(); - } - - private boolean runWithHttpApi() { - return bisqEnvironment.getDesktopWithHttpApi().toLowerCase().equals("true"); - } - - private boolean runWithGrpcApi() { - return bisqEnvironment.getDesktopWithGrpcApi().toLowerCase().equals("true"); - } -} diff --git a/src/main/java/bisq/desktop/main/MainView.java b/src/main/java/bisq/desktop/main/MainView.java index 0ccdc80d6c8..7716fa8c54a 100644 --- a/src/main/java/bisq/desktop/main/MainView.java +++ b/src/main/java/bisq/desktop/main/MainView.java @@ -82,6 +82,7 @@ import javafx.beans.value.ChangeListener; +import lombok.Setter; import lombok.extern.slf4j.Slf4j; import static javafx.scene.layout.AnchorPane.setBottomAnchor; @@ -95,6 +96,8 @@ public class MainView extends InitializableView { // If after 30 sec we have not got connected we show "open network settings" button private final static int SHOW_TOR_SETTINGS_DELAY_SEC = 90; private Label versionLabel; + @Setter + private Runnable onUiReadyHandler; public static StackPane getRootContainer() { return MainView.rootContainer; @@ -309,7 +312,7 @@ protected void initialize() { }); // Delay a bit to give time for rendering the splash screen - UserThread.execute(model::start); + UserThread.execute(() -> onUiReadyHandler.run()); } private Tuple2 getBalanceBox(String text) { diff --git a/src/main/java/bisq/desktop/main/MainViewModel.java b/src/main/java/bisq/desktop/main/MainViewModel.java index 80100f44365..ffef4dad7ff 100644 --- a/src/main/java/bisq/desktop/main/MainViewModel.java +++ b/src/main/java/bisq/desktop/main/MainViewModel.java @@ -82,7 +82,7 @@ import lombok.extern.slf4j.Slf4j; @Slf4j -public class MainViewModel implements ViewModel { +public class MainViewModel implements ViewModel, BisqSetup.BisqSetupCompleteListener { private final BisqSetup bisqSetup; private final WalletsSetup walletsSetup; private final User user; @@ -109,7 +109,6 @@ public class MainViewModel implements ViewModel { @Getter private BooleanProperty showAppScreen = new SimpleBooleanProperty(); - final ObservableList priceFeedComboBoxItems = FXCollections.observableArrayList(); private final BooleanProperty isSplashScreenRemoved = new SimpleBooleanProperty(); private Timer checkNumberOfBtcPeersTimer; @@ -173,19 +172,95 @@ public MainViewModel(BisqSetup bisqSetup, BalanceWithConfirmationTextField.setWalletService(btcWalletService); GUIUtil.setFeeService(feeService); + + setupHandlers(); + bisqSetup.addBisqSetupCompleteListener(this); } /////////////////////////////////////////////////////////////////////////////////////////// - // API + // BisqSetupCompleteListener /////////////////////////////////////////////////////////////////////////////////////////// - public void start() { - setupHandlers(); + @Override + public void onSetupComplete() { + // We handle the trade period here as we display a global popup if we reached dispute time + tradesAndUIReady = EasyBind.combine(isSplashScreenRemoved, tradeManager.pendingTradesInitializedProperty(), (a, b) -> a && b); + tradesAndUIReady.subscribe((observable, oldValue, newValue) -> { + if (newValue) { + tradeManager.applyTradePeriodState(); + + tradeManager.getTradableList().forEach(trade -> { + Date maxTradePeriodDate = trade.getMaxTradePeriodDate(); + String key; + switch (trade.getTradePeriodState()) { + case FIRST_HALF: + break; + case SECOND_HALF: + key = "displayHalfTradePeriodOver" + trade.getId(); + if (DontShowAgainLookup.showAgain(key)) { + DontShowAgainLookup.dontShowAgain(key, true); + new Popup<>().warning(Res.get("popup.warning.tradePeriod.halfReached", + trade.getShortId(), + formatter.formatDateTime(maxTradePeriodDate))) + .show(); + } + break; + case TRADE_PERIOD_OVER: + key = "displayTradePeriodOver" + trade.getId(); + if (DontShowAgainLookup.showAgain(key)) { + DontShowAgainLookup.dontShowAgain(key, true); + new Popup<>().warning(Res.get("popup.warning.tradePeriod.ended", + trade.getShortId(), + formatter.formatDateTime(maxTradePeriodDate))) + .show(); + } + break; + } + }); + } + }); + + setupP2PNumPeersWatcher(); + setupBtcNumPeersWatcher(); + + marketPricePresentation.setup(); + + if (DevEnv.isDevMode()) { + preferences.setShowOwnOffersInOfferBook(true); + setupDevDummyPaymentAccounts(); + } - bisqSetup.start(this::onSetupComplete); + getShowAppScreen().set(true); } + + /////////////////////////////////////////////////////////////////////////////////////////// + // UI handlers + /////////////////////////////////////////////////////////////////////////////////////////// + + // After showAppScreen is set and splash screen is faded out + void onSplashScreenRemoved() { + isSplashScreenRemoved.set(true); + + // Delay that as we want to know what is the current path of the navigation which is set + // in MainView showAppScreen handler + notificationCenter.onAllServicesAndViewsInitialized(); + } + + void onOpenDownloadWindow() { + bisqSetup.displayAlertIfPresent(user.getDisplayedAlert(), true); + } + + void setPriceFeedComboBoxItem(PriceFeedComboBoxItem item) { + marketPricePresentation.setPriceFeedComboBoxItem(item); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Private + /////////////////////////////////////////////////////////////////////////////////////////// + private void setupHandlers() { bisqSetup.setDisplayTacHandler(acceptedHandler -> UserThread.runAfter(() -> { //noinspection FunctionalExpressionCanBeFolded @@ -271,84 +346,6 @@ private void setupHandlers() { .show()); } - private void onSetupComplete() { - // We handle the trade period here as we display a global popup if we reached dispute time - tradesAndUIReady = EasyBind.combine(isSplashScreenRemoved, tradeManager.pendingTradesInitializedProperty(), (a, b) -> a && b); - tradesAndUIReady.subscribe((observable, oldValue, newValue) -> { - if (newValue) { - tradeManager.applyTradePeriodState(); - - tradeManager.getTradableList().forEach(trade -> { - Date maxTradePeriodDate = trade.getMaxTradePeriodDate(); - String key; - switch (trade.getTradePeriodState()) { - case FIRST_HALF: - break; - case SECOND_HALF: - key = "displayHalfTradePeriodOver" + trade.getId(); - if (DontShowAgainLookup.showAgain(key)) { - DontShowAgainLookup.dontShowAgain(key, true); - new Popup<>().warning(Res.get("popup.warning.tradePeriod.halfReached", - trade.getShortId(), - formatter.formatDateTime(maxTradePeriodDate))) - .show(); - } - break; - case TRADE_PERIOD_OVER: - key = "displayTradePeriodOver" + trade.getId(); - if (DontShowAgainLookup.showAgain(key)) { - DontShowAgainLookup.dontShowAgain(key, true); - new Popup<>().warning(Res.get("popup.warning.tradePeriod.ended", - trade.getShortId(), - formatter.formatDateTime(maxTradePeriodDate))) - .show(); - } - break; - } - }); - } - }); - - setupP2PNumPeersWatcher(); - setupBtcNumPeersWatcher(); - - marketPricePresentation.setup(); - - if (DevEnv.isDevMode()) { - preferences.setShowOwnOffersInOfferBook(true); - setupDevDummyPaymentAccounts(); - } - - getShowAppScreen().set(true); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // UI handlers - /////////////////////////////////////////////////////////////////////////////////////////// - - // After showAppScreen is set and splash screen is faded out - void onSplashScreenRemoved() { - isSplashScreenRemoved.set(true); - - // Delay that as we want to know what is the current path of the navigation which is set - // in MainView showAppScreen handler - notificationCenter.onAllServicesAndViewsInitialized(); - } - - void onOpenDownloadWindow() { - bisqSetup.displayAlertIfPresent(user.getDisplayedAlert(), true); - } - - void setPriceFeedComboBoxItem(PriceFeedComboBoxItem item) { - marketPricePresentation.setPriceFeedComboBoxItem(item); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Private - /////////////////////////////////////////////////////////////////////////////////////////// - private void setupP2PNumPeersWatcher() { p2PService.getNumConnectedPeers().addListener((observable, oldValue, newValue) -> { int numPeers = (int) newValue; From b2aaed9c0d6796e4471e587674a4aedd9f0eb38a Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Fri, 8 Jun 2018 13:25:23 +0200 Subject: [PATCH 099/197] Remove protectedDataStore at blindVote - Fix issue with same address for change and issuance candidate (use freshReceiveAddress instead of currentReceiveAddress) - Check if issuance candidate ended up in an issuance tx at StateService.isBsqTxOutputType - Change dust value to 546 - Remove blockHash in BlindVoteAppendOnlyPayload --- src/main/java/bisq/desktop/util/validation/BsqValidator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/bisq/desktop/util/validation/BsqValidator.java b/src/main/java/bisq/desktop/util/validation/BsqValidator.java index 7774dc6fb38..ac9c59b8572 100644 --- a/src/main/java/bisq/desktop/util/validation/BsqValidator.java +++ b/src/main/java/bisq/desktop/util/validation/BsqValidator.java @@ -43,7 +43,7 @@ public class BsqValidator extends AltcoinValidator { private Coin maxValue; @Nullable private Coin availableBalance; - private Coin minValue = Coin.valueOf(2730); // dust + private Coin minValue = Coin.valueOf(546); // dust @Override protected double getMinValue() { From 15baead905caae48aca05778b554dc3422c3c283 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Fri, 8 Jun 2018 13:42:58 +0200 Subject: [PATCH 100/197] Add mavenLocal, updatte hashes --- build.gradle | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/build.gradle b/build.gradle index e8b117982ac..e68e044d809 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,6 @@ buildscript { repositories { + mavenLocal() jcenter() } dependencies { @@ -33,6 +34,7 @@ tasks.withType(JavaCompile) { sourceSets.main.resources.srcDirs += ['src/main/java'] // to copy fxml and css files repositories { + mavenLocal() jcenter() maven { url 'https://jitpack.io' } maven { url 'https://raw.githubusercontent.com/JesusMcCloud/tor-binary/master/release/' } @@ -109,13 +111,15 @@ dependencyVerification { 'org.apache.commons:commons-lang3:734c8356420cc8e30c795d64fd1fcd5d44ea9d90342a2cc3262c5158fbc6d98b', 'org.bouncycastle:bcprov-jdk15on:963e1ee14f808ffb99897d848ddcdb28fa91ddda867eb18d303e82728f878349', 'net.sf.jopt-simple:jopt-simple:6f45c00908265947c39221035250024f2caec9a15c1c8cf553ebeecee289f342', - 'network.bisq.btcd-cli4j:btcd-cli4j-daemon:300e2fb9500398f4c5cec6ae07d16d07570dbe0eb9944061eb67ab7db18fa72c', - 'network.bisq.btcd-cli4j:btcd-cli4j-core:63baeecea21940670e054bba6b041959e49fa094a496c141b9da55401ee4a8e7', + 'network.bisq.btcd-cli4j:btcd-cli4j-daemon:cf19fddccfd9c5302498dfdb29a7fead8faff04912285bfdaacad1fd7a27f646', + 'network.bisq.btcd-cli4j:btcd-cli4j-core:cc063c3a501ee6dd6f2e2e98ce59e82d720a52522acc1ec0751434dece4851e4', 'com.fasterxml.jackson.core:jackson-databind:fcf3c2b0c332f5f54604f7e27fa7ee502378a2cc5df6a944bbfae391872c32ff', 'com.fasterxml.jackson.core:jackson-core:39a74610521d7fb9eb3f437bb8739bbf47f6435be12d17bf954c731a0c6352bb', 'com.fasterxml.jackson.core:jackson-annotations:2566b3a6662afa3c6af4f5b25006cb46be2efc68f1b5116291d6998a8cdf7ed3', 'org.apache.httpcomponents:httpclient:db3d1b6c2d6a5e5ad47577ad61854e2f0e0936199b8e05eb541ed52349263135', 'org.fxmisc.easybind:easybind:666af296dda6de68751668a62661571b5238ac6f1c07c8a204fc6f902b222aaf', + 'com.github.bisq-network.bitcoinj:bitcoinj-core:05c94cc68f1524ed08f5aa815f5f09d99a3aae5ab277527d7729ee74d0aece13', + 'com.lambdaworks:scrypt:9a82d218099fb14c10c0e86e7eefeebd8c104de920acdc47b8b4b7a686fb73b4', 'com.google.zxing:javase:0ec23e2ec12664ddd6347c8920ad647bb3b9da290f897a88516014b56cc77eb9', 'commons-logging:commons-logging:daddea1ea0be0f56978ab3006b8ac92834afeefbd9b7e4e6316fca57df0fa636', 'javax.inject:javax.inject:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff', @@ -127,18 +131,16 @@ dependencyVerification { 'com.cedricwalter:tor-binary-windows:9487a735dadcadc6ede5ffad36a911c2d4a484f996be93d71094f26591b8c29e', 'com.github.ravn:jsocks:3c71600af027b2b6d4244e4ad14d98ff2352a379410daebefff5d8cd48d742a4', 'org.apache.httpcomponents:httpcore:d7f853dee87680b07293d30855b39b9eb56c1297bd16ff1cd6f19ddb8fa745fb', + 'com.madgag.spongycastle:core:8d6240b974b0aca4d3da9c7dd44d42339d8a374358aca5fc98e50a995764511f', + 'net.jcip:jcip-annotations:be5805392060c71474bf6c9a67a099471274d30b83eef84bfc4e0889a4f1dcc0', + 'org.bitcoinj:orchid:f836325cfa0466a011cb755c9b0fee6368487a2352eb45f4306ad9e4c18de080', + 'com.squareup.okhttp:okhttp:b4c943138fcef2bcc9d2006b2250c4aabbedeafc5947ed7c0af7fd103ceb2707', 'com.google.zxing:core:11aae8fd974ab25faa8208be50468eb12349cd239e93e7c797377fa13e381729', 'com.cedricwalter:tor-binary-geoip:7fc7b5ebf80d65ec53d97dd8d3878b8d2c85dc04f3943e5e85e7ba641655492b', 'com.github.JesusMcCloud:jtorctl:c6ef92e46074d8d26db718ce0fe4b64b8cf7b934b7377d164c5d613b4cd7b847', 'org.apache.commons:commons-compress:a778bbd659722889245fc52a0ec2873fbbb89ec661bc1ad3dc043c0757c784c4', 'org.tukaani:xz:a594643d73cc01928cf6ca5ce100e094ea9d73af760a5d4fb6b75fa673ecec96', - 'org.objenesis:objenesis:5e168368fbc250af3c79aa5fef0c3467a2d64e5a7bd74005f25d8399aeb0708d', - 'com.github.bisq-network.bitcoinj:bitcoinj-core:05c94cc68f1524ed08f5aa815f5f09d99a3aae5ab277527d7729ee74d0aece13', - 'com.lambdaworks:scrypt:9a82d218099fb14c10c0e86e7eefeebd8c104de920acdc47b8b4b7a686fb73b4', - 'com.madgag.spongycastle:core:8d6240b974b0aca4d3da9c7dd44d42339d8a374358aca5fc98e50a995764511f', - 'net.jcip:jcip-annotations:be5805392060c71474bf6c9a67a099471274d30b83eef84bfc4e0889a4f1dcc0', - 'org.bitcoinj:orchid:f836325cfa0466a011cb755c9b0fee6368487a2352eb45f4306ad9e4c18de080', - 'com.squareup.okhttp:okhttp:b4c943138fcef2bcc9d2006b2250c4aabbedeafc5947ed7c0af7fd103ceb2707', 'com.squareup.okio:okio:114bdc1f47338a68bcbc95abf2f5cdc72beeec91812f2fcd7b521c1937876266', + 'org.objenesis:objenesis:5e168368fbc250af3c79aa5fef0c3467a2d64e5a7bd74005f25d8399aeb0708d', ] } From ac17955dbe66450b7705ff9282a2916a4857ecaf Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sat, 16 Jun 2018 13:15:58 +0200 Subject: [PATCH 101/197] Add mavenLocal to repositories --- build.gradle | 2 -- 1 file changed, 2 deletions(-) diff --git a/build.gradle b/build.gradle index e68e044d809..1f8457c6579 100644 --- a/build.gradle +++ b/build.gradle @@ -111,8 +111,6 @@ dependencyVerification { 'org.apache.commons:commons-lang3:734c8356420cc8e30c795d64fd1fcd5d44ea9d90342a2cc3262c5158fbc6d98b', 'org.bouncycastle:bcprov-jdk15on:963e1ee14f808ffb99897d848ddcdb28fa91ddda867eb18d303e82728f878349', 'net.sf.jopt-simple:jopt-simple:6f45c00908265947c39221035250024f2caec9a15c1c8cf553ebeecee289f342', - 'network.bisq.btcd-cli4j:btcd-cli4j-daemon:cf19fddccfd9c5302498dfdb29a7fead8faff04912285bfdaacad1fd7a27f646', - 'network.bisq.btcd-cli4j:btcd-cli4j-core:cc063c3a501ee6dd6f2e2e98ce59e82d720a52522acc1ec0751434dece4851e4', 'com.fasterxml.jackson.core:jackson-databind:fcf3c2b0c332f5f54604f7e27fa7ee502378a2cc5df6a944bbfae391872c32ff', 'com.fasterxml.jackson.core:jackson-core:39a74610521d7fb9eb3f437bb8739bbf47f6435be12d17bf954c731a0c6352bb', 'com.fasterxml.jackson.core:jackson-annotations:2566b3a6662afa3c6af4f5b25006cb46be2efc68f1b5116291d6998a8cdf7ed3', From 9c3865a331c538af92f78bbbec50ef5dede8e193 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sat, 16 Jun 2018 13:39:27 +0200 Subject: [PATCH 102/197] Use verbosity in getBlock rpc call to get all txs Update to btcd-cli4j cb5c474b --- build.gradle | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build.gradle b/build.gradle index 1f8457c6579..e68e044d809 100644 --- a/build.gradle +++ b/build.gradle @@ -111,6 +111,8 @@ dependencyVerification { 'org.apache.commons:commons-lang3:734c8356420cc8e30c795d64fd1fcd5d44ea9d90342a2cc3262c5158fbc6d98b', 'org.bouncycastle:bcprov-jdk15on:963e1ee14f808ffb99897d848ddcdb28fa91ddda867eb18d303e82728f878349', 'net.sf.jopt-simple:jopt-simple:6f45c00908265947c39221035250024f2caec9a15c1c8cf553ebeecee289f342', + 'network.bisq.btcd-cli4j:btcd-cli4j-daemon:cf19fddccfd9c5302498dfdb29a7fead8faff04912285bfdaacad1fd7a27f646', + 'network.bisq.btcd-cli4j:btcd-cli4j-core:cc063c3a501ee6dd6f2e2e98ce59e82d720a52522acc1ec0751434dece4851e4', 'com.fasterxml.jackson.core:jackson-databind:fcf3c2b0c332f5f54604f7e27fa7ee502378a2cc5df6a944bbfae391872c32ff', 'com.fasterxml.jackson.core:jackson-core:39a74610521d7fb9eb3f437bb8739bbf47f6435be12d17bf954c731a0c6352bb', 'com.fasterxml.jackson.core:jackson-annotations:2566b3a6662afa3c6af4f5b25006cb46be2efc68f1b5116291d6998a8cdf7ed3', From a21fed6b52f3d26f2b53e02db9da28b26e7b3c36 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sat, 16 Jun 2018 14:48:20 +0200 Subject: [PATCH 103/197] Merge branch 'api-integration' into voting # Conflicts: # src/main/java/bisq/core/arbitration/DisputeManager.java Merge branch 'api-integration' into voting # Conflicts: # build.gradle # src/main/java/bisq/desktop/main/dao/BaseProposalView.java # src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java # src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java # src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java # src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java # src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java # src/main/java/bisq/desktop/util/GUIUtil.java --- build.gradle | 61 ------------------- .../main/dao/BaseProposalListItem.java | 2 +- .../desktop/main/dao/BaseProposalView.java | 4 +- .../main/dao/proposal/ProposalItemsView.java | 4 +- .../main/dao/proposal/ProposalListItem.java | 2 +- .../active/ActiveProposalListItem.java | 2 +- .../proposal/active/ActiveProposalsView.java | 4 +- .../closed/ClosedProposalListItem.java | 2 +- .../proposal/closed/ClosedProposalsView.java | 4 +- .../dashboard/ProposalDashboardView.java | 2 +- .../dao/proposal/make/MakeProposalView.java | 5 +- .../dao/proposal/myvotes/MyVotesView.java | 11 +--- .../voting/active/ActiveBallotListItem.java | 2 +- .../dao/voting/active/ActiveBallotsView.java | 4 +- .../voting/closed/ClosedBallotListItem.java | 2 +- .../dao/voting/closed/ClosedBallotsView.java | 4 +- .../voting/dashboard/VotingDashboardView.java | 2 +- 17 files changed, 24 insertions(+), 93 deletions(-) diff --git a/build.gradle b/build.gradle index ddb2b5ed5e3..de214c95ba0 100644 --- a/build.gradle +++ b/build.gradle @@ -74,66 +74,5 @@ installDist.destinationDir = file('build/app') // generated with `./gradlew -q calculateChecksums | grep -v network.bisq:bisq-` dependencyVerification { verify = [ - 'network.bisq.libdohj:libdohj-core:cef7db8a2032ffbc229ccacc29b7d13e8ee1daf1cd60ee8f988cdfa60a041d8e', - 'org.controlsfx:controlsfx:b98f1c9507c05600f80323674b33d15674926c71b0116f70085b62bdacf1e573', - 'org.reactfx:reactfx:81ec8fe545d65661222735711114c2ce427e2187a65f1722e8ac4e4805beeca3', - 'net.glxn:qrgen:c85d9d8512d91e8ad11fe56259a7825bd50ce0245447e236cf168d1b17591882', - 'de.jensd:fontawesomefx:73bacc991a0a6f5cf0f911767c8db161e0949dbca61e8371eb4342e3da96887b', - 'de.jensd:fontawesomefx-materialdesignfont:8f700556bbfdc4a581224d3bd6ff869b8a03f6670bd7e0fc78884bd2f31fdb64', - 'de.jensd:fontawesomefx-commons:e1505a31433f1b2902478217651afc78dae5ab09670336afc46e582a1dea1e4d', - 'com.googlecode.jcsv:jcsv:73ca7d715e90c8d2c2635cc284543b038245a34f70790660ed590e157b8714a2', - 'com.google.protobuf:protobuf-java:b5e2d91812d183c9f053ffeebcbcda034d4de6679521940a19064714966c2cd4', - 'com.google.code.gson:gson:2d43eb5ea9e133d2ee2405cc14f5ee08951b8361302fdd93494a3a997b508d32', - 'com.googlecode.json-simple:json-simple:4e69696892b88b41c55d49ab2fdcc21eead92bf54acc588c0050596c3b75199c', - 'org.springframework:spring-core:c451e8417adb2ffb2445636da5e44a2f59307c4100037a1fe387c3fba4f29b52', - 'ch.qos.logback:logback-classic:e66efc674e94837344bc5b748ff510c37a44eeff86cbfdbf9e714ef2eb374013', - 'org.slf4j:slf4j-api:3a4cd4969015f3beb4b5b4d81dbafc01765fb60b8a439955ca64d8476fef553e', - 'ch.qos.logback:logback-core:4cd46fa17d77057b39160058df2f21ebbc2aded51d0edcc25d2c1cecc042a005', - 'com.google.code.findbugs:jsr305:c885ce34249682bc0236b4a7d56efcc12048e6135a5baf7a9cde8ad8cda13fcd', - 'com.google.guava:guava:36a666e3b71ae7f0f0dca23654b67e086e6c93d192f60ba5dfd5519db6c288c8', - 'com.google.inject:guice:9b9df27a5b8c7864112b4137fd92b36c3f1395bfe57be42fedf2f520ead1a93e', - 'com.github.JesusMcCloud.netlayer:tor.native:de44e782b21838d3426dbff99abbfd1cbb8e5d3f6d5e997441ff4fd8354934fa', - 'com.github.JesusMcCloud.netlayer:tor:3896950c56a41985f901ff9475524ac162cba18b2d5a0ed39810b20ddaf5128a', - 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:841b021d62fc007ce2883963ff9440d5393fb1f6a0604ed68cd016afcaf02967', - 'com.github.MicroUtils:kotlin-logging:7dbd501cc210d721f730d480c53ee2a6e3c154ae89b07dc7dee224b9c5aca9eb', - 'org.jetbrains.kotlin:kotlin-stdlib-jdk7:bd8cd4e3ef391cd468434747b7939c49e80f8bf4ae10355a65382bfb54fd633c', - 'org.jetbrains.kotlin:kotlin-stdlib:e1c39d27f23a7fe2d3e4ac65e80a53e98fdcf60e07de9d53b8b841c5944fc810', - 'org.jetbrains:annotations:ace2a10dc8e2d5fd34925ecac03e4988b2c0f851650c94b8cef49ba1bd111478', - 'org.bouncycastle:bcpg-jdk15on:de3355b821fc81dd32e1f3f560d5b3eca1c678fd2400011d0bfc69fb91bcde85', - 'commons-io:commons-io:cc6a41dc3eaacc9e440a6bd0d2890b20d36b4ee408fe2d67122f328bb6e01581', - 'org.apache.commons:commons-lang3:734c8356420cc8e30c795d64fd1fcd5d44ea9d90342a2cc3262c5158fbc6d98b', - 'org.bouncycastle:bcprov-jdk15on:963e1ee14f808ffb99897d848ddcdb28fa91ddda867eb18d303e82728f878349', - 'net.sf.jopt-simple:jopt-simple:6f45c00908265947c39221035250024f2caec9a15c1c8cf553ebeecee289f342', - 'network.bisq.btcd-cli4j:btcd-cli4j-daemon:cf19fddccfd9c5302498dfdb29a7fead8faff04912285bfdaacad1fd7a27f646', - 'network.bisq.btcd-cli4j:btcd-cli4j-core:cc063c3a501ee6dd6f2e2e98ce59e82d720a52522acc1ec0751434dece4851e4', - 'com.fasterxml.jackson.core:jackson-databind:fcf3c2b0c332f5f54604f7e27fa7ee502378a2cc5df6a944bbfae391872c32ff', - 'com.fasterxml.jackson.core:jackson-core:39a74610521d7fb9eb3f437bb8739bbf47f6435be12d17bf954c731a0c6352bb', - 'com.fasterxml.jackson.core:jackson-annotations:2566b3a6662afa3c6af4f5b25006cb46be2efc68f1b5116291d6998a8cdf7ed3', - 'org.apache.httpcomponents:httpclient:db3d1b6c2d6a5e5ad47577ad61854e2f0e0936199b8e05eb541ed52349263135', - 'org.fxmisc.easybind:easybind:666af296dda6de68751668a62661571b5238ac6f1c07c8a204fc6f902b222aaf', - 'com.github.bisq-network.bitcoinj:bitcoinj-core:05c94cc68f1524ed08f5aa815f5f09d99a3aae5ab277527d7729ee74d0aece13', - 'com.lambdaworks:scrypt:9a82d218099fb14c10c0e86e7eefeebd8c104de920acdc47b8b4b7a686fb73b4', - 'com.google.zxing:javase:0ec23e2ec12664ddd6347c8920ad647bb3b9da290f897a88516014b56cc77eb9', - 'commons-logging:commons-logging:daddea1ea0be0f56978ab3006b8ac92834afeefbd9b7e4e6316fca57df0fa636', - 'javax.inject:javax.inject:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff', - 'aopalliance:aopalliance:0addec670fedcd3f113c5c8091d783280d23f75e3acb841b61a9cdb079376a08', - 'commons-codec:commons-codec:ad19d2601c3abf0b946b5c3a4113e226a8c1e3305e395b90013b78dd94a723ce', - 'com.cedricwalter:tor-binary-macos:87790e9eade1e44eeadc81f92670f338cd47ef1b39b46a4b022c75d0cf6465fd', - 'com.cedricwalter:tor-binary-linux32:814f6da3b662c96490bcb09781764dd31dfe497ea9c25c73fe61170d2a78086f', - 'com.cedricwalter:tor-binary-linux64:9da7f8a166ad0a767a5373ca67c68971c9c0cac17964eed2e0850bfecc228312', - 'com.cedricwalter:tor-binary-windows:9487a735dadcadc6ede5ffad36a911c2d4a484f996be93d71094f26591b8c29e', - 'com.github.ravn:jsocks:3c71600af027b2b6d4244e4ad14d98ff2352a379410daebefff5d8cd48d742a4', - 'org.apache.httpcomponents:httpcore:d7f853dee87680b07293d30855b39b9eb56c1297bd16ff1cd6f19ddb8fa745fb', - 'com.madgag.spongycastle:core:8d6240b974b0aca4d3da9c7dd44d42339d8a374358aca5fc98e50a995764511f', - 'net.jcip:jcip-annotations:be5805392060c71474bf6c9a67a099471274d30b83eef84bfc4e0889a4f1dcc0', - 'org.bitcoinj:orchid:f836325cfa0466a011cb755c9b0fee6368487a2352eb45f4306ad9e4c18de080', - 'com.squareup.okhttp:okhttp:b4c943138fcef2bcc9d2006b2250c4aabbedeafc5947ed7c0af7fd103ceb2707', - 'com.google.zxing:core:11aae8fd974ab25faa8208be50468eb12349cd239e93e7c797377fa13e381729', - 'com.cedricwalter:tor-binary-geoip:7fc7b5ebf80d65ec53d97dd8d3878b8d2c85dc04f3943e5e85e7ba641655492b', - 'com.github.JesusMcCloud:jtorctl:c6ef92e46074d8d26db718ce0fe4b64b8cf7b934b7377d164c5d613b4cd7b847', - 'org.apache.commons:commons-compress:a778bbd659722889245fc52a0ec2873fbbb89ec661bc1ad3dc043c0757c784c4', - 'org.tukaani:xz:a594643d73cc01928cf6ca5ce100e094ea9d73af760a5d4fb6b75fa673ecec96', - 'com.squareup.okio:okio:114bdc1f47338a68bcbc95abf2f5cdc72beeec91812f2fcd7b521c1937876266', - 'org.objenesis:objenesis:5e168368fbc250af3c79aa5fef0c3467a2d64e5a7bd74005f25d8399aeb0708d', ] } diff --git a/src/main/java/bisq/desktop/main/dao/BaseProposalListItem.java b/src/main/java/bisq/desktop/main/dao/BaseProposalListItem.java index 064a7497806..d62cda396f7 100644 --- a/src/main/java/bisq/desktop/main/dao/BaseProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/BaseProposalListItem.java @@ -18,7 +18,6 @@ package bisq.desktop.main.dao; import bisq.desktop.components.indicator.TxConfidenceIndicator; -import bisq.desktop.util.BsqFormatter; import bisq.core.btc.listeners.TxConfidenceListener; import bisq.core.btc.wallet.BsqWalletService; @@ -29,6 +28,7 @@ import bisq.core.dao.state.period.DaoPhase; import bisq.core.dao.voting.proposal.Proposal; import bisq.core.locale.Res; +import bisq.core.util.BsqFormatter; import org.bitcoinj.core.Transaction; import org.bitcoinj.core.TransactionConfidence; diff --git a/src/main/java/bisq/desktop/main/dao/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/BaseProposalView.java index 769555016aa..04fb3227ab9 100644 --- a/src/main/java/bisq/desktop/main/dao/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/BaseProposalView.java @@ -25,14 +25,14 @@ import bisq.desktop.components.TableGroupHeadline; import bisq.desktop.main.dao.proposal.ProposalDetailsWindow; import bisq.desktop.main.dao.proposal.ProposalDisplay; -import bisq.core.util.BSFormatter; -import bisq.core.util.BsqFormatter; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; import bisq.core.dao.state.period.DaoPhase; import bisq.core.dao.voting.proposal.Proposal; import bisq.core.locale.Res; +import bisq.core.util.BSFormatter; +import bisq.core.util.BsqFormatter; import javax.inject.Inject; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalItemsView.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalItemsView.java index 5c84bf97261..7bf96b91d25 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalItemsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalItemsView.java @@ -19,12 +19,12 @@ import bisq.desktop.common.view.FxmlView; import bisq.desktop.main.dao.BaseProposalView; -import bisq.desktop.util.BSFormatter; -import bisq.desktop.util.BsqFormatter; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; import bisq.core.dao.voting.proposal.Proposal; +import bisq.core.util.BSFormatter; +import bisq.core.util.BsqFormatter; import javax.inject.Inject; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index b31127b39e4..275c58423ba 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -18,11 +18,11 @@ package bisq.desktop.main.dao.proposal; import bisq.desktop.main.dao.BaseProposalListItem; -import bisq.core.util.BsqFormatter; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; import bisq.core.dao.voting.proposal.Proposal; +import bisq.core.util.BsqFormatter; import lombok.EqualsAndHashCode; import lombok.ToString; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalListItem.java index e12dbb376d0..cd7362e4e60 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalListItem.java @@ -19,13 +19,13 @@ import bisq.desktop.components.AutoTooltipButton; import bisq.desktop.main.dao.proposal.ProposalListItem; -import bisq.desktop.util.BsqFormatter; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; import bisq.core.dao.state.period.DaoPhase; import bisq.core.dao.voting.proposal.Proposal; import bisq.core.locale.Res; +import bisq.core.util.BsqFormatter; import lombok.EqualsAndHashCode; import lombok.Getter; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index bb58971ebba..b5862f302ef 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -26,14 +26,14 @@ import bisq.desktop.main.dao.voting.VotingView; import bisq.desktop.main.dao.voting.active.ActiveBallotsView; import bisq.desktop.main.overlays.popups.Popup; -import bisq.core.util.BSFormatter; -import bisq.core.util.BsqFormatter; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; import bisq.core.dao.state.period.DaoPhase; import bisq.core.dao.voting.proposal.Proposal; import bisq.core.locale.Res; +import bisq.core.util.BSFormatter; +import bisq.core.util.BsqFormatter; import javax.inject.Inject; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalListItem.java index 4334fbb0f21..3720e42b933 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalListItem.java @@ -18,11 +18,11 @@ package bisq.desktop.main.dao.proposal.closed; import bisq.desktop.main.dao.proposal.ProposalListItem; -import bisq.desktop.util.BsqFormatter; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; import bisq.core.dao.voting.proposal.Proposal; +import bisq.core.util.BsqFormatter; import lombok.EqualsAndHashCode; import lombok.ToString; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java index d9c8d767799..996fd1d98f1 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java @@ -19,12 +19,12 @@ import bisq.desktop.common.view.FxmlView; import bisq.desktop.main.dao.proposal.ProposalItemsView; -import bisq.core.util.BSFormatter; -import bisq.core.util.BsqFormatter; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; import bisq.core.dao.voting.proposal.Proposal; +import bisq.core.util.BSFormatter; +import bisq.core.util.BsqFormatter; import javax.inject.Inject; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java index 7978f950190..edee3379c97 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java @@ -20,13 +20,13 @@ import bisq.desktop.common.view.ActivatableView; import bisq.desktop.common.view.FxmlView; import bisq.desktop.components.SeparatedPhaseBars; -import bisq.desktop.util.BSFormatter; import bisq.desktop.util.Layout; import bisq.core.dao.DaoFacade; import bisq.core.dao.state.ChainHeightListener; import bisq.core.dao.state.period.DaoPhase; import bisq.core.locale.Res; +import bisq.core.util.BSFormatter; import bisq.common.UserThread; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index 27f34e8eba0..1bc761770bf 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -21,8 +21,6 @@ import bisq.desktop.common.view.FxmlView; import bisq.desktop.main.dao.proposal.ProposalDisplay; import bisq.desktop.main.overlays.popups.Popup; -import bisq.core.util.BSFormatter; -import bisq.core.util.BsqFormatter; import bisq.desktop.util.GUIUtil; import bisq.desktop.util.Layout; @@ -41,7 +39,8 @@ import bisq.core.dao.voting.proposal.ProposalWithTransaction; import bisq.core.locale.Res; import bisq.core.provider.fee.FeeService; -import bisq.core.util.CoinUtil; +import bisq.core.util.BSFormatter; +import bisq.core.util.BsqFormatter; import bisq.network.p2p.P2PService; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java index 57e8ddc5ddd..def2bbaac1b 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java @@ -19,19 +19,12 @@ import bisq.desktop.common.view.ActivatableView; import bisq.desktop.common.view.FxmlView; -import bisq.desktop.components.AutoTooltipLabel; -import bisq.desktop.components.AutoTooltipTableColumn; -import bisq.desktop.components.HyperlinkWithIcon; -import bisq.desktop.components.TableGroupHeadline; -import bisq.desktop.main.dao.proposal.ProposalListItem; -import bisq.core.util.BSFormatter; -import bisq.core.util.BsqFormatter; -import bisq.desktop.util.GUIUtil; -import bisq.desktop.util.Layout; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; import bisq.core.user.Preferences; +import bisq.core.util.BSFormatter; +import bisq.core.util.BsqFormatter; import javax.inject.Inject; diff --git a/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotListItem.java b/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotListItem.java index 327896885ee..4c080e354f2 100644 --- a/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotListItem.java +++ b/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotListItem.java @@ -18,7 +18,6 @@ package bisq.desktop.main.dao.voting.active; import bisq.desktop.main.dao.BaseProposalListItem; -import bisq.desktop.util.BsqFormatter; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; @@ -27,6 +26,7 @@ import bisq.core.dao.voting.ballot.vote.BooleanVote; import bisq.core.dao.voting.ballot.vote.Vote; import bisq.core.dao.voting.proposal.Proposal; +import bisq.core.util.BsqFormatter; import lombok.EqualsAndHashCode; import lombok.Getter; diff --git a/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.java b/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.java index 2b81719b858..3375123ee12 100644 --- a/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.java +++ b/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.java @@ -23,8 +23,6 @@ import bisq.desktop.main.dao.BaseProposalListItem; import bisq.desktop.main.dao.BaseProposalView; import bisq.desktop.main.overlays.popups.Popup; -import bisq.desktop.util.BSFormatter; -import bisq.desktop.util.BsqFormatter; import bisq.desktop.util.GUIUtil; import bisq.desktop.util.Layout; @@ -40,6 +38,8 @@ import bisq.core.dao.voting.ballot.vote.BooleanVote; import bisq.core.dao.voting.proposal.Proposal; import bisq.core.locale.Res; +import bisq.core.util.BSFormatter; +import bisq.core.util.BsqFormatter; import bisq.common.util.Tuple2; import bisq.common.util.Tuple3; diff --git a/src/main/java/bisq/desktop/main/dao/voting/closed/ClosedBallotListItem.java b/src/main/java/bisq/desktop/main/dao/voting/closed/ClosedBallotListItem.java index e95000a7a9b..1aac2fa0067 100644 --- a/src/main/java/bisq/desktop/main/dao/voting/closed/ClosedBallotListItem.java +++ b/src/main/java/bisq/desktop/main/dao/voting/closed/ClosedBallotListItem.java @@ -18,7 +18,6 @@ package bisq.desktop.main.dao.voting.closed; import bisq.desktop.main.dao.BaseProposalListItem; -import bisq.desktop.util.BsqFormatter; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; @@ -27,6 +26,7 @@ import bisq.core.dao.voting.ballot.vote.BooleanVote; import bisq.core.dao.voting.ballot.vote.Vote; import bisq.core.dao.voting.proposal.Proposal; +import bisq.core.util.BsqFormatter; import lombok.EqualsAndHashCode; import lombok.Getter; diff --git a/src/main/java/bisq/desktop/main/dao/voting/closed/ClosedBallotsView.java b/src/main/java/bisq/desktop/main/dao/voting/closed/ClosedBallotsView.java index a3f19ad85a5..016208d46d8 100644 --- a/src/main/java/bisq/desktop/main/dao/voting/closed/ClosedBallotsView.java +++ b/src/main/java/bisq/desktop/main/dao/voting/closed/ClosedBallotsView.java @@ -20,12 +20,12 @@ import bisq.desktop.common.view.FxmlView; import bisq.desktop.main.dao.BaseProposalListItem; import bisq.desktop.main.dao.BaseProposalView; -import bisq.desktop.util.BSFormatter; -import bisq.desktop.util.BsqFormatter; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; import bisq.core.dao.voting.ballot.Ballot; +import bisq.core.util.BSFormatter; +import bisq.core.util.BsqFormatter; import javax.inject.Inject; diff --git a/src/main/java/bisq/desktop/main/dao/voting/dashboard/VotingDashboardView.java b/src/main/java/bisq/desktop/main/dao/voting/dashboard/VotingDashboardView.java index a0f4cf3188c..a3b90950f20 100644 --- a/src/main/java/bisq/desktop/main/dao/voting/dashboard/VotingDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/voting/dashboard/VotingDashboardView.java @@ -19,9 +19,9 @@ import bisq.desktop.common.view.FxmlView; import bisq.desktop.main.dao.proposal.dashboard.ProposalDashboardView; -import bisq.desktop.util.BSFormatter; import bisq.core.dao.DaoFacade; +import bisq.core.util.BSFormatter; import javax.inject.Inject; From a4debc7c87155a1b89ee80a6a3ad8b8cd4506c77 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Tue, 19 Jun 2018 19:51:57 +0200 Subject: [PATCH 104/197] Add merit implementation --- src/main/java/bisq/desktop/main/MainViewModel.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/bisq/desktop/main/MainViewModel.java b/src/main/java/bisq/desktop/main/MainViewModel.java index ffef4dad7ff..5bec9e6b2a4 100644 --- a/src/main/java/bisq/desktop/main/MainViewModel.java +++ b/src/main/java/bisq/desktop/main/MainViewModel.java @@ -327,10 +327,14 @@ private void setupHandlers() { .information(Res.get("popup.securityRecommendation.msg")) .dontShowAgainId(key) .show()); - bisqSetup.setDisplayLocalhostHandler(key -> + bisqSetup.setDisplayLocalhostHandler(key -> { + if (!DevEnv.isDevMode()) { new Popup<>().backgroundInfo(Res.get("popup.bitcoinLocalhostNode.msg")) .dontShowAgainId(key) - .show()); + .show(); + } + }); + bisqSetup.setWrongOSArchitectureHandler(msg -> new Popup<>().warning(msg).show()); corruptedDatabaseFilesHandler.getCorruptedDatabaseFiles().ifPresent(files -> { From 56f4caf7bcec20491cf5720722d3876aa0f52226 Mon Sep 17 00:00:00 2001 From: sqrrm Date: Sun, 10 Jun 2018 15:22:17 +0200 Subject: [PATCH 105/197] Add basic UI for bond lockup --- .../java/bisq/desktop/main/dao/DaoView.java | 15 +- .../desktop/main/dao/bonding/BondingView.fxml | 31 +++ .../desktop/main/dao/bonding/BondingView.java | 120 +++++++++ .../main/dao/bonding/Lock/LockupBSQView.fxml | 33 +++ .../main/dao/bonding/Lock/LockupBSQView.java | 230 ++++++++++++++++++ 5 files changed, 427 insertions(+), 2 deletions(-) create mode 100644 src/main/java/bisq/desktop/main/dao/bonding/BondingView.fxml create mode 100644 src/main/java/bisq/desktop/main/dao/bonding/BondingView.java create mode 100644 src/main/java/bisq/desktop/main/dao/bonding/Lock/LockupBSQView.fxml create mode 100644 src/main/java/bisq/desktop/main/dao/bonding/Lock/LockupBSQView.java diff --git a/src/main/java/bisq/desktop/main/dao/DaoView.java b/src/main/java/bisq/desktop/main/dao/DaoView.java index ac70e01937b..ed9250ee1ea 100644 --- a/src/main/java/bisq/desktop/main/dao/DaoView.java +++ b/src/main/java/bisq/desktop/main/dao/DaoView.java @@ -25,6 +25,7 @@ import bisq.desktop.common.view.View; import bisq.desktop.common.view.ViewLoader; import bisq.desktop.main.MainView; +import bisq.desktop.main.dao.bonding.BondingView; import bisq.desktop.main.dao.proposal.ProposalView; import bisq.desktop.main.dao.voting.VotingView; import bisq.desktop.main.dao.wallet.BsqWalletView; @@ -48,7 +49,7 @@ public class DaoView extends ActivatableViewAndModel { @FXML - Tab bsqWalletTab, proposalsTab, votingTab; + Tab bsqWalletTab, proposalsTab, votingTab, bondingTab; private Navigation.Listener navigationListener; private ChangeListener tabChangeListener; @@ -69,13 +70,15 @@ private DaoView(CachingViewLoader viewLoader, Navigation navigation) { public void initialize() { proposalsTab = new Tab(Res.get("dao.tab.proposals")); votingTab = new Tab(Res.get("dao.tab.voting")); + bondingTab = new Tab(Res.get("dao.tab.bonding")); proposalsTab.setClosable(false); votingTab.setClosable(false); //TODO - root.getTabs().addAll(proposalsTab, votingTab); + root.getTabs().addAll(proposalsTab, votingTab, bondingTab); if (!BisqEnvironment.isDAOActivatedAndBaseCurrencySupportingBsq() || !DevEnv.isDaoPhase2Activated()) { votingTab.setDisable(true); + bondingTab.setDisable(true); proposalsTab.setDisable(true); } @@ -106,6 +109,9 @@ public void initialize() { } else if (newValue == votingTab) { //noinspection unchecked navigation.navigateTo(MainView.class, DaoView.class, VotingView.class); + } else if (newValue == bondingTab) { + //noinspection unchecked + navigation.navigateTo(MainView.class, DaoView.class, BondingView.class); } }; } @@ -126,6 +132,9 @@ else if (selectedItem == proposalsTab) else if (selectedItem == votingTab) //noinspection unchecked navigation.navigateTo(MainView.class, DaoView.class, VotingView.class); + else if (selectedItem == bondingTab) + //noinspection unchecked + navigation.navigateTo(MainView.class, DaoView.class, BondingView.class); } } @@ -144,6 +153,8 @@ private void loadView(Class viewClass) { selectedTab = proposalsTab; } else if (view instanceof VotingView) { selectedTab = votingTab; + } else if (view instanceof BondingView) { + selectedTab = bondingTab; } selectedTab.setContent(view.getRoot()); diff --git a/src/main/java/bisq/desktop/main/dao/bonding/BondingView.fxml b/src/main/java/bisq/desktop/main/dao/bonding/BondingView.fxml new file mode 100644 index 00000000000..64f72f9e4f8 --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/bonding/BondingView.fxml @@ -0,0 +1,31 @@ + + + + + + + + + + + + diff --git a/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java b/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java new file mode 100644 index 00000000000..45ce35b1959 --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java @@ -0,0 +1,120 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.desktop.main.dao.bonding; + +import bisq.desktop.Navigation; +import bisq.desktop.common.view.ActivatableViewAndModel; +import bisq.desktop.common.view.CachingViewLoader; +import bisq.desktop.common.view.FxmlView; +import bisq.desktop.common.view.View; +import bisq.desktop.common.view.ViewLoader; +import bisq.desktop.common.view.ViewPath; +import bisq.desktop.components.MenuItem; +import bisq.desktop.main.MainView; +import bisq.desktop.main.dao.DaoView; +import bisq.desktop.main.dao.bonding.Lock.LockupBSQView; + +import bisq.core.locale.Res; + +import javax.inject.Inject; + +import de.jensd.fx.fontawesome.AwesomeIcon; + +import javafx.fxml.FXML; + +import javafx.scene.control.ToggleGroup; +import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.VBox; + +import java.util.Arrays; +import java.util.List; + +@FxmlView +public class BondingView extends ActivatableViewAndModel { + + private final ViewLoader viewLoader; + private final Navigation navigation; + + private MenuItem lockupBSQ; + private Navigation.Listener listener; + + @FXML + private VBox leftVBox; + @FXML + private AnchorPane content; + + private Class selectedViewClass; + + @Inject + private BondingView(CachingViewLoader viewLoader, Navigation navigation) { + this.viewLoader = viewLoader; + this.navigation = navigation; + } + + @Override + public void initialize() { + listener = viewPath -> { + if (viewPath.size() != 4 || viewPath.indexOf(bisq.desktop.main.dao.bonding.BondingView.class) != 2) + return; + + selectedViewClass = viewPath.tip(); + loadView(selectedViewClass); + }; + + ToggleGroup toggleGroup = new ToggleGroup(); + final List> baseNavPath = Arrays.asList(MainView.class, DaoView.class, bisq.desktop.main.dao.bonding.BondingView.class); + lockupBSQ = new MenuItem(navigation, toggleGroup, Res.get("dao.bonding.menuItem.lockupBSQ"), + LockupBSQView.class, AwesomeIcon.LIST_UL, baseNavPath); + leftVBox.getChildren().addAll(lockupBSQ); + } + + @Override + protected void activate() { + navigation.addListener(listener); + ViewPath viewPath = navigation.getCurrentPath(); + if (viewPath.size() == 3 && viewPath.indexOf(BondingView.class) == 2 || + viewPath.size() == 2 && viewPath.indexOf(DaoView.class) == 1) { + if (selectedViewClass == null) + selectedViewClass = LockupBSQView.class; + + loadView(selectedViewClass); + + } else if (viewPath.size() == 4 && viewPath.indexOf(BondingView.class) == 2) { + selectedViewClass = viewPath.get(3); + loadView(selectedViewClass); + } + } + + @Override + protected void deactivate() { + navigation.removeListener(listener); + + lockupBSQ.deactivate(); + } + + private void loadView(Class viewClass) { + View view = viewLoader.load(viewClass); + content.getChildren().setAll(view.getRoot()); + + if (view instanceof LockupBSQView) lockupBSQ.setSelected(true); + } + + public Class getSelectedViewClass() { + return selectedViewClass; + } +} diff --git a/src/main/java/bisq/desktop/main/dao/bonding/Lock/LockupBSQView.fxml b/src/main/java/bisq/desktop/main/dao/bonding/Lock/LockupBSQView.fxml new file mode 100644 index 00000000000..d36a497c353 --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/bonding/Lock/LockupBSQView.fxml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + diff --git a/src/main/java/bisq/desktop/main/dao/bonding/Lock/LockupBSQView.java b/src/main/java/bisq/desktop/main/dao/bonding/Lock/LockupBSQView.java new file mode 100644 index 00000000000..c359d131a26 --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/bonding/Lock/LockupBSQView.java @@ -0,0 +1,230 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.desktop.main.dao.bonding.Lock; + +import bisq.desktop.Navigation; +import bisq.desktop.common.view.ActivatableView; +import bisq.desktop.common.view.FxmlView; +import bisq.desktop.components.InputTextField; +import bisq.desktop.main.MainView; +import bisq.desktop.main.dao.wallet.BsqBalanceUtil; +import bisq.desktop.main.funds.FundsView; +import bisq.desktop.main.funds.deposit.DepositView; +import bisq.desktop.main.overlays.popups.Popup; +import bisq.desktop.util.BSFormatter; +import bisq.desktop.util.BsqFormatter; +import bisq.desktop.util.GUIUtil; +import bisq.desktop.util.Layout; +import bisq.desktop.util.validation.BsqAddressValidator; +import bisq.desktop.util.validation.BsqValidator; + +import bisq.core.btc.Restrictions; +import bisq.core.btc.wallet.BsqBalanceListener; +import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.btc.wallet.BtcWalletService; +import bisq.core.btc.wallet.TxBroadcastException; +import bisq.core.btc.wallet.TxBroadcastTimeoutException; +import bisq.core.btc.wallet.TxBroadcaster; +import bisq.core.btc.wallet.TxMalleabilityException; +import bisq.core.btc.wallet.WalletsManager; +import bisq.core.btc.wallet.WalletsSetup; +import bisq.core.locale.Res; +import bisq.core.util.CoinUtil; + +import bisq.network.p2p.P2PService; + +import org.bitcoinj.core.Address; +import org.bitcoinj.core.Coin; +import org.bitcoinj.core.InsufficientMoneyException; +import org.bitcoinj.core.Transaction; + +import javax.inject.Inject; + +import javafx.scene.control.Button; +import javafx.scene.layout.GridPane; + +import javafx.beans.value.ChangeListener; + +import static bisq.desktop.util.FormBuilder.addButtonAfterGroup; +import static bisq.desktop.util.FormBuilder.addLabelInputTextField; +import static bisq.desktop.util.FormBuilder.addTitledGroupBg; + +@FxmlView +public class LockupBSQView extends ActivatableView implements BsqBalanceListener { + private final BsqWalletService bsqWalletService; + private final BtcWalletService btcWalletService; + private final WalletsManager walletsManager; + private final WalletsSetup walletsSetup; + private final P2PService p2PService; + private final BsqFormatter bsqFormatter; + private final BSFormatter btcFormatter; + private final Navigation navigation; + private final BsqBalanceUtil bsqBalanceUtil; + private final BsqValidator bsqValidator; + + private int gridRow = 0; + private InputTextField amountInputTextField; + private Button lockupButton; + private ChangeListener focusOutListener; + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Constructor, lifecycle + /////////////////////////////////////////////////////////////////////////////////////////// + + @Inject + private LockupBSQView(BsqWalletService bsqWalletService, + BtcWalletService btcWalletService, + WalletsManager walletsManager, + WalletsSetup walletsSetup, + P2PService p2PService, + BsqFormatter bsqFormatter, + BSFormatter btcFormatter, + Navigation navigation, + BsqBalanceUtil bsqBalanceUtil, + BsqValidator bsqValidator, + BsqAddressValidator bsqAddressValidator) { + this.bsqWalletService = bsqWalletService; + this.btcWalletService = btcWalletService; + this.walletsManager = walletsManager; + this.walletsSetup = walletsSetup; + this.p2PService = p2PService; + this.bsqFormatter = bsqFormatter; + this.btcFormatter = btcFormatter; + this.navigation = navigation; + this.bsqBalanceUtil = bsqBalanceUtil; + this.bsqValidator = bsqValidator; + } + + @Override + public void initialize() { + // TODO: Show balance locked up in bonds + gridRow = bsqBalanceUtil.addGroup(root, gridRow); + + addTitledGroupBg(root, ++gridRow, 3, Res.get("dao.bonding.lock.lockBSQ"), Layout.GROUP_DISTANCE); + + amountInputTextField = addLabelInputTextField(root, gridRow, Res.get("dao.bonding.lock.amount"), + Layout.FIRST_ROW_AND_GROUP_DISTANCE).second; + amountInputTextField.setPromptText(Res.get("dao.bonding.lock.setAmount", Restrictions.getMinNonDustOutput().value)); + amountInputTextField.setValidator(bsqValidator); + + focusOutListener = (observable, oldValue, newValue) -> { + if (!newValue) + onUpdateBalances(bsqWalletService.getAvailableBalance(), bsqWalletService.getPendingBalance(), + bsqWalletService.getLockedForVotingBalance(), bsqWalletService.getLockedInBondsBalance()); + }; + + lockupButton = addButtonAfterGroup(root, ++gridRow, Res.get("dao.bonding.lock.lockupButton")); + + lockupButton.setOnAction((event) -> { + if (GUIUtil.isReadyForTxBroadcast(p2PService, walletsSetup)) { + Address lockupAddress = bsqWalletService.getUnusedAddress(); + Coin lockupAmount = bsqFormatter.parseToCoin(amountInputTextField.getText()); + try { + // TODO: Implement lockup bond function (this is just sending BSQ) + Transaction preparedSendTx = bsqWalletService.getPreparedSendTx(lockupAddress.toString(), lockupAmount); + Transaction txWithBtcFee = btcWalletService.completePreparedSendBsqTx(preparedSendTx, true); + Transaction signedTx = bsqWalletService.signTx(txWithBtcFee); + Coin miningFee = signedTx.getFee(); + int txSize = signedTx.bitcoinSerialize().length; + new Popup<>().headLine(Res.get("dao.bonding.lock.sendFunds.headline")) + .confirmation(Res.get("dao.bonding.lock.sendFunds.details", + bsqFormatter.formatCoinWithCode(lockupAmount), + bsqFormatter.getBsqAddressStringFromAddress(lockupAddress), + btcFormatter.formatCoinWithCode(miningFee), + CoinUtil.getFeePerByte(miningFee, txSize), + txSize / 1000d, + bsqFormatter.formatCoinWithCode(lockupAmount))) + .actionButtonText(Res.get("shared.yes")) + .onAction(() -> { + walletsManager.publishAndCommitBsqTx(txWithBtcFee, new TxBroadcaster.Callback() { + @Override + public void onSuccess(Transaction transaction) { + log.debug("Successfully sent tx with id " + txWithBtcFee.getHashAsString()); + } + + @Override + public void onTimeout(TxBroadcastTimeoutException exception) { + //TODO handle + new Popup<>().warning(exception.toString()); + } + + @Override + public void onTxMalleability(TxMalleabilityException exception) { + //TODO handle + new Popup<>().warning(exception.toString()); + } + + @Override + public void onFailure(TxBroadcastException exception) { + //TODO handle + new Popup<>().warning(exception.toString()); + } + }); + + amountInputTextField.setText(""); + }) + .closeButtonText(Res.get("shared.cancel")) + .show(); + } catch (Throwable t) { + if (t instanceof InsufficientMoneyException) { + final Coin missingCoin = ((InsufficientMoneyException) t).missing; + final String missing = missingCoin != null ? missingCoin.toFriendlyString() : "null"; + //noinspection unchecked + new Popup<>().warning(Res.get("popup.warning.insufficientBtcFundsForBsqTx", missing)) + .actionButtonTextWithGoTo("navigation.funds.depositFunds") + .onAction(() -> navigation.navigateTo(MainView.class, FundsView.class, DepositView.class)) + .show(); + } else { + log.error(t.toString()); + t.printStackTrace(); + new Popup<>().warning(t.getMessage()).show(); + } + } + } else { + GUIUtil.showNotReadyForTxBroadcastPopups(p2PService, walletsSetup); + } + }); + } + + @Override + protected void activate() { + bsqBalanceUtil.activate(); + amountInputTextField.focusedProperty().addListener(focusOutListener); + bsqWalletService.addBsqBalanceListener(this); + onUpdateBalances(bsqWalletService.getAvailableBalance(), bsqWalletService.getPendingBalance(), + bsqWalletService.getLockedForVotingBalance(), bsqWalletService.getLockedInBondsBalance()); + } + + @Override + protected void deactivate() { + bsqBalanceUtil.deactivate(); + amountInputTextField.focusedProperty().removeListener(focusOutListener); + bsqWalletService.removeBsqBalanceListener(this); + } + + @Override + public void onUpdateBalances(Coin confirmedBalance, + Coin pendingBalance, + Coin lockedForVotingBalance, + Coin lockedInBondsBalance) { + bsqValidator.setAvailableBalance(confirmedBalance); + boolean isValid = bsqValidator.validate(amountInputTextField.getText()).isValid; + lockupButton.setDisable(!isValid); + } +} From 3ac0d225eff4f0ccdd97da78c4748fdb8d936634 Mon Sep 17 00:00:00 2001 From: sqrrm Date: Tue, 19 Jun 2018 12:16:24 +0200 Subject: [PATCH 106/197] Add actual lockup functionality --- .../main/dao/bonding/Lock/LockupBSQView.java | 67 +++++++------------ 1 file changed, 23 insertions(+), 44 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/bonding/Lock/LockupBSQView.java b/src/main/java/bisq/desktop/main/dao/bonding/Lock/LockupBSQView.java index c359d131a26..a9df896d98a 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/Lock/LockupBSQView.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/Lock/LockupBSQView.java @@ -43,6 +43,8 @@ import bisq.core.btc.wallet.TxMalleabilityException; import bisq.core.btc.wallet.WalletsManager; import bisq.core.btc.wallet.WalletsSetup; +import bisq.core.dao.DaoFacade; +import bisq.core.dao.voting.proposal.param.Param; import bisq.core.locale.Res; import bisq.core.util.CoinUtil; @@ -67,18 +69,17 @@ @FxmlView public class LockupBSQView extends ActivatableView implements BsqBalanceListener { private final BsqWalletService bsqWalletService; - private final BtcWalletService btcWalletService; - private final WalletsManager walletsManager; private final WalletsSetup walletsSetup; private final P2PService p2PService; private final BsqFormatter bsqFormatter; - private final BSFormatter btcFormatter; private final Navigation navigation; private final BsqBalanceUtil bsqBalanceUtil; private final BsqValidator bsqValidator; + private final DaoFacade daoFacade; private int gridRow = 0; private InputTextField amountInputTextField; + private InputTextField timeInputTextField; private Button lockupButton; private ChangeListener focusOutListener; @@ -98,17 +99,16 @@ private LockupBSQView(BsqWalletService bsqWalletService, Navigation navigation, BsqBalanceUtil bsqBalanceUtil, BsqValidator bsqValidator, - BsqAddressValidator bsqAddressValidator) { + BsqAddressValidator bsqAddressValidator, + DaoFacade daoFacade) { this.bsqWalletService = bsqWalletService; - this.btcWalletService = btcWalletService; - this.walletsManager = walletsManager; this.walletsSetup = walletsSetup; this.p2PService = p2PService; this.bsqFormatter = bsqFormatter; - this.btcFormatter = btcFormatter; this.navigation = navigation; this.bsqBalanceUtil = bsqBalanceUtil; this.bsqValidator = bsqValidator; + this.daoFacade = daoFacade; } @Override @@ -116,12 +116,17 @@ public void initialize() { // TODO: Show balance locked up in bonds gridRow = bsqBalanceUtil.addGroup(root, gridRow); - addTitledGroupBg(root, ++gridRow, 3, Res.get("dao.bonding.lock.lockBSQ"), Layout.GROUP_DISTANCE); + addTitledGroupBg(root, ++gridRow, 4, Res.get("dao.bonding.lock.lockBSQ"), Layout.GROUP_DISTANCE); amountInputTextField = addLabelInputTextField(root, gridRow, Res.get("dao.bonding.lock.amount"), Layout.FIRST_ROW_AND_GROUP_DISTANCE).second; amountInputTextField.setPromptText(Res.get("dao.bonding.lock.setAmount", Restrictions.getMinNonDustOutput().value)); amountInputTextField.setValidator(bsqValidator); + timeInputTextField = addLabelInputTextField(root, ++gridRow, Res.get("dao.bonding.lock.time"), Layout.GRID_GAP).second; + timeInputTextField.setPromptText(Res.get("dao.bonding.lock.setTime", + Param.LOCKTIME_MIN.getDefaultValue(), Param.LOCKTIME_MAX.getDefaultValue())); + // TODO: add some int validator +// timeInputTextField.setValidator(bsqValidator); focusOutListener = (observable, oldValue, newValue) -> { if (!newValue) @@ -135,48 +140,22 @@ public void initialize() { if (GUIUtil.isReadyForTxBroadcast(p2PService, walletsSetup)) { Address lockupAddress = bsqWalletService.getUnusedAddress(); Coin lockupAmount = bsqFormatter.parseToCoin(amountInputTextField.getText()); + int lockupTime = Integer.parseInt(timeInputTextField.getText()); try { - // TODO: Implement lockup bond function (this is just sending BSQ) - Transaction preparedSendTx = bsqWalletService.getPreparedSendTx(lockupAddress.toString(), lockupAmount); - Transaction txWithBtcFee = btcWalletService.completePreparedSendBsqTx(preparedSendTx, true); - Transaction signedTx = bsqWalletService.signTx(txWithBtcFee); - Coin miningFee = signedTx.getFee(); - int txSize = signedTx.bitcoinSerialize().length; new Popup<>().headLine(Res.get("dao.bonding.lock.sendFunds.headline")) .confirmation(Res.get("dao.bonding.lock.sendFunds.details", bsqFormatter.formatCoinWithCode(lockupAmount), - bsqFormatter.getBsqAddressStringFromAddress(lockupAddress), - btcFormatter.formatCoinWithCode(miningFee), - CoinUtil.getFeePerByte(miningFee, txSize), - txSize / 1000d, - bsqFormatter.formatCoinWithCode(lockupAmount))) + lockupTime + )) .actionButtonText(Res.get("shared.yes")) .onAction(() -> { - walletsManager.publishAndCommitBsqTx(txWithBtcFee, new TxBroadcaster.Callback() { - @Override - public void onSuccess(Transaction transaction) { - log.debug("Successfully sent tx with id " + txWithBtcFee.getHashAsString()); - } - - @Override - public void onTimeout(TxBroadcastTimeoutException exception) { - //TODO handle - new Popup<>().warning(exception.toString()); - } - - @Override - public void onTxMalleability(TxMalleabilityException exception) { - //TODO handle - new Popup<>().warning(exception.toString()); - } - - @Override - public void onFailure(TxBroadcastException exception) { - //TODO handle - new Popup<>().warning(exception.toString()); - } - }); - + daoFacade.publishLockupTx(lockupAmount, + lockupTime, + () -> { + new Popup<>().confirmation(Res.get("dao.tx.published.success")).show(); + }, + errorMessage -> new Popup<>().warning(errorMessage.toString()).show() + ); amountInputTextField.setText(""); }) .closeButtonText(Res.get("shared.cancel")) From d5d7ea8e7e9196010c71e071ed1fdab1805c0737 Mon Sep 17 00:00:00 2001 From: sqrrm Date: Tue, 19 Jun 2018 20:40:39 +0200 Subject: [PATCH 107/197] Add unlock functionality --- .../desktop/main/dao/bonding/BondingView.java | 15 +- .../main/dao/bonding/Lock/LockupBSQView.java | 16 +- .../bonding/unlock/LockedBsqTxListItem.java | 142 ++++++ .../dao/bonding/unlock/UnlockBSQView.fxml | 33 ++ .../dao/bonding/unlock/UnlockBSQView.java | 462 ++++++++++++++++++ .../dao/voting/active/ActiveBallotsView.java | 6 +- .../main/dao/wallet/BsqBalanceUtil.java | 12 +- .../main/dao/wallet/send/BsqSendView.java | 9 +- .../desktop/main/dao/wallet/tx/BsqTxView.java | 3 +- .../main/offer/EditableOfferDataModel.java | 3 +- 10 files changed, 676 insertions(+), 25 deletions(-) create mode 100644 src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedBsqTxListItem.java create mode 100644 src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.fxml create mode 100644 src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java diff --git a/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java b/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java index 45ce35b1959..02db6be4550 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java @@ -28,6 +28,7 @@ import bisq.desktop.main.MainView; import bisq.desktop.main.dao.DaoView; import bisq.desktop.main.dao.bonding.Lock.LockupBSQView; +import bisq.desktop.main.dao.bonding.unlock.UnlockBSQView; import bisq.core.locale.Res; @@ -51,6 +52,7 @@ public class BondingView extends ActivatableViewAndModel { private final Navigation navigation; private MenuItem lockupBSQ; + private MenuItem unlockBSQ; private Navigation.Listener listener; @FXML @@ -80,11 +82,16 @@ public void initialize() { final List> baseNavPath = Arrays.asList(MainView.class, DaoView.class, bisq.desktop.main.dao.bonding.BondingView.class); lockupBSQ = new MenuItem(navigation, toggleGroup, Res.get("dao.bonding.menuItem.lockupBSQ"), LockupBSQView.class, AwesomeIcon.LIST_UL, baseNavPath); - leftVBox.getChildren().addAll(lockupBSQ); + unlockBSQ = new MenuItem(navigation, toggleGroup, Res.get("dao.bonding.menuItem.unlockBSQ"), + UnlockBSQView.class, AwesomeIcon.LIST_UL, baseNavPath); + leftVBox.getChildren().addAll(lockupBSQ, unlockBSQ); } @Override protected void activate() { + lockupBSQ.activate(); + unlockBSQ.activate(); + navigation.addListener(listener); ViewPath viewPath = navigation.getCurrentPath(); if (viewPath.size() == 3 && viewPath.indexOf(BondingView.class) == 2 || @@ -105,6 +112,7 @@ protected void deactivate() { navigation.removeListener(listener); lockupBSQ.deactivate(); + unlockBSQ.deactivate(); } private void loadView(Class viewClass) { @@ -112,9 +120,6 @@ private void loadView(Class viewClass) { content.getChildren().setAll(view.getRoot()); if (view instanceof LockupBSQView) lockupBSQ.setSelected(true); - } - - public Class getSelectedViewClass() { - return selectedViewClass; + else if (view instanceof UnlockBSQView) unlockBSQ.setSelected(true); } } diff --git a/src/main/java/bisq/desktop/main/dao/bonding/Lock/LockupBSQView.java b/src/main/java/bisq/desktop/main/dao/bonding/Lock/LockupBSQView.java index a9df896d98a..fa6dcff5e3a 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/Lock/LockupBSQView.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/Lock/LockupBSQView.java @@ -37,23 +37,17 @@ import bisq.core.btc.wallet.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; -import bisq.core.btc.wallet.TxBroadcastException; -import bisq.core.btc.wallet.TxBroadcastTimeoutException; -import bisq.core.btc.wallet.TxBroadcaster; -import bisq.core.btc.wallet.TxMalleabilityException; import bisq.core.btc.wallet.WalletsManager; import bisq.core.btc.wallet.WalletsSetup; import bisq.core.dao.DaoFacade; import bisq.core.dao.voting.proposal.param.Param; import bisq.core.locale.Res; -import bisq.core.util.CoinUtil; import bisq.network.p2p.P2PService; import org.bitcoinj.core.Address; import org.bitcoinj.core.Coin; import org.bitcoinj.core.InsufficientMoneyException; -import org.bitcoinj.core.Transaction; import javax.inject.Inject; @@ -131,14 +125,14 @@ public void initialize() { focusOutListener = (observable, oldValue, newValue) -> { if (!newValue) onUpdateBalances(bsqWalletService.getAvailableBalance(), bsqWalletService.getPendingBalance(), - bsqWalletService.getLockedForVotingBalance(), bsqWalletService.getLockedInBondsBalance()); + bsqWalletService.getLockedForVotingBalance(), bsqWalletService.getLockedInBondsBalance(), + bsqWalletService.getUnlockingBondsBalance()); }; lockupButton = addButtonAfterGroup(root, ++gridRow, Res.get("dao.bonding.lock.lockupButton")); lockupButton.setOnAction((event) -> { if (GUIUtil.isReadyForTxBroadcast(p2PService, walletsSetup)) { - Address lockupAddress = bsqWalletService.getUnusedAddress(); Coin lockupAmount = bsqFormatter.parseToCoin(amountInputTextField.getText()); int lockupTime = Integer.parseInt(timeInputTextField.getText()); try { @@ -187,7 +181,8 @@ protected void activate() { amountInputTextField.focusedProperty().addListener(focusOutListener); bsqWalletService.addBsqBalanceListener(this); onUpdateBalances(bsqWalletService.getAvailableBalance(), bsqWalletService.getPendingBalance(), - bsqWalletService.getLockedForVotingBalance(), bsqWalletService.getLockedInBondsBalance()); + bsqWalletService.getLockedForVotingBalance(), bsqWalletService.getLockedInBondsBalance(), + bsqWalletService.getUnlockingBondsBalance()); } @Override @@ -201,7 +196,8 @@ protected void deactivate() { public void onUpdateBalances(Coin confirmedBalance, Coin pendingBalance, Coin lockedForVotingBalance, - Coin lockedInBondsBalance) { + Coin lockedInBondsBalance, + Coin unlockingBondsBalance) { bsqValidator.setAvailableBalance(confirmedBalance); boolean isValid = bsqValidator.validate(amountInputTextField.getText()).isValid; lockupButton.setDisable(!isValid); diff --git a/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedBsqTxListItem.java b/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedBsqTxListItem.java new file mode 100644 index 00000000000..e0edda082b9 --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedBsqTxListItem.java @@ -0,0 +1,142 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.desktop.main.dao.bonding.unlock; + +import bisq.desktop.components.AutoTooltipButton; +import bisq.desktop.components.indicator.TxConfidenceIndicator; +import bisq.desktop.util.BsqFormatter; +import bisq.desktop.util.GUIUtil; + +import bisq.core.btc.listeners.TxConfidenceListener; +import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.btc.wallet.BtcWalletService; +import bisq.core.dao.DaoFacade; +import bisq.core.dao.state.StateService; +import bisq.core.dao.state.blockchain.TxType; +import bisq.core.locale.Res; + +import org.bitcoinj.core.Coin; +import org.bitcoinj.core.Transaction; +import org.bitcoinj.core.TransactionConfidence; + +import javafx.scene.control.Tooltip; + +import java.util.Date; +import java.util.Optional; + +import lombok.Data; + +import static com.google.common.base.Preconditions.checkNotNull; + +@Data +class LockedBsqTxListItem { + private final Transaction transaction; + private final BsqWalletService bsqWalletService; + private final BtcWalletService btcWalletService; + private final DaoFacade daoFacade; + private final StateService stateService; + private final BsqFormatter bsqFormatter; + private final Date date; + private final String txId; + + private int confirmations = 0; + private Coin amount; + private int lockTime; + private AutoTooltipButton button; + + private TxConfidenceIndicator txConfidenceIndicator; + private TxConfidenceListener txConfidenceListener; + private boolean issuanceTx; + + LockedBsqTxListItem(Transaction transaction, + BsqWalletService bsqWalletService, + BtcWalletService btcWalletService, + DaoFacade daoFacade, + StateService stateService, + Date date, + BsqFormatter bsqFormatter) { + this.transaction = transaction; + this.bsqWalletService = bsqWalletService; + this.btcWalletService = btcWalletService; + this.daoFacade = daoFacade; + this.stateService = stateService; + this.date = date; + this.bsqFormatter = bsqFormatter; + + txId = transaction.getHashAsString(); + + setupConfidence(bsqWalletService); + + checkNotNull(transaction, "transaction must not be null as we only have list items from transactions " + + "which are available in the wallet"); + + amount = bsqWalletService.getValueLockedUpInBond(transaction); + + Optional opLockTime = stateService.getLockTime(transaction.getHashAsString()); + lockTime = opLockTime.isPresent() ? opLockTime.get() : -1; + + button = new AutoTooltipButton(); + button.setMinWidth(70); + button.setText(Res.get("dao.bonding.unlock.unlock")); + button.setVisible(true); + button.setManaged(true); + } + + private void setupConfidence(BsqWalletService bsqWalletService) { + txConfidenceIndicator = new TxConfidenceIndicator(); + txConfidenceIndicator.setId("funds-confidence"); + Tooltip tooltip = new Tooltip(); + txConfidenceIndicator.setProgress(0); + txConfidenceIndicator.setPrefSize(24, 24); + txConfidenceIndicator.setTooltip(tooltip); + + txConfidenceListener = new TxConfidenceListener(txId) { + @Override + public void onTransactionConfidenceChanged(TransactionConfidence confidence) { + updateConfidence(confidence, tooltip); + } + }; + bsqWalletService.addTxConfidenceListener(txConfidenceListener); + updateConfidence(bsqWalletService.getConfidenceForTxId(txId), tooltip); + } + + private void updateConfidence(TransactionConfidence confidence, Tooltip tooltip) { + if (confidence != null) { + GUIUtil.updateConfidence(confidence, tooltip, txConfidenceIndicator); + confirmations = confidence.getDepthInBlocks(); + } + } + + public boolean isLocked() { + return getTxType() == TxType.LOCK_UP; + } + + public void cleanup() { + bsqWalletService.removeTxConfidenceListener(txConfidenceListener); + } + + public TxType getTxType() { + return daoFacade.getTx(txId) + .flatMap(tx -> daoFacade.getTxType(tx.getId())) + .orElse(confirmations == 0 ? TxType.UNVERIFIED : TxType.UNDEFINED_TX_TYPE); + } + + public void setAmount(Coin amount) { + this.amount = amount; + } +} diff --git a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.fxml b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.fxml new file mode 100644 index 00000000000..70ab749e2ab --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.fxml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + diff --git a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java new file mode 100644 index 00000000000..18889c79fc8 --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java @@ -0,0 +1,462 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.desktop.main.dao.bonding.unlock; + +import bisq.desktop.Navigation; +import bisq.desktop.common.view.ActivatableView; +import bisq.desktop.common.view.FxmlView; +import bisq.desktop.components.AutoTooltipTableColumn; +import bisq.desktop.components.HyperlinkWithIcon; +import bisq.desktop.main.MainView; +import bisq.desktop.main.dao.wallet.BsqBalanceUtil; +import bisq.desktop.main.funds.FundsView; +import bisq.desktop.main.funds.deposit.DepositView; +import bisq.desktop.main.overlays.popups.Popup; +import bisq.desktop.util.BsqFormatter; +import bisq.desktop.util.GUIUtil; +import bisq.desktop.util.validation.BsqValidator; + +import bisq.core.btc.wallet.BsqBalanceListener; +import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.btc.wallet.BtcWalletService; +import bisq.core.btc.wallet.WalletsSetup; +import bisq.core.dao.DaoFacade; +import bisq.core.dao.state.BlockListener; +import bisq.core.dao.state.StateService; +import bisq.core.dao.state.blockchain.Block; +import bisq.core.dao.state.blockchain.Tx; +import bisq.core.dao.state.blockchain.TxOutput; +import bisq.core.dao.state.blockchain.TxType; +import bisq.core.locale.Res; +import bisq.core.user.Preferences; + +import bisq.network.p2p.P2PService; + +import org.bitcoinj.core.Coin; +import org.bitcoinj.core.InsufficientMoneyException; +import org.bitcoinj.core.Transaction; + +import javax.inject.Inject; + +import de.jensd.fx.fontawesome.AwesomeIcon; + +import javafx.scene.control.Button; +import javafx.scene.control.TableCell; +import javafx.scene.control.TableColumn; +import javafx.scene.control.TableView; +import javafx.scene.control.Tooltip; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.Pane; +import javafx.scene.layout.VBox; + +import javafx.geometry.Insets; + +import javafx.beans.property.DoubleProperty; +import javafx.beans.property.ReadOnlyObjectWrapper; +import javafx.beans.property.SimpleDoubleProperty; +import javafx.beans.value.ChangeListener; + +import javafx.collections.FXCollections; +import javafx.collections.ListChangeListener; +import javafx.collections.ObservableList; +import javafx.collections.transformation.FilteredList; + +import javafx.util.Callback; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +@FxmlView +public class UnlockBSQView extends ActivatableView implements BsqBalanceListener, BlockListener { + private TableView tableView; + private Pane rootParent; + + private final BsqWalletService bsqWalletService; + private final BtcWalletService btcWalletService; + private final BsqFormatter bsqFormatter; + private final BsqBalanceUtil bsqBalanceUtil; + private final BsqValidator bsqValidator; + private final DaoFacade daoFacade; + private final Preferences preferences; + private final StateService stateService; + private final WalletsSetup walletsSetup; + private final P2PService p2PService; + private final Navigation navigation; + + private int gridRow = 0; + private boolean synched; + private LockedBsqTxListItem selectedItem; + + private final ObservableList observableList = FXCollections.observableArrayList(); + private final FilteredList lockedTxs = new FilteredList<>(observableList); + + private ListChangeListener walletBsqTransactionsListener; + private ChangeListener walletChainHeightListener; + private final DoubleProperty initialOccupiedHeight = new SimpleDoubleProperty(-1); + private ChangeListener parentHeightListener; + + /////////////////////////////////////////////////////////////////////////////////////////// + // Constructor, lifecycle + /////////////////////////////////////////////////////////////////////////////////////////// + + @Inject + private UnlockBSQView(BsqWalletService bsqWalletService, + BtcWalletService btcWalletService, + BsqFormatter bsqFormatter, + BsqBalanceUtil bsqBalanceUtil, + BsqValidator bsqValidator, + DaoFacade daoFacade, + Preferences preferences, + StateService stateService, + WalletsSetup walletsSetup, + P2PService p2PService, + Navigation navigation) { + this.bsqWalletService = bsqWalletService; + this.btcWalletService = btcWalletService; + this.bsqFormatter = bsqFormatter; + this.bsqBalanceUtil = bsqBalanceUtil; + this.bsqValidator = bsqValidator; + this.daoFacade = daoFacade; + this.preferences = preferences; + this.stateService = stateService; + this.walletsSetup = walletsSetup; + this.p2PService = p2PService; + this.navigation = navigation; + } + + @Override + public void initialize() { + // TODO: Show balance locked up in bonds + gridRow = bsqBalanceUtil.addGroup(root, gridRow); + + tableView = new TableView<>(); + tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); + addTxIdColumn(); + addAmountColumn(); + addLockTimeColumn(); + addUnlockColumn(); + + lockedTxs.setPredicate(item -> item.isLocked()); + walletBsqTransactionsListener = change -> updateList(); + walletChainHeightListener = (observable, oldValue, newValue) -> onUpdateAnyChainHeight(); + parentHeightListener = (observable, oldValue, newValue) -> layout(); + + VBox vBox = new VBox(); + vBox.setSpacing(10); + GridPane.setRowIndex(vBox, ++gridRow); + GridPane.setColumnSpan(vBox, 2); + GridPane.setMargin(vBox, new Insets(40, -10, 5, -10)); + vBox.getChildren().addAll(tableView); + root.getChildren().add(vBox); + + } + + private void addTxIdColumn() { + TableColumn column = new AutoTooltipTableColumn<>(Res.get("shared.txId")); + + column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); + column.setMinWidth(60); + column.setCellFactory( + new Callback, TableCell>() { + + @Override + public TableCell call(TableColumn column) { + return new TableCell() { + private HyperlinkWithIcon hyperlinkWithIcon; + + @Override + public void updateItem(final LockedBsqTxListItem item, boolean empty) { + super.updateItem(item, empty); + + if (item != null && !empty) { + String transactionId = item.getTxId(); + hyperlinkWithIcon = new HyperlinkWithIcon(transactionId, AwesomeIcon.EXTERNAL_LINK); + hyperlinkWithIcon.setOnAction(event -> openTxInBlockExplorer(item)); + hyperlinkWithIcon.setTooltip(new Tooltip(Res.get("tooltip.openBlockchainForTx", transactionId))); + setGraphic(hyperlinkWithIcon); + } else { + setGraphic(null); + if (hyperlinkWithIcon != null) + hyperlinkWithIcon.setOnAction(null); + } + } + }; + } + }); + tableView.getColumns().add(column); + } + + private void addAmountColumn() { + TableColumn column = + new AutoTooltipTableColumn<>(Res.get("shared.amountWithCur", "BSQ")); + column.setMinWidth(120); + column.setMaxWidth(column.getMinWidth()); + + column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + column.setCellFactory(new Callback, + TableCell>() { + + @Override + public TableCell call(TableColumn column) { + return new TableCell() { + + @Override + public void updateItem(final LockedBsqTxListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null && !empty) { + TxType txType = item.getTxType(); + setText(item.getConfirmations() > 0 && txType.ordinal() > TxType.INVALID.ordinal() ? + bsqFormatter.formatCoin(item.getAmount()) : + Res.get("shared.na")); + } else + setText(""); + } + }; + } + }); + tableView.getColumns().add(column); + } + + private void addLockTimeColumn() { + TableColumn column = + new AutoTooltipTableColumn<>(Res.get("dao.bonding.unlock.time")); + column.setMinWidth(120); + column.setMaxWidth(column.getMinWidth()); + + column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + column.setCellFactory(new Callback, + TableCell>() { + + @Override + public TableCell call(TableColumn column) { + return new TableCell() { + + @Override + public void updateItem(final LockedBsqTxListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null && !empty) { + TxType txType = item.getTxType(); + setText(item.getConfirmations() > 0 && txType.ordinal() > TxType.INVALID.ordinal() ? + Integer.toString(item.getLockTime()) : + Res.get("shared.na")); + } else + setText(""); + } + }; + } + }); + tableView.getColumns().add(column); + } + + private void addUnlockColumn() { + TableColumn unlockColumn = new TableColumn<>(); + unlockColumn.setMinWidth(130); + unlockColumn.setMaxWidth(unlockColumn.getMinWidth()); + + unlockColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + + unlockColumn.setCellFactory(new Callback, + TableCell>() { + + @Override + public TableCell call(TableColumn column) { + return new TableCell() { + Button button; + + @Override + public void updateItem(final LockedBsqTxListItem item, boolean empty) { + super.updateItem(item, empty); + + if (item != null && !empty) { + if (button == null) { + button = item.getButton(); + button.setOnAction(e -> { + UnlockBSQView.this.selectedItem = item; + UnlockBSQView.this.onButtonClick(); + }); + setGraphic(button); + } + } else { + setGraphic(null); + if (button != null) { + button.setOnAction(null); + button = null; + } + } + } + }; + } + }); + unlockColumn.setComparator(Comparator.comparing(LockedBsqTxListItem::getConfirmations)); + tableView.getColumns().add(unlockColumn); + } + + private void onButtonClick() { + if (GUIUtil.isReadyForTxBroadcast(p2PService, walletsSetup)) { + Optional lockedTxOutput = stateService.getLockedTxOutput(selectedItem.getTxId()); + if (!lockedTxOutput.isPresent()) { + log.warn("Locked output not found, txId = ", selectedItem.getTxId()); + return; + } + + Coin unlockAmount = Coin.valueOf(lockedTxOutput.get().getValue()); + Optional opLockTime = stateService.getLockTime(lockedTxOutput.get()); + int lockTime = opLockTime.isPresent() ? opLockTime.get() : -1; + + try { + new Popup<>().headLine(Res.get("dao.bonding.unlock.sendTx.headline")) + .confirmation(Res.get("dao.bonding.unlock.sendTx.details", + bsqFormatter.formatCoinWithCode(unlockAmount), + lockTime + )) + .actionButtonText(Res.get("shared.yes")) + .onAction(() -> { + daoFacade.publishUnlockTx(selectedItem.getTxId(), + () -> { + new Popup<>().confirmation(Res.get("dao.tx.published.success")).show(); + }, + errorMessage -> new Popup<>().warning(errorMessage.toString()).show() + ); + }) + .closeButtonText(Res.get("shared.cancel")) + .show(); + } catch (Throwable t) { + if (t instanceof InsufficientMoneyException) { + final Coin missingCoin = ((InsufficientMoneyException) t).missing; + final String missing = missingCoin != null ? missingCoin.toFriendlyString() : "null"; + //noinspection unchecked + new Popup<>().warning(Res.get("popup.warning.insufficientBtcFundsForBsqTx", missing)) + .actionButtonTextWithGoTo("navigation.funds.depositFunds") + .onAction(() -> navigation.navigateTo(MainView.class, FundsView.class, DepositView.class)) + .show(); + } else { + log.error(t.toString()); + t.printStackTrace(); + new Popup<>().warning(t.getMessage()).show(); + } + } + } else { + GUIUtil.showNotReadyForTxBroadcastPopups(p2PService, walletsSetup); + } + log.info("unlock tx: {}", selectedItem.getTxId()); + } + + private void openTxInBlockExplorer(LockedBsqTxListItem item) { + if (item.getTxId() != null) + GUIUtil.openWebPage(preferences.getBsqBlockChainExplorer().txUrl + item.getTxId()); + } + + @Override + protected void activate() { + bsqBalanceUtil.activate(); + bsqWalletService.addBsqBalanceListener(this); + onUpdateBalances(bsqWalletService.getAvailableBalance(), bsqWalletService.getPendingBalance(), + bsqWalletService.getLockedForVotingBalance(), bsqWalletService.getLockedInBondsBalance(), + bsqWalletService.getUnlockingBondsBalance()); + + bsqWalletService.getWalletTransactions().addListener(walletBsqTransactionsListener); + bsqWalletService.addBsqBalanceListener(this); + btcWalletService.getChainHeightProperty().addListener(walletChainHeightListener); + + tableView.setItems(lockedTxs); + + daoFacade.addBlockListener(this); + + if (root.getParent() instanceof Pane) { + rootParent = (Pane) root.getParent(); + rootParent.heightProperty().addListener(parentHeightListener); + } + + updateList(); + onUpdateAnyChainHeight(); + layout(); + } + + @Override + public void onBlockAdded(Block block) { + onUpdateAnyChainHeight(); + } + + private void onUpdateAnyChainHeight() { + final int bsqBlockChainHeight = daoFacade.getChainHeight(); + final int bsqWalletChainHeight = bsqWalletService.getBestChainHeight(); + if (bsqWalletChainHeight > 0) { + synched = bsqWalletChainHeight == bsqBlockChainHeight; + } + updateList(); + } + + private void updateList() { + observableList.forEach(LockedBsqTxListItem::cleanup); + + // copy list to avoid ConcurrentModificationException + final List walletTransactions = new ArrayList<>(bsqWalletService.getWalletTransactions()); + List items = walletTransactions.stream() + .map(transaction -> { + return new LockedBsqTxListItem(transaction, + bsqWalletService, + btcWalletService, + daoFacade, + stateService, + transaction.getUpdateTime(), + bsqFormatter); + }) + .collect(Collectors.toList()); + observableList.setAll(items); + } + + private void layout() { + GUIUtil.fillAvailableHeight(root, tableView, initialOccupiedHeight); + } + + @Override + protected void deactivate() { + bsqBalanceUtil.deactivate(); + bsqWalletService.removeBsqBalanceListener(this); + + + bsqBalanceUtil.deactivate(); + lockedTxs.predicateProperty().unbind(); + bsqWalletService.getWalletTransactions().removeListener(walletBsqTransactionsListener); + bsqWalletService.removeBsqBalanceListener(this); + btcWalletService.getChainHeightProperty().removeListener(walletChainHeightListener); + daoFacade.removeBlockListener(this); + + observableList.forEach(LockedBsqTxListItem::cleanup); + + if (rootParent != null) + rootParent.heightProperty().removeListener(parentHeightListener); + } + + @Override + public void onUpdateBalances(Coin confirmedBalance, + Coin pendingBalance, + Coin lockedForVotingBalance, + Coin lockedInBondsBalance, + Coin unlockingBondsBalance) { + bsqValidator.setAvailableBalance(confirmedBalance); + } +} diff --git a/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.java b/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.java index 3375123ee12..f99bbf44006 100644 --- a/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.java +++ b/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.java @@ -114,7 +114,8 @@ protected void activate() { onUpdateBalances(bsqWalletService.getAvailableBalance(), bsqWalletService.getPendingBalance(), bsqWalletService.getLockedForVotingBalance(), - bsqWalletService.getLockedInBondsBalance()); + bsqWalletService.getLockedInBondsBalance(), + bsqWalletService.getUnlockingBondsBalance()); voteButton.setOnAction(e -> onVote()); @@ -141,7 +142,8 @@ protected void deactivate() { public void onUpdateBalances(Coin confirmedBalance, Coin pendingBalance, Coin lockedForVotingBalance, - Coin lockedInBondsBalance) { + Coin lockedInBondsBalance, + Coin unlockingBondsBalance) { stakeInputTextField.setPromptText(Res.get("dao.proposal.myVote.stake.prompt", bsqFormatter.formatCoinWithCode(confirmedBalance))); } diff --git a/src/main/java/bisq/desktop/main/dao/wallet/BsqBalanceUtil.java b/src/main/java/bisq/desktop/main/dao/wallet/BsqBalanceUtil.java index 1ca4b54dbe3..0514f5b915a 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/BsqBalanceUtil.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/BsqBalanceUtil.java @@ -83,7 +83,8 @@ public void activate() { onUpdateBalances(bsqWalletService.getAvailableBalance(), bsqWalletService.getPendingBalance(), bsqWalletService.getLockedForVotingBalance(), - bsqWalletService.getLockedInBondsBalance()); + bsqWalletService.getLockedInBondsBalance(), + bsqWalletService.getUnlockingBondsBalance()); bsqWalletService.addBsqBalanceListener(this); } @@ -96,11 +97,16 @@ public void deactivate() { public void onUpdateBalances(Coin confirmedBalance, Coin pendingBalance, Coin lockedForVotingBalance, - Coin lockedInBondsBalance) { + Coin lockedInBondsBalance, + Coin unlockingBondsBalance) { confirmedBalanceTextField.setText(bsqFormatter.formatCoinWithCode(confirmedBalance)); pendingBalanceTextField.setText(bsqFormatter.formatCoinWithCode(pendingBalance)); lockedForVoteBalanceTextField.setText(bsqFormatter.formatCoinWithCode(lockedForVotingBalance)); - final Coin total = confirmedBalance.add(pendingBalance).add(lockedForVotingBalance).add(lockedInBondsBalance); + final Coin total = confirmedBalance + .add(pendingBalance) + .add(lockedForVotingBalance) + .add(lockedInBondsBalance) + .add(unlockingBondsBalance); totalBalanceTextField.setText(bsqFormatter.formatCoinWithCode(total)); } } diff --git a/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java b/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java index 20c9f82d207..24ef771b1ef 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java @@ -131,7 +131,8 @@ public void initialize() { focusOutListener = (observable, oldValue, newValue) -> { if (!newValue) onUpdateBalances(bsqWalletService.getAvailableBalance(), bsqWalletService.getPendingBalance(), - bsqWalletService.getLockedForVotingBalance(), bsqWalletService.getLockedInBondsBalance()); + bsqWalletService.getLockedForVotingBalance(), bsqWalletService.getLockedInBondsBalance(), + bsqWalletService.getUnlockingBondsBalance()); }; sendButton = addButtonAfterGroup(root, ++gridRow, Res.get("dao.wallet.send.send")); @@ -215,7 +216,8 @@ protected void activate() { amountInputTextField.focusedProperty().addListener(focusOutListener); bsqWalletService.addBsqBalanceListener(this); onUpdateBalances(bsqWalletService.getAvailableBalance(), bsqWalletService.getPendingBalance(), - bsqWalletService.getLockedForVotingBalance(), bsqWalletService.getLockedInBondsBalance()); + bsqWalletService.getLockedForVotingBalance(), bsqWalletService.getLockedInBondsBalance(), + bsqWalletService.getUnlockingBondsBalance()); } @Override @@ -230,7 +232,8 @@ protected void deactivate() { public void onUpdateBalances(Coin confirmedBalance, Coin pendingBalance, Coin lockedForVotingBalance, - Coin lockedInBondsBalance) { + Coin lockedInBondsBalance, + Coin unlockingBondsBalance) { bsqValidator.setAvailableBalance(confirmedBalance); boolean isValid = bsqAddressValidator.validate(receiversAddressInputTextField.getText()).isValid && bsqValidator.validate(amountInputTextField.getText()).isValid; diff --git a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java index 6681643fa4a..ab1a2f95a85 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java @@ -208,7 +208,8 @@ protected void deactivate() { public void onUpdateBalances(Coin confirmedBalance, Coin pendingBalance, Coin lockedForVotingBalance, - Coin lockedInBondsBalance) { + Coin lockedInBondsBalance, + Coin unlockingBondsBalance) { updateList(); } diff --git a/src/main/java/bisq/desktop/main/offer/EditableOfferDataModel.java b/src/main/java/bisq/desktop/main/offer/EditableOfferDataModel.java index dd824518a9f..3ed69b4f6b2 100644 --- a/src/main/java/bisq/desktop/main/offer/EditableOfferDataModel.java +++ b/src/main/java/bisq/desktop/main/offer/EditableOfferDataModel.java @@ -539,7 +539,8 @@ void onCurrencySelected(TradeCurrency tradeCurrency) { public void onUpdateBalances(Coin confirmedBalance, Coin pendingBalance, Coin lockedForVotingBalance, - Coin lockedInBondsBalance) { + Coin lockedInBondsBalance, + Coin unlockingBondsBalance) { updateBalance(); } From a637d94c4bcc2ffdc8d94244c6aca7e5a6fe57de Mon Sep 17 00:00:00 2001 From: sqrrm Date: Mon, 25 Jun 2018 14:10:39 +0200 Subject: [PATCH 108/197] Fix rebase issues --- .../bisq/desktop/main/dao/bonding/Lock/LockupBSQView.java | 4 ++-- .../desktop/main/dao/bonding/unlock/LockedBsqTxListItem.java | 2 +- .../bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/bonding/Lock/LockupBSQView.java b/src/main/java/bisq/desktop/main/dao/bonding/Lock/LockupBSQView.java index fa6dcff5e3a..08fe2d739d7 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/Lock/LockupBSQView.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/Lock/LockupBSQView.java @@ -26,8 +26,6 @@ import bisq.desktop.main.funds.FundsView; import bisq.desktop.main.funds.deposit.DepositView; import bisq.desktop.main.overlays.popups.Popup; -import bisq.desktop.util.BSFormatter; -import bisq.desktop.util.BsqFormatter; import bisq.desktop.util.GUIUtil; import bisq.desktop.util.Layout; import bisq.desktop.util.validation.BsqAddressValidator; @@ -42,6 +40,8 @@ import bisq.core.dao.DaoFacade; import bisq.core.dao.voting.proposal.param.Param; import bisq.core.locale.Res; +import bisq.core.util.BSFormatter; +import bisq.core.util.BsqFormatter; import bisq.network.p2p.P2PService; diff --git a/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedBsqTxListItem.java b/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedBsqTxListItem.java index e0edda082b9..042865cc982 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedBsqTxListItem.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedBsqTxListItem.java @@ -19,7 +19,6 @@ import bisq.desktop.components.AutoTooltipButton; import bisq.desktop.components.indicator.TxConfidenceIndicator; -import bisq.desktop.util.BsqFormatter; import bisq.desktop.util.GUIUtil; import bisq.core.btc.listeners.TxConfidenceListener; @@ -29,6 +28,7 @@ import bisq.core.dao.state.StateService; import bisq.core.dao.state.blockchain.TxType; import bisq.core.locale.Res; +import bisq.core.util.BsqFormatter; import org.bitcoinj.core.Coin; import org.bitcoinj.core.Transaction; diff --git a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java index 18889c79fc8..e296affd493 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java @@ -27,7 +27,6 @@ import bisq.desktop.main.funds.FundsView; import bisq.desktop.main.funds.deposit.DepositView; import bisq.desktop.main.overlays.popups.Popup; -import bisq.desktop.util.BsqFormatter; import bisq.desktop.util.GUIUtil; import bisq.desktop.util.validation.BsqValidator; @@ -44,6 +43,7 @@ import bisq.core.dao.state.blockchain.TxType; import bisq.core.locale.Res; import bisq.core.user.Preferences; +import bisq.core.util.BsqFormatter; import bisq.network.p2p.P2PService; From 6475aaa36b20d8674d734eda3fac2df4b028c3c3 Mon Sep 17 00:00:00 2001 From: sqrrm Date: Mon, 25 Jun 2018 16:54:47 +0200 Subject: [PATCH 109/197] Display locked amount --- .../main/dao/bonding/unlock/UnlockBSQView.java | 1 - .../bisq/desktop/main/dao/wallet/BsqBalanceUtil.java | 12 ++++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java index e296affd493..7e3fa2438bd 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java @@ -38,7 +38,6 @@ import bisq.core.dao.state.BlockListener; import bisq.core.dao.state.StateService; import bisq.core.dao.state.blockchain.Block; -import bisq.core.dao.state.blockchain.Tx; import bisq.core.dao.state.blockchain.TxOutput; import bisq.core.dao.state.blockchain.TxType; import bisq.core.locale.Res; diff --git a/src/main/java/bisq/desktop/main/dao/wallet/BsqBalanceUtil.java b/src/main/java/bisq/desktop/main/dao/wallet/BsqBalanceUtil.java index 0514f5b915a..c38ceaa319d 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/BsqBalanceUtil.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/BsqBalanceUtil.java @@ -43,7 +43,7 @@ public class BsqBalanceUtil implements BsqBalanceListener { private final BsqWalletService bsqWalletService; private final BsqFormatter bsqFormatter; private TextField confirmedBalanceTextField, pendingBalanceTextField, lockedForVoteBalanceTextField, - totalBalanceTextField; + lockedInBondsBalanceTextField, totalBalanceTextField; @Inject private BsqBalanceUtil(BsqWalletService bsqWalletService, @@ -53,7 +53,7 @@ private BsqBalanceUtil(BsqWalletService bsqWalletService, } public int addGroup(GridPane gridPane, int gridRow) { - addTitledGroupBg(gridPane, gridRow, 4, Res.get("shared.balance")); + addTitledGroupBg(gridPane, gridRow, 5, Res.get("shared.balance")); confirmedBalanceTextField = addLabelTextField(gridPane, gridRow, Res.getWithCol("shared.availableBsqBalance"), Layout.FIRST_ROW_DISTANCE).second; confirmedBalanceTextField.setMouseTransparent(false); @@ -71,6 +71,12 @@ public int addGroup(GridPane gridPane, int gridRow) { lockedForVoteBalanceTextField.setMaxWidth(confirmedBalanceTextField.getMaxWidth()); lockedForVoteBalanceTextField.setAlignment(Pos.CENTER_RIGHT); + lockedInBondsBalanceTextField = addLabelTextField(gridPane, ++gridRow, Res.getWithCol( + "shared.lockedInBonds")).second; + lockedInBondsBalanceTextField.setMouseTransparent(false); + lockedInBondsBalanceTextField.setMaxWidth(confirmedBalanceTextField.getMaxWidth()); + lockedInBondsBalanceTextField.setAlignment(Pos.CENTER_RIGHT); + totalBalanceTextField = addLabelTextField(gridPane, ++gridRow, Res.getWithCol("shared.totalBsqBalance")).second; totalBalanceTextField.setMouseTransparent(false); totalBalanceTextField.setMaxWidth(confirmedBalanceTextField.getMaxWidth()); @@ -102,6 +108,8 @@ public void onUpdateBalances(Coin confirmedBalance, confirmedBalanceTextField.setText(bsqFormatter.formatCoinWithCode(confirmedBalance)); pendingBalanceTextField.setText(bsqFormatter.formatCoinWithCode(pendingBalance)); lockedForVoteBalanceTextField.setText(bsqFormatter.formatCoinWithCode(lockedForVotingBalance)); + lockedInBondsBalanceTextField.setText(bsqFormatter.formatCoinWithCode( + lockedInBondsBalance.add(unlockingBondsBalance))); final Coin total = confirmedBalance .add(pendingBalance) .add(lockedForVotingBalance) From ce36a91f645222fa2251a12d1228e251c5ccd3c0 Mon Sep 17 00:00:00 2001 From: sqrrm Date: Mon, 25 Jun 2018 17:36:23 +0200 Subject: [PATCH 110/197] Don't show unlocked bonds in unlockview --- .../dao/bonding/unlock/LockedBsqTxListItem.java | 14 +++++++++++--- .../main/dao/bonding/unlock/UnlockBSQView.java | 2 +- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedBsqTxListItem.java b/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedBsqTxListItem.java index 042865cc982..cb617632700 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedBsqTxListItem.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedBsqTxListItem.java @@ -26,6 +26,7 @@ import bisq.core.btc.wallet.BtcWalletService; import bisq.core.dao.DaoFacade; import bisq.core.dao.state.StateService; +import bisq.core.dao.state.blockchain.TxOutput; import bisq.core.dao.state.blockchain.TxType; import bisq.core.locale.Res; import bisq.core.util.BsqFormatter; @@ -78,7 +79,7 @@ class LockedBsqTxListItem { this.date = date; this.bsqFormatter = bsqFormatter; - txId = transaction.getHashAsString(); + this.txId = transaction.getHashAsString(); setupConfidence(bsqWalletService); @@ -122,14 +123,21 @@ private void updateConfidence(TransactionConfidence confidence, Tooltip tooltip) } } - public boolean isLocked() { - return getTxType() == TxType.LOCK_UP; + public boolean isLockedAndUnspent() { + return !isSpent() && getTxType() == TxType.LOCK_UP; } public void cleanup() { bsqWalletService.removeTxConfidenceListener(txConfidenceListener); } + public boolean isSpent() { + Optional optionalTxOutput = stateService.getLockedTxOutput(txId); + if (optionalTxOutput.isPresent()) + return !stateService.isUnspent(optionalTxOutput.get()); + return true; + } + public TxType getTxType() { return daoFacade.getTx(txId) .flatMap(tx -> daoFacade.getTxType(tx.getId())) diff --git a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java index 7e3fa2438bd..c7543e841fc 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java @@ -153,7 +153,7 @@ public void initialize() { addLockTimeColumn(); addUnlockColumn(); - lockedTxs.setPredicate(item -> item.isLocked()); + lockedTxs.setPredicate(item -> item.isLockedAndUnspent()); walletBsqTransactionsListener = change -> updateList(); walletChainHeightListener = (observable, oldValue, newValue) -> onUpdateAnyChainHeight(); parentHeightListener = (observable, oldValue, newValue) -> layout(); From 60e58f7bcb2d72ff6ec27c5b93760ba6dce1e4e3 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Thu, 28 Jun 2018 12:42:14 +0200 Subject: [PATCH 111/197] Renaming, cleanup, small fixes --- src/main/java/bisq/desktop/main/dao/DaoView.java | 1 - .../desktop/main/dao/bonding/Lock/LockupBSQView.java | 11 +---------- .../main/dao/bonding/unlock/LockedBsqTxListItem.java | 2 +- .../main/dao/bonding/unlock/UnlockBSQView.java | 4 ++-- .../bisq/desktop/main/dao/wallet/BsqBalanceUtil.java | 2 ++ 5 files changed, 6 insertions(+), 14 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/DaoView.java b/src/main/java/bisq/desktop/main/dao/DaoView.java index ed9250ee1ea..3db4293a348 100644 --- a/src/main/java/bisq/desktop/main/dao/DaoView.java +++ b/src/main/java/bisq/desktop/main/dao/DaoView.java @@ -73,7 +73,6 @@ public void initialize() { bondingTab = new Tab(Res.get("dao.tab.bonding")); proposalsTab.setClosable(false); votingTab.setClosable(false); - //TODO root.getTabs().addAll(proposalsTab, votingTab, bondingTab); if (!BisqEnvironment.isDAOActivatedAndBaseCurrencySupportingBsq() || !DevEnv.isDaoPhase2Activated()) { diff --git a/src/main/java/bisq/desktop/main/dao/bonding/Lock/LockupBSQView.java b/src/main/java/bisq/desktop/main/dao/bonding/Lock/LockupBSQView.java index 08fe2d739d7..dc182d99ffc 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/Lock/LockupBSQView.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/Lock/LockupBSQView.java @@ -28,24 +28,19 @@ import bisq.desktop.main.overlays.popups.Popup; import bisq.desktop.util.GUIUtil; import bisq.desktop.util.Layout; -import bisq.desktop.util.validation.BsqAddressValidator; import bisq.desktop.util.validation.BsqValidator; import bisq.core.btc.Restrictions; import bisq.core.btc.wallet.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.btc.wallet.BtcWalletService; -import bisq.core.btc.wallet.WalletsManager; import bisq.core.btc.wallet.WalletsSetup; import bisq.core.dao.DaoFacade; import bisq.core.dao.voting.proposal.param.Param; import bisq.core.locale.Res; -import bisq.core.util.BSFormatter; import bisq.core.util.BsqFormatter; import bisq.network.p2p.P2PService; -import org.bitcoinj.core.Address; import org.bitcoinj.core.Coin; import org.bitcoinj.core.InsufficientMoneyException; @@ -84,16 +79,12 @@ public class LockupBSQView extends ActivatableView implements Bs @Inject private LockupBSQView(BsqWalletService bsqWalletService, - BtcWalletService btcWalletService, - WalletsManager walletsManager, WalletsSetup walletsSetup, P2PService p2PService, BsqFormatter bsqFormatter, - BSFormatter btcFormatter, Navigation navigation, BsqBalanceUtil bsqBalanceUtil, BsqValidator bsqValidator, - BsqAddressValidator bsqAddressValidator, DaoFacade daoFacade) { this.bsqWalletService = bsqWalletService; this.walletsSetup = walletsSetup; @@ -118,7 +109,7 @@ public void initialize() { amountInputTextField.setValidator(bsqValidator); timeInputTextField = addLabelInputTextField(root, ++gridRow, Res.get("dao.bonding.lock.time"), Layout.GRID_GAP).second; timeInputTextField.setPromptText(Res.get("dao.bonding.lock.setTime", - Param.LOCKTIME_MIN.getDefaultValue(), Param.LOCKTIME_MAX.getDefaultValue())); + Param.LOCK_TIME_MIN.getDefaultValue(), Param.LOCK_TIME_MAX.getDefaultValue())); // TODO: add some int validator // timeInputTextField.setValidator(bsqValidator); diff --git a/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedBsqTxListItem.java b/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedBsqTxListItem.java index cb617632700..872c646e0b4 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedBsqTxListItem.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedBsqTxListItem.java @@ -124,7 +124,7 @@ private void updateConfidence(TransactionConfidence confidence, Tooltip tooltip) } public boolean isLockedAndUnspent() { - return !isSpent() && getTxType() == TxType.LOCK_UP; + return !isSpent() && getTxType() == TxType.LOCKUP; } public void cleanup() { diff --git a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java index c7543e841fc..c91926cee42 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java @@ -101,7 +101,7 @@ public class UnlockBSQView extends ActivatableView implements Bs private final Navigation navigation; private int gridRow = 0; - private boolean synched; + private boolean synced; private LockedBsqTxListItem selectedItem; private final ObservableList observableList = FXCollections.observableArrayList(); @@ -403,7 +403,7 @@ private void onUpdateAnyChainHeight() { final int bsqBlockChainHeight = daoFacade.getChainHeight(); final int bsqWalletChainHeight = bsqWalletService.getBestChainHeight(); if (bsqWalletChainHeight > 0) { - synched = bsqWalletChainHeight == bsqBlockChainHeight; + synced = bsqWalletChainHeight == bsqBlockChainHeight; } updateList(); } diff --git a/src/main/java/bisq/desktop/main/dao/wallet/BsqBalanceUtil.java b/src/main/java/bisq/desktop/main/dao/wallet/BsqBalanceUtil.java index c38ceaa319d..f75c0654e10 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/BsqBalanceUtil.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/BsqBalanceUtil.java @@ -77,6 +77,8 @@ public int addGroup(GridPane gridPane, int gridRow) { lockedInBondsBalanceTextField.setMaxWidth(confirmedBalanceTextField.getMaxWidth()); lockedInBondsBalanceTextField.setAlignment(Pos.CENTER_RIGHT); + // TODO add unlockinBondsBalanceTextField + totalBalanceTextField = addLabelTextField(gridPane, ++gridRow, Res.getWithCol("shared.totalBsqBalance")).second; totalBalanceTextField.setMouseTransparent(false); totalBalanceTextField.setMaxWidth(confirmedBalanceTextField.getMaxWidth()); From 90297201f26ab6a8e1e2426e92c487863ad05409 Mon Sep 17 00:00:00 2001 From: sqrrm Date: Thu, 28 Jun 2018 14:47:26 +0200 Subject: [PATCH 112/197] Add bonding dashboard --- .../desktop/main/dao/bonding/BondingView.java | 14 +++-- .../main/dao/bonding/Lock/LockupBSQView.fxml | 3 +- .../dashboard/BondingDashboardView.fxml | 33 +++++++++++ .../dashboard/BondingDashboardView.java | 58 +++++++++++++++++++ .../dao/bonding/unlock/UnlockBSQView.fxml | 3 +- .../dao/bonding/unlock/UnlockBSQView.java | 2 - .../main/dao/wallet/BsqBalanceUtil.java | 29 ++++++++++ 7 files changed, 134 insertions(+), 8 deletions(-) create mode 100644 src/main/java/bisq/desktop/main/dao/bonding/dashboard/BondingDashboardView.fxml create mode 100644 src/main/java/bisq/desktop/main/dao/bonding/dashboard/BondingDashboardView.java diff --git a/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java b/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java index 02db6be4550..425a3954cb2 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java @@ -28,7 +28,9 @@ import bisq.desktop.main.MainView; import bisq.desktop.main.dao.DaoView; import bisq.desktop.main.dao.bonding.Lock.LockupBSQView; +import bisq.desktop.main.dao.bonding.dashboard.BondingDashboardView; import bisq.desktop.main.dao.bonding.unlock.UnlockBSQView; +import bisq.desktop.main.dao.voting.dashboard.VotingDashboardView; import bisq.core.locale.Res; @@ -51,8 +53,7 @@ public class BondingView extends ActivatableViewAndModel { private final ViewLoader viewLoader; private final Navigation navigation; - private MenuItem lockupBSQ; - private MenuItem unlockBSQ; + private MenuItem dashboard, lockupBSQ, unlockBSQ; private Navigation.Listener listener; @FXML @@ -80,15 +81,18 @@ public void initialize() { ToggleGroup toggleGroup = new ToggleGroup(); final List> baseNavPath = Arrays.asList(MainView.class, DaoView.class, bisq.desktop.main.dao.bonding.BondingView.class); + dashboard = new MenuItem(navigation, toggleGroup, Res.get("shared.dashboard"), + BondingDashboardView.class, AwesomeIcon.DASHBOARD, baseNavPath); lockupBSQ = new MenuItem(navigation, toggleGroup, Res.get("dao.bonding.menuItem.lockupBSQ"), LockupBSQView.class, AwesomeIcon.LIST_UL, baseNavPath); unlockBSQ = new MenuItem(navigation, toggleGroup, Res.get("dao.bonding.menuItem.unlockBSQ"), UnlockBSQView.class, AwesomeIcon.LIST_UL, baseNavPath); - leftVBox.getChildren().addAll(lockupBSQ, unlockBSQ); + leftVBox.getChildren().addAll(dashboard, lockupBSQ, unlockBSQ); } @Override protected void activate() { + dashboard.activate(); lockupBSQ.activate(); unlockBSQ.activate(); @@ -111,6 +115,7 @@ protected void activate() { protected void deactivate() { navigation.removeListener(listener); + dashboard.deactivate(); lockupBSQ.deactivate(); unlockBSQ.deactivate(); } @@ -119,7 +124,8 @@ private void loadView(Class viewClass) { View view = viewLoader.load(viewClass); content.getChildren().setAll(view.getRoot()); - if (view instanceof LockupBSQView) lockupBSQ.setSelected(true); + if (view instanceof BondingDashboardView) dashboard.setSelected(true); + else if (view instanceof LockupBSQView) lockupBSQ.setSelected(true); else if (view instanceof UnlockBSQView) unlockBSQ.setSelected(true); } } diff --git a/src/main/java/bisq/desktop/main/dao/bonding/Lock/LockupBSQView.fxml b/src/main/java/bisq/desktop/main/dao/bonding/Lock/LockupBSQView.fxml index d36a497c353..ee4747bfad8 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/Lock/LockupBSQView.fxml +++ b/src/main/java/bisq/desktop/main/dao/bonding/Lock/LockupBSQView.fxml @@ -22,8 +22,9 @@ diff --git a/src/main/java/bisq/desktop/main/dao/bonding/dashboard/BondingDashboardView.fxml b/src/main/java/bisq/desktop/main/dao/bonding/dashboard/BondingDashboardView.fxml new file mode 100644 index 00000000000..aac6faa76a9 --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/bonding/dashboard/BondingDashboardView.fxml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + diff --git a/src/main/java/bisq/desktop/main/dao/bonding/dashboard/BondingDashboardView.java b/src/main/java/bisq/desktop/main/dao/bonding/dashboard/BondingDashboardView.java new file mode 100644 index 00000000000..1d0ae8ea84f --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/bonding/dashboard/BondingDashboardView.java @@ -0,0 +1,58 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.desktop.main.dao.bonding.dashboard; + +import bisq.desktop.common.view.ActivatableView; +import bisq.desktop.common.view.FxmlView; +import bisq.desktop.main.dao.wallet.BsqBalanceUtil; + +import javax.inject.Inject; + +import javafx.scene.layout.GridPane; + +@FxmlView +public class BondingDashboardView extends ActivatableView { + private final BsqBalanceUtil bsqBalanceUtil; + + private int gridRow = 0; + + /////////////////////////////////////////////////////////////////////////////////////////// + // Constructor, lifecycle + /////////////////////////////////////////////////////////////////////////////////////////// + + @Inject + private BondingDashboardView(BsqBalanceUtil bsqBalanceUtil) { + this.bsqBalanceUtil = bsqBalanceUtil; + } + + public void initialize() { + gridRow = bsqBalanceUtil.addGroup(root, gridRow); + gridRow = bsqBalanceUtil.addBondBalanceGroup(root, gridRow); + } + + @Override + protected void activate() { + bsqBalanceUtil.activate(); + } + + @Override + protected void deactivate() { + bsqBalanceUtil.deactivate(); + } +} + diff --git a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.fxml b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.fxml index 70ab749e2ab..89d177e6a2f 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.fxml +++ b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.fxml @@ -22,8 +22,9 @@ diff --git a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java index c91926cee42..41a576e8e28 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java @@ -436,8 +436,6 @@ protected void deactivate() { bsqBalanceUtil.deactivate(); bsqWalletService.removeBsqBalanceListener(this); - - bsqBalanceUtil.deactivate(); lockedTxs.predicateProperty().unbind(); bsqWalletService.getWalletTransactions().removeListener(walletBsqTransactionsListener); bsqWalletService.removeBsqBalanceListener(this); diff --git a/src/main/java/bisq/desktop/main/dao/wallet/BsqBalanceUtil.java b/src/main/java/bisq/desktop/main/dao/wallet/BsqBalanceUtil.java index f75c0654e10..fd64178482c 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/BsqBalanceUtil.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/BsqBalanceUtil.java @@ -33,6 +33,7 @@ import javafx.geometry.Pos; +import lombok.Getter; import lombok.extern.slf4j.Slf4j; import static bisq.desktop.util.FormBuilder.addLabelTextField; @@ -42,9 +43,14 @@ public class BsqBalanceUtil implements BsqBalanceListener { private final BsqWalletService bsqWalletService; private final BsqFormatter bsqFormatter; + + // Displaying general BSQ info private TextField confirmedBalanceTextField, pendingBalanceTextField, lockedForVoteBalanceTextField, lockedInBondsBalanceTextField, totalBalanceTextField; + // Displaying bond dashboard info + private TextField lockedAmountTextField, unlockingAmountTextField; + @Inject private BsqBalanceUtil(BsqWalletService bsqWalletService, BsqFormatter bsqFormatter) { @@ -87,6 +93,23 @@ public int addGroup(GridPane gridPane, int gridRow) { return gridRow; } + public int addBondBalanceGroup(GridPane gridPane, int gridRow) { + addTitledGroupBg(gridPane, ++gridRow, 2, Res.get("dao.bonding.dashboard.lockedHeadline"), Layout.GROUP_DISTANCE); + + lockedAmountTextField = addLabelTextField(gridPane, gridRow, Res.get("dao.bonding.dashboard.lockedAmount"), + Layout.FIRST_ROW_DISTANCE + Layout.GROUP_DISTANCE).second; + lockedAmountTextField.setMouseTransparent(false); + lockedAmountTextField.setMaxWidth(150); + lockedAmountTextField.setAlignment(Pos.CENTER_RIGHT); + + unlockingAmountTextField = addLabelTextField(gridPane, ++gridRow, Res.get("dao.bonding.dashboard.unlockingAmount")).second; + unlockingAmountTextField.setMouseTransparent(false); + unlockingAmountTextField.setMaxWidth(150); + unlockingAmountTextField.setAlignment(Pos.CENTER_RIGHT); + + return gridRow; + } + public void activate() { onUpdateBalances(bsqWalletService.getAvailableBalance(), bsqWalletService.getPendingBalance(), @@ -112,6 +135,12 @@ public void onUpdateBalances(Coin confirmedBalance, lockedForVoteBalanceTextField.setText(bsqFormatter.formatCoinWithCode(lockedForVotingBalance)); lockedInBondsBalanceTextField.setText(bsqFormatter.formatCoinWithCode( lockedInBondsBalance.add(unlockingBondsBalance))); + + if (lockedAmountTextField != null && unlockingAmountTextField != null) { + lockedAmountTextField.setText(bsqFormatter.formatCoinWithCode(lockedInBondsBalance)); + unlockingAmountTextField.setText(bsqFormatter.formatCoinWithCode(unlockingBondsBalance)); + } + final Coin total = confirmedBalance .add(pendingBalance) .add(lockedForVotingBalance) From 8e5983793c665e12ff6a23300e01e1f5d7a6a0f6 Mon Sep 17 00:00:00 2001 From: sqrrm Date: Thu, 28 Jun 2018 16:30:46 +0200 Subject: [PATCH 113/197] Rename package Lock to lockup --- src/main/java/bisq/desktop/main/dao/bonding/BondingView.java | 3 +-- .../main/dao/bonding/{Lock => lockup}/LockupBSQView.fxml | 2 +- .../main/dao/bonding/{Lock => lockup}/LockupBSQView.java | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) rename src/main/java/bisq/desktop/main/dao/bonding/{Lock => lockup}/LockupBSQView.fxml (98%) rename src/main/java/bisq/desktop/main/dao/bonding/{Lock => lockup}/LockupBSQView.java (99%) diff --git a/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java b/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java index 425a3954cb2..9a7d709b0f0 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java @@ -27,10 +27,9 @@ import bisq.desktop.components.MenuItem; import bisq.desktop.main.MainView; import bisq.desktop.main.dao.DaoView; -import bisq.desktop.main.dao.bonding.Lock.LockupBSQView; import bisq.desktop.main.dao.bonding.dashboard.BondingDashboardView; +import bisq.desktop.main.dao.bonding.lockup.LockupBSQView; import bisq.desktop.main.dao.bonding.unlock.UnlockBSQView; -import bisq.desktop.main.dao.voting.dashboard.VotingDashboardView; import bisq.core.locale.Res; diff --git a/src/main/java/bisq/desktop/main/dao/bonding/Lock/LockupBSQView.fxml b/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupBSQView.fxml similarity index 98% rename from src/main/java/bisq/desktop/main/dao/bonding/Lock/LockupBSQView.fxml rename to src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupBSQView.fxml index ee4747bfad8..51175737f57 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/Lock/LockupBSQView.fxml +++ b/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupBSQView.fxml @@ -21,7 +21,7 @@ -. */ -package bisq.desktop.main.dao.bonding.Lock; +package bisq.desktop.main.dao.bonding.lockup; import bisq.desktop.Navigation; import bisq.desktop.common.view.ActivatableView; From 3eb187acff65d1e6113fe0561678f03c728395bc Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Thu, 28 Jun 2018 19:59:57 +0200 Subject: [PATCH 114/197] Remove http-api --- build.gradle | 1 - 1 file changed, 1 deletion(-) diff --git a/build.gradle b/build.gradle index de214c95ba0..c6448a95683 100644 --- a/build.gradle +++ b/build.gradle @@ -45,7 +45,6 @@ dependencies { compile 'network.bisq:bisq-common:-SNAPSHOT' compile 'network.bisq:bisq-core:-SNAPSHOT' compile 'network.bisq:bisq-p2p:-SNAPSHOT' - compile 'network.bisq:bisq-http-api:-SNAPSHOT' compile 'network.bisq:bisq-grpc:-SNAPSHOT' compile 'org.controlsfx:controlsfx:8.0.6_20' compile 'org.reactfx:reactfx:2.0-M3' From 4136ed786f3b7c36a7d6c58543842a93502127af Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Thu, 28 Jun 2018 20:06:30 +0200 Subject: [PATCH 115/197] Remove http-api --- src/main/java/bisq/desktop/app/BisqAppMain.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/main/java/bisq/desktop/app/BisqAppMain.java b/src/main/java/bisq/desktop/app/BisqAppMain.java index 3e0f95b43d9..b1a724c18e5 100644 --- a/src/main/java/bisq/desktop/app/BisqAppMain.java +++ b/src/main/java/bisq/desktop/app/BisqAppMain.java @@ -41,13 +41,12 @@ import bisq.grpc.BisqGrpcServer; -import bisq.httpapi.BisqHttpApiServer; @Slf4j public class BisqAppMain extends BisqExecutable { private BisqApp application; - @Nullable - private BisqHttpApiServer bisqHttpApiServer; + /* @Nullable + private BisqHttpApiServer bisqHttpApiServer;*/ @Nullable private BisqGrpcServer bisqGrpcServer; @@ -132,10 +131,10 @@ protected void startApplication() { protected void onApplicationStarted() { super.onApplicationStarted(); - if (runWithHttpApi()) { + /* if (runWithHttpApi()) { final BisqFacade bisqFacade = injector.getInstance(BisqFacade.class); bisqHttpApiServer = new BisqHttpApiServer(bisqFacade); - } + }*/ if (runWithGrpcApi()) { final BisqFacade bisqFacade = injector.getInstance(BisqFacade.class); From a78180ecc6930ef97706f642d6455435389d1d82 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Fri, 29 Jun 2018 00:14:29 +0200 Subject: [PATCH 116/197] Merged master --- .../paymentmethods/MoneyGramForm.java | 4 +- .../java/bisq/desktop/main/MainViewModel.java | 172 +++++++++--------- .../bisq/desktop/main/market/MarketView.java | 7 +- .../main/offer/MutableOfferDataModel.java | 2 - .../offer/offerbook/OfferBookViewModel.java | 7 +- .../editoffer/EditOfferDataModel.java | 1 - .../java/bisq/desktop/util/FormBuilder.java | 8 - 7 files changed, 98 insertions(+), 103 deletions(-) diff --git a/src/main/java/bisq/desktop/components/paymentmethods/MoneyGramForm.java b/src/main/java/bisq/desktop/components/paymentmethods/MoneyGramForm.java index 43ff83121ca..f145182084e 100644 --- a/src/main/java/bisq/desktop/components/paymentmethods/MoneyGramForm.java +++ b/src/main/java/bisq/desktop/components/paymentmethods/MoneyGramForm.java @@ -69,8 +69,8 @@ public static int addFormForBuyer(GridPane gridPane, int gridRow, addLabelTextFieldWithCopyIcon(gridPane, ++gridRow, Res.getWithCol("payment.account.fullName"), payload.getHolderName()); FormBuilder.addLabelTextFieldWithCopyIcon(gridPane, ++gridRow, - Res.getWithCol("payment.bank.country"), - CountryUtil.getNameAndCode(((MoneyGramAccountPayload) paymentAccountPayload).getCountryCode())); + Res.getWithCol("payment.bank.country"), + CountryUtil.getNameAndCode(((MoneyGramAccountPayload) paymentAccountPayload).getCountryCode())); if (BankUtil.isStateRequired(payload.getCountryCode())) addLabelTextFieldWithCopyIcon(gridPane, ++gridRow, Res.get("payment.account.state"), payload.getState()); diff --git a/src/main/java/bisq/desktop/main/MainViewModel.java b/src/main/java/bisq/desktop/main/MainViewModel.java index b042825bba9..bb5f03032e4 100644 --- a/src/main/java/bisq/desktop/main/MainViewModel.java +++ b/src/main/java/bisq/desktop/main/MainViewModel.java @@ -81,7 +81,7 @@ import lombok.extern.slf4j.Slf4j; @Slf4j -public class MainViewModel implements ViewModel { +public class MainViewModel implements ViewModel, BisqSetup.BisqSetupCompleteListener { private final BisqSetup bisqSetup; private final WalletsSetup walletsSetup; private final User user; @@ -169,19 +169,95 @@ public MainViewModel(BisqSetup bisqSetup, BalanceWithConfirmationTextField.setWalletService(btcWalletService); GUIUtil.setFeeService(feeService); + + setupHandlers(); + bisqSetup.addBisqSetupCompleteListener(this); } /////////////////////////////////////////////////////////////////////////////////////////// - // API + // BisqSetupCompleteListener /////////////////////////////////////////////////////////////////////////////////////////// - public void start() { - setupHandlers(); + @Override + public void onSetupComplete() { + // We handle the trade period here as we display a global popup if we reached dispute time + tradesAndUIReady = EasyBind.combine(isSplashScreenRemoved, tradeManager.pendingTradesInitializedProperty(), (a, b) -> a && b); + tradesAndUIReady.subscribe((observable, oldValue, newValue) -> { + if (newValue) { + tradeManager.applyTradePeriodState(); + + tradeManager.getTradableList().forEach(trade -> { + Date maxTradePeriodDate = trade.getMaxTradePeriodDate(); + String key; + switch (trade.getTradePeriodState()) { + case FIRST_HALF: + break; + case SECOND_HALF: + key = "displayHalfTradePeriodOver" + trade.getId(); + if (DontShowAgainLookup.showAgain(key)) { + DontShowAgainLookup.dontShowAgain(key, true); + new Popup<>().warning(Res.get("popup.warning.tradePeriod.halfReached", + trade.getShortId(), + formatter.formatDateTime(maxTradePeriodDate))) + .show(); + } + break; + case TRADE_PERIOD_OVER: + key = "displayTradePeriodOver" + trade.getId(); + if (DontShowAgainLookup.showAgain(key)) { + DontShowAgainLookup.dontShowAgain(key, true); + new Popup<>().warning(Res.get("popup.warning.tradePeriod.ended", + trade.getShortId(), + formatter.formatDateTime(maxTradePeriodDate))) + .show(); + } + break; + } + }); + } + }); - bisqSetup.start(this::onSetupComplete); + setupP2PNumPeersWatcher(); + setupBtcNumPeersWatcher(); + + marketPricePresentation.setup(); + + if (DevEnv.isDevMode()) { + preferences.setShowOwnOffersInOfferBook(true); + setupDevDummyPaymentAccounts(); + } + + getShowAppScreen().set(true); } + + /////////////////////////////////////////////////////////////////////////////////////////// + // UI handlers + /////////////////////////////////////////////////////////////////////////////////////////// + + // After showAppScreen is set and splash screen is faded out + void onSplashScreenRemoved() { + isSplashScreenRemoved.set(true); + + // Delay that as we want to know what is the current path of the navigation which is set + // in MainView showAppScreen handler + notificationCenter.onAllServicesAndViewsInitialized(); + } + + void onOpenDownloadWindow() { + bisqSetup.displayAlertIfPresent(user.getDisplayedAlert(), true); + } + + void setPriceFeedComboBoxItem(PriceFeedComboBoxItem item) { + marketPricePresentation.setPriceFeedComboBoxItem(item); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Private + /////////////////////////////////////////////////////////////////////////////////////////// + private void setupHandlers() { bisqSetup.setDisplayTacHandler(acceptedHandler -> UserThread.runAfter(() -> { //noinspection FunctionalExpressionCanBeFolded @@ -248,10 +324,14 @@ private void setupHandlers() { .information(Res.get("popup.securityRecommendation.msg")) .dontShowAgainId(key) .show()); - bisqSetup.setDisplayLocalhostHandler(key -> + bisqSetup.setDisplayLocalhostHandler(key -> { + if (!DevEnv.isDevMode()) { new Popup<>().backgroundInfo(Res.get("popup.bitcoinLocalhostNode.msg")) .dontShowAgainId(key) - .show()); + .show(); + } + }); + bisqSetup.setWrongOSArchitectureHandler(msg -> new Popup<>().warning(msg).show()); corruptedDatabaseFilesHandler.getCorruptedDatabaseFiles().ifPresent(files -> { @@ -267,84 +347,6 @@ private void setupHandlers() { .show()); } - private void onSetupComplete() { - // We handle the trade period here as we display a global popup if we reached dispute time - tradesAndUIReady = EasyBind.combine(isSplashScreenRemoved, tradeManager.pendingTradesInitializedProperty(), (a, b) -> a && b); - tradesAndUIReady.subscribe((observable, oldValue, newValue) -> { - if (newValue) { - tradeManager.applyTradePeriodState(); - - tradeManager.getTradableList().forEach(trade -> { - Date maxTradePeriodDate = trade.getMaxTradePeriodDate(); - String key; - switch (trade.getTradePeriodState()) { - case FIRST_HALF: - break; - case SECOND_HALF: - key = "displayHalfTradePeriodOver" + trade.getId(); - if (DontShowAgainLookup.showAgain(key)) { - DontShowAgainLookup.dontShowAgain(key, true); - new Popup<>().warning(Res.get("popup.warning.tradePeriod.halfReached", - trade.getShortId(), - formatter.formatDateTime(maxTradePeriodDate))) - .show(); - } - break; - case TRADE_PERIOD_OVER: - key = "displayTradePeriodOver" + trade.getId(); - if (DontShowAgainLookup.showAgain(key)) { - DontShowAgainLookup.dontShowAgain(key, true); - new Popup<>().warning(Res.get("popup.warning.tradePeriod.ended", - trade.getShortId(), - formatter.formatDateTime(maxTradePeriodDate))) - .show(); - } - break; - } - }); - } - }); - - setupP2PNumPeersWatcher(); - setupBtcNumPeersWatcher(); - - marketPricePresentation.setup(); - - if (DevEnv.isDevMode()) { - preferences.setShowOwnOffersInOfferBook(true); - setupDevDummyPaymentAccounts(); - } - - getShowAppScreen().set(true); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // UI handlers - /////////////////////////////////////////////////////////////////////////////////////////// - - // After showAppScreen is set and splash screen is faded out - void onSplashScreenRemoved() { - isSplashScreenRemoved.set(true); - - // Delay that as we want to know what is the current path of the navigation which is set - // in MainView showAppScreen handler - notificationCenter.onAllServicesAndViewsInitialized(); - } - - void onOpenDownloadWindow() { - bisqSetup.displayAlertIfPresent(user.getDisplayedAlert(), true); - } - - void setPriceFeedComboBoxItem(PriceFeedComboBoxItem item) { - marketPricePresentation.setPriceFeedComboBoxItem(item); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Private - /////////////////////////////////////////////////////////////////////////////////////////// - private void setupP2PNumPeersWatcher() { p2PService.getNumConnectedPeers().addListener((observable, oldValue, newValue) -> { int numPeers = (int) newValue; diff --git a/src/main/java/bisq/desktop/main/market/MarketView.java b/src/main/java/bisq/desktop/main/market/MarketView.java index 68b1cccd258..9009f194e71 100644 --- a/src/main/java/bisq/desktop/main/market/MarketView.java +++ b/src/main/java/bisq/desktop/main/market/MarketView.java @@ -29,6 +29,7 @@ import bisq.desktop.main.market.spread.SpreadView; import bisq.desktop.main.market.trades.TradesChartsView; import bisq.desktop.main.offer.offerbook.OfferBook; +import bisq.desktop.main.offer.offerbook.OfferBookListItem; import bisq.desktop.main.overlays.popups.Popup; import bisq.core.locale.Res; @@ -179,8 +180,8 @@ private String getAllTradesWithReferralId() { // We don't use the list from the tradeStatisticsManager as that has filtered the duplicates but we want to get // all items of both traders in case the referral ID was only set by one trader. // If both traders had set it the tradeStatistics is only delivered once. - // If both traders used a differnet refferral ID then we would get 2 objects. - List list = p2PService.getP2PDataStorage().getPersistableNetworkPayloadList().getMap().values().stream() + // If both traders used a different referral ID then we would get 2 objects. + List list = p2PService.getP2PDataStorage().getAppendOnlyDataStoreMap().values().stream() .filter(e -> e instanceof TradeStatistics2) .map(e -> (TradeStatistics2) e) .filter(tradeStatistics2 -> tradeStatistics2.getExtraDataMap() != null) @@ -203,7 +204,7 @@ private String getAllTradesWithReferralId() { private String getAllOffersWithReferralId() { List list = offerBook.getOfferBookListItems().stream() - .map(offerBookListItem -> offerBookListItem.getOffer()) + .map(OfferBookListItem::getOffer) .filter(offer -> offer.getOfferPayload().getExtraDataMap() != null) .filter(offer -> offer.getOfferPayload().getExtraDataMap().get(OfferPayload.REFERRAL_ID) != null) .map(offer -> { diff --git a/src/main/java/bisq/desktop/main/offer/MutableOfferDataModel.java b/src/main/java/bisq/desktop/main/offer/MutableOfferDataModel.java index 9c9f052797c..13132854648 100644 --- a/src/main/java/bisq/desktop/main/offer/MutableOfferDataModel.java +++ b/src/main/java/bisq/desktop/main/offer/MutableOfferDataModel.java @@ -90,8 +90,6 @@ import java.util.Optional; import java.util.UUID; -import javax.annotation.Nullable; - import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookViewModel.java b/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookViewModel.java index 43c15cc09f7..4aa7f1bdeb4 100644 --- a/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookViewModel.java +++ b/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookViewModel.java @@ -534,7 +534,8 @@ boolean hasMatchingArbitrator(Offer offer) { } boolean isIgnored(Offer offer) { - return preferences.getIgnoreTradersList().stream().anyMatch(i -> i.equals(offer.getMakerNodeAddress().getHostNameWithoutPostFix())); + return preferences.getIgnoreTradersList().stream() + .anyMatch(i -> i.equals(offer.getMakerNodeAddress().getHostNameWithoutPostFix())); } boolean isOfferBanned(Offer offer) { @@ -555,7 +556,9 @@ boolean isNodeAddressBanned(Offer offer) { boolean isInsufficientTradeLimit(Offer offer) { Optional accountOptional = getMostMaturePaymentAccountForOffer(offer); - final long myTradeLimit = accountOptional.map(paymentAccount -> accountAgeWitnessService.getMyTradeLimit(paymentAccount, offer.getCurrencyCode())).orElse(0L); + final long myTradeLimit = accountOptional + .map(paymentAccount -> accountAgeWitnessService.getMyTradeLimit(paymentAccount, offer.getCurrencyCode())) + .orElse(0L); final long offerMinAmount = offer.getMinAmount().value; log.debug("isInsufficientTradeLimit accountOptional={}, myTradeLimit={}, offerMinAmount={}, ", accountOptional.isPresent() ? accountOptional.get().getAccountName() : "null", diff --git a/src/main/java/bisq/desktop/main/portfolio/editoffer/EditOfferDataModel.java b/src/main/java/bisq/desktop/main/portfolio/editoffer/EditOfferDataModel.java index 56b85f6feca..49b58a629f3 100644 --- a/src/main/java/bisq/desktop/main/portfolio/editoffer/EditOfferDataModel.java +++ b/src/main/java/bisq/desktop/main/portfolio/editoffer/EditOfferDataModel.java @@ -45,7 +45,6 @@ import bisq.common.crypto.KeyRing; import bisq.common.handlers.ErrorMessageHandler; import bisq.common.handlers.ResultHandler; -import bisq.common.proto.persistable.PersistenceProtoResolver; import com.google.inject.Inject; diff --git a/src/main/java/bisq/desktop/util/FormBuilder.java b/src/main/java/bisq/desktop/util/FormBuilder.java index 66bbcf304e7..7b5d2049ae5 100644 --- a/src/main/java/bisq/desktop/util/FormBuilder.java +++ b/src/main/java/bisq/desktop/util/FormBuilder.java @@ -77,14 +77,6 @@ import java.util.Set; import java.util.concurrent.CopyOnWriteArraySet; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - - -import de.jensd.fx.glyphs.GlyphIcons; -import de.jensd.fx.glyphs.materialdesignicons.utils.MaterialDesignIconFactory; - public class FormBuilder { public static final String MATERIAL_DESIGN_ICONS = "'Material Design Icons'"; public static final String FONTAWESOME_ICONS = "FontAwesome"; From 15ad8f8f40e875ed6fcdfacc237b96aa8e365d2a Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Fri, 29 Jun 2018 11:59:40 +0200 Subject: [PATCH 117/197] Update gradle files - Move mavenLocal on top to resolve local jars first - Comment out annotationProcessor and testAnnotationProcessor entries as they conflict with grpc build (don't know why). Complete project build works also without the annotationProcessor entries. - Comment out btcd-cli4j entries in dependencyVerification as they cause build failure. TODO investigate why... --- build.gradle | 106 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 101 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index c6448a95683..45fcfc862d5 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ buildscript { repositories { - jcenter() mavenLocal() + jcenter() } dependencies { classpath 'com.github.jengelman.gradle.plugins:shadow:2.0.4' @@ -34,11 +34,11 @@ tasks.withType(JavaCompile) { sourceSets.main.resources.srcDirs += ['src/main/java'] // to copy fxml and css files repositories { + mavenLocal() jcenter() maven { url 'https://jitpack.io' } maven { url 'https://raw.githubusercontent.com/JesusMcCloud/tor-binary/master/release/' } maven { url 'https://dl.bintray.com/jerady/maven' } - mavenLocal() } dependencies { @@ -54,7 +54,7 @@ dependencies { compile 'de.jensd:fontawesomefx-materialdesignfont:1.7.22-4' compile 'com.googlecode.jcsv:jcsv:1.4.0' compileOnly 'org.projectlombok:lombok:1.16.16' - annotationProcessor 'org.projectlombok:lombok:1.16.16' + // annotationProcessor 'org.projectlombok:lombok:1.16.16' testCompile('org.mockito:mockito-core:2.8.9') { exclude(module: 'objenesis') } @@ -64,14 +64,110 @@ dependencies { testCompile 'org.springframework:spring-test:4.3.6.RELEASE' testCompile 'com.natpryce:make-it-easy:4.0.1' testCompileOnly 'org.projectlombok:lombok:1.16.16' - testAnnotationProcessor 'org.projectlombok:lombok:1.16.16' + // testAnnotationProcessor 'org.projectlombok:lombok:1.16.16' } build.dependsOn installDist installDist.destinationDir = file('build/app') -// generated with `./gradlew -q calculateChecksums | grep -v network.bisq:bisq-` +// To update the `dependencyVerification` block below: +// +// 1. Remove the block entirely +// 2. Replace the block with the following command: +// +// ./gradlew -q calculateChecksums | grep -v network.bisq:bisq- >> build.gradle +// +// 3. Run `git diff` to verify that expected hashes have changed +// 4. Commit the changes + dependencyVerification { verify = [ + 'org.controlsfx:controlsfx:b98f1c9507c05600f80323674b33d15674926c71b0116f70085b62bdacf1e573', + 'org.reactfx:reactfx:81ec8fe545d65661222735711114c2ce427e2187a65f1722e8ac4e4805beeca3', + 'net.glxn:qrgen:c85d9d8512d91e8ad11fe56259a7825bd50ce0245447e236cf168d1b17591882', + 'de.jensd:fontawesomefx:73bacc991a0a6f5cf0f911767c8db161e0949dbca61e8371eb4342e3da96887b', + 'de.jensd:fontawesomefx-materialdesignfont:8f700556bbfdc4a581224d3bd6ff869b8a03f6670bd7e0fc78884bd2f31fdb64', + 'de.jensd:fontawesomefx-commons:e1505a31433f1b2902478217651afc78dae5ab09670336afc46e582a1dea1e4d', + 'com.googlecode.jcsv:jcsv:73ca7d715e90c8d2c2635cc284543b038245a34f70790660ed590e157b8714a2', + /* + TODO investigate why it fails if that is set. prob. related to master using diff. version and handling in jitpack... + 'network.bisq.btcd-cli4j:btcd-cli4j-daemon:cf19fddccfd9c5302498dfdb29a7fead8faff04912285bfdaacad1fd7a27f646', + 'network.bisq.btcd-cli4j:btcd-cli4j-core:cc063c3a501ee6dd6f2e2e98ce59e82d720a52522acc1ec0751434dece4851e4', + */ + 'io.grpc:grpc-alts:9cb1d830d8f465ff3011904bad3211192e6eec6562e61a88b2823c8de71c2f37', + 'io.grpc:grpc-protobuf:0acf523d0eacae11e2c094112737c77af39789cb30332f2359004a6ab67e36a1', + 'com.google.api.grpc:proto-google-common-protos:cfe1da4c0e82820c32a83c4bf25b42f4d3b7113177321c437a9fff3c42e1f4c9', + 'com.google.protobuf:protobuf-java-util:8bd8a5de6d7e05dce16c8198c8013ebd9c703e10db957fb6dfab0ad24bcd8adc', + 'com.google.protobuf:protobuf-java:b5e2d91812d183c9f053ffeebcbcda034d4de6679521940a19064714966c2cd4', + 'io.grpc:grpc-netty:631526592a1496ef2850154f58b45bef63682653c9910facccd550408baf1dc3', + 'io.grpc:grpc-stub:b72069a9b331fb7e638e3f684968df78b995c41dec89a3cc4d31d554050d663b', + 'io.grpc:grpc-protobuf-lite:1f81c360acd3d61b32a4ffb065d34fccdf951076490f2dd05070fb3169263d05', + 'io.grpc:grpc-core:63e02c0fd675797c19861cbd7d254c629145f943a593032febd5676d77bc8678', + 'com.google.code.gson:gson:2d43eb5ea9e133d2ee2405cc14f5ee08951b8361302fdd93494a3a997b508d32', + 'com.googlecode.json-simple:json-simple:4e69696892b88b41c55d49ab2fdcc21eead92bf54acc588c0050596c3b75199c', + 'org.springframework:spring-core:c451e8417adb2ffb2445636da5e44a2f59307c4100037a1fe387c3fba4f29b52', + 'ch.qos.logback:logback-classic:e66efc674e94837344bc5b748ff510c37a44eeff86cbfdbf9e714ef2eb374013', + 'org.slf4j:slf4j-api:3a4cd4969015f3beb4b5b4d81dbafc01765fb60b8a439955ca64d8476fef553e', + 'ch.qos.logback:logback-core:4cd46fa17d77057b39160058df2f21ebbc2aded51d0edcc25d2c1cecc042a005', + 'com.google.code.findbugs:jsr305:c885ce34249682bc0236b4a7d56efcc12048e6135a5baf7a9cde8ad8cda13fcd', + 'com.google.guava:guava:36a666e3b71ae7f0f0dca23654b67e086e6c93d192f60ba5dfd5519db6c288c8', + 'com.google.inject:guice:9b9df27a5b8c7864112b4137fd92b36c3f1395bfe57be42fedf2f520ead1a93e', + 'network.bisq.libdohj:libdohj-core:cef7db8a2032ffbc229ccacc29b7d13e8ee1daf1cd60ee8f988cdfa60a041d8e', + 'com.github.JesusMcCloud.netlayer:tor.native:de44e782b21838d3426dbff99abbfd1cbb8e5d3f6d5e997441ff4fd8354934fa', + 'com.github.JesusMcCloud.netlayer:tor:3896950c56a41985f901ff9475524ac162cba18b2d5a0ed39810b20ddaf5128a', + 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:841b021d62fc007ce2883963ff9440d5393fb1f6a0604ed68cd016afcaf02967', + 'com.github.MicroUtils:kotlin-logging:7dbd501cc210d721f730d480c53ee2a6e3c154ae89b07dc7dee224b9c5aca9eb', + 'org.jetbrains.kotlin:kotlin-stdlib-jdk7:bd8cd4e3ef391cd468434747b7939c49e80f8bf4ae10355a65382bfb54fd633c', + 'org.jetbrains.kotlin:kotlin-stdlib:e1c39d27f23a7fe2d3e4ac65e80a53e98fdcf60e07de9d53b8b841c5944fc810', + 'org.jetbrains:annotations:ace2a10dc8e2d5fd34925ecac03e4988b2c0f851650c94b8cef49ba1bd111478', + 'org.bouncycastle:bcpg-jdk15on:de3355b821fc81dd32e1f3f560d5b3eca1c678fd2400011d0bfc69fb91bcde85', + 'commons-io:commons-io:cc6a41dc3eaacc9e440a6bd0d2890b20d36b4ee408fe2d67122f328bb6e01581', + 'org.apache.commons:commons-lang3:8ac96fc686512d777fca85e144f196cd7cfe0c0aec23127229497d1a38ff651c', + 'org.bouncycastle:bcprov-jdk15on:963e1ee14f808ffb99897d848ddcdb28fa91ddda867eb18d303e82728f878349', + 'net.sf.jopt-simple:jopt-simple:6f45c00908265947c39221035250024f2caec9a15c1c8cf553ebeecee289f342', + 'com.fasterxml.jackson.core:jackson-databind:fcf3c2b0c332f5f54604f7e27fa7ee502378a2cc5df6a944bbfae391872c32ff', + 'com.fasterxml.jackson.core:jackson-core:39a74610521d7fb9eb3f437bb8739bbf47f6435be12d17bf954c731a0c6352bb', + 'com.fasterxml.jackson.core:jackson-annotations:2566b3a6662afa3c6af4f5b25006cb46be2efc68f1b5116291d6998a8cdf7ed3', + 'org.apache.httpcomponents:httpclient:db3d1b6c2d6a5e5ad47577ad61854e2f0e0936199b8e05eb541ed52349263135', + 'org.fxmisc.easybind:easybind:666af296dda6de68751668a62661571b5238ac6f1c07c8a204fc6f902b222aaf', + 'io.netty:netty-tcnative-boringssl-static:762aa9b16025e373f73534e8b78bf1552b60bfb1c2c9b579de49e9e5517680de', + 'com.google.zxing:javase:0ec23e2ec12664ddd6347c8920ad647bb3b9da290f897a88516014b56cc77eb9', + 'commons-logging:commons-logging:daddea1ea0be0f56978ab3006b8ac92834afeefbd9b7e4e6316fca57df0fa636', + 'javax.inject:javax.inject:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff', + 'aopalliance:aopalliance:0addec670fedcd3f113c5c8091d783280d23f75e3acb841b61a9cdb079376a08', + 'com.github.bisq-network.bitcoinj:bitcoinj-core:05c94cc68f1524ed08f5aa815f5f09d99a3aae5ab277527d7729ee74d0aece13', + 'com.lambdaworks:scrypt:9a82d218099fb14c10c0e86e7eefeebd8c104de920acdc47b8b4b7a686fb73b4', + 'commons-codec:commons-codec:ad19d2601c3abf0b946b5c3a4113e226a8c1e3305e395b90013b78dd94a723ce', + 'com.cedricwalter:tor-binary-macos:87790e9eade1e44eeadc81f92670f338cd47ef1b39b46a4b022c75d0cf6465fd', + 'com.cedricwalter:tor-binary-linux32:814f6da3b662c96490bcb09781764dd31dfe497ea9c25c73fe61170d2a78086f', + 'com.cedricwalter:tor-binary-linux64:9da7f8a166ad0a767a5373ca67c68971c9c0cac17964eed2e0850bfecc228312', + 'com.cedricwalter:tor-binary-windows:9487a735dadcadc6ede5ffad36a911c2d4a484f996be93d71094f26591b8c29e', + 'com.github.ravn:jsocks:3c71600af027b2b6d4244e4ad14d98ff2352a379410daebefff5d8cd48d742a4', + 'org.apache.httpcomponents:httpcore:d7f853dee87680b07293d30855b39b9eb56c1297bd16ff1cd6f19ddb8fa745fb', + 'io.netty:netty-codec-http2:6c616bf4dee8fd4bfd9e133b7dba8f6e115042e8dc347aef8f184027b1f9821f', + 'io.netty:netty-handler-proxy:1d7931e5511890a146303a07819863b6261fdd7b3c22c2c50634f82e362f336c', + 'com.google.zxing:core:11aae8fd974ab25faa8208be50468eb12349cd239e93e7c797377fa13e381729', + 'com.madgag.spongycastle:core:8d6240b974b0aca4d3da9c7dd44d42339d8a374358aca5fc98e50a995764511f', + 'net.jcip:jcip-annotations:be5805392060c71474bf6c9a67a099471274d30b83eef84bfc4e0889a4f1dcc0', + 'org.bitcoinj:orchid:f836325cfa0466a011cb755c9b0fee6368487a2352eb45f4306ad9e4c18de080', + 'com.squareup.okhttp:okhttp:b4c943138fcef2bcc9d2006b2250c4aabbedeafc5947ed7c0af7fd103ceb2707', + 'com.cedricwalter:tor-binary-geoip:7fc7b5ebf80d65ec53d97dd8d3878b8d2c85dc04f3943e5e85e7ba641655492b', + 'com.github.JesusMcCloud:jtorctl:c6ef92e46074d8d26db718ce0fe4b64b8cf7b934b7377d164c5d613b4cd7b847', + 'org.apache.commons:commons-compress:a778bbd659722889245fc52a0ec2873fbbb89ec661bc1ad3dc043c0757c784c4', + 'org.tukaani:xz:a594643d73cc01928cf6ca5ce100e094ea9d73af760a5d4fb6b75fa673ecec96', + 'io.grpc:grpc-context:817a68c7e5ef48eaede2ab16be9417af5b8ca37d08e90f26925690b9dd6730ca', + 'com.google.errorprone:error_prone_annotations:de3c873b5dc06060f7a2a4d9b872a3f4dc1955c18095ef9702d13477e437782a', + 'io.opencensus:opencensus-contrib-grpc-metrics:21c37058d708ff7aed46cc7e0f226d6816190376b086574eafab2c5fa05724fe', + 'io.opencensus:opencensus-api:f4457f4a81b9021188c44884eb7184d938a35fc0623f1aa0b1eba6f6b96e93a2', + 'io.netty:netty-codec-http:6de1a2ce4dc8b284aa49dcaa6183c20f5e978c70e28cf8905682fabc5f208612', + 'io.netty:netty-handler:bfcc1716f57641c4d1521fe2d8988c412fc6d28b0eca773b53e0a262efd7fcfe', + 'io.netty:netty-codec-socks:7cdd49bcde53f563547ff3313778dcaa7c68cfb07540c0b362953645538d5698', + 'io.netty:netty-codec:536ea827a0506c5e1a800ffa64a8b5485ff87a40102b169389c57e280fa40d86', + 'io.netty:netty-transport:08250e03630c66048eaf7257020bef8b11c0d77dafd699a15e795a4d3db19ab3', + 'com.squareup.okio:okio:114bdc1f47338a68bcbc95abf2f5cdc72beeec91812f2fcd7b521c1937876266', + 'org.objenesis:objenesis:5e168368fbc250af3c79aa5fef0c3467a2d64e5a7bd74005f25d8399aeb0708d', + 'io.netty:netty-buffer:11c6333d88de70d8ca392b7e65a7256829ef6d3344e58788d9ee0da3e8087a63', + 'io.netty:netty-resolver:623743441feb2db7df48501e0b78f4c34037eae624b732941213a149de293fc1', + 'io.netty:netty-common:469193e9df5c82505aa2ba0ba1417adcadf493313d7dade36998b9c18997cfcc', ] } From d9ce3cf55e83f512bf207e7270490547660de4c7 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Fri, 29 Jun 2018 23:27:03 +0200 Subject: [PATCH 118/197] Refactor mutable data handling in State The data handling with flat maps for each type of mutable data as we used before feels very un-intuitive to use. This commit changes the flat map to a tree structure. We use a map of mutableTx objects. The mutableTx contains the immutable Tx and a map of mutableTxOutputs as well as mutable fields like type. The mutableTxOutput contains an immutable TxOutput and mutable fields like type. That commit might have broken something in the bonding. Should be fixed in updates... --- .../desktop/main/dao/bonding/unlock/LockedBsqTxListItem.java | 2 +- .../bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java | 2 +- .../java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java | 2 +- .../desktop/main/funds/transactions/TransactionsListItem.java | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedBsqTxListItem.java b/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedBsqTxListItem.java index 872c646e0b4..c5344d39eff 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedBsqTxListItem.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedBsqTxListItem.java @@ -140,7 +140,7 @@ public boolean isSpent() { public TxType getTxType() { return daoFacade.getTx(txId) - .flatMap(tx -> daoFacade.getTxType(tx.getId())) + .flatMap(tx -> daoFacade.getOptionalTxType(tx.getId())) .orElse(confirmations == 0 ? TxType.UNVERIFIED : TxType.UNDEFINED_TX_TYPE); } diff --git a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java index 41a576e8e28..4c3e88f46d6 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java @@ -322,7 +322,7 @@ private void onButtonClick() { } Coin unlockAmount = Coin.valueOf(lockedTxOutput.get().getValue()); - Optional opLockTime = stateService.getLockTime(lockedTxOutput.get()); + Optional opLockTime = stateService.getLockTime(selectedItem.getTxId()); int lockTime = opLockTime.isPresent() ? opLockTime.get() : -1; try { diff --git a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java index c1c54d49552..1c07ff2efe1 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java @@ -160,7 +160,7 @@ public void cleanup() { public TxType getTxType() { return daoFacade.getTx(txId) - .flatMap(tx -> daoFacade.getTxType(tx.getId())) + .flatMap(tx -> daoFacade.getOptionalTxType(tx.getId())) .orElse(confirmations == 0 ? TxType.UNVERIFIED : TxType.UNDEFINED_TX_TYPE); } diff --git a/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java b/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java index 03ceec37459..e63d20f0750 100644 --- a/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java +++ b/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java @@ -133,7 +133,7 @@ class TransactionsListItem { txFeeForBsqPayment = true; // - final Optional txTypeOptional = daoFacade.getTxType(txId); + final Optional txTypeOptional = daoFacade.getOptionalTxType(txId); if (txTypeOptional.isPresent() && txTypeOptional.get().equals(TxType.COMPENSATION_REQUEST)) details = Res.get("funds.tx.proposal"); } else { From 0d39aad91f7e3c939d000b41d5ca1bd914bb72ad Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sat, 7 Jul 2018 18:57:02 +0200 Subject: [PATCH 119/197] Apply fixes to stateService --- .../main/dao/bonding/unlock/LockedBsqTxListItem.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedBsqTxListItem.java b/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedBsqTxListItem.java index c5344d39eff..c2fe23af6ed 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedBsqTxListItem.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedBsqTxListItem.java @@ -133,9 +133,10 @@ public void cleanup() { public boolean isSpent() { Optional optionalTxOutput = stateService.getLockedTxOutput(txId); - if (optionalTxOutput.isPresent()) - return !stateService.isUnspent(optionalTxOutput.get()); - return true; + if (!optionalTxOutput.isPresent()) + return true; + + return !stateService.isUnspent(optionalTxOutput.get().getKey()); } public TxType getTxType() { From a7ddd27725982ce7b34298a9f461f714422dd698 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sat, 7 Jul 2018 21:01:27 +0200 Subject: [PATCH 120/197] Set TxOutputType at TxOutputProcessor --- .../desktop/main/dao/bonding/unlock/LockedBsqTxListItem.java | 1 + .../java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java | 1 + 2 files changed, 2 insertions(+) diff --git a/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedBsqTxListItem.java b/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedBsqTxListItem.java index c2fe23af6ed..ec828bf2ba5 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedBsqTxListItem.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedBsqTxListItem.java @@ -88,6 +88,7 @@ class LockedBsqTxListItem { amount = bsqWalletService.getValueLockedUpInBond(transaction); + //TODO SQ: use DaoFacade instead of direct access to stateService Optional opLockTime = stateService.getLockTime(transaction.getHashAsString()); lockTime = opLockTime.isPresent() ? opLockTime.get() : -1; diff --git a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java index 4c3e88f46d6..76b392c65da 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java @@ -322,6 +322,7 @@ private void onButtonClick() { } Coin unlockAmount = Coin.valueOf(lockedTxOutput.get().getValue()); + //TODO SQ: use DaoFacade instead of direct access to stateService Optional opLockTime = stateService.getLockTime(selectedItem.getTxId()); int lockTime = opLockTime.isPresent() ? opLockTime.get() : -1; From bdb40cd51433d8e6750d992129e8465573d1d143 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sat, 7 Jul 2018 22:00:00 +0200 Subject: [PATCH 121/197] Fix wrong equals check at litenode. Cleanups --- .../desktop/main/dao/bonding/unlock/LockedBsqTxListItem.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedBsqTxListItem.java b/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedBsqTxListItem.java index ec828bf2ba5..67ce3f24e3f 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedBsqTxListItem.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedBsqTxListItem.java @@ -90,7 +90,7 @@ class LockedBsqTxListItem { //TODO SQ: use DaoFacade instead of direct access to stateService Optional opLockTime = stateService.getLockTime(transaction.getHashAsString()); - lockTime = opLockTime.isPresent() ? opLockTime.get() : -1; + lockTime = opLockTime.orElse(-1); button = new AutoTooltipButton(); button.setMinWidth(70); From 387078b1572b660e869b4215a2b47baeffaeeadd Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sun, 8 Jul 2018 21:04:23 +0200 Subject: [PATCH 122/197] Improve logs, cleanup --- .../desktop/main/dao/proposal/make/MakeProposalView.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index 1bc761770bf..fbd8462beb6 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -170,9 +170,9 @@ public void onChainHeightChanged(int blockHeight) { private void publishMyProposal(ProposalType type) { try { - final ProposalWithTransaction ballotWithTransaction = getBallotWithTransaction(type); - Proposal proposal = ballotWithTransaction.getProposal(); - Transaction transaction = ballotWithTransaction.getTransaction(); + final ProposalWithTransaction proposalWithTransaction = getProposalWithTransaction(type); + Proposal proposal = proposalWithTransaction.getProposal(); + Transaction transaction = proposalWithTransaction.getTransaction(); Coin miningFee = transaction.getFee(); int txSize = transaction.bitcoinSerialize().length; final Coin fee = daoFacade.getProposalFee(); @@ -210,7 +210,7 @@ private void doPublishMyProposal(Proposal proposal, Transaction transaction) { errorMessage -> new Popup<>().warning(errorMessage).show()); } - private ProposalWithTransaction getBallotWithTransaction(ProposalType type) + private ProposalWithTransaction getProposalWithTransaction(ProposalType type) throws InsufficientMoneyException, TransactionVerificationException, ValidationException, WalletException, IOException { From 052c46fe0669dab9c3562cb127996d1f51223aa0 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Mon, 9 Jul 2018 22:13:52 +0200 Subject: [PATCH 123/197] Add param request --- .../main/dao/proposal/ProposalDisplay.java | 98 ++++++++++++++----- .../dao/proposal/make/MakeProposalView.java | 33 ++++++- 2 files changed, 102 insertions(+), 29 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java index e273fcb80d1..84dc41247a6 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java @@ -32,10 +32,13 @@ import bisq.core.dao.voting.proposal.ProposalType; import bisq.core.dao.voting.proposal.compensation.CompensationConsensus; import bisq.core.dao.voting.proposal.compensation.CompensationProposal; +import bisq.core.dao.voting.proposal.param.Param; +import bisq.core.dao.voting.proposal.param.ParamProposal; import bisq.core.locale.Res; import bisq.core.provider.fee.FeeService; import bisq.core.util.BsqFormatter; +import javafx.scene.control.ComboBox; import javafx.scene.control.ScrollPane; import javafx.scene.control.TextArea; import javafx.scene.layout.AnchorPane; @@ -47,7 +50,10 @@ import javafx.beans.value.ChangeListener; -import java.util.Objects; +import javafx.collections.FXCollections; + +import javafx.util.StringConverter; + import java.util.UUID; import lombok.extern.slf4j.Slf4j; @@ -64,7 +70,9 @@ public class ProposalDisplay { private BsqWalletService bsqWalletService; public InputTextField uidTextField, nameTextField, titleTextField, linkInputTextField; @Nullable - public InputTextField requestedBsqTextField, bsqAddressTextField; + public InputTextField requestedBsqTextField, bsqAddressTextField, paramValueTextField; + @Nullable + public ComboBox paramComboBox; private int gridRow; public TextArea descriptionTextArea; private HyperlinkWithIcon linkHyperlinkWithIcon; @@ -96,12 +104,16 @@ public void createAllFields(String title, int gridRowStartIndex, double top, Pro this.gridRowStartIndex = gridRowStartIndex; this.gridRow = gridRowStartIndex; int rowSpan; + + boolean hasAddedFields = proposalType == ProposalType.COMPENSATION_REQUEST || + proposalType == ProposalType.CHANGE_PARAM; + ; if (isMakeProposalScreen) { - rowSpan = proposalType == ProposalType.COMPENSATION_REQUEST ? 7 : 5; + rowSpan = hasAddedFields ? 7 : 5; } else if (showDetails) { - rowSpan = proposalType == ProposalType.COMPENSATION_REQUEST ? 8 : 6; + rowSpan = hasAddedFields ? 8 : 6; } else { - rowSpan = proposalType == ProposalType.COMPENSATION_REQUEST ? 5 : 4; + rowSpan = hasAddedFields ? 5 : 4; } addTitledGroupBg(gridPane, gridRow, rowSpan, title, top); @@ -117,7 +129,8 @@ public void createAllFields(String title, int gridRowStartIndex, double top, Pro titleTextField = addLabelInputTextField(gridPane, ++gridRow, Res.getWithCol("dao.proposal.title")).second; - descriptionTextArea = addLabelTextArea(gridPane, ++gridRow, Res.get("dao.proposal.display.description"), Res.get("dao.proposal.display.description.prompt", maxLengthDescriptionText)).second; + descriptionTextArea = addLabelTextArea(gridPane, ++gridRow, Res.get("dao.proposal.display.description"), + Res.get("dao.proposal.display.description.prompt", maxLengthDescriptionText)).second; descriptionTextArea.setMaxHeight(42); // for 2 lines descriptionTextArea.setMinHeight(descriptionTextArea.getMaxHeight()); if (isMakeProposalScreen) @@ -129,23 +142,44 @@ public void createAllFields(String title, int gridRowStartIndex, double top, Pro linkHyperlinkWithIcon.setManaged(false); linkInputTextField.setPromptText(Res.get("dao.proposal.display.link.prompt")); - if (proposalType == ProposalType.COMPENSATION_REQUEST) { - requestedBsqTextField = addLabelInputTextField(gridPane, ++gridRow, Res.get("dao.proposal.display.requestedBsq")).second; - - if (feeService != null) { - BsqValidator bsqValidator = new BsqValidator(bsqFormatter); - //TODO should we use the BSQ or a BTC validator? Technically it is BTC at that stage... - //bsqValidator.setMinValue(feeService.getCreateCompensationRequestFee()); - bsqValidator.setMinValue(CompensationConsensus.getMinCompensationRequestAmount()); - Objects.requireNonNull(requestedBsqTextField).setValidator(bsqValidator); - } - // TODO validator, addressTF - if (showDetails) { - bsqAddressTextField = addLabelInputTextField(gridPane, ++gridRow, - Res.get("dao.proposal.display.bsqAddress")).second; - Objects.requireNonNull(bsqAddressTextField).setText("B" + bsqWalletService.getUnusedAddress().toBase58()); - bsqAddressTextField.setValidator(new BsqAddressValidator(bsqFormatter)); - } + switch (proposalType) { + case COMPENSATION_REQUEST: + requestedBsqTextField = addLabelInputTextField(gridPane, ++gridRow, Res.get("dao.proposal.display.requestedBsq")).second; + if (feeService != null) { + BsqValidator bsqValidator = new BsqValidator(bsqFormatter); + //TODO should we use the BSQ or a BTC validator? Technically it is BTC at that stage... + //bsqValidator.setMinValue(feeService.getCreateCompensationRequestFee()); + bsqValidator.setMinValue(CompensationConsensus.getMinCompensationRequestAmount()); + requestedBsqTextField.setValidator(bsqValidator); + } + // TODO validator, addressTF + if (showDetails) { + bsqAddressTextField = addLabelInputTextField(gridPane, ++gridRow, + Res.get("dao.proposal.display.bsqAddress")).second; + bsqAddressTextField.setText("B" + bsqWalletService.getUnusedAddress().toBase58()); + bsqAddressTextField.setValidator(new BsqAddressValidator(bsqFormatter)); + } + break; + case GENERIC: + break; + case CHANGE_PARAM: + paramComboBox = addLabelComboBox(gridPane, ++gridRow, Res.get("dao.proposal.display.paramComboBox.label")).second; + paramComboBox.setItems(FXCollections.observableArrayList(Param.values())); + paramComboBox.setConverter(new StringConverter() { + @Override + public String toString(Param param) { + return param.name(); + } + + @Override + public Param fromString(String string) { + return null; + } + }); + paramValueTextField = addLabelInputTextField(gridPane, ++gridRow, Res.get("dao.proposal.display.paramValue")).second; + break; + case REMOVE_ALTCOIN: + break; } if (!isMakeProposalScreen && showDetails) @@ -167,9 +201,13 @@ public void applyProposalPayload(Proposal proposal) { linkHyperlinkWithIcon.setOnAction(e -> GUIUtil.openWebPage(proposal.getLink())); if (proposal instanceof CompensationProposal) { CompensationProposal compensationProposal = (CompensationProposal) proposal; - Objects.requireNonNull(requestedBsqTextField).setText(bsqFormatter.formatCoinWithCode(compensationProposal.getRequestedBsq())); + requestedBsqTextField.setText(bsqFormatter.formatCoinWithCode(compensationProposal.getRequestedBsq())); if (bsqAddressTextField != null) bsqAddressTextField.setText(compensationProposal.getBsqAddress()); + } else if (proposal instanceof ParamProposal) { + ParamProposal paramProposal = (ParamProposal) proposal; + paramComboBox.getSelectionModel().select(paramProposal.getParam()); + paramValueTextField.setText(String.valueOf(paramProposal.getParamValue())); } if (txIdTextField != null) txIdTextField.setup(proposal.getTxId()); @@ -184,6 +222,8 @@ public void clearForm() { if (linkHyperlinkWithIcon != null) linkHyperlinkWithIcon.clear(); if (requestedBsqTextField != null) requestedBsqTextField.clear(); if (bsqAddressTextField != null) bsqAddressTextField.clear(); + if (paramComboBox != null) paramComboBox.getSelectionModel().clearSelection(); + if (paramValueTextField != null) paramValueTextField.clear(); if (txIdTextField != null) txIdTextField.cleanup(); if (descriptionTextArea != null) descriptionTextArea.textProperty().removeListener(descriptionTextAreaListener); } @@ -198,6 +238,11 @@ public void fillWithMock() { requestedBsqTextField.setText("14000"); if (bsqAddressTextField != null) bsqAddressTextField.setText("B" + bsqWalletService.getUnusedAddress().toBase58()); + + if (paramComboBox != null) + paramComboBox.getSelectionModel().select(8); // PROPOSAL_FEE + if (paramValueTextField != null) + paramValueTextField.setText("333"); } public void setEditable(boolean isEditable) { @@ -210,6 +255,11 @@ public void setEditable(boolean isEditable) { if (bsqAddressTextField != null) bsqAddressTextField.setEditable(isEditable); + if (paramComboBox != null) + paramComboBox.setEditable(isEditable); + if (paramValueTextField != null) + paramValueTextField.setEditable(isEditable); + linkInputTextField.setVisible(true); linkInputTextField.setManaged(true); linkHyperlinkWithIcon.setVisible(false); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index fbd8462beb6..be9ad2eafbe 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -37,6 +37,7 @@ import bisq.core.dao.voting.proposal.ProposalConsensus; import bisq.core.dao.voting.proposal.ProposalType; import bisq.core.dao.voting.proposal.ProposalWithTransaction; +import bisq.core.dao.voting.proposal.param.Param; import bisq.core.locale.Res; import bisq.core.provider.fee.FeeService; import bisq.core.util.BSFormatter; @@ -63,12 +64,12 @@ import java.io.IOException; import java.util.Arrays; -import java.util.Objects; import static bisq.desktop.util.FormBuilder.addButtonAfterGroup; import static bisq.desktop.util.FormBuilder.addLabelComboBox; import static bisq.desktop.util.FormBuilder.addTitledGroupBg; import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; @FxmlView public class MakeProposalView extends ActivatableView implements ChainHeightListener { @@ -218,12 +219,16 @@ private ProposalWithTransaction getProposalWithTransaction(ProposalType type) switch (type) { case COMPENSATION_REQUEST: + checkNotNull(proposalDisplay.requestedBsqTextField, + "proposalDisplay.requestedBsqTextField must not be null"); + checkNotNull(proposalDisplay.bsqAddressTextField, + "proposalDisplay.bsqAddressTextField must not be null"); return daoFacade.getCompensationProposalWithTransaction(proposalDisplay.nameTextField.getText(), proposalDisplay.titleTextField.getText(), proposalDisplay.descriptionTextArea.getText(), proposalDisplay.linkInputTextField.getText(), - bsqFormatter.parseToCoin(Objects.requireNonNull(proposalDisplay.requestedBsqTextField).getText()), - Objects.requireNonNull(proposalDisplay.bsqAddressTextField).getText()); + bsqFormatter.parseToCoin(proposalDisplay.requestedBsqTextField.getText()), + proposalDisplay.bsqAddressTextField.getText()); case GENERIC: //TODO throw new RuntimeException("Not implemented yet"); @@ -234,8 +239,26 @@ private ProposalWithTransaction getProposalWithTransaction(ProposalType type) proposalDisplay.descriptionTextArea.getText(), proposalDisplay.linkInputTextField.getText());*/ case CHANGE_PARAM: - //TODO - throw new RuntimeException("Not implemented yet"); + Param selectedParam = proposalDisplay.paramComboBox.getSelectionModel().getSelectedItem(); + if (selectedParam == null) + throw new ValidationException("selectedParam is null"); + String paramValueAsString = proposalDisplay.paramValueTextField.getText(); + if (paramValueAsString == null || paramValueAsString.isEmpty()) + throw new ValidationException("paramValue is null or empty"); + long paramValue; + try { + paramValue = Long.valueOf(paramValueAsString); + } catch (Throwable t) { + throw new ValidationException("paramValue is not a long value", t); + } + //TODO add more custom param validation + + return daoFacade.getParamProposalWithTransaction(proposalDisplay.nameTextField.getText(), + proposalDisplay.titleTextField.getText(), + proposalDisplay.descriptionTextArea.getText(), + proposalDisplay.linkInputTextField.getText(), + selectedParam, + paramValue); case REMOVE_ALTCOIN: //TODO throw new RuntimeException("Not implemented yet"); From 0f1a23a651da09e29869b4ae06824cccdca50744 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Mon, 9 Jul 2018 22:15:57 +0200 Subject: [PATCH 124/197] Rename --- .../desktop/main/dao/proposal/ProposalDisplay.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java index 84dc41247a6..f88b2a30f46 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java @@ -32,8 +32,8 @@ import bisq.core.dao.voting.proposal.ProposalType; import bisq.core.dao.voting.proposal.compensation.CompensationConsensus; import bisq.core.dao.voting.proposal.compensation.CompensationProposal; +import bisq.core.dao.voting.proposal.param.ChangeParamProposal; import bisq.core.dao.voting.proposal.param.Param; -import bisq.core.dao.voting.proposal.param.ParamProposal; import bisq.core.locale.Res; import bisq.core.provider.fee.FeeService; import bisq.core.util.BsqFormatter; @@ -204,10 +204,10 @@ public void applyProposalPayload(Proposal proposal) { requestedBsqTextField.setText(bsqFormatter.formatCoinWithCode(compensationProposal.getRequestedBsq())); if (bsqAddressTextField != null) bsqAddressTextField.setText(compensationProposal.getBsqAddress()); - } else if (proposal instanceof ParamProposal) { - ParamProposal paramProposal = (ParamProposal) proposal; - paramComboBox.getSelectionModel().select(paramProposal.getParam()); - paramValueTextField.setText(String.valueOf(paramProposal.getParamValue())); + } else if (proposal instanceof ChangeParamProposal) { + ChangeParamProposal changeParamProposal = (ChangeParamProposal) proposal; + paramComboBox.getSelectionModel().select(changeParamProposal.getParam()); + paramValueTextField.setText(String.valueOf(changeParamProposal.getParamValue())); } if (txIdTextField != null) txIdTextField.setup(proposal.getTxId()); From 70d37d31aed82aa105ad11328aed018a8642fdd6 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Tue, 10 Jul 2018 01:23:39 +0200 Subject: [PATCH 125/197] Change param map in state --- .../desktop/main/dao/proposal/ProposalDisplay.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java index f88b2a30f46..7dab772d419 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java @@ -107,13 +107,17 @@ public void createAllFields(String title, int gridRowStartIndex, double top, Pro boolean hasAddedFields = proposalType == ProposalType.COMPENSATION_REQUEST || proposalType == ProposalType.CHANGE_PARAM; - ; if (isMakeProposalScreen) { rowSpan = hasAddedFields ? 7 : 5; } else if (showDetails) { rowSpan = hasAddedFields ? 8 : 6; } else { - rowSpan = hasAddedFields ? 5 : 4; + if (proposalType == ProposalType.COMPENSATION_REQUEST) + rowSpan = 5; + else if (proposalType == ProposalType.CHANGE_PARAM) + rowSpan = 6; + else + rowSpan = 4; } addTitledGroupBg(gridPane, gridRow, rowSpan, title, top); @@ -256,7 +260,7 @@ public void setEditable(boolean isEditable) { bsqAddressTextField.setEditable(isEditable); if (paramComboBox != null) - paramComboBox.setEditable(isEditable); + paramComboBox.setDisable(!isEditable); if (paramValueTextField != null) paramValueTextField.setEditable(isEditable); From e0ed19cf1c3b995e2593b750fd5c9fed9103c692 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Tue, 10 Jul 2018 01:46:35 +0200 Subject: [PATCH 126/197] Move Param class --- .../bisq/desktop/main/dao/bonding/lockup/LockupBSQView.java | 2 +- .../java/bisq/desktop/main/dao/proposal/ProposalDisplay.java | 2 +- .../bisq/desktop/main/dao/proposal/make/MakeProposalView.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupBSQView.java b/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupBSQView.java index dc22e4e61a1..73dba3769f7 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupBSQView.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupBSQView.java @@ -35,7 +35,7 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.WalletsSetup; import bisq.core.dao.DaoFacade; -import bisq.core.dao.voting.proposal.param.Param; +import bisq.core.dao.state.ext.Param; import bisq.core.locale.Res; import bisq.core.util.BsqFormatter; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java index 7dab772d419..5b94cd124e9 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java @@ -27,13 +27,13 @@ import bisq.desktop.util.validation.BsqValidator; import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.dao.state.ext.Param; import bisq.core.dao.voting.proposal.Proposal; import bisq.core.dao.voting.proposal.ProposalConsensus; import bisq.core.dao.voting.proposal.ProposalType; import bisq.core.dao.voting.proposal.compensation.CompensationConsensus; import bisq.core.dao.voting.proposal.compensation.CompensationProposal; import bisq.core.dao.voting.proposal.param.ChangeParamProposal; -import bisq.core.dao.voting.proposal.param.Param; import bisq.core.locale.Res; import bisq.core.provider.fee.FeeService; import bisq.core.util.BsqFormatter; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index be9ad2eafbe..ea17468e479 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -31,13 +31,13 @@ import bisq.core.btc.wallet.WalletsSetup; import bisq.core.dao.DaoFacade; import bisq.core.dao.state.ChainHeightListener; +import bisq.core.dao.state.ext.Param; import bisq.core.dao.state.period.DaoPhase; import bisq.core.dao.voting.ValidationException; import bisq.core.dao.voting.proposal.Proposal; import bisq.core.dao.voting.proposal.ProposalConsensus; import bisq.core.dao.voting.proposal.ProposalType; import bisq.core.dao.voting.proposal.ProposalWithTransaction; -import bisq.core.dao.voting.proposal.param.Param; import bisq.core.locale.Res; import bisq.core.provider.fee.FeeService; import bisq.core.util.BSFormatter; From 41ad79345480f9a6de892b56532a5faa7d9af0dc Mon Sep 17 00:00:00 2001 From: sqrrm Date: Wed, 11 Jul 2018 14:43:05 +0200 Subject: [PATCH 127/197] Exclude spending of locked BSQ in pending balance --- .../desktop/main/dao/bonding/unlock/LockedBsqTxListItem.java | 2 +- .../bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedBsqTxListItem.java b/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedBsqTxListItem.java index 67ce3f24e3f..15cd19d3ad1 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedBsqTxListItem.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedBsqTxListItem.java @@ -133,7 +133,7 @@ public void cleanup() { } public boolean isSpent() { - Optional optionalTxOutput = stateService.getLockedTxOutput(txId); + Optional optionalTxOutput = stateService.getLockupTxOutput(txId); if (!optionalTxOutput.isPresent()) return true; diff --git a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java index 76b392c65da..93b9ac7d15d 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java @@ -315,7 +315,7 @@ public void updateItem(final LockedBsqTxListItem item, boolean empty) { private void onButtonClick() { if (GUIUtil.isReadyForTxBroadcast(p2PService, walletsSetup)) { - Optional lockedTxOutput = stateService.getLockedTxOutput(selectedItem.getTxId()); + Optional lockedTxOutput = stateService.getLockupTxOutput(selectedItem.getTxId()); if (!lockedTxOutput.isPresent()) { log.warn("Locked output not found, txId = ", selectedItem.getTxId()); return; From 2d264b0db21393dca573277c6325dd59ffa63efb Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Thu, 12 Jul 2018 09:27:26 +0200 Subject: [PATCH 128/197] Add BSQ emergency wallet tool and show BTC balance --- src/main/java/bisq/desktop/app/BisqApp.java | 21 ++-- .../overlays/windows/EmptyWalletWindow.java | 108 ++++++++++++------ 2 files changed, 85 insertions(+), 44 deletions(-) diff --git a/src/main/java/bisq/desktop/app/BisqApp.java b/src/main/java/bisq/desktop/app/BisqApp.java index 3eca300e7df..f1380916155 100644 --- a/src/main/java/bisq/desktop/app/BisqApp.java +++ b/src/main/java/bisq/desktop/app/BisqApp.java @@ -34,9 +34,7 @@ import bisq.core.alert.AlertManager; import bisq.core.app.AppOptionKeys; -import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; -import bisq.core.btc.wallet.WalletService; import bisq.core.btc.wallet.WalletsManager; import bisq.core.filter.FilterManager; import bisq.core.locale.Res; @@ -249,7 +247,9 @@ private void addSceneKeyEventHandler(Scene scene, Injector injector) { stop(); } else { if (Utilities.isAltOrCtrlPressed(KeyCode.E, keyEvent)) { - showEmptyWalletPopup(injector.getInstance(BtcWalletService.class), injector); + showBtcEmergencyWalletPopup(injector); + } else if (Utilities.isAltOrCtrlPressed(KeyCode.B, keyEvent)) { + showBsqEmergencyWalletPopup(injector); } else if (Utilities.isAltOrCtrlPressed(KeyCode.M, keyEvent)) { showSendAlertMessagePopup(injector); } else if (Utilities.isAltOrCtrlPressed(KeyCode.F, keyEvent)) { @@ -267,10 +267,7 @@ private void addSceneKeyEventHandler(Scene scene, Injector injector) { new Popup<>().warning(Res.get("popup.warning.walletNotInitialized")).show(); } else if (DevEnv.isDevMode()) { // dev ode only - if (Utilities.isAltOrCtrlPressed(KeyCode.B, keyEvent)) { - // BSQ empty wallet not public yet - showEmptyWalletPopup(injector.getInstance(BsqWalletService.class), injector); - } else if (Utilities.isAltOrCtrlPressed(KeyCode.P, keyEvent)) { + if (Utilities.isAltOrCtrlPressed(KeyCode.P, keyEvent)) { showFPSWindow(scene); } else if (Utilities.isAltOrCtrlPressed(KeyCode.Z, keyEvent)) { showDebugWindow(scene, injector); @@ -298,9 +295,15 @@ private void showFilterPopup(Injector injector) { .show(); } - private void showEmptyWalletPopup(WalletService walletService, Injector injector) { + private void showBtcEmergencyWalletPopup(Injector injector) { EmptyWalletWindow emptyWalletWindow = injector.getInstance(EmptyWalletWindow.class); - emptyWalletWindow.setWalletService(walletService); + emptyWalletWindow.setIsBtc(true); + emptyWalletWindow.show(); + } + + private void showBsqEmergencyWalletPopup(Injector injector) { + EmptyWalletWindow emptyWalletWindow = injector.getInstance(EmptyWalletWindow.class); + emptyWalletWindow.setIsBtc(false); emptyWalletWindow.show(); } diff --git a/src/main/java/bisq/desktop/main/overlays/windows/EmptyWalletWindow.java b/src/main/java/bisq/desktop/main/overlays/windows/EmptyWalletWindow.java index a6e5575f2c5..e52921f787b 100644 --- a/src/main/java/bisq/desktop/main/overlays/windows/EmptyWalletWindow.java +++ b/src/main/java/bisq/desktop/main/overlays/windows/EmptyWalletWindow.java @@ -25,16 +25,18 @@ import bisq.desktop.util.Transitions; import bisq.core.btc.Restrictions; +import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.btc.wallet.BtcWalletService; import bisq.core.btc.wallet.WalletService; import bisq.core.btc.wallet.WalletsSetup; import bisq.core.locale.Res; import bisq.core.offer.OpenOfferManager; import bisq.core.util.BSFormatter; +import bisq.core.util.BsqFormatter; import bisq.network.p2p.P2PService; import bisq.common.UserThread; -import bisq.common.util.Tuple2; import org.bitcoinj.core.AddressFormatException; import org.bitcoinj.core.Coin; @@ -44,7 +46,6 @@ import javafx.scene.Scene; import javafx.scene.control.Button; -import javafx.scene.control.Label; import javafx.scene.control.TextField; import javafx.scene.input.KeyCode; import javafx.scene.layout.GridPane; @@ -68,13 +69,16 @@ public class EmptyWalletWindow extends Overlay { private final WalletPasswordWindow walletPasswordWindow; private final P2PService p2PService; private final WalletsSetup walletsSetup; - private final BSFormatter formatter; + private final BtcWalletService btcWalletService; + private final BsqWalletService bsqWalletService; + private final BSFormatter btcFormatter; + private final BsqFormatter bsqFormatter; private final OpenOfferManager openOfferManager; private Button emptyWalletButton; private InputTextField addressInputTextField; private TextField balanceTextField; - private WalletService walletService; + private boolean isBtc; /////////////////////////////////////////////////////////////////////////////////////////// @@ -86,19 +90,25 @@ public EmptyWalletWindow(WalletPasswordWindow walletPasswordWindow, OpenOfferManager openOfferManager, P2PService p2PService, WalletsSetup walletsSetup, - BSFormatter formatter) { + BtcWalletService btcWalletService, + BsqWalletService bsqWalletService, + BSFormatter btcFormatter, + BsqFormatter bsqFormatter) { this.walletPasswordWindow = walletPasswordWindow; this.openOfferManager = openOfferManager; this.p2PService = p2PService; this.walletsSetup = walletsSetup; - this.formatter = formatter; + this.btcWalletService = btcWalletService; + this.bsqWalletService = bsqWalletService; + this.btcFormatter = btcFormatter; + this.bsqFormatter = bsqFormatter; type = Type.Instruction; } public void show() { if (headLine == null) - headLine = Res.get("emptyWalletWindow.headline"); + headLine = Res.get("emptyWalletWindow.headline", getCurrency()); width = 700; createGridPane(); @@ -109,6 +119,10 @@ public void show() { display(); } + private String getCurrency() { + return isBtc ? "BTC" : "BSQ"; + } + /////////////////////////////////////////////////////////////////////////////////////////// // Protected @@ -126,44 +140,64 @@ protected void setupKeyHandler(Scene scene) { } } + public void setIsBtc(boolean isBtc) { + this.isBtc = isBtc; + } + private void addContent() { - addMultilineLabel(gridPane, ++rowIndex, Res.get("emptyWalletWindow.info"), 10); + if (isBtc) + addMultilineLabel(gridPane, ++rowIndex, Res.get("emptyWalletWindow.info"), 10); - Coin totalBalance = walletService.getAvailableBalance(); + Coin totalBalance = getWalletService().getAvailableBalance(); balanceTextField = addLabelTextField(gridPane, ++rowIndex, Res.get("emptyWalletWindow.balance"), - formatter.formatCoinWithCode(totalBalance), 10).second; - - Tuple2 tuple = addLabelInputTextField(gridPane, ++rowIndex, Res.get("emptyWalletWindow.address")); - addressInputTextField = tuple.second; - emptyWalletButton = new AutoTooltipButton(Res.get("emptyWalletWindow.button")); - boolean isBalanceSufficient = Restrictions.isAboveDust(totalBalance); - emptyWalletButton.setDefaultButton(isBalanceSufficient); - emptyWalletButton.setDisable(!isBalanceSufficient && addressInputTextField.getText().length() > 0); - emptyWalletButton.setOnAction(e -> { - if (addressInputTextField.getText().length() > 0 && isBalanceSufficient) { - if (walletService.isEncrypted()) { - walletPasswordWindow - .onAesKey(this::doEmptyWallet) - .onClose(this::blurAgain) - .show(); - } else { - doEmptyWallet(null); - } - } - }); + getFormatter().formatCoinWithCode(totalBalance), 10).second; + if (isBtc) { + addressInputTextField = addLabelInputTextField(gridPane, ++rowIndex, Res.get("emptyWalletWindow.address")).second; + } else { + addLabelTextField(gridPane, ++rowIndex, Res.get("emptyWalletWindow.bsq.btcBalance"), + bsqWalletService.getBtcBalance().value + " Satoshi", 10); + } closeButton = new AutoTooltipButton(Res.get("shared.cancel")); closeButton.setOnAction(e -> { hide(); closeHandlerOptional.ifPresent(Runnable::run); }); - closeButton.setDefaultButton(!isBalanceSufficient); + + if (isBtc) { + emptyWalletButton = new AutoTooltipButton(Res.get("emptyWalletWindow.button")); + boolean isBalanceSufficient = Restrictions.isAboveDust(totalBalance); + emptyWalletButton.setDefaultButton(isBalanceSufficient); + emptyWalletButton.setDisable(!isBalanceSufficient && addressInputTextField.getText().length() > 0); + emptyWalletButton.setOnAction(e -> { + if (addressInputTextField.getText().length() > 0 && isBalanceSufficient) { + if (getWalletService().isEncrypted()) { + walletPasswordWindow + .onAesKey(this::doEmptyWallet) + .onClose(this::blurAgain) + .show(); + } else { + doEmptyWallet(null); + } + } + }); + + closeButton.setDefaultButton(!isBalanceSufficient); + } else { + closeButton.setDefaultButton(true); + closeButton.setText(Res.get("shared.close")); + } HBox hBox = new HBox(); hBox.setSpacing(10); GridPane.setRowIndex(hBox, ++rowIndex); GridPane.setColumnIndex(hBox, 1); - hBox.getChildren().addAll(emptyWalletButton, closeButton); + + if (isBtc) + hBox.getChildren().addAll(emptyWalletButton, closeButton); + else + hBox.getChildren().addAll(closeButton); + gridPane.getChildren().add(hBox); GridPane.setMargin(hBox, new Insets(10, 0, 0, 0)); } @@ -188,11 +222,11 @@ private void doEmptyWallet2(KeyParameter aesKey) { emptyWalletButton.setDisable(true); openOfferManager.removeAllOpenOffers(() -> { try { - walletService.emptyWallet(addressInputTextField.getText(), + getWalletService().emptyWallet(addressInputTextField.getText(), aesKey, () -> { closeButton.setText(Res.get("shared.close")); - balanceTextField.setText(formatter.formatCoinWithCode(walletService.getAvailableBalance())); + balanceTextField.setText(getFormatter().formatCoinWithCode(getWalletService().getAvailableBalance())); emptyWalletButton.setDisable(true); log.debug("wallet empty successful"); onClose(() -> UserThread.runAfter(() -> new Popup<>() @@ -212,7 +246,11 @@ private void doEmptyWallet2(KeyParameter aesKey) { }); } - public void setWalletService(WalletService walletService) { - this.walletService = walletService; + private WalletService getWalletService() { + return isBtc ? btcWalletService : bsqWalletService; + } + + private BSFormatter getFormatter() { + return isBtc ? btcFormatter : bsqFormatter; } } From 84173fd106f4b1b2f5a84171fcdf2592fde12d18 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Thu, 12 Jul 2018 09:44:25 +0200 Subject: [PATCH 129/197] Add display of non-BSQ satoshi --- .../dao/bonding/lockup/LockupBSQView.java | 15 +++++-- .../dao/bonding/unlock/UnlockBSQView.java | 8 +++- .../dao/voting/active/ActiveBallotsView.java | 2 + .../main/dao/wallet/BsqBalanceUtil.java | 41 ++++++++----------- .../main/dao/wallet/send/BsqSendView.java | 21 ++++++---- .../desktop/main/dao/wallet/tx/BsqTxView.java | 1 + .../main/offer/MutableOfferDataModel.java | 5 ++- .../overlays/windows/EmptyWalletWindow.java | 2 +- 8 files changed, 56 insertions(+), 39 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupBSQView.java b/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupBSQView.java index 73dba3769f7..afe58fbdfce 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupBSQView.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupBSQView.java @@ -115,8 +115,11 @@ public void initialize() { focusOutListener = (observable, oldValue, newValue) -> { if (!newValue) - onUpdateBalances(bsqWalletService.getAvailableBalance(), bsqWalletService.getPendingBalance(), - bsqWalletService.getLockedForVotingBalance(), bsqWalletService.getLockedInBondsBalance(), + onUpdateBalances(bsqWalletService.getAvailableBalance(), + bsqWalletService.getAvailableNonBsqBalance(), + bsqWalletService.getPendingBalance(), + bsqWalletService.getLockedForVotingBalance(), + bsqWalletService.getLockedInBondsBalance(), bsqWalletService.getUnlockingBondsBalance()); }; @@ -171,8 +174,11 @@ protected void activate() { bsqBalanceUtil.activate(); amountInputTextField.focusedProperty().addListener(focusOutListener); bsqWalletService.addBsqBalanceListener(this); - onUpdateBalances(bsqWalletService.getAvailableBalance(), bsqWalletService.getPendingBalance(), - bsqWalletService.getLockedForVotingBalance(), bsqWalletService.getLockedInBondsBalance(), + onUpdateBalances(bsqWalletService.getAvailableBalance(), + bsqWalletService.getAvailableNonBsqBalance(), + bsqWalletService.getPendingBalance(), + bsqWalletService.getLockedForVotingBalance(), + bsqWalletService.getLockedInBondsBalance(), bsqWalletService.getUnlockingBondsBalance()); } @@ -185,6 +191,7 @@ protected void deactivate() { @Override public void onUpdateBalances(Coin confirmedBalance, + Coin availableNonBsqBalance, Coin pendingBalance, Coin lockedForVotingBalance, Coin lockedInBondsBalance, diff --git a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java index 93b9ac7d15d..1f2b3259057 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java @@ -373,8 +373,11 @@ private void openTxInBlockExplorer(LockedBsqTxListItem item) { protected void activate() { bsqBalanceUtil.activate(); bsqWalletService.addBsqBalanceListener(this); - onUpdateBalances(bsqWalletService.getAvailableBalance(), bsqWalletService.getPendingBalance(), - bsqWalletService.getLockedForVotingBalance(), bsqWalletService.getLockedInBondsBalance(), + onUpdateBalances(bsqWalletService.getAvailableBalance(), + bsqWalletService.getAvailableNonBsqBalance(), + bsqWalletService.getPendingBalance(), + bsqWalletService.getLockedForVotingBalance(), + bsqWalletService.getLockedInBondsBalance(), bsqWalletService.getUnlockingBondsBalance()); bsqWalletService.getWalletTransactions().addListener(walletBsqTransactionsListener); @@ -451,6 +454,7 @@ protected void deactivate() { @Override public void onUpdateBalances(Coin confirmedBalance, + Coin availableNonBsqBalance, Coin pendingBalance, Coin lockedForVotingBalance, Coin lockedInBondsBalance, diff --git a/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.java b/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.java index f99bbf44006..05f76f7da24 100644 --- a/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.java +++ b/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.java @@ -112,6 +112,7 @@ protected void activate() { daoFacade.getActiveOrMyUnconfirmedBallots().addListener(listChangeListener); onUpdateBalances(bsqWalletService.getAvailableBalance(), + bsqWalletService.getAvailableNonBsqBalance(), bsqWalletService.getPendingBalance(), bsqWalletService.getLockedForVotingBalance(), bsqWalletService.getLockedInBondsBalance(), @@ -140,6 +141,7 @@ protected void deactivate() { @Override public void onUpdateBalances(Coin confirmedBalance, + Coin availableNonBsqBalance, Coin pendingBalance, Coin lockedForVotingBalance, Coin lockedInBondsBalance, diff --git a/src/main/java/bisq/desktop/main/dao/wallet/BsqBalanceUtil.java b/src/main/java/bisq/desktop/main/dao/wallet/BsqBalanceUtil.java index fd64178482c..d2f536f57cb 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/BsqBalanceUtil.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/BsqBalanceUtil.java @@ -33,7 +33,6 @@ import javafx.geometry.Pos; -import lombok.Getter; import lombok.extern.slf4j.Slf4j; import static bisq.desktop.util.FormBuilder.addLabelTextField; @@ -45,7 +44,7 @@ public class BsqBalanceUtil implements BsqBalanceListener { private final BsqFormatter bsqFormatter; // Displaying general BSQ info - private TextField confirmedBalanceTextField, pendingBalanceTextField, lockedForVoteBalanceTextField, + private TextField availableBalanceTextField, availableNonBsqBalanceTextField, unverifiedBalanceTextField, lockedForVoteBalanceTextField, lockedInBondsBalanceTextField, totalBalanceTextField; // Displaying bond dashboard info @@ -59,36 +58,29 @@ private BsqBalanceUtil(BsqWalletService bsqWalletService, } public int addGroup(GridPane gridPane, int gridRow) { - addTitledGroupBg(gridPane, gridRow, 5, Res.get("shared.balance")); - confirmedBalanceTextField = addLabelTextField(gridPane, gridRow, Res.getWithCol("shared.availableBsqBalance"), + addTitledGroupBg(gridPane, gridRow, 6, Res.get("shared.balance")); + availableBalanceTextField = addLabelTextField(gridPane, gridRow, Res.getWithCol("shared.availableBsqBalance"), Layout.FIRST_ROW_DISTANCE).second; - confirmedBalanceTextField.setMouseTransparent(false); - confirmedBalanceTextField.setMaxWidth(150); - confirmedBalanceTextField.setAlignment(Pos.CENTER_RIGHT); + availableBalanceTextField.setMouseTransparent(false); - pendingBalanceTextField = addLabelTextField(gridPane, ++gridRow, Res.getWithCol("shared.unverifiedBsqBalance")).second; - pendingBalanceTextField.setMouseTransparent(false); - pendingBalanceTextField.setMaxWidth(confirmedBalanceTextField.getMaxWidth()); - pendingBalanceTextField.setAlignment(Pos.CENTER_RIGHT); + availableNonBsqBalanceTextField = addLabelTextField(gridPane, ++gridRow, Res.getWithCol("shared.availableNonBsqBalance")).second; + availableNonBsqBalanceTextField.setMouseTransparent(false); + + unverifiedBalanceTextField = addLabelTextField(gridPane, ++gridRow, Res.getWithCol("shared.unverifiedBsqBalance")).second; + unverifiedBalanceTextField.setMouseTransparent(false); lockedForVoteBalanceTextField = addLabelTextField(gridPane, ++gridRow, Res.getWithCol("shared" + ".lockedForVoteBalance")).second; lockedForVoteBalanceTextField.setMouseTransparent(false); - lockedForVoteBalanceTextField.setMaxWidth(confirmedBalanceTextField.getMaxWidth()); - lockedForVoteBalanceTextField.setAlignment(Pos.CENTER_RIGHT); lockedInBondsBalanceTextField = addLabelTextField(gridPane, ++gridRow, Res.getWithCol( "shared.lockedInBonds")).second; lockedInBondsBalanceTextField.setMouseTransparent(false); - lockedInBondsBalanceTextField.setMaxWidth(confirmedBalanceTextField.getMaxWidth()); - lockedInBondsBalanceTextField.setAlignment(Pos.CENTER_RIGHT); // TODO add unlockinBondsBalanceTextField totalBalanceTextField = addLabelTextField(gridPane, ++gridRow, Res.getWithCol("shared.totalBsqBalance")).second; totalBalanceTextField.setMouseTransparent(false); - totalBalanceTextField.setMaxWidth(confirmedBalanceTextField.getMaxWidth()); - totalBalanceTextField.setAlignment(Pos.CENTER_RIGHT); return gridRow; } @@ -112,6 +104,7 @@ public int addBondBalanceGroup(GridPane gridPane, int gridRow) { public void activate() { onUpdateBalances(bsqWalletService.getAvailableBalance(), + bsqWalletService.getAvailableNonBsqBalance(), bsqWalletService.getPendingBalance(), bsqWalletService.getLockedForVotingBalance(), bsqWalletService.getLockedInBondsBalance(), @@ -125,13 +118,15 @@ public void deactivate() { @Override - public void onUpdateBalances(Coin confirmedBalance, - Coin pendingBalance, + public void onUpdateBalances(Coin availableBalance, + Coin availableNonBsqBalance, + Coin unverifiedBalance, Coin lockedForVotingBalance, Coin lockedInBondsBalance, Coin unlockingBondsBalance) { - confirmedBalanceTextField.setText(bsqFormatter.formatCoinWithCode(confirmedBalance)); - pendingBalanceTextField.setText(bsqFormatter.formatCoinWithCode(pendingBalance)); + availableBalanceTextField.setText(bsqFormatter.formatCoinWithCode(availableBalance)); + availableNonBsqBalanceTextField.setText(bsqFormatter.formatSatoshi(availableNonBsqBalance.value)); + unverifiedBalanceTextField.setText(bsqFormatter.formatCoinWithCode(unverifiedBalance)); lockedForVoteBalanceTextField.setText(bsqFormatter.formatCoinWithCode(lockedForVotingBalance)); lockedInBondsBalanceTextField.setText(bsqFormatter.formatCoinWithCode( lockedInBondsBalance.add(unlockingBondsBalance))); @@ -141,8 +136,8 @@ public void onUpdateBalances(Coin confirmedBalance, unlockingAmountTextField.setText(bsqFormatter.formatCoinWithCode(unlockingBondsBalance)); } - final Coin total = confirmedBalance - .add(pendingBalance) + final Coin total = availableBalance + .add(unverifiedBalance) .add(lockedForVotingBalance) .add(lockedInBondsBalance) .add(unlockingBondsBalance); diff --git a/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java b/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java index 24ef771b1ef..31252a84787 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java @@ -130,8 +130,11 @@ public void initialize() { focusOutListener = (observable, oldValue, newValue) -> { if (!newValue) - onUpdateBalances(bsqWalletService.getAvailableBalance(), bsqWalletService.getPendingBalance(), - bsqWalletService.getLockedForVotingBalance(), bsqWalletService.getLockedInBondsBalance(), + onUpdateBalances(bsqWalletService.getAvailableBalance(), + bsqWalletService.getAvailableNonBsqBalance(), + bsqWalletService.getPendingBalance(), + bsqWalletService.getLockedForVotingBalance(), + bsqWalletService.getLockedInBondsBalance(), bsqWalletService.getUnlockingBondsBalance()); }; @@ -215,8 +218,11 @@ protected void activate() { receiversAddressInputTextField.focusedProperty().addListener(focusOutListener); amountInputTextField.focusedProperty().addListener(focusOutListener); bsqWalletService.addBsqBalanceListener(this); - onUpdateBalances(bsqWalletService.getAvailableBalance(), bsqWalletService.getPendingBalance(), - bsqWalletService.getLockedForVotingBalance(), bsqWalletService.getLockedInBondsBalance(), + onUpdateBalances(bsqWalletService.getAvailableBalance(), + bsqWalletService.getAvailableNonBsqBalance(), + bsqWalletService.getPendingBalance(), + bsqWalletService.getLockedForVotingBalance(), + bsqWalletService.getLockedInBondsBalance(), bsqWalletService.getUnlockingBondsBalance()); } @@ -229,12 +235,13 @@ protected void deactivate() { } @Override - public void onUpdateBalances(Coin confirmedBalance, - Coin pendingBalance, + public void onUpdateBalances(Coin availableBalance, + Coin availableNonBsqBalance, + Coin unverifiedBalance, Coin lockedForVotingBalance, Coin lockedInBondsBalance, Coin unlockingBondsBalance) { - bsqValidator.setAvailableBalance(confirmedBalance); + bsqValidator.setAvailableBalance(availableBalance); boolean isValid = bsqAddressValidator.validate(receiversAddressInputTextField.getText()).isValid && bsqValidator.validate(amountInputTextField.getText()).isValid; sendButton.setDisable(!isValid); diff --git a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java index ab1a2f95a85..def9b15b57f 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java @@ -206,6 +206,7 @@ protected void deactivate() { @Override public void onUpdateBalances(Coin confirmedBalance, + Coin availableNonBsqBalance, Coin pendingBalance, Coin lockedForVotingBalance, Coin lockedInBondsBalance, diff --git a/src/main/java/bisq/desktop/main/offer/MutableOfferDataModel.java b/src/main/java/bisq/desktop/main/offer/MutableOfferDataModel.java index 13132854648..fe1e855c3fe 100644 --- a/src/main/java/bisq/desktop/main/offer/MutableOfferDataModel.java +++ b/src/main/java/bisq/desktop/main/offer/MutableOfferDataModel.java @@ -551,8 +551,9 @@ void onCurrencySelected(TradeCurrency tradeCurrency) { } @Override - public void onUpdateBalances(Coin confirmedBalance, - Coin pendingBalance, + public void onUpdateBalances(Coin availableBalance, + Coin availableNonBsqBalance, + Coin unverifiedBalance, Coin lockedForVotingBalance, Coin lockedInBondsBalance, Coin unlockingBondsBalance) { diff --git a/src/main/java/bisq/desktop/main/overlays/windows/EmptyWalletWindow.java b/src/main/java/bisq/desktop/main/overlays/windows/EmptyWalletWindow.java index e52921f787b..06d410dffc7 100644 --- a/src/main/java/bisq/desktop/main/overlays/windows/EmptyWalletWindow.java +++ b/src/main/java/bisq/desktop/main/overlays/windows/EmptyWalletWindow.java @@ -156,7 +156,7 @@ private void addContent() { addressInputTextField = addLabelInputTextField(gridPane, ++rowIndex, Res.get("emptyWalletWindow.address")).second; } else { addLabelTextField(gridPane, ++rowIndex, Res.get("emptyWalletWindow.bsq.btcBalance"), - bsqWalletService.getBtcBalance().value + " Satoshi", 10); + bsqFormatter.formatSatoshi(bsqWalletService.getAvailableNonBsqBalance().value), 10); } closeButton = new AutoTooltipButton(Res.get("shared.cancel")); closeButton.setOnAction(e -> { From cb6de8cad0bdf77b38983c7ef0e97ee9c8cd6dd6 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Thu, 12 Jul 2018 10:08:04 +0200 Subject: [PATCH 130/197] Use scroll pane in all DAO views --- .../account/settings/AccountSettingsView.fxml | 2 +- .../desktop/main/dao/BaseProposalView.java | 1 + .../desktop/main/dao/bonding/BondingView.fxml | 15 ++++-- .../dashboard/BondingDashboardView.fxml | 7 ++- .../dao/bonding/lockup/LockupBSQView.fxml | 6 +-- .../dao/bonding/unlock/UnlockBSQView.fxml | 6 +-- .../dao/bonding/unlock/UnlockBSQView.java | 22 ++------- .../main/dao/proposal/ProposalView.fxml | 16 ++++-- .../proposal/active/ActiveProposalsView.fxml | 6 +-- .../proposal/closed/ClosedProposalsView.fxml | 7 +-- .../dashboard/ProposalDashboardView.fxml | 10 +++- .../dashboard/ProposalDashboardView.java | 49 +++++-------------- .../dao/proposal/make/MakeProposalView.fxml | 8 ++- .../dao/proposal/myvotes/MyVotesView.fxml | 4 +- .../main/dao/proposal/votes/VotesView.fxml | 4 +- .../desktop/main/dao/voting/VotingView.fxml | 16 ++++-- .../dao/voting/active/ActiveBallotsView.fxml | 6 +-- .../dao/voting/closed/ClosedBallotsView.fxml | 7 +-- .../dao/voting/closed/VotingHistoryView.fxml | 4 +- .../voting/dashboard/VotingDashboardView.fxml | 10 +++- .../main/dao/voting/vote/VoteView.fxml | 4 +- .../main/dao/wallet/BsqWalletView.fxml | 16 ++++-- .../wallet/dashboard/BsqDashboardView.fxml | 8 ++- .../dao/wallet/receive/BsqReceiveView.fxml | 5 +- .../main/dao/wallet/send/BsqSendView.fxml | 4 +- .../desktop/main/dao/wallet/tx/BsqTxView.fxml | 9 ++-- .../desktop/main/dao/wallet/tx/BsqTxView.java | 18 ------- 27 files changed, 123 insertions(+), 147 deletions(-) diff --git a/src/main/java/bisq/desktop/main/account/settings/AccountSettingsView.fxml b/src/main/java/bisq/desktop/main/account/settings/AccountSettingsView.fxml index 882c23ba4ea..2e96c1f7c1f 100644 --- a/src/main/java/bisq/desktop/main/account/settings/AccountSettingsView.fxml +++ b/src/main/java/bisq/desktop/main/account/settings/AccountSettingsView.fxml @@ -21,7 +21,7 @@ (); proposalTableView.setPlaceholder(new AutoTooltipLabel(Res.get("table.placeholder.noData"))); proposalTableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); + proposalTableView.setPrefHeight(200); createProposalColumns(proposalTableView); GridPane.setRowIndex(proposalTableView, gridRow); diff --git a/src/main/java/bisq/desktop/main/dao/bonding/BondingView.fxml b/src/main/java/bisq/desktop/main/dao/bonding/BondingView.fxml index 64f72f9e4f8..84b322ce5af 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/BondingView.fxml +++ b/src/main/java/bisq/desktop/main/dao/bonding/BondingView.fxml @@ -17,15 +17,22 @@ ~ along with Bisq. If not, see . --> + - - + + + + + diff --git a/src/main/java/bisq/desktop/main/dao/bonding/dashboard/BondingDashboardView.fxml b/src/main/java/bisq/desktop/main/dao/bonding/dashboard/BondingDashboardView.fxml index aac6faa76a9..48d8c4cd00e 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/dashboard/BondingDashboardView.fxml +++ b/src/main/java/bisq/desktop/main/dao/bonding/dashboard/BondingDashboardView.fxml @@ -18,14 +18,13 @@ --> - + - diff --git a/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupBSQView.fxml b/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupBSQView.fxml index 51175737f57..97e58cfa7c0 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupBSQView.fxml +++ b/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupBSQView.fxml @@ -23,12 +23,12 @@ - + diff --git a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.fxml b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.fxml index 89d177e6a2f..7287a21faea 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.fxml +++ b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.fxml @@ -23,12 +23,12 @@ - + diff --git a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java index 1f2b3259057..f536c472600 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.java @@ -65,9 +65,7 @@ import javafx.geometry.Insets; -import javafx.beans.property.DoubleProperty; import javafx.beans.property.ReadOnlyObjectWrapper; -import javafx.beans.property.SimpleDoubleProperty; import javafx.beans.value.ChangeListener; import javafx.collections.FXCollections; @@ -109,8 +107,7 @@ public class UnlockBSQView extends ActivatableView implements Bs private ListChangeListener walletBsqTransactionsListener; private ChangeListener walletChainHeightListener; - private final DoubleProperty initialOccupiedHeight = new SimpleDoubleProperty(-1); - private ChangeListener parentHeightListener; + /////////////////////////////////////////////////////////////////////////////////////////// // Constructor, lifecycle @@ -148,15 +145,15 @@ public void initialize() { tableView = new TableView<>(); tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); + tableView.setPrefHeight(300); addTxIdColumn(); addAmountColumn(); addLockTimeColumn(); addUnlockColumn(); - lockedTxs.setPredicate(item -> item.isLockedAndUnspent()); + lockedTxs.setPredicate(LockedBsqTxListItem::isLockedAndUnspent); walletBsqTransactionsListener = change -> updateList(); walletChainHeightListener = (observable, oldValue, newValue) -> onUpdateAnyChainHeight(); - parentHeightListener = (observable, oldValue, newValue) -> layout(); VBox vBox = new VBox(); vBox.setSpacing(10); @@ -388,14 +385,8 @@ protected void activate() { daoFacade.addBlockListener(this); - if (root.getParent() instanceof Pane) { - rootParent = (Pane) root.getParent(); - rootParent.heightProperty().addListener(parentHeightListener); - } - updateList(); onUpdateAnyChainHeight(); - layout(); } @Override @@ -431,10 +422,6 @@ private void updateList() { observableList.setAll(items); } - private void layout() { - GUIUtil.fillAvailableHeight(root, tableView, initialOccupiedHeight); - } - @Override protected void deactivate() { bsqBalanceUtil.deactivate(); @@ -447,9 +434,6 @@ protected void deactivate() { daoFacade.removeBlockListener(this); observableList.forEach(LockedBsqTxListItem::cleanup); - - if (rootParent != null) - rootParent.heightProperty().removeListener(parentHeightListener); } @Override diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalView.fxml b/src/main/java/bisq/desktop/main/dao/proposal/ProposalView.fxml index 7209d295000..a4518328f8b 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalView.fxml +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalView.fxml @@ -17,15 +17,21 @@ ~ along with Bisq. If not, see . --> + - - - + + + + + diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.fxml b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.fxml index 1b176157fd1..97c66cdc0bd 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.fxml +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.fxml @@ -22,10 +22,10 @@ - diff --git a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.fxml b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.fxml index 697a94a2517..d59856e8b55 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.fxml +++ b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.fxml @@ -22,11 +22,12 @@ - + diff --git a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.fxml b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.fxml index c40a5b12f62..8dcdc823735 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.fxml +++ b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.fxml @@ -18,9 +18,15 @@ --> + + + + + diff --git a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java index edee3379c97..8c75d779670 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java @@ -33,12 +33,8 @@ import javax.inject.Inject; import javafx.scene.control.TextField; -import javafx.scene.layout.AnchorPane; -import javafx.scene.layout.ColumnConstraints; import javafx.scene.layout.GridPane; -import javafx.scene.layout.Priority; -import javafx.geometry.HPos; import javafx.geometry.Insets; import org.fxmisc.easybind.EasyBind; @@ -63,7 +59,6 @@ public class ProposalDashboardView extends ActivatableView imple private List phaseBarsItems; private DaoPhase.Phase currentPhase; private Subscription phaseSubscription; - private GridPane gridPane; private int gridRow = 0; private SeparatedPhaseBars separatedPhaseBars; private TextField currentPhaseTextField, currentBlockHeightTextField, proposalTextField, blindVoteTextField, voteRevealTextField, voteResultTextField; @@ -81,46 +76,26 @@ public ProposalDashboardView(DaoFacade daoFacade, BSFormatter formatter) { @Override public void initialize() { - root.getStyleClass().add("compensation-root"); - AnchorPane topAnchorPane = new AnchorPane(); - root.getChildren().add(topAnchorPane); - - gridPane = new GridPane(); - gridPane.setHgap(5); - gridPane.setVgap(5); - AnchorPane.setBottomAnchor(gridPane, 10d); - AnchorPane.setRightAnchor(gridPane, 10d); - AnchorPane.setLeftAnchor(gridPane, 10d); - AnchorPane.setTopAnchor(gridPane, 10d); - ColumnConstraints columnConstraints1 = new ColumnConstraints(); - columnConstraints1.setHalignment(HPos.RIGHT); - columnConstraints1.setHgrow(Priority.SOMETIMES); - columnConstraints1.setMinWidth(200); - ColumnConstraints columnConstraints2 = new ColumnConstraints(); - columnConstraints2.setHgrow(Priority.ALWAYS); - gridPane.getColumnConstraints().addAll(columnConstraints1, columnConstraints2); - topAnchorPane.getChildren().add(gridPane); - // cycle bar - addTitledGroupBg(gridPane, gridRow, 1, Res.get("dao.cycle.headline")); + addTitledGroupBg(root, gridRow, 1, Res.get("dao.cycle.headline")); separatedPhaseBars = createSeparatedPhaseBars(); GridPane.setColumnSpan(separatedPhaseBars, 2); GridPane.setColumnIndex(separatedPhaseBars, 0); GridPane.setMargin(separatedPhaseBars, new Insets(Layout.FIRST_ROW_DISTANCE - 6, 0, 0, 0)); GridPane.setRowIndex(separatedPhaseBars, gridRow); - gridPane.getChildren().add(separatedPhaseBars); + root.getChildren().add(separatedPhaseBars); - addTitledGroupBg(gridPane, ++gridRow, 6, Res.get("dao.cycle.overview.headline"), Layout.GROUP_DISTANCE); - currentBlockHeightTextField = addLabelTextField(gridPane, gridRow, Res.get("dao.cycle.currentBlockHeight"), + addTitledGroupBg(root, ++gridRow, 6, Res.get("dao.cycle.overview.headline"), Layout.GROUP_DISTANCE); + currentBlockHeightTextField = addLabelTextField(root, gridRow, Res.get("dao.cycle.currentBlockHeight"), "", Layout.FIRST_ROW_AND_GROUP_DISTANCE).second; - currentPhaseTextField = addLabelTextField(gridPane, ++gridRow, Res.get("dao.cycle.currentPhase"), "").second; - proposalTextField = addLabelTextField(gridPane, ++gridRow, Res.get("dao.cycle.proposal"), "").second; - blindVoteTextField = addLabelTextField(gridPane, ++gridRow, Res.get("dao.cycle.blindVote"), "").second; - voteRevealTextField = addLabelTextField(gridPane, ++gridRow, Res.get("dao.cycle.voteReveal"), "").second; - voteResultTextField = addLabelTextField(gridPane, ++gridRow, Res.get("dao.cycle.voteResult"), "").second; - - addTitledGroupBg(gridPane, ++gridRow, 1, Res.get("dao.cycle.info.headline"), Layout.GROUP_DISTANCE); - addMultilineLabel(gridPane, gridRow, Res.get("dao.cycle.info.details"), Layout.FIRST_ROW_AND_GROUP_DISTANCE); + currentPhaseTextField = addLabelTextField(root, ++gridRow, Res.get("dao.cycle.currentPhase"), "").second; + proposalTextField = addLabelTextField(root, ++gridRow, Res.get("dao.cycle.proposal"), "").second; + blindVoteTextField = addLabelTextField(root, ++gridRow, Res.get("dao.cycle.blindVote"), "").second; + voteRevealTextField = addLabelTextField(root, ++gridRow, Res.get("dao.cycle.voteReveal"), "").second; + voteResultTextField = addLabelTextField(root, ++gridRow, Res.get("dao.cycle.voteResult"), "").second; + + addTitledGroupBg(root, ++gridRow, 1, Res.get("dao.cycle.info.headline"), Layout.GROUP_DISTANCE); + addMultilineLabel(root, gridRow, Res.get("dao.cycle.info.details"), Layout.FIRST_ROW_AND_GROUP_DISTANCE); } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.fxml b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.fxml index 8b573addc05..80e2272e3d1 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.fxml +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.fxml @@ -22,13 +22,11 @@ - - + - diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.fxml b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.fxml index 2424e2b2021..9250e4571ab 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.fxml +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.fxml @@ -23,8 +23,8 @@ diff --git a/src/main/java/bisq/desktop/main/dao/proposal/votes/VotesView.fxml b/src/main/java/bisq/desktop/main/dao/proposal/votes/VotesView.fxml index 2adf38de747..add21b35de1 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/votes/VotesView.fxml +++ b/src/main/java/bisq/desktop/main/dao/proposal/votes/VotesView.fxml @@ -23,8 +23,8 @@ diff --git a/src/main/java/bisq/desktop/main/dao/voting/VotingView.fxml b/src/main/java/bisq/desktop/main/dao/voting/VotingView.fxml index 35fed3b3c38..65f16c9d2dd 100644 --- a/src/main/java/bisq/desktop/main/dao/voting/VotingView.fxml +++ b/src/main/java/bisq/desktop/main/dao/voting/VotingView.fxml @@ -17,15 +17,21 @@ ~ along with Bisq. If not, see . --> + - - - + + + + + diff --git a/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.fxml b/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.fxml index 833129da2b1..e2c84c86546 100644 --- a/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.fxml +++ b/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.fxml @@ -22,10 +22,10 @@ - diff --git a/src/main/java/bisq/desktop/main/dao/voting/closed/ClosedBallotsView.fxml b/src/main/java/bisq/desktop/main/dao/voting/closed/ClosedBallotsView.fxml index 77b723ecc0c..bd54b16c97a 100644 --- a/src/main/java/bisq/desktop/main/dao/voting/closed/ClosedBallotsView.fxml +++ b/src/main/java/bisq/desktop/main/dao/voting/closed/ClosedBallotsView.fxml @@ -22,12 +22,13 @@ - + diff --git a/src/main/java/bisq/desktop/main/dao/voting/closed/VotingHistoryView.fxml b/src/main/java/bisq/desktop/main/dao/voting/closed/VotingHistoryView.fxml index 0986c567857..a08e3faa5c1 100644 --- a/src/main/java/bisq/desktop/main/dao/voting/closed/VotingHistoryView.fxml +++ b/src/main/java/bisq/desktop/main/dao/voting/closed/VotingHistoryView.fxml @@ -22,8 +22,8 @@ diff --git a/src/main/java/bisq/desktop/main/dao/voting/dashboard/VotingDashboardView.fxml b/src/main/java/bisq/desktop/main/dao/voting/dashboard/VotingDashboardView.fxml index c40a5b12f62..8dcdc823735 100644 --- a/src/main/java/bisq/desktop/main/dao/voting/dashboard/VotingDashboardView.fxml +++ b/src/main/java/bisq/desktop/main/dao/voting/dashboard/VotingDashboardView.fxml @@ -18,9 +18,15 @@ --> + + + + + diff --git a/src/main/java/bisq/desktop/main/dao/voting/vote/VoteView.fxml b/src/main/java/bisq/desktop/main/dao/voting/vote/VoteView.fxml index 42c0593329f..af532cb4d3e 100644 --- a/src/main/java/bisq/desktop/main/dao/voting/vote/VoteView.fxml +++ b/src/main/java/bisq/desktop/main/dao/voting/vote/VoteView.fxml @@ -23,8 +23,8 @@ diff --git a/src/main/java/bisq/desktop/main/dao/wallet/BsqWalletView.fxml b/src/main/java/bisq/desktop/main/dao/wallet/BsqWalletView.fxml index cd519d16edf..701da401d42 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/BsqWalletView.fxml +++ b/src/main/java/bisq/desktop/main/dao/wallet/BsqWalletView.fxml @@ -18,15 +18,21 @@ --> + - - - + + + + + diff --git a/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.fxml b/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.fxml index bb59f975fec..7ee966a25ba 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.fxml +++ b/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.fxml @@ -22,13 +22,11 @@ - - + - diff --git a/src/main/java/bisq/desktop/main/dao/wallet/receive/BsqReceiveView.fxml b/src/main/java/bisq/desktop/main/dao/wallet/receive/BsqReceiveView.fxml index 65647c4a253..541c78debb8 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/receive/BsqReceiveView.fxml +++ b/src/main/java/bisq/desktop/main/dao/wallet/receive/BsqReceiveView.fxml @@ -23,11 +23,12 @@ + diff --git a/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.fxml b/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.fxml index 13ab468ba50..dd2f73cc711 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.fxml +++ b/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.fxml @@ -23,8 +23,8 @@ diff --git a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.fxml b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.fxml index c2f99a220f9..f91d65a273a 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.fxml +++ b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.fxml @@ -22,13 +22,12 @@ - - + - + diff --git a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java index def9b15b57f..ee3a403b00a 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java @@ -60,9 +60,7 @@ import javafx.geometry.Insets; -import javafx.beans.property.DoubleProperty; import javafx.beans.property.ReadOnlyObjectWrapper; -import javafx.beans.property.SimpleDoubleProperty; import javafx.beans.value.ChangeListener; import javafx.collections.FXCollections; @@ -93,9 +91,7 @@ public class BsqTxView extends ActivatableView implements BsqBal private final ObservableList observableList = FXCollections.observableArrayList(); // Need to be DoubleProperty as we pass it as reference - private final DoubleProperty initialOccupiedHeight = new SimpleDoubleProperty(-1); private final SortedList sortedList = new SortedList<>(observableList); - private ChangeListener parentHeightListener; private ListChangeListener walletBsqTransactionsListener; private int gridRow = 0; private Label chainHeightLabel; @@ -161,7 +157,6 @@ public void initialize() { root.getChildren().add(vBox); walletBsqTransactionsListener = change -> updateList(); - parentHeightListener = (observable, oldValue, newValue) -> layout(); //TODO do we want to get notified from wallet side? walletChainHeightListener = (observable, oldValue, newValue) -> onUpdateAnyChainHeight(); } @@ -178,14 +173,8 @@ protected void activate() { daoFacade.addBlockListener(this); - if (root.getParent() instanceof Pane) { - rootParent = (Pane) root.getParent(); - rootParent.heightProperty().addListener(parentHeightListener); - } - updateList(); onUpdateAnyChainHeight(); - layout(); } @Override @@ -198,9 +187,6 @@ protected void deactivate() { daoFacade.removeBlockListener(this); observableList.forEach(BsqTxListItem::cleanup); - - if (rootParent != null) - rootParent.heightProperty().removeListener(parentHeightListener); } @@ -270,10 +256,6 @@ private void updateList() { observableList.setAll(items); } - private void layout() { - GUIUtil.fillAvailableHeight(root, tableView, initialOccupiedHeight); - } - private void addDateColumn() { TableColumn column = new AutoTooltipTableColumn<>(Res.get("shared.dateTime")); column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); From 4e5126c02bbace9ca9af11c088aefb206729b824 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Fri, 13 Jul 2018 00:15:18 +0200 Subject: [PATCH 131/197] Show bond info, cleanups, handle non-BSQ funds --- .../java/bisq/desktop/main/dao/DaoView.java | 1 + .../desktop/main/dao/bonding/BondingView.java | 14 +- .../{LockupBSQView.fxml => LockupView.fxml} | 2 +- .../{LockupBSQView.java => LockupView.java} | 43 ++- ...qTxListItem.java => LockedTxListItem.java} | 17 +- .../{UnlockBSQView.fxml => UnlockView.fxml} | 2 +- .../{UnlockBSQView.java => UnlockView.java} | 111 ++++--- .../dao/voting/active/ActiveBallotsView.java | 2 +- .../main/dao/wallet/BsqBalanceUtil.java | 10 +- .../wallet/dashboard/BsqDashboardView.java | 31 +- .../main/dao/wallet/send/BsqSendView.java | 303 +++++++++++++----- .../overlays/windows/EmptyWalletWindow.java | 2 +- 12 files changed, 340 insertions(+), 198 deletions(-) rename src/main/java/bisq/desktop/main/dao/bonding/lockup/{LockupBSQView.fxml => LockupView.fxml} (98%) rename src/main/java/bisq/desktop/main/dao/bonding/lockup/{LockupBSQView.java => LockupView.java} (83%) rename src/main/java/bisq/desktop/main/dao/bonding/unlock/{LockedBsqTxListItem.java => LockedTxListItem.java} (92%) rename src/main/java/bisq/desktop/main/dao/bonding/unlock/{UnlockBSQView.fxml => UnlockView.fxml} (98%) rename src/main/java/bisq/desktop/main/dao/bonding/unlock/{UnlockBSQView.java => UnlockView.java} (78%) diff --git a/src/main/java/bisq/desktop/main/dao/DaoView.java b/src/main/java/bisq/desktop/main/dao/DaoView.java index 3db4293a348..93e59ab82e9 100644 --- a/src/main/java/bisq/desktop/main/dao/DaoView.java +++ b/src/main/java/bisq/desktop/main/dao/DaoView.java @@ -73,6 +73,7 @@ public void initialize() { bondingTab = new Tab(Res.get("dao.tab.bonding")); proposalsTab.setClosable(false); votingTab.setClosable(false); + bondingTab.setClosable(false); root.getTabs().addAll(proposalsTab, votingTab, bondingTab); if (!BisqEnvironment.isDAOActivatedAndBaseCurrencySupportingBsq() || !DevEnv.isDaoPhase2Activated()) { diff --git a/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java b/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java index 9a7d709b0f0..2c1f4c2585c 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java @@ -28,8 +28,8 @@ import bisq.desktop.main.MainView; import bisq.desktop.main.dao.DaoView; import bisq.desktop.main.dao.bonding.dashboard.BondingDashboardView; -import bisq.desktop.main.dao.bonding.lockup.LockupBSQView; -import bisq.desktop.main.dao.bonding.unlock.UnlockBSQView; +import bisq.desktop.main.dao.bonding.lockup.LockupView; +import bisq.desktop.main.dao.bonding.unlock.UnlockView; import bisq.core.locale.Res; @@ -83,9 +83,9 @@ public void initialize() { dashboard = new MenuItem(navigation, toggleGroup, Res.get("shared.dashboard"), BondingDashboardView.class, AwesomeIcon.DASHBOARD, baseNavPath); lockupBSQ = new MenuItem(navigation, toggleGroup, Res.get("dao.bonding.menuItem.lockupBSQ"), - LockupBSQView.class, AwesomeIcon.LIST_UL, baseNavPath); + LockupView.class, AwesomeIcon.LIST_UL, baseNavPath); unlockBSQ = new MenuItem(navigation, toggleGroup, Res.get("dao.bonding.menuItem.unlockBSQ"), - UnlockBSQView.class, AwesomeIcon.LIST_UL, baseNavPath); + UnlockView.class, AwesomeIcon.LIST_UL, baseNavPath); leftVBox.getChildren().addAll(dashboard, lockupBSQ, unlockBSQ); } @@ -100,7 +100,7 @@ protected void activate() { if (viewPath.size() == 3 && viewPath.indexOf(BondingView.class) == 2 || viewPath.size() == 2 && viewPath.indexOf(DaoView.class) == 1) { if (selectedViewClass == null) - selectedViewClass = LockupBSQView.class; + selectedViewClass = LockupView.class; loadView(selectedViewClass); @@ -124,7 +124,7 @@ private void loadView(Class viewClass) { content.getChildren().setAll(view.getRoot()); if (view instanceof BondingDashboardView) dashboard.setSelected(true); - else if (view instanceof LockupBSQView) lockupBSQ.setSelected(true); - else if (view instanceof UnlockBSQView) unlockBSQ.setSelected(true); + else if (view instanceof LockupView) lockupBSQ.setSelected(true); + else if (view instanceof UnlockView) unlockBSQ.setSelected(true); } } diff --git a/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupBSQView.fxml b/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.fxml similarity index 98% rename from src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupBSQView.fxml rename to src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.fxml index 97e58cfa7c0..0129e40e85d 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupBSQView.fxml +++ b/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.fxml @@ -21,7 +21,7 @@ - implements BsqBalanceListener { +public class LockupView extends ActivatableView implements BsqBalanceListener { private final BsqWalletService bsqWalletService; private final WalletsSetup walletsSetup; private final P2PService p2PService; @@ -65,6 +66,7 @@ public class LockupBSQView extends ActivatableView implements Bs private final BsqBalanceUtil bsqBalanceUtil; private final BsqValidator bsqValidator; private final DaoFacade daoFacade; + private final IntegerValidator integerValidator; private int gridRow = 0; private InputTextField amountInputTextField; @@ -78,14 +80,14 @@ public class LockupBSQView extends ActivatableView implements Bs /////////////////////////////////////////////////////////////////////////////////////////// @Inject - private LockupBSQView(BsqWalletService bsqWalletService, - WalletsSetup walletsSetup, - P2PService p2PService, - BsqFormatter bsqFormatter, - Navigation navigation, - BsqBalanceUtil bsqBalanceUtil, - BsqValidator bsqValidator, - DaoFacade daoFacade) { + private LockupView(BsqWalletService bsqWalletService, + WalletsSetup walletsSetup, + P2PService p2PService, + BsqFormatter bsqFormatter, + Navigation navigation, + BsqBalanceUtil bsqBalanceUtil, + BsqValidator bsqValidator, + DaoFacade daoFacade) { this.bsqWalletService = bsqWalletService; this.walletsSetup = walletsSetup; this.p2PService = p2PService; @@ -94,6 +96,15 @@ private LockupBSQView(BsqWalletService bsqWalletService, this.bsqBalanceUtil = bsqBalanceUtil; this.bsqValidator = bsqValidator; this.daoFacade = daoFacade; + + + integerValidator = new IntegerValidator(); + // In the UI we don't allow 0 as that would mean that the tx gets spent + // in the same block as the unspent tx and we don't support unconfirmed txs in the DAO. Technically though 0 + // works as well. + integerValidator.setMinValue(BondingConsensus.getMinLockTime()); + // Max value is max of a short int as we use only 2 bytes in the opReturn for the lockTime + integerValidator.setMaxValue(BondingConsensus.getMaxLockTime()); } @Override @@ -105,19 +116,18 @@ public void initialize() { amountInputTextField = addLabelInputTextField(root, gridRow, Res.get("dao.bonding.lock.amount"), Layout.FIRST_ROW_AND_GROUP_DISTANCE).second; - amountInputTextField.setPromptText(Res.get("dao.bonding.lock.setAmount", Restrictions.getMinNonDustOutput().value)); + amountInputTextField.setPromptText(Res.get("dao.bonding.lock.setAmount", bsqFormatter.formatCoinWithCode(Restrictions.getMinNonDustOutput()))); amountInputTextField.setValidator(bsqValidator); timeInputTextField = addLabelInputTextField(root, ++gridRow, Res.get("dao.bonding.lock.time"), Layout.GRID_GAP).second; timeInputTextField.setPromptText(Res.get("dao.bonding.lock.setTime", - Param.LOCK_TIME_MIN.getDefaultValue(), Param.LOCK_TIME_MAX.getDefaultValue())); - // TODO: add some int validator -// timeInputTextField.setValidator(bsqValidator); + String.valueOf(BondingConsensus.getMinLockTime()), String.valueOf(BondingConsensus.getMaxLockTime()))); + timeInputTextField.setValidator(integerValidator); focusOutListener = (observable, oldValue, newValue) -> { if (!newValue) onUpdateBalances(bsqWalletService.getAvailableBalance(), bsqWalletService.getAvailableNonBsqBalance(), - bsqWalletService.getPendingBalance(), + bsqWalletService.getUnverifiedBalance(), bsqWalletService.getLockedForVotingBalance(), bsqWalletService.getLockedInBondsBalance(), bsqWalletService.getUnlockingBondsBalance()); @@ -145,6 +155,7 @@ public void initialize() { errorMessage -> new Popup<>().warning(errorMessage.toString()).show() ); amountInputTextField.setText(""); + timeInputTextField.setText(""); }) .closeButtonText(Res.get("shared.cancel")) .show(); @@ -176,7 +187,7 @@ protected void activate() { bsqWalletService.addBsqBalanceListener(this); onUpdateBalances(bsqWalletService.getAvailableBalance(), bsqWalletService.getAvailableNonBsqBalance(), - bsqWalletService.getPendingBalance(), + bsqWalletService.getUnverifiedBalance(), bsqWalletService.getLockedForVotingBalance(), bsqWalletService.getLockedInBondsBalance(), bsqWalletService.getUnlockingBondsBalance()); diff --git a/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedBsqTxListItem.java b/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedTxListItem.java similarity index 92% rename from src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedBsqTxListItem.java rename to src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedTxListItem.java index 15cd19d3ad1..4f146e0e6de 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedBsqTxListItem.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedTxListItem.java @@ -45,7 +45,7 @@ import static com.google.common.base.Preconditions.checkNotNull; @Data -class LockedBsqTxListItem { +class LockedTxListItem { private final Transaction transaction; private final BsqWalletService bsqWalletService; private final BtcWalletService btcWalletService; @@ -64,13 +64,13 @@ class LockedBsqTxListItem { private TxConfidenceListener txConfidenceListener; private boolean issuanceTx; - LockedBsqTxListItem(Transaction transaction, - BsqWalletService bsqWalletService, - BtcWalletService btcWalletService, - DaoFacade daoFacade, - StateService stateService, - Date date, - BsqFormatter bsqFormatter) { + LockedTxListItem(Transaction transaction, + BsqWalletService bsqWalletService, + BtcWalletService btcWalletService, + DaoFacade daoFacade, + StateService stateService, + Date date, + BsqFormatter bsqFormatter) { this.transaction = transaction; this.bsqWalletService = bsqWalletService; this.btcWalletService = btcWalletService; @@ -132,6 +132,7 @@ public void cleanup() { bsqWalletService.removeTxConfidenceListener(txConfidenceListener); } + // TODO SQ use daoFacade public boolean isSpent() { Optional optionalTxOutput = stateService.getLockupTxOutput(txId); if (!optionalTxOutput.isPresent()) diff --git a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.fxml b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.fxml similarity index 98% rename from src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.fxml rename to src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.fxml index 7287a21faea..025947f64cf 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockBSQView.fxml +++ b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.fxml @@ -21,7 +21,7 @@ - implements BsqBalanceListener, BlockListener { - private TableView tableView; - private Pane rootParent; +public class UnlockView extends ActivatableView implements BsqBalanceListener, BlockListener { + private TableView tableView; private final BsqWalletService bsqWalletService; private final BtcWalletService btcWalletService; @@ -100,10 +98,10 @@ public class UnlockBSQView extends ActivatableView implements Bs private int gridRow = 0; private boolean synced; - private LockedBsqTxListItem selectedItem; + private LockedTxListItem selectedItem; - private final ObservableList observableList = FXCollections.observableArrayList(); - private final FilteredList lockedTxs = new FilteredList<>(observableList); + private final ObservableList observableList = FXCollections.observableArrayList(); + private final FilteredList lockedTxs = new FilteredList<>(observableList); private ListChangeListener walletBsqTransactionsListener; private ChangeListener walletChainHeightListener; @@ -114,17 +112,17 @@ public class UnlockBSQView extends ActivatableView implements Bs /////////////////////////////////////////////////////////////////////////////////////////// @Inject - private UnlockBSQView(BsqWalletService bsqWalletService, - BtcWalletService btcWalletService, - BsqFormatter bsqFormatter, - BsqBalanceUtil bsqBalanceUtil, - BsqValidator bsqValidator, - DaoFacade daoFacade, - Preferences preferences, - StateService stateService, - WalletsSetup walletsSetup, - P2PService p2PService, - Navigation navigation) { + private UnlockView(BsqWalletService bsqWalletService, + BtcWalletService btcWalletService, + BsqFormatter bsqFormatter, + BsqBalanceUtil bsqBalanceUtil, + BsqValidator bsqValidator, + DaoFacade daoFacade, + Preferences preferences, + StateService stateService, + WalletsSetup walletsSetup, + P2PService p2PService, + Navigation navigation) { this.bsqWalletService = bsqWalletService; this.btcWalletService = btcWalletService; this.bsqFormatter = bsqFormatter; @@ -151,7 +149,7 @@ public void initialize() { addLockTimeColumn(); addUnlockColumn(); - lockedTxs.setPredicate(LockedBsqTxListItem::isLockedAndUnspent); + lockedTxs.setPredicate(LockedTxListItem::isLockedAndUnspent); walletBsqTransactionsListener = change -> updateList(); walletChainHeightListener = (observable, oldValue, newValue) -> onUpdateAnyChainHeight(); @@ -166,22 +164,22 @@ public void initialize() { } private void addTxIdColumn() { - TableColumn column = new AutoTooltipTableColumn<>(Res.get("shared.txId")); + TableColumn column = new AutoTooltipTableColumn<>(Res.get("shared.txId")); column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); column.setMinWidth(60); column.setCellFactory( - new Callback, TableCell>() { + new Callback, TableCell>() { @Override - public TableCell call(TableColumn column) { - return new TableCell() { + public TableCell call(TableColumn column) { + return new TableCell() { private HyperlinkWithIcon hyperlinkWithIcon; @Override - public void updateItem(final LockedBsqTxListItem item, boolean empty) { + public void updateItem(final LockedTxListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { @@ -203,22 +201,22 @@ public void updateItem(final LockedBsqTxListItem item, boolean empty) { } private void addAmountColumn() { - TableColumn column = + TableColumn column = new AutoTooltipTableColumn<>(Res.get("shared.amountWithCur", "BSQ")); column.setMinWidth(120); column.setMaxWidth(column.getMinWidth()); column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - column.setCellFactory(new Callback, - TableCell>() { + column.setCellFactory(new Callback, + TableCell>() { @Override - public TableCell call(TableColumn column) { - return new TableCell() { + public TableCell call(TableColumn column) { + return new TableCell() { @Override - public void updateItem(final LockedBsqTxListItem item, boolean empty) { + public void updateItem(final LockedTxListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { TxType txType = item.getTxType(); @@ -235,22 +233,22 @@ public void updateItem(final LockedBsqTxListItem item, boolean empty) { } private void addLockTimeColumn() { - TableColumn column = + TableColumn column = new AutoTooltipTableColumn<>(Res.get("dao.bonding.unlock.time")); column.setMinWidth(120); column.setMaxWidth(column.getMinWidth()); column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - column.setCellFactory(new Callback, - TableCell>() { + column.setCellFactory(new Callback, + TableCell>() { @Override - public TableCell call(TableColumn column) { - return new TableCell() { + public TableCell call(TableColumn column) { + return new TableCell() { @Override - public void updateItem(final LockedBsqTxListItem item, boolean empty) { + public void updateItem(final LockedTxListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { TxType txType = item.getTxType(); @@ -267,31 +265,31 @@ public void updateItem(final LockedBsqTxListItem item, boolean empty) { } private void addUnlockColumn() { - TableColumn unlockColumn = new TableColumn<>(); + TableColumn unlockColumn = new TableColumn<>(); unlockColumn.setMinWidth(130); unlockColumn.setMaxWidth(unlockColumn.getMinWidth()); unlockColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - unlockColumn.setCellFactory(new Callback, - TableCell>() { + unlockColumn.setCellFactory(new Callback, + TableCell>() { @Override - public TableCell call(TableColumn column) { - return new TableCell() { + public TableCell call(TableColumn column) { + return new TableCell() { Button button; @Override - public void updateItem(final LockedBsqTxListItem item, boolean empty) { + public void updateItem(final LockedTxListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { if (button == null) { button = item.getButton(); button.setOnAction(e -> { - UnlockBSQView.this.selectedItem = item; - UnlockBSQView.this.onButtonClick(); + UnlockView.this.selectedItem = item; + UnlockView.this.onButtonClick(); }); setGraphic(button); } @@ -306,12 +304,13 @@ public void updateItem(final LockedBsqTxListItem item, boolean empty) { }; } }); - unlockColumn.setComparator(Comparator.comparing(LockedBsqTxListItem::getConfirmations)); + unlockColumn.setComparator(Comparator.comparing(LockedTxListItem::getConfirmations)); tableView.getColumns().add(unlockColumn); } private void onButtonClick() { if (GUIUtil.isReadyForTxBroadcast(p2PService, walletsSetup)) { + // TODO SQ use daoFacade Optional lockedTxOutput = stateService.getLockupTxOutput(selectedItem.getTxId()); if (!lockedTxOutput.isPresent()) { log.warn("Locked output not found, txId = ", selectedItem.getTxId()); @@ -361,7 +360,7 @@ private void onButtonClick() { log.info("unlock tx: {}", selectedItem.getTxId()); } - private void openTxInBlockExplorer(LockedBsqTxListItem item) { + private void openTxInBlockExplorer(LockedTxListItem item) { if (item.getTxId() != null) GUIUtil.openWebPage(preferences.getBsqBlockChainExplorer().txUrl + item.getTxId()); } @@ -372,7 +371,7 @@ protected void activate() { bsqWalletService.addBsqBalanceListener(this); onUpdateBalances(bsqWalletService.getAvailableBalance(), bsqWalletService.getAvailableNonBsqBalance(), - bsqWalletService.getPendingBalance(), + bsqWalletService.getUnverifiedBalance(), bsqWalletService.getLockedForVotingBalance(), bsqWalletService.getLockedInBondsBalance(), bsqWalletService.getUnlockingBondsBalance()); @@ -404,13 +403,13 @@ private void onUpdateAnyChainHeight() { } private void updateList() { - observableList.forEach(LockedBsqTxListItem::cleanup); + observableList.forEach(LockedTxListItem::cleanup); // copy list to avoid ConcurrentModificationException final List walletTransactions = new ArrayList<>(bsqWalletService.getWalletTransactions()); - List items = walletTransactions.stream() + List items = walletTransactions.stream() .map(transaction -> { - return new LockedBsqTxListItem(transaction, + return new LockedTxListItem(transaction, bsqWalletService, btcWalletService, daoFacade, @@ -433,7 +432,7 @@ protected void deactivate() { btcWalletService.getChainHeightProperty().removeListener(walletChainHeightListener); daoFacade.removeBlockListener(this); - observableList.forEach(LockedBsqTxListItem::cleanup); + observableList.forEach(LockedTxListItem::cleanup); } @Override diff --git a/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.java b/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.java index 05f76f7da24..8cc9fc33ca1 100644 --- a/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.java +++ b/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.java @@ -113,7 +113,7 @@ protected void activate() { onUpdateBalances(bsqWalletService.getAvailableBalance(), bsqWalletService.getAvailableNonBsqBalance(), - bsqWalletService.getPendingBalance(), + bsqWalletService.getUnverifiedBalance(), bsqWalletService.getLockedForVotingBalance(), bsqWalletService.getLockedInBondsBalance(), bsqWalletService.getUnlockingBondsBalance()); diff --git a/src/main/java/bisq/desktop/main/dao/wallet/BsqBalanceUtil.java b/src/main/java/bisq/desktop/main/dao/wallet/BsqBalanceUtil.java index d2f536f57cb..51d8d23e520 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/BsqBalanceUtil.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/BsqBalanceUtil.java @@ -31,8 +31,6 @@ import javafx.scene.control.TextField; import javafx.scene.layout.GridPane; -import javafx.geometry.Pos; - import lombok.extern.slf4j.Slf4j; import static bisq.desktop.util.FormBuilder.addLabelTextField; @@ -91,13 +89,9 @@ public int addBondBalanceGroup(GridPane gridPane, int gridRow) { lockedAmountTextField = addLabelTextField(gridPane, gridRow, Res.get("dao.bonding.dashboard.lockedAmount"), Layout.FIRST_ROW_DISTANCE + Layout.GROUP_DISTANCE).second; lockedAmountTextField.setMouseTransparent(false); - lockedAmountTextField.setMaxWidth(150); - lockedAmountTextField.setAlignment(Pos.CENTER_RIGHT); unlockingAmountTextField = addLabelTextField(gridPane, ++gridRow, Res.get("dao.bonding.dashboard.unlockingAmount")).second; unlockingAmountTextField.setMouseTransparent(false); - unlockingAmountTextField.setMaxWidth(150); - unlockingAmountTextField.setAlignment(Pos.CENTER_RIGHT); return gridRow; } @@ -105,7 +99,7 @@ public int addBondBalanceGroup(GridPane gridPane, int gridRow) { public void activate() { onUpdateBalances(bsqWalletService.getAvailableBalance(), bsqWalletService.getAvailableNonBsqBalance(), - bsqWalletService.getPendingBalance(), + bsqWalletService.getUnverifiedBalance(), bsqWalletService.getLockedForVotingBalance(), bsqWalletService.getLockedInBondsBalance(), bsqWalletService.getUnlockingBondsBalance()); @@ -125,7 +119,7 @@ public void onUpdateBalances(Coin availableBalance, Coin lockedInBondsBalance, Coin unlockingBondsBalance) { availableBalanceTextField.setText(bsqFormatter.formatCoinWithCode(availableBalance)); - availableNonBsqBalanceTextField.setText(bsqFormatter.formatSatoshi(availableNonBsqBalance.value)); + availableNonBsqBalanceTextField.setText(bsqFormatter.formatBtcSatoshi(availableNonBsqBalance.value)); unverifiedBalanceTextField.setText(bsqFormatter.formatCoinWithCode(unverifiedBalance)); lockedForVoteBalanceTextField.setText(bsqFormatter.formatCoinWithCode(lockedForVotingBalance)); lockedInBondsBalanceTextField.setText(bsqFormatter.formatCoinWithCode( diff --git a/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java b/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java index 91b53abb38b..2fdafd4fb27 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java @@ -67,8 +67,9 @@ public class BsqDashboardView extends ActivatableView implements private int gridRow = 0; private TextField genesisIssueAmountTextField, compRequestIssueAmountTextField, availableAmountTextField, - burntAmountTextField, allTxTextField, - burntTxTextField/*, spentTxTextField*/, + burntAmountTextField, totalLockedUpAmountTextField, totalUnlockingAmountTextField, + totalUnlockedAmountTextField, allTxTextField, + burntTxTextField, utxoTextField, priceTextField, marketCapTextField; private ChangeListener priceChangeListener; private HyperlinkWithIcon hyperlinkWithIcon; @@ -95,7 +96,7 @@ private BsqDashboardView(BsqBalanceUtil bsqBalanceUtil, public void initialize() { gridRow = bsqBalanceUtil.addGroup(root, gridRow); - addTitledGroupBg(root, ++gridRow, 11, Res.get("dao.wallet.dashboard.statistics"), Layout.GROUP_DISTANCE); + addTitledGroupBg(root, ++gridRow, 14, Res.get("dao.wallet.dashboard.statistics"), Layout.GROUP_DISTANCE); addLabelTextField(root, gridRow, Res.get("dao.wallet.dashboard.genesisBlockHeight"), String.valueOf(daoFacade.getGenesisBlockHeight()), Layout.FIRST_ROW_AND_GROUP_DISTANCE); @@ -114,12 +115,13 @@ public void initialize() { compRequestIssueAmountTextField = addLabelTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.compRequestIssueAmount")).second; availableAmountTextField = addLabelTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.availableAmount")).second; burntAmountTextField = addLabelTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.burntAmount")).second; + totalLockedUpAmountTextField = addLabelTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.totalLockedUpAmount")).second; + totalUnlockingAmountTextField = addLabelTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.totalUnlockingAmount")).second; + totalUnlockedAmountTextField = addLabelTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.totalUnlockedAmount")).second; allTxTextField = addLabelTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.allTx")).second; utxoTextField = addLabelTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.utxo")).second; - // spentTxTextField = addLabelTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.spentTxo")).second; burntTxTextField = addLabelTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.burntTx")).second; - priceTextField = addLabelTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.price")).second; marketCapTextField = addLabelTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.marketCap")).second; @@ -158,26 +160,31 @@ public void onBlockAdded(Block block) { } private void updateWithBsqBlockChainData() { - final Coin issuedAmountFromGenesis = daoFacade.getGenesisTotalSupply(); + Coin issuedAmountFromGenesis = daoFacade.getGenesisTotalSupply(); genesisIssueAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(issuedAmountFromGenesis)); - final Coin issuedAmountFromCompRequests = Coin.valueOf(daoFacade.getTotalIssuedAmountFromCompRequests()); + Coin issuedAmountFromCompRequests = Coin.valueOf(daoFacade.getTotalIssuedAmountFromCompRequests()); compRequestIssueAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(issuedAmountFromCompRequests)); - final Coin burntFee = Coin.valueOf(daoFacade.getTotalBurntFee()); - final Coin availableAmount = issuedAmountFromGenesis.add(issuedAmountFromCompRequests).subtract(burntFee); + Coin burntFee = Coin.valueOf(daoFacade.getTotalBurntFee()); + Coin totalLockedUpAmount = Coin.valueOf(daoFacade.getTotalLockedUpAmount()); + Coin totalUnlockingAmount = Coin.valueOf(daoFacade.getTotalAmountOfUnLockingTxOutputs()); + Coin totalUnlockedAmount = Coin.valueOf(daoFacade.getTotalAmountOfUnLockedTxOutputs()); + Coin availableAmount = issuedAmountFromGenesis.add(issuedAmountFromCompRequests).subtract(burntFee); availableAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(availableAmount)); burntAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(burntFee)); + totalLockedUpAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(totalLockedUpAmount)); + totalUnlockingAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(totalUnlockingAmount)); + totalUnlockedAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(totalUnlockedAmount)); allTxTextField.setText(String.valueOf(daoFacade.getTxs().size())); utxoTextField.setText(String.valueOf(daoFacade.getUnspentTxOutputs().size())); - //spentTxTextField.setText(String.valueOf(stateService.getSpentTxOutputs().size())); burntTxTextField.setText(String.valueOf(daoFacade.getFeeTxs().size())); } private void updatePrice() { - final Coin issuedAmount = daoFacade.getGenesisTotalSupply(); - final MarketPrice bsqMarketPrice = priceFeedService.getMarketPrice("BSQ"); + Coin issuedAmount = daoFacade.getGenesisTotalSupply(); + MarketPrice bsqMarketPrice = priceFeedService.getMarketPrice("BSQ"); if (bsqMarketPrice != null) { long bsqPrice = MathUtils.roundDoubleToLong(MathUtils.scaleUpByPowerOf10(bsqMarketPrice.getPrice(), Altcoin.SMALLEST_UNIT_EXPONENT)); priceTextField.setText(bsqFormatter.formatPrice(Price.valueOf("BSQ", bsqPrice)) + " BSQ/BTC"); diff --git a/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java b/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java index 31252a84787..67e5ddcbab0 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java @@ -21,6 +21,7 @@ import bisq.desktop.common.view.ActivatableView; import bisq.desktop.common.view.FxmlView; import bisq.desktop.components.InputTextField; +import bisq.desktop.components.TitledGroupBg; import bisq.desktop.main.MainView; import bisq.desktop.main.dao.wallet.BsqBalanceUtil; import bisq.desktop.main.funds.FundsView; @@ -30,6 +31,7 @@ import bisq.desktop.util.Layout; import bisq.desktop.util.validation.BsqAddressValidator; import bisq.desktop.util.validation.BsqValidator; +import bisq.desktop.util.validation.BtcValidator; import bisq.core.btc.Restrictions; import bisq.core.btc.wallet.BsqBalanceListener; @@ -45,9 +47,13 @@ import bisq.core.util.BSFormatter; import bisq.core.util.BsqFormatter; import bisq.core.util.CoinUtil; +import bisq.core.util.validation.BtcAddressValidator; import bisq.network.p2p.P2PService; +import bisq.common.handlers.ResultHandler; +import bisq.common.util.Tuple2; + import org.bitcoinj.core.Coin; import org.bitcoinj.core.InsufficientMoneyException; import org.bitcoinj.core.Transaction; @@ -55,6 +61,7 @@ import javax.inject.Inject; import javafx.scene.control.Button; +import javafx.scene.control.Label; import javafx.scene.layout.GridPane; import javafx.beans.value.ChangeListener; @@ -75,13 +82,18 @@ public class BsqSendView extends ActivatableView implements BsqB private final Navigation navigation; private final BsqBalanceUtil bsqBalanceUtil; private final BsqValidator bsqValidator; + private final BtcValidator btcValidator; private final BsqAddressValidator bsqAddressValidator; + private final BtcAddressValidator btcAddressValidator; private int gridRow = 0; - private InputTextField amountInputTextField; - private Button sendButton; - private InputTextField receiversAddressInputTextField; + private InputTextField amountInputTextField, btcAmountInputTextField; + private Button sendButton, sendBtcButton; + private InputTextField receiversAddressInputTextField, receiversBtcAddressInputTextField; private ChangeListener focusOutListener; + private TitledGroupBg btcTitledGroupBg; + private Label receiversBtcAddressLabel; + private Label btcAmountLabel; /////////////////////////////////////////////////////////////////////////////////////////// @@ -99,7 +111,9 @@ private BsqSendView(BsqWalletService bsqWalletService, Navigation navigation, BsqBalanceUtil bsqBalanceUtil, BsqValidator bsqValidator, - BsqAddressValidator bsqAddressValidator) { + BtcValidator btcValidator, + BsqAddressValidator bsqAddressValidator, + BtcAddressValidator btcAddressValidator) { this.bsqWalletService = bsqWalletService; this.btcWalletService = btcWalletService; this.walletsManager = walletsManager; @@ -110,14 +124,81 @@ private BsqSendView(BsqWalletService bsqWalletService, this.navigation = navigation; this.bsqBalanceUtil = bsqBalanceUtil; this.bsqValidator = bsqValidator; + this.btcValidator = btcValidator; this.bsqAddressValidator = bsqAddressValidator; + this.btcAddressValidator = btcAddressValidator; } @Override public void initialize() { gridRow = bsqBalanceUtil.addGroup(root, gridRow); - addTitledGroupBg(root, ++gridRow, 3, Res.get("dao.wallet.send.sendFunds"), Layout.GROUP_DISTANCE); + addSendBsqGroup(); + addSendBtcGroup(); + + focusOutListener = (observable, oldValue, newValue) -> { + if (!newValue) + onUpdateBalances(bsqWalletService.getAvailableBalance(), + bsqWalletService.getAvailableNonBsqBalance(), + bsqWalletService.getUnverifiedBalance(), + bsqWalletService.getLockedForVotingBalance(), + bsqWalletService.getLockedInBondsBalance(), + bsqWalletService.getUnlockingBondsBalance()); + }; + + setSendBtcGroupVisibleState(false); + } + + @Override + protected void activate() { + setSendBtcGroupVisibleState(false); + bsqBalanceUtil.activate(); + receiversAddressInputTextField.focusedProperty().addListener(focusOutListener); + amountInputTextField.focusedProperty().addListener(focusOutListener); + + receiversBtcAddressInputTextField.focusedProperty().addListener(focusOutListener); + btcAmountInputTextField.focusedProperty().addListener(focusOutListener); + + bsqWalletService.addBsqBalanceListener(this); + onUpdateBalances(bsqWalletService.getAvailableBalance(), + bsqWalletService.getAvailableNonBsqBalance(), + bsqWalletService.getUnverifiedBalance(), + bsqWalletService.getLockedForVotingBalance(), + bsqWalletService.getLockedInBondsBalance(), + bsqWalletService.getUnlockingBondsBalance()); + } + + + @Override + protected void deactivate() { + bsqBalanceUtil.deactivate(); + receiversAddressInputTextField.focusedProperty().removeListener(focusOutListener); + amountInputTextField.focusedProperty().removeListener(focusOutListener); + bsqWalletService.removeBsqBalanceListener(this); + } + + @Override + public void onUpdateBalances(Coin availableBalance, + Coin availableNonBsqBalance, + Coin unverifiedBalance, + Coin lockedForVotingBalance, + Coin lockedInBondsBalance, + Coin unlockingBondsBalance) { + bsqValidator.setAvailableBalance(availableBalance); + boolean isValid = bsqAddressValidator.validate(receiversAddressInputTextField.getText()).isValid && + bsqValidator.validate(amountInputTextField.getText()).isValid; + sendButton.setDisable(!isValid); + + boolean isBtcValid = btcAddressValidator.validate(receiversBtcAddressInputTextField.getText()).isValid && + btcValidator.validate(btcAmountInputTextField.getText()).isValid; + sendBtcButton.setDisable(!isBtcValid); + + setSendBtcGroupVisibleState(availableNonBsqBalance.isPositive()); + + } + + private void addSendBsqGroup() { + addTitledGroupBg(root, ++gridRow, 2, Res.get("dao.wallet.send.sendFunds"), Layout.GROUP_DISTANCE); receiversAddressInputTextField = addLabelInputTextField(root, gridRow, Res.get("dao.wallet.send.receiverAddress"), Layout.FIRST_ROW_AND_GROUP_DISTANCE).second; @@ -125,14 +206,14 @@ public void initialize() { receiversAddressInputTextField.setValidator(bsqAddressValidator); amountInputTextField = addLabelInputTextField(root, ++gridRow, Res.get("dao.wallet.send.amount")).second; - amountInputTextField.setPromptText(Res.get("dao.wallet.send.setAmount", Restrictions.getMinNonDustOutput().value)); + amountInputTextField.setPromptText(Res.get("dao.wallet.send.setAmount", bsqFormatter.formatCoin(Restrictions.getMinNonDustOutput()))); amountInputTextField.setValidator(bsqValidator); focusOutListener = (observable, oldValue, newValue) -> { if (!newValue) onUpdateBalances(bsqWalletService.getAvailableBalance(), bsqWalletService.getAvailableNonBsqBalance(), - bsqWalletService.getPendingBalance(), + bsqWalletService.getUnverifiedBalance(), bsqWalletService.getLockedForVotingBalance(), bsqWalletService.getLockedInBondsBalance(), bsqWalletService.getUnlockingBondsBalance()); @@ -151,60 +232,18 @@ public void initialize() { Transaction signedTx = bsqWalletService.signTx(txWithBtcFee); Coin miningFee = signedTx.getFee(); int txSize = signedTx.bitcoinSerialize().length; - new Popup<>().headLine(Res.get("dao.wallet.send.sendFunds.headline")) - .confirmation(Res.get("dao.wallet.send.sendFunds.details", - bsqFormatter.formatCoinWithCode(receiverAmount), - receiversAddressInputTextField.getText(), - btcFormatter.formatCoinWithCode(miningFee), - CoinUtil.getFeePerByte(miningFee, txSize), - txSize / 1000d, - bsqFormatter.formatCoinWithCode(receiverAmount))) - .actionButtonText(Res.get("shared.yes")) - .onAction(() -> { - walletsManager.publishAndCommitBsqTx(txWithBtcFee, new TxBroadcaster.Callback() { - @Override - public void onSuccess(Transaction transaction) { - log.debug("Successfully sent tx with id " + txWithBtcFee.getHashAsString()); - } - - @Override - public void onTimeout(TxBroadcastTimeoutException exception) { - //TODO handle - new Popup<>().warning(exception.toString()); - } - - @Override - public void onTxMalleability(TxMalleabilityException exception) { - //TODO handle - new Popup<>().warning(exception.toString()); - } - - @Override - public void onFailure(TxBroadcastException exception) { - //TODO handle - new Popup<>().warning(exception.toString()); - } - }); - + showTxPopup(receiverAmount, + txWithBtcFee, + miningFee, + txSize, + receiversAddressInputTextField.getText(), + bsqFormatter, + () -> { receiversAddressInputTextField.setText(""); amountInputTextField.setText(""); - }) - .closeButtonText(Res.get("shared.cancel")) - .show(); + }); } catch (Throwable t) { - if (t instanceof InsufficientMoneyException) { - final Coin missingCoin = ((InsufficientMoneyException) t).missing; - final String missing = missingCoin != null ? missingCoin.toFriendlyString() : "null"; - //noinspection unchecked - new Popup<>().warning(Res.get("popup.warning.insufficientBtcFundsForBsqTx", missing)) - .actionButtonTextWithGoTo("navigation.funds.depositFunds") - .onAction(() -> navigation.navigateTo(MainView.class, FundsView.class, DepositView.class)) - .show(); - } else { - log.error(t.toString()); - t.printStackTrace(); - new Popup<>().warning(t.getMessage()).show(); - } + hanldeError(t); } } else { GUIUtil.showNotReadyForTxBroadcastPopups(p2PService, walletsSetup); @@ -212,39 +251,129 @@ public void onFailure(TxBroadcastException exception) { }); } - @Override - protected void activate() { - bsqBalanceUtil.activate(); - receiversAddressInputTextField.focusedProperty().addListener(focusOutListener); - amountInputTextField.focusedProperty().addListener(focusOutListener); - bsqWalletService.addBsqBalanceListener(this); - onUpdateBalances(bsqWalletService.getAvailableBalance(), - bsqWalletService.getAvailableNonBsqBalance(), - bsqWalletService.getPendingBalance(), - bsqWalletService.getLockedForVotingBalance(), - bsqWalletService.getLockedInBondsBalance(), - bsqWalletService.getUnlockingBondsBalance()); + private void setSendBtcGroupVisibleState(boolean visible) { + btcTitledGroupBg.setVisible(visible); + receiversBtcAddressLabel.setVisible(visible); + receiversBtcAddressInputTextField.setVisible(visible); + btcAmountInputTextField.setVisible(visible); + btcAmountLabel.setVisible(visible); + sendBtcButton.setVisible(visible); + + btcTitledGroupBg.setManaged(visible); + receiversBtcAddressLabel.setManaged(visible); + receiversBtcAddressInputTextField.setManaged(visible); + btcAmountInputTextField.setManaged(visible); + btcAmountLabel.setManaged(visible); + sendBtcButton.setManaged(visible); } - @Override - protected void deactivate() { - bsqBalanceUtil.deactivate(); - receiversAddressInputTextField.focusedProperty().removeListener(focusOutListener); - amountInputTextField.focusedProperty().removeListener(focusOutListener); - bsqWalletService.removeBsqBalanceListener(this); + private void addSendBtcGroup() { + btcTitledGroupBg = addTitledGroupBg(root, ++gridRow, 2, Res.get("dao.wallet.send.sendBtcFunds"), Layout.GROUP_DISTANCE); + + Tuple2 tuple = addLabelInputTextField(root, gridRow, + Res.get("dao.wallet.send.receiverBtcAddress"), Layout.FIRST_ROW_AND_GROUP_DISTANCE); + receiversBtcAddressLabel = tuple.first; + receiversBtcAddressInputTextField = tuple.second; + receiversBtcAddressInputTextField.setPromptText(Res.get("dao.wallet.send.setDestinationAddress")); + receiversBtcAddressInputTextField.setValidator(btcAddressValidator); + + Tuple2 tuple2 = addLabelInputTextField(root, ++gridRow, Res.get("dao.wallet.send.btcAmount")); + btcAmountLabel = tuple2.first; + btcAmountInputTextField = tuple2.second; + btcAmountInputTextField.setPromptText(Res.get("dao.wallet.send.setBtcAmount", Restrictions.getMinNonDustOutput().value)); + btcAmountInputTextField.setValidator(btcValidator); + + sendBtcButton = addButtonAfterGroup(root, ++gridRow, Res.get("dao.wallet.send.sendBtc")); + + sendBtcButton.setOnAction((event) -> { + // TODO break up in methods + if (GUIUtil.isReadyForTxBroadcast(p2PService, walletsSetup)) { + String receiversAddressString = receiversBtcAddressInputTextField.getText(); + Coin receiverAmount = bsqFormatter.parseSatoshiToBtc(btcAmountInputTextField.getText()); + try { + Transaction preparedSendTx = bsqWalletService.getPreparedSendBtcTx(receiversAddressString, receiverAmount); + Transaction txWithBtcFee = btcWalletService.completePreparedSendBsqTx(preparedSendTx, true); + Transaction signedTx = bsqWalletService.signTx(txWithBtcFee); + Coin miningFee = signedTx.getFee(); + int txSize = signedTx.bitcoinSerialize().length; + showTxPopup(receiverAmount, + txWithBtcFee, + miningFee, + txSize, receiversBtcAddressInputTextField.getText(), + btcFormatter, + () -> { + receiversBtcAddressInputTextField.setText(""); + btcAmountInputTextField.setText(""); + }); + } catch (Throwable t) { + hanldeError(t); + } + } else { + GUIUtil.showNotReadyForTxBroadcastPopups(p2PService, walletsSetup); + } + }); } - @Override - public void onUpdateBalances(Coin availableBalance, - Coin availableNonBsqBalance, - Coin unverifiedBalance, - Coin lockedForVotingBalance, - Coin lockedInBondsBalance, - Coin unlockingBondsBalance) { - bsqValidator.setAvailableBalance(availableBalance); - boolean isValid = bsqAddressValidator.validate(receiversAddressInputTextField.getText()).isValid && - bsqValidator.validate(amountInputTextField.getText()).isValid; - sendButton.setDisable(!isValid); + private void hanldeError(Throwable t) { + if (t instanceof InsufficientMoneyException) { + final Coin missingCoin = ((InsufficientMoneyException) t).missing; + final String missing = missingCoin != null ? missingCoin.toFriendlyString() : "null"; + //noinspection unchecked + new Popup<>().warning(Res.get("popup.warning.insufficientBtcFundsForBsqTx", missing)) + .actionButtonTextWithGoTo("navigation.funds.depositFunds") + .onAction(() -> navigation.navigateTo(MainView.class, FundsView.class, DepositView.class)) + .show(); + } else { + log.error(t.toString()); + t.printStackTrace(); + new Popup<>().warning(t.getMessage()).show(); + } + } + + private void showTxPopup(Coin receiverAmount, + Transaction txWithBtcFee, + Coin miningFee, + int txSize, String address, + BSFormatter formatter, + ResultHandler resultHandler) { + new Popup<>().headLine(Res.get("dao.wallet.send.sendFunds.headline")) + .confirmation(Res.get("dao.wallet.send.sendFunds.details", + formatter.formatCoinWithCode(receiverAmount), + address, + formatter.formatCoinWithCode(miningFee), + CoinUtil.getFeePerByte(miningFee, txSize), + txSize / 1000d, + formatter.formatCoinWithCode(receiverAmount))) + .actionButtonText(Res.get("shared.yes")) + .onAction(() -> { + walletsManager.publishAndCommitBsqTx(txWithBtcFee, new TxBroadcaster.Callback() { + @Override + public void onSuccess(Transaction transaction) { + log.debug("Successfully sent tx with id " + txWithBtcFee.getHashAsString()); + } + + @Override + public void onTimeout(TxBroadcastTimeoutException exception) { + //TODO handle + new Popup<>().warning(exception.toString()); + } + + @Override + public void onTxMalleability(TxMalleabilityException exception) { + //TODO handle + new Popup<>().warning(exception.toString()); + } + + @Override + public void onFailure(TxBroadcastException exception) { + //TODO handle + new Popup<>().warning(exception.toString()); + } + }); + resultHandler.handleResult(); + }) + .closeButtonText(Res.get("shared.cancel")) + .show(); } } diff --git a/src/main/java/bisq/desktop/main/overlays/windows/EmptyWalletWindow.java b/src/main/java/bisq/desktop/main/overlays/windows/EmptyWalletWindow.java index 06d410dffc7..2281ed72166 100644 --- a/src/main/java/bisq/desktop/main/overlays/windows/EmptyWalletWindow.java +++ b/src/main/java/bisq/desktop/main/overlays/windows/EmptyWalletWindow.java @@ -156,7 +156,7 @@ private void addContent() { addressInputTextField = addLabelInputTextField(gridPane, ++rowIndex, Res.get("emptyWalletWindow.address")).second; } else { addLabelTextField(gridPane, ++rowIndex, Res.get("emptyWalletWindow.bsq.btcBalance"), - bsqFormatter.formatSatoshi(bsqWalletService.getAvailableNonBsqBalance().value), 10); + bsqFormatter.formatBtcSatoshi(bsqWalletService.getAvailableNonBsqBalance().value), 10); } closeButton = new AutoTooltipButton(Res.get("shared.cancel")); closeButton.setOnAction(e -> { From d4a02872922fcf3d83f6fffba3244a59b9e77bfb Mon Sep 17 00:00:00 2001 From: sqrrm Date: Thu, 12 Jul 2018 19:01:06 +0200 Subject: [PATCH 132/197] Remove getValueLockedUpInBond --- .../desktop/main/dao/bonding/unlock/LockedTxListItem.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedTxListItem.java b/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedTxListItem.java index 4f146e0e6de..dde2eaea57d 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedTxListItem.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedTxListItem.java @@ -56,7 +56,7 @@ class LockedTxListItem { private final String txId; private int confirmations = 0; - private Coin amount; + private Coin amount = Coin.ZERO; private int lockTime; private AutoTooltipButton button; @@ -86,7 +86,8 @@ class LockedTxListItem { checkNotNull(transaction, "transaction must not be null as we only have list items from transactions " + "which are available in the wallet"); - amount = bsqWalletService.getValueLockedUpInBond(transaction); + stateService.getLockupTxOutput(transaction.getHashAsString()).ifPresent( + out -> amount = Coin.valueOf(out.getValue())); //TODO SQ: use DaoFacade instead of direct access to stateService Optional opLockTime = stateService.getLockTime(transaction.getHashAsString()); From 5011d4f629098e9b062edf43607f83e8c5b2caa3 Mon Sep 17 00:00:00 2001 From: sqrrm Date: Fri, 13 Jul 2018 15:36:13 +0200 Subject: [PATCH 133/197] Use daoFacade from outside of core Rename locked to lockup where appropriate --- .../desktop/main/dao/bonding/unlock/LockedTxListItem.java | 6 ++---- .../bisq/desktop/main/dao/bonding/unlock/UnlockView.java | 6 ++---- .../desktop/main/dao/wallet/dashboard/BsqDashboardView.java | 2 +- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedTxListItem.java b/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedTxListItem.java index dde2eaea57d..83cfd15c8fc 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedTxListItem.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedTxListItem.java @@ -89,8 +89,7 @@ class LockedTxListItem { stateService.getLockupTxOutput(transaction.getHashAsString()).ifPresent( out -> amount = Coin.valueOf(out.getValue())); - //TODO SQ: use DaoFacade instead of direct access to stateService - Optional opLockTime = stateService.getLockTime(transaction.getHashAsString()); + Optional opLockTime = daoFacade.getLockTime(transaction.getHashAsString()); lockTime = opLockTime.orElse(-1); button = new AutoTooltipButton(); @@ -133,9 +132,8 @@ public void cleanup() { bsqWalletService.removeTxConfidenceListener(txConfidenceListener); } - // TODO SQ use daoFacade public boolean isSpent() { - Optional optionalTxOutput = stateService.getLockupTxOutput(txId); + Optional optionalTxOutput = daoFacade.getLockupTxOutput(txId); if (!optionalTxOutput.isPresent()) return true; diff --git a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java index 16b1e7aa6b1..8e17443664a 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java @@ -310,16 +310,14 @@ public void updateItem(final LockedTxListItem item, boolean empty) { private void onButtonClick() { if (GUIUtil.isReadyForTxBroadcast(p2PService, walletsSetup)) { - // TODO SQ use daoFacade - Optional lockedTxOutput = stateService.getLockupTxOutput(selectedItem.getTxId()); + Optional lockedTxOutput = daoFacade.getLockupTxOutput(selectedItem.getTxId()); if (!lockedTxOutput.isPresent()) { log.warn("Locked output not found, txId = ", selectedItem.getTxId()); return; } Coin unlockAmount = Coin.valueOf(lockedTxOutput.get().getValue()); - //TODO SQ: use DaoFacade instead of direct access to stateService - Optional opLockTime = stateService.getLockTime(selectedItem.getTxId()); + Optional opLockTime = daoFacade.getLockTime(selectedItem.getTxId()); int lockTime = opLockTime.isPresent() ? opLockTime.get() : -1; try { diff --git a/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java b/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java index 2fdafd4fb27..ed0c4e82277 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java @@ -167,7 +167,7 @@ private void updateWithBsqBlockChainData() { compRequestIssueAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(issuedAmountFromCompRequests)); Coin burntFee = Coin.valueOf(daoFacade.getTotalBurntFee()); - Coin totalLockedUpAmount = Coin.valueOf(daoFacade.getTotalLockedUpAmount()); + Coin totalLockedUpAmount = Coin.valueOf(daoFacade.getTotalLockupAmount()); Coin totalUnlockingAmount = Coin.valueOf(daoFacade.getTotalAmountOfUnLockingTxOutputs()); Coin totalUnlockedAmount = Coin.valueOf(daoFacade.getTotalAmountOfUnLockedTxOutputs()); Coin availableAmount = issuedAmountFromGenesis.add(issuedAmountFromCompRequests).subtract(burntFee); From 069802bbe509f4535cbabc07058c401eddd6c5b1 Mon Sep 17 00:00:00 2001 From: sqrrm Date: Fri, 13 Jul 2018 15:57:04 +0200 Subject: [PATCH 134/197] Rename locked to lockup To avoid confusion and be more specific, 'lockup' should be used when refering to LOCKUP outputs. This is to keep the more generic usage of 'locked' as referring to funds that can't be spent right now for whatever reason --- .../main/dao/bonding/lockup/LockupView.java | 7 +- ...dTxListItem.java => LockupTxListItem.java} | 6 +- .../main/dao/bonding/unlock/UnlockView.java | 95 +++++++++---------- .../dao/voting/active/ActiveBallotsView.java | 4 +- .../main/dao/wallet/BsqBalanceUtil.java | 20 ++-- .../main/dao/wallet/send/BsqSendView.java | 8 +- .../desktop/main/dao/wallet/tx/BsqTxView.java | 2 +- 7 files changed, 70 insertions(+), 72 deletions(-) rename src/main/java/bisq/desktop/main/dao/bonding/unlock/{LockedTxListItem.java => LockupTxListItem.java} (97%) diff --git a/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java b/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java index f889cbb01b3..2e26def51da 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java @@ -109,7 +109,6 @@ private LockupView(BsqWalletService bsqWalletService, @Override public void initialize() { - // TODO: Show balance locked up in bonds gridRow = bsqBalanceUtil.addGroup(root, gridRow); addTitledGroupBg(root, ++gridRow, 4, Res.get("dao.bonding.lock.lockBSQ"), Layout.GROUP_DISTANCE); @@ -129,7 +128,7 @@ public void initialize() { bsqWalletService.getAvailableNonBsqBalance(), bsqWalletService.getUnverifiedBalance(), bsqWalletService.getLockedForVotingBalance(), - bsqWalletService.getLockedInBondsBalance(), + bsqWalletService.getLockupBondsBalance(), bsqWalletService.getUnlockingBondsBalance()); }; @@ -189,7 +188,7 @@ protected void activate() { bsqWalletService.getAvailableNonBsqBalance(), bsqWalletService.getUnverifiedBalance(), bsqWalletService.getLockedForVotingBalance(), - bsqWalletService.getLockedInBondsBalance(), + bsqWalletService.getLockupBondsBalance(), bsqWalletService.getUnlockingBondsBalance()); } @@ -205,7 +204,7 @@ public void onUpdateBalances(Coin confirmedBalance, Coin availableNonBsqBalance, Coin pendingBalance, Coin lockedForVotingBalance, - Coin lockedInBondsBalance, + Coin lockupBondsBalance, Coin unlockingBondsBalance) { bsqValidator.setAvailableBalance(confirmedBalance); boolean isValid = bsqValidator.validate(amountInputTextField.getText()).isValid; diff --git a/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedTxListItem.java b/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockupTxListItem.java similarity index 97% rename from src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedTxListItem.java rename to src/main/java/bisq/desktop/main/dao/bonding/unlock/LockupTxListItem.java index 83cfd15c8fc..8af2df71d7d 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockedTxListItem.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockupTxListItem.java @@ -45,7 +45,7 @@ import static com.google.common.base.Preconditions.checkNotNull; @Data -class LockedTxListItem { +class LockupTxListItem { private final Transaction transaction; private final BsqWalletService bsqWalletService; private final BtcWalletService btcWalletService; @@ -64,7 +64,7 @@ class LockedTxListItem { private TxConfidenceListener txConfidenceListener; private boolean issuanceTx; - LockedTxListItem(Transaction transaction, + LockupTxListItem(Transaction transaction, BsqWalletService bsqWalletService, BtcWalletService btcWalletService, DaoFacade daoFacade, @@ -124,7 +124,7 @@ private void updateConfidence(TransactionConfidence confidence, Tooltip tooltip) } } - public boolean isLockedAndUnspent() { + public boolean isLockupAndUnspent() { return !isSpent() && getTxType() == TxType.LOCKUP; } diff --git a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java index 8e17443664a..edc577aec69 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java @@ -82,7 +82,7 @@ @FxmlView public class UnlockView extends ActivatableView implements BsqBalanceListener, BlockListener { - private TableView tableView; + private TableView tableView; private final BsqWalletService bsqWalletService; private final BtcWalletService btcWalletService; @@ -98,10 +98,10 @@ public class UnlockView extends ActivatableView implements BsqBa private int gridRow = 0; private boolean synced; - private LockedTxListItem selectedItem; + private LockupTxListItem selectedItem; - private final ObservableList observableList = FXCollections.observableArrayList(); - private final FilteredList lockedTxs = new FilteredList<>(observableList); + private final ObservableList observableList = FXCollections.observableArrayList(); + private final FilteredList lockupTxs = new FilteredList<>(observableList); private ListChangeListener walletBsqTransactionsListener; private ChangeListener walletChainHeightListener; @@ -138,7 +138,6 @@ private UnlockView(BsqWalletService bsqWalletService, @Override public void initialize() { - // TODO: Show balance locked up in bonds gridRow = bsqBalanceUtil.addGroup(root, gridRow); tableView = new TableView<>(); @@ -149,7 +148,7 @@ public void initialize() { addLockTimeColumn(); addUnlockColumn(); - lockedTxs.setPredicate(LockedTxListItem::isLockedAndUnspent); + lockupTxs.setPredicate(LockupTxListItem::isLockupAndUnspent); walletBsqTransactionsListener = change -> updateList(); walletChainHeightListener = (observable, oldValue, newValue) -> onUpdateAnyChainHeight(); @@ -164,22 +163,22 @@ public void initialize() { } private void addTxIdColumn() { - TableColumn column = new AutoTooltipTableColumn<>(Res.get("shared.txId")); + TableColumn column = new AutoTooltipTableColumn<>(Res.get("shared.txId")); column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); column.setMinWidth(60); column.setCellFactory( - new Callback, TableCell>() { + new Callback, TableCell>() { @Override - public TableCell call(TableColumn column) { - return new TableCell() { + public TableCell call(TableColumn column) { + return new TableCell() { private HyperlinkWithIcon hyperlinkWithIcon; @Override - public void updateItem(final LockedTxListItem item, boolean empty) { + public void updateItem(final LockupTxListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { @@ -201,22 +200,22 @@ public void updateItem(final LockedTxListItem item, boolean empty) { } private void addAmountColumn() { - TableColumn column = + TableColumn column = new AutoTooltipTableColumn<>(Res.get("shared.amountWithCur", "BSQ")); column.setMinWidth(120); column.setMaxWidth(column.getMinWidth()); column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - column.setCellFactory(new Callback, - TableCell>() { + column.setCellFactory(new Callback, + TableCell>() { @Override - public TableCell call(TableColumn column) { - return new TableCell() { + public TableCell call(TableColumn column) { + return new TableCell() { @Override - public void updateItem(final LockedTxListItem item, boolean empty) { + public void updateItem(final LockupTxListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { TxType txType = item.getTxType(); @@ -233,22 +232,22 @@ public void updateItem(final LockedTxListItem item, boolean empty) { } private void addLockTimeColumn() { - TableColumn column = + TableColumn column = new AutoTooltipTableColumn<>(Res.get("dao.bonding.unlock.time")); column.setMinWidth(120); column.setMaxWidth(column.getMinWidth()); column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - column.setCellFactory(new Callback, - TableCell>() { + column.setCellFactory(new Callback, + TableCell>() { @Override - public TableCell call(TableColumn column) { - return new TableCell() { + public TableCell call(TableColumn column) { + return new TableCell() { @Override - public void updateItem(final LockedTxListItem item, boolean empty) { + public void updateItem(final LockupTxListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { TxType txType = item.getTxType(); @@ -265,23 +264,23 @@ public void updateItem(final LockedTxListItem item, boolean empty) { } private void addUnlockColumn() { - TableColumn unlockColumn = new TableColumn<>(); + TableColumn unlockColumn = new TableColumn<>(); unlockColumn.setMinWidth(130); unlockColumn.setMaxWidth(unlockColumn.getMinWidth()); unlockColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - unlockColumn.setCellFactory(new Callback, - TableCell>() { + unlockColumn.setCellFactory(new Callback, + TableCell>() { @Override - public TableCell call(TableColumn column) { - return new TableCell() { + public TableCell call(TableColumn column) { + return new TableCell() { Button button; @Override - public void updateItem(final LockedTxListItem item, boolean empty) { + public void updateItem(final LockupTxListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { @@ -304,19 +303,19 @@ public void updateItem(final LockedTxListItem item, boolean empty) { }; } }); - unlockColumn.setComparator(Comparator.comparing(LockedTxListItem::getConfirmations)); + unlockColumn.setComparator(Comparator.comparing(LockupTxListItem::getConfirmations)); tableView.getColumns().add(unlockColumn); } private void onButtonClick() { if (GUIUtil.isReadyForTxBroadcast(p2PService, walletsSetup)) { - Optional lockedTxOutput = daoFacade.getLockupTxOutput(selectedItem.getTxId()); - if (!lockedTxOutput.isPresent()) { - log.warn("Locked output not found, txId = ", selectedItem.getTxId()); + Optional lockupTxOutput = daoFacade.getLockupTxOutput(selectedItem.getTxId()); + if (!lockupTxOutput.isPresent()) { + log.warn("Lockup output not found, txId = ", selectedItem.getTxId()); return; } - Coin unlockAmount = Coin.valueOf(lockedTxOutput.get().getValue()); + Coin unlockAmount = Coin.valueOf(lockupTxOutput.get().getValue()); Optional opLockTime = daoFacade.getLockTime(selectedItem.getTxId()); int lockTime = opLockTime.isPresent() ? opLockTime.get() : -1; @@ -358,7 +357,7 @@ private void onButtonClick() { log.info("unlock tx: {}", selectedItem.getTxId()); } - private void openTxInBlockExplorer(LockedTxListItem item) { + private void openTxInBlockExplorer(LockupTxListItem item) { if (item.getTxId() != null) GUIUtil.openWebPage(preferences.getBsqBlockChainExplorer().txUrl + item.getTxId()); } @@ -371,14 +370,14 @@ protected void activate() { bsqWalletService.getAvailableNonBsqBalance(), bsqWalletService.getUnverifiedBalance(), bsqWalletService.getLockedForVotingBalance(), - bsqWalletService.getLockedInBondsBalance(), + bsqWalletService.getLockupBondsBalance(), bsqWalletService.getUnlockingBondsBalance()); bsqWalletService.getWalletTransactions().addListener(walletBsqTransactionsListener); bsqWalletService.addBsqBalanceListener(this); btcWalletService.getChainHeightProperty().addListener(walletChainHeightListener); - tableView.setItems(lockedTxs); + tableView.setItems(lockupTxs); daoFacade.addBlockListener(this); @@ -401,13 +400,13 @@ private void onUpdateAnyChainHeight() { } private void updateList() { - observableList.forEach(LockedTxListItem::cleanup); + observableList.forEach(LockupTxListItem::cleanup); // copy list to avoid ConcurrentModificationException final List walletTransactions = new ArrayList<>(bsqWalletService.getWalletTransactions()); - List items = walletTransactions.stream() + List items = walletTransactions.stream() .map(transaction -> { - return new LockedTxListItem(transaction, + return new LockupTxListItem(transaction, bsqWalletService, btcWalletService, daoFacade, @@ -424,13 +423,13 @@ protected void deactivate() { bsqBalanceUtil.deactivate(); bsqWalletService.removeBsqBalanceListener(this); - lockedTxs.predicateProperty().unbind(); + lockupTxs.predicateProperty().unbind(); bsqWalletService.getWalletTransactions().removeListener(walletBsqTransactionsListener); bsqWalletService.removeBsqBalanceListener(this); btcWalletService.getChainHeightProperty().removeListener(walletChainHeightListener); daoFacade.removeBlockListener(this); - observableList.forEach(LockedTxListItem::cleanup); + observableList.forEach(LockupTxListItem::cleanup); } @Override @@ -438,7 +437,7 @@ public void onUpdateBalances(Coin confirmedBalance, Coin availableNonBsqBalance, Coin pendingBalance, Coin lockedForVotingBalance, - Coin lockedInBondsBalance, + Coin lockupBondsBalance, Coin unlockingBondsBalance) { bsqValidator.setAvailableBalance(confirmedBalance); } diff --git a/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.java b/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.java index 8cc9fc33ca1..1bf63b9210b 100644 --- a/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.java +++ b/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.java @@ -115,7 +115,7 @@ protected void activate() { bsqWalletService.getAvailableNonBsqBalance(), bsqWalletService.getUnverifiedBalance(), bsqWalletService.getLockedForVotingBalance(), - bsqWalletService.getLockedInBondsBalance(), + bsqWalletService.getLockupBondsBalance(), bsqWalletService.getUnlockingBondsBalance()); voteButton.setOnAction(e -> onVote()); @@ -144,7 +144,7 @@ public void onUpdateBalances(Coin confirmedBalance, Coin availableNonBsqBalance, Coin pendingBalance, Coin lockedForVotingBalance, - Coin lockedInBondsBalance, + Coin lockupBondsBalance, Coin unlockingBondsBalance) { stakeInputTextField.setPromptText(Res.get("dao.proposal.myVote.stake.prompt", bsqFormatter.formatCoinWithCode(confirmedBalance))); diff --git a/src/main/java/bisq/desktop/main/dao/wallet/BsqBalanceUtil.java b/src/main/java/bisq/desktop/main/dao/wallet/BsqBalanceUtil.java index 51d8d23e520..3014f451d65 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/BsqBalanceUtil.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/BsqBalanceUtil.java @@ -46,7 +46,7 @@ public class BsqBalanceUtil implements BsqBalanceListener { lockedInBondsBalanceTextField, totalBalanceTextField; // Displaying bond dashboard info - private TextField lockedAmountTextField, unlockingAmountTextField; + private TextField lockupAmountTextField, unlockingAmountTextField; @Inject private BsqBalanceUtil(BsqWalletService bsqWalletService, @@ -84,11 +84,11 @@ public int addGroup(GridPane gridPane, int gridRow) { } public int addBondBalanceGroup(GridPane gridPane, int gridRow) { - addTitledGroupBg(gridPane, ++gridRow, 2, Res.get("dao.bonding.dashboard.lockedHeadline"), Layout.GROUP_DISTANCE); + addTitledGroupBg(gridPane, ++gridRow, 2, Res.get("dao.bonding.dashboard.bondsHeadline"), Layout.GROUP_DISTANCE); - lockedAmountTextField = addLabelTextField(gridPane, gridRow, Res.get("dao.bonding.dashboard.lockedAmount"), + lockupAmountTextField = addLabelTextField(gridPane, gridRow, Res.get("dao.bonding.dashboard.lockupAmount"), Layout.FIRST_ROW_DISTANCE + Layout.GROUP_DISTANCE).second; - lockedAmountTextField.setMouseTransparent(false); + lockupAmountTextField.setMouseTransparent(false); unlockingAmountTextField = addLabelTextField(gridPane, ++gridRow, Res.get("dao.bonding.dashboard.unlockingAmount")).second; unlockingAmountTextField.setMouseTransparent(false); @@ -101,7 +101,7 @@ public void activate() { bsqWalletService.getAvailableNonBsqBalance(), bsqWalletService.getUnverifiedBalance(), bsqWalletService.getLockedForVotingBalance(), - bsqWalletService.getLockedInBondsBalance(), + bsqWalletService.getLockupBondsBalance(), bsqWalletService.getUnlockingBondsBalance()); bsqWalletService.addBsqBalanceListener(this); } @@ -116,24 +116,24 @@ public void onUpdateBalances(Coin availableBalance, Coin availableNonBsqBalance, Coin unverifiedBalance, Coin lockedForVotingBalance, - Coin lockedInBondsBalance, + Coin lockupBondsBalance, Coin unlockingBondsBalance) { availableBalanceTextField.setText(bsqFormatter.formatCoinWithCode(availableBalance)); availableNonBsqBalanceTextField.setText(bsqFormatter.formatBtcSatoshi(availableNonBsqBalance.value)); unverifiedBalanceTextField.setText(bsqFormatter.formatCoinWithCode(unverifiedBalance)); lockedForVoteBalanceTextField.setText(bsqFormatter.formatCoinWithCode(lockedForVotingBalance)); lockedInBondsBalanceTextField.setText(bsqFormatter.formatCoinWithCode( - lockedInBondsBalance.add(unlockingBondsBalance))); + lockupBondsBalance.add(unlockingBondsBalance))); - if (lockedAmountTextField != null && unlockingAmountTextField != null) { - lockedAmountTextField.setText(bsqFormatter.formatCoinWithCode(lockedInBondsBalance)); + if (lockupAmountTextField != null && unlockingAmountTextField != null) { + lockupAmountTextField.setText(bsqFormatter.formatCoinWithCode(lockupBondsBalance)); unlockingAmountTextField.setText(bsqFormatter.formatCoinWithCode(unlockingBondsBalance)); } final Coin total = availableBalance .add(unverifiedBalance) .add(lockedForVotingBalance) - .add(lockedInBondsBalance) + .add(lockupBondsBalance) .add(unlockingBondsBalance); totalBalanceTextField.setText(bsqFormatter.formatCoinWithCode(total)); } diff --git a/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java b/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java index 67e5ddcbab0..693fd9ebcaf 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java @@ -142,7 +142,7 @@ public void initialize() { bsqWalletService.getAvailableNonBsqBalance(), bsqWalletService.getUnverifiedBalance(), bsqWalletService.getLockedForVotingBalance(), - bsqWalletService.getLockedInBondsBalance(), + bsqWalletService.getLockupBondsBalance(), bsqWalletService.getUnlockingBondsBalance()); }; @@ -164,7 +164,7 @@ protected void activate() { bsqWalletService.getAvailableNonBsqBalance(), bsqWalletService.getUnverifiedBalance(), bsqWalletService.getLockedForVotingBalance(), - bsqWalletService.getLockedInBondsBalance(), + bsqWalletService.getLockupBondsBalance(), bsqWalletService.getUnlockingBondsBalance()); } @@ -182,7 +182,7 @@ public void onUpdateBalances(Coin availableBalance, Coin availableNonBsqBalance, Coin unverifiedBalance, Coin lockedForVotingBalance, - Coin lockedInBondsBalance, + Coin lockupBondsBalance, Coin unlockingBondsBalance) { bsqValidator.setAvailableBalance(availableBalance); boolean isValid = bsqAddressValidator.validate(receiversAddressInputTextField.getText()).isValid && @@ -215,7 +215,7 @@ private void addSendBsqGroup() { bsqWalletService.getAvailableNonBsqBalance(), bsqWalletService.getUnverifiedBalance(), bsqWalletService.getLockedForVotingBalance(), - bsqWalletService.getLockedInBondsBalance(), + bsqWalletService.getLockupBondsBalance(), bsqWalletService.getUnlockingBondsBalance()); }; diff --git a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java index ee3a403b00a..fcbc943a49e 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java @@ -195,7 +195,7 @@ public void onUpdateBalances(Coin confirmedBalance, Coin availableNonBsqBalance, Coin pendingBalance, Coin lockedForVotingBalance, - Coin lockedInBondsBalance, + Coin lockupBondsBalance, Coin unlockingBondsBalance) { updateList(); } From b7f131f6845ba0880e7158b3b37d4b9140ec9759 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Fri, 13 Jul 2018 20:18:40 +0200 Subject: [PATCH 135/197] Add TODOs --- .../main/dao/bonding/unlock/LockupTxListItem.java | 13 ++++++++----- .../desktop/main/dao/bonding/unlock/UnlockView.java | 7 ++++++- .../main/dao/wallet/dashboard/BsqDashboardView.java | 2 +- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockupTxListItem.java b/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockupTxListItem.java index 8af2df71d7d..1efa5eec582 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockupTxListItem.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockupTxListItem.java @@ -50,7 +50,10 @@ class LockupTxListItem { private final BsqWalletService bsqWalletService; private final BtcWalletService btcWalletService; private final DaoFacade daoFacade; + + //TODO SQ stateService should not be used outside in desktop private final StateService stateService; + private final BsqFormatter bsqFormatter; private final Date date; private final String txId; @@ -86,8 +89,9 @@ class LockupTxListItem { checkNotNull(transaction, "transaction must not be null as we only have list items from transactions " + "which are available in the wallet"); - stateService.getLockupTxOutput(transaction.getHashAsString()).ifPresent( - out -> amount = Coin.valueOf(out.getValue())); + //TODO SQ use daoFacade + stateService.getLockupTxOutput(transaction.getHashAsString()) + .ifPresent(out -> amount = Coin.valueOf(out.getValue())); Optional opLockTime = daoFacade.getLockTime(transaction.getHashAsString()); lockTime = opLockTime.orElse(-1); @@ -134,10 +138,9 @@ public void cleanup() { public boolean isSpent() { Optional optionalTxOutput = daoFacade.getLockupTxOutput(txId); - if (!optionalTxOutput.isPresent()) - return true; + return optionalTxOutput.map(txOutput -> !stateService.isUnspent(txOutput.getKey())) + .orElse(true); - return !stateService.isUnspent(optionalTxOutput.get().getKey()); } public TxType getTxType() { diff --git a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java index edc577aec69..20c197ad384 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java @@ -91,7 +91,10 @@ public class UnlockView extends ActivatableView implements BsqBa private final BsqValidator bsqValidator; private final DaoFacade daoFacade; private final Preferences preferences; + + //TODO SQ stateService should not be used outside in desktop private final StateService stateService; + private final WalletsSetup walletsSetup; private final P2PService p2PService; private final Navigation navigation; @@ -317,7 +320,7 @@ private void onButtonClick() { Coin unlockAmount = Coin.valueOf(lockupTxOutput.get().getValue()); Optional opLockTime = daoFacade.getLockTime(selectedItem.getTxId()); - int lockTime = opLockTime.isPresent() ? opLockTime.get() : -1; + int lockTime = opLockTime.orElse(-1); try { new Popup<>().headLine(Res.get("dao.bonding.unlock.sendTx.headline")) @@ -337,6 +340,8 @@ private void onButtonClick() { .closeButtonText(Res.get("shared.cancel")) .show(); } catch (Throwable t) { + //TODO SQ conde analysis of intellij says that the following is always false, but don't understand why... + // but mostly they are right ;-) if (t instanceof InsufficientMoneyException) { final Coin missingCoin = ((InsufficientMoneyException) t).missing; final String missing = missingCoin != null ? missingCoin.toFriendlyString() : "null"; diff --git a/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java b/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java index ed0c4e82277..2f3a5e39102 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java @@ -151,7 +151,7 @@ protected void deactivate() { /////////////////////////////////////////////////////////////////////////////////////////// - // StateService.Listener + // BlockListener /////////////////////////////////////////////////////////////////////////////////////////// @Override From f307b1e336acb98663e66a31b688eea3393bb192 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Fri, 13 Jul 2018 21:09:07 +0200 Subject: [PATCH 136/197] Remove unneeded model --- .../desktop/main/account/AccountView.java | 5 ++-- .../main/account/AccountViewModel.java | 29 ------------------- 2 files changed, 2 insertions(+), 32 deletions(-) delete mode 100644 src/main/java/bisq/desktop/main/account/AccountViewModel.java diff --git a/src/main/java/bisq/desktop/main/account/AccountView.java b/src/main/java/bisq/desktop/main/account/AccountView.java index 4b1480eea55..e843e0dc43c 100644 --- a/src/main/java/bisq/desktop/main/account/AccountView.java +++ b/src/main/java/bisq/desktop/main/account/AccountView.java @@ -49,7 +49,7 @@ import javafx.event.EventHandler; @FxmlView -public class AccountView extends ActivatableView { +public class AccountView extends ActivatableView { @FXML Tab accountSettingsTab; @@ -67,8 +67,7 @@ public class AccountView extends ActivatableView { private EventHandler keyEventEventHandler; @Inject - private AccountView(AccountViewModel model, CachingViewLoader viewLoader, Navigation navigation) { - super(model); + private AccountView(CachingViewLoader viewLoader, Navigation navigation) { this.viewLoader = viewLoader; this.navigation = navigation; } diff --git a/src/main/java/bisq/desktop/main/account/AccountViewModel.java b/src/main/java/bisq/desktop/main/account/AccountViewModel.java deleted file mode 100644 index 84af84cde7e..00000000000 --- a/src/main/java/bisq/desktop/main/account/AccountViewModel.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.desktop.main.account; - -import bisq.desktop.common.model.ViewModel; - -import com.google.inject.Inject; - -class AccountViewModel implements ViewModel { - - @Inject - public AccountViewModel() { - } -} From dfcda392d5e997faaab544309601cddfc5836bc4 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Fri, 13 Jul 2018 22:07:16 +0200 Subject: [PATCH 137/197] Handle case if multiple param proposals got voted ok --- src/main/java/bisq/desktop/main/account/AccountView.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/bisq/desktop/main/account/AccountView.java b/src/main/java/bisq/desktop/main/account/AccountView.java index e843e0dc43c..881ba0a75c5 100644 --- a/src/main/java/bisq/desktop/main/account/AccountView.java +++ b/src/main/java/bisq/desktop/main/account/AccountView.java @@ -60,7 +60,7 @@ public class AccountView extends ActivatableView { private final ViewLoader viewLoader; private final Navigation navigation; private Tab selectedTab; - Tab arbitratorRegistrationTab; + private Tab arbitratorRegistrationTab; private ArbitratorRegistrationView arbitratorRegistrationView; private AccountSettingsView accountSettingsView; private Scene scene; From 9f01e9e4e020f3512f6268be9528846514f024fd Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sun, 15 Jul 2018 10:52:40 +0200 Subject: [PATCH 138/197] Add voteResult view --- src/main/java/bisq/desktop/bisq.css | 8 + .../java/bisq/desktop/main/dao/DaoView.fxml | 3 - .../java/bisq/desktop/main/dao/DaoView.java | 22 +- .../main/dao/cycles/CyclesListItem.java | 73 +++ .../CyclesView.fxml} | 14 +- .../desktop/main/dao/cycles/CyclesView.java | 374 ++++++++++++++++ .../dao/cycles/cycle/CycleDetailsWindow.java | 88 ++++ .../main/dao/cycles/cycle/CycleDisplay.java | 419 ++++++++++++++++++ .../main/dao/cycles/cycle/CycleListItem.java | 99 +++++ .../main/dao/cycles/model/CycleResult.java | 76 ++++ .../main/dao/proposal/ProposalDisplay.java | 2 +- .../main/dao/proposal/ProposalView.java | 16 +- .../dashboard/ProposalDashboardView.java | 27 +- .../dao/proposal/make/MakeProposalView.java | 4 +- .../dao/proposal/myvotes/MyVotesView.java | 363 --------------- .../dao/proposal/myvotes/VoteListItem.java | 196 -------- .../main/dao/proposal/votes/VotesView.fxml | 33 -- .../main/dao/proposal/votes/VotesView.java | 50 --- src/main/java/bisq/desktop/util/GUIUtil.java | 11 +- .../java/bisq/desktop/AwesomeFontDemo.java | 2 +- 20 files changed, 1192 insertions(+), 688 deletions(-) create mode 100644 src/main/java/bisq/desktop/main/dao/cycles/CyclesListItem.java rename src/main/java/bisq/desktop/main/dao/{proposal/myvotes/MyVotesView.fxml => cycles/CyclesView.fxml} (76%) create mode 100644 src/main/java/bisq/desktop/main/dao/cycles/CyclesView.java create mode 100644 src/main/java/bisq/desktop/main/dao/cycles/cycle/CycleDetailsWindow.java create mode 100644 src/main/java/bisq/desktop/main/dao/cycles/cycle/CycleDisplay.java create mode 100644 src/main/java/bisq/desktop/main/dao/cycles/cycle/CycleListItem.java create mode 100644 src/main/java/bisq/desktop/main/dao/cycles/model/CycleResult.java delete mode 100644 src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java delete mode 100644 src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java delete mode 100644 src/main/java/bisq/desktop/main/dao/proposal/votes/VotesView.fxml delete mode 100644 src/main/java/bisq/desktop/main/dao/proposal/votes/VotesView.java diff --git a/src/main/java/bisq/desktop/bisq.css b/src/main/java/bisq/desktop/bisq.css index ae7a42c387a..e619c38fa3b 100644 --- a/src/main/java/bisq/desktop/bisq.css +++ b/src/main/java/bisq/desktop/bisq.css @@ -373,6 +373,14 @@ bg color of non edit textFields: fafafa -fx-text-fill: -bs-green; } +.dao-accepted-icon { + -fx-text-fill: -bs-green; +} + +.dao-rejected-icon { + -fx-text-fill: -bs-error-red; +} + .version { -fx-text-fill: black; -fx-underline: false; diff --git a/src/main/java/bisq/desktop/main/dao/DaoView.fxml b/src/main/java/bisq/desktop/main/dao/DaoView.fxml index 90bd84c653d..5c75ca6afbd 100644 --- a/src/main/java/bisq/desktop/main/dao/DaoView.fxml +++ b/src/main/java/bisq/desktop/main/dao/DaoView.fxml @@ -17,13 +17,10 @@ ~ along with Bisq. If not, see . --> - - - diff --git a/src/main/java/bisq/desktop/main/dao/DaoView.java b/src/main/java/bisq/desktop/main/dao/DaoView.java index 93e59ab82e9..73f18eef6d1 100644 --- a/src/main/java/bisq/desktop/main/dao/DaoView.java +++ b/src/main/java/bisq/desktop/main/dao/DaoView.java @@ -26,6 +26,7 @@ import bisq.desktop.common.view.ViewLoader; import bisq.desktop.main.MainView; import bisq.desktop.main.dao.bonding.BondingView; +import bisq.desktop.main.dao.cycles.CyclesView; import bisq.desktop.main.dao.proposal.ProposalView; import bisq.desktop.main.dao.voting.VotingView; import bisq.desktop.main.dao.wallet.BsqWalletView; @@ -49,7 +50,7 @@ public class DaoView extends ActivatableViewAndModel { @FXML - Tab bsqWalletTab, proposalsTab, votingTab, bondingTab; + Tab bsqWalletTab, proposalsTab, votingTab, resultsTab, bondingTab; private Navigation.Listener navigationListener; private ChangeListener tabChangeListener; @@ -68,22 +69,27 @@ private DaoView(CachingViewLoader viewLoader, Navigation navigation) { @Override public void initialize() { + bsqWalletTab = new Tab(Res.get("dao.tab.bsqWallet")); proposalsTab = new Tab(Res.get("dao.tab.proposals")); votingTab = new Tab(Res.get("dao.tab.voting")); + resultsTab = new Tab(Res.get("dao.tab.results")); bondingTab = new Tab(Res.get("dao.tab.bonding")); + + bsqWalletTab.setClosable(false); proposalsTab.setClosable(false); votingTab.setClosable(false); + resultsTab.setClosable(false); bondingTab.setClosable(false); - root.getTabs().addAll(proposalsTab, votingTab, bondingTab); + + root.getTabs().addAll(bsqWalletTab, proposalsTab, votingTab, resultsTab, bondingTab); if (!BisqEnvironment.isDAOActivatedAndBaseCurrencySupportingBsq() || !DevEnv.isDaoPhase2Activated()) { votingTab.setDisable(true); bondingTab.setDisable(true); + resultsTab.setDisable(true); proposalsTab.setDisable(true); } - bsqWalletTab.setText(Res.get("dao.tab.bsqWallet")); - navigationListener = viewPath -> { if (viewPath.size() == 3 && viewPath.indexOf(DaoView.class) == 1) { if (proposalsTab == null && viewPath.get(2).equals(BsqWalletView.class)) @@ -109,6 +115,9 @@ public void initialize() { } else if (newValue == votingTab) { //noinspection unchecked navigation.navigateTo(MainView.class, DaoView.class, VotingView.class); + } else if (newValue == resultsTab) { + //noinspection unchecked + navigation.navigateTo(MainView.class, DaoView.class, CyclesView.class); } else if (newValue == bondingTab) { //noinspection unchecked navigation.navigateTo(MainView.class, DaoView.class, BondingView.class); @@ -132,6 +141,9 @@ else if (selectedItem == proposalsTab) else if (selectedItem == votingTab) //noinspection unchecked navigation.navigateTo(MainView.class, DaoView.class, VotingView.class); + else if (selectedItem == resultsTab) + //noinspection unchecked + navigation.navigateTo(MainView.class, DaoView.class, CyclesView.class); else if (selectedItem == bondingTab) //noinspection unchecked navigation.navigateTo(MainView.class, DaoView.class, BondingView.class); @@ -153,6 +165,8 @@ private void loadView(Class viewClass) { selectedTab = proposalsTab; } else if (view instanceof VotingView) { selectedTab = votingTab; + } else if (view instanceof CyclesView) { + selectedTab = resultsTab; } else if (view instanceof BondingView) { selectedTab = bondingTab; } diff --git a/src/main/java/bisq/desktop/main/dao/cycles/CyclesListItem.java b/src/main/java/bisq/desktop/main/dao/cycles/CyclesListItem.java new file mode 100644 index 00000000000..f7b1cf13734 --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/cycles/CyclesListItem.java @@ -0,0 +1,73 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.desktop.main.dao.cycles; + +import bisq.desktop.main.dao.cycles.model.CycleResult; + +import bisq.core.dao.voting.proposal.compensation.CompensationProposal; +import bisq.core.locale.Res; +import bisq.core.util.BsqFormatter; + +import org.bitcoinj.core.Coin; + +import java.util.Date; + +import lombok.Getter; + +public class CyclesListItem { + private BsqFormatter bsqFormatter; + @Getter + private CycleResult cycleResult; + + public CyclesListItem(CycleResult cycleResult, + BsqFormatter bsqFormatter) { + this.cycleResult = cycleResult; + this.bsqFormatter = bsqFormatter; + } + + public String getCycle() { + int displayIndex = cycleResult.getCycleIndex() + 1; + String dateTime = bsqFormatter.formatDateTime(new Date(cycleResult.getCycleStartTime())); + return Res.get("dao.results.results.table.item.cycle", displayIndex, dateTime); + } + + public String getNumProposals() { + return String.valueOf(cycleResult.getEvaluatedProposals().size()); + } + + public String getNumVotesAsString() { + return String.valueOf(cycleResult.getNumVotes()); + } + + public String getStake() { + return bsqFormatter.formatCoinWithCode(Coin.valueOf(cycleResult.getTotalStake())); + } + + public String getIssuance() { + long totalIssuance = cycleResult.getEvaluatedProposals().stream() + .filter(e -> e.getProposal() instanceof CompensationProposal) + .map(e -> (CompensationProposal) e.getProposal()) + .mapToLong(e -> e.getRequestedBsq().value) + .sum(); + return bsqFormatter.formatCoinWithCode(Coin.valueOf(totalIssuance)); + } + + public Long getCycleStartTime() { + return cycleResult.getCycleStartTime(); + } +} diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.fxml b/src/main/java/bisq/desktop/main/dao/cycles/CyclesView.fxml similarity index 76% rename from src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.fxml rename to src/main/java/bisq/desktop/main/dao/cycles/CyclesView.fxml index 9250e4571ab..ef067e5f4fd 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.fxml +++ b/src/main/java/bisq/desktop/main/dao/cycles/CyclesView.fxml @@ -17,17 +17,21 @@ ~ along with Bisq. If not, see . --> - - + + + + + - + diff --git a/src/main/java/bisq/desktop/main/dao/cycles/CyclesView.java b/src/main/java/bisq/desktop/main/dao/cycles/CyclesView.java new file mode 100644 index 00000000000..e68c8a3d90f --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/cycles/CyclesView.java @@ -0,0 +1,374 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.desktop.main.dao.cycles; + + +import bisq.desktop.common.model.Activatable; +import bisq.desktop.common.view.ActivatableViewAndModel; +import bisq.desktop.common.view.FxmlView; +import bisq.desktop.components.AutoTooltipLabel; +import bisq.desktop.components.AutoTooltipTableColumn; +import bisq.desktop.components.TableGroupHeadline; +import bisq.desktop.main.dao.cycles.cycle.CycleDisplay; +import bisq.desktop.main.dao.cycles.model.CycleResult; + +import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.dao.DaoFacade; +import bisq.core.dao.state.ChainHeightListener; +import bisq.core.dao.state.StateService; +import bisq.core.dao.state.period.Cycle; +import bisq.core.dao.state.period.CycleService; +import bisq.core.dao.voting.proposal.Proposal; +import bisq.core.dao.voting.proposal.ProposalService; +import bisq.core.dao.voting.proposal.storage.appendonly.ProposalPayload; +import bisq.core.dao.voting.voteresult.EvaluatedProposal; +import bisq.core.dao.voting.voteresult.VoteResultService; +import bisq.core.locale.Res; +import bisq.core.util.BsqFormatter; + +import javax.inject.Inject; + +import javafx.scene.control.ScrollPane; +import javafx.scene.control.TableCell; +import javafx.scene.control.TableColumn; +import javafx.scene.control.TableView; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.Priority; + +import javafx.geometry.Insets; + +import javafx.beans.property.ReadOnlyObjectWrapper; +import javafx.beans.value.ChangeListener; + +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.collections.transformation.SortedList; + +import javafx.util.Callback; + +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; + +@FxmlView +public class CyclesView extends ActivatableViewAndModel implements ChainHeightListener { + private final DaoFacade daoFacade; + // TODO use daoFacade once dev work completed + private final StateService stateService; + private final CycleService cycleService; + private final VoteResultService voteResultService; + private final ProposalService proposalService; + private final BsqWalletService bsqWalletService; + private final BsqFormatter bsqFormatter; + + private int gridRow = 0; + private TableView tableView; + + private final ObservableList itemList = FXCollections.observableArrayList(); + private final SortedList sortedList = new SortedList<>(itemList); + private ChangeListener selectedItemListener; + private CyclesListItem selectedItem; + + private GridPane resultGridPane; + private CycleDisplay proposalsDisplay; + private ScrollPane resultDisplayView; + private boolean resultDisplayInitialized; + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Constructor, lifecycle + /////////////////////////////////////////////////////////////////////////////////////////// + + @Inject + private CyclesView(DaoFacade daoFacade, + StateService stateService, + CycleService cycleService, + VoteResultService voteResultService, + ProposalService proposalService, + BsqWalletService bsqWalletService, + BsqFormatter bsqFormatter) { + this.daoFacade = daoFacade; + this.stateService = stateService; + this.cycleService = cycleService; + this.voteResultService = voteResultService; + this.proposalService = proposalService; + this.bsqWalletService = bsqWalletService; + this.bsqFormatter = bsqFormatter; + } + + @Override + public void initialize() { + daoFacade.addChainHeightListener(this); + + resultGridPane = new GridPane(); + createResultsTable(); + createResultDisplay(); + + selectedItemListener = (observable, oldValue, newValue) -> onCycleListItemSelected(newValue); + } + + @Override + protected void activate() { + tableView.getSelectionModel().selectedItemProperty().addListener(selectedItemListener); + fillCycleList(); + } + + @Override + protected void deactivate() { + tableView.getSelectionModel().selectedItemProperty().removeListener(selectedItemListener); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // ChainHeightListener + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public void onChainHeightChanged(int blockHeight) { + fillCycleList(); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // UI handlers + /////////////////////////////////////////////////////////////////////////////////////////// + + private void onCycleListItemSelected(CyclesListItem item) { + selectedItem = item; + if (selectedItem != null) + createAllFieldsOnResultDisplay(selectedItem); + else + hideResultDisplay(); + + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Create views + /////////////////////////////////////////////////////////////////////////////////////////// + + private void createResultsTable() { + TableGroupHeadline headline = new TableGroupHeadline(Res.get("dao.results.results.header")); + GridPane.setRowIndex(headline, ++gridRow); + GridPane.setMargin(headline, new Insets(0, -10, -10, -10)); + GridPane.setColumnSpan(headline, 2); + root.getChildren().add(headline); + + tableView = new TableView<>(); + tableView.setPlaceholder(new AutoTooltipLabel(Res.get("table.placeholder.noData"))); + tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); + tableView.setPrefHeight(200); + + createColumns(tableView); + GridPane.setRowIndex(tableView, gridRow); + GridPane.setMargin(tableView, new Insets(20, -10, 5, -10)); + GridPane.setColumnSpan(tableView, 2); + GridPane.setHgrow(tableView, Priority.ALWAYS); + root.getChildren().add(tableView); + + tableView.setItems(sortedList); + sortedList.comparatorProperty().bind(tableView.comparatorProperty()); + } + + private void createResultDisplay() { + proposalsDisplay = new CycleDisplay(resultGridPane, bsqWalletService, bsqFormatter); + resultDisplayView = proposalsDisplay.getView(); + GridPane.setMargin(resultDisplayView, new Insets(10, -10, 0, -10)); + GridPane.setRowIndex(resultDisplayView, ++gridRow); + GridPane.setColumnSpan(resultDisplayView, 2); + root.getChildren().add(resultDisplayView); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Private + /////////////////////////////////////////////////////////////////////////////////////////// + + private void fillCycleList() { + itemList.clear(); + stateService.getCycles().forEach(this::addCycleListItem); + Collections.reverse(itemList); + } + + private void addCycleListItem(Cycle cycle) { + List proposalsForCycle = proposalService.getAppendOnlyStoreList().stream() + .filter(proposalPayload -> cycleService.isTxInCycle(cycle, proposalPayload.getProposal().getTxId())) + .map(ProposalPayload::getProposal) + .collect(Collectors.toList()); + + List evaluatedProposalsForCycle = voteResultService.getAllEvaluatedProposals().stream() + .filter(evaluatedProposal -> cycleService.isTxInCycle(cycle, evaluatedProposal.getProposal().getTxId())) + .collect(Collectors.toList()); + + long cycleStartTime = stateService.getBlockAtHeight(cycle.getHeightOfFirstBlock()) + .map(e -> e.getTime() * 1000) + .orElse(0L); + int cycleIndex = cycleService.getCycleIndex(cycle); + CycleResult cycleResult = new CycleResult(cycle, + cycleIndex, + cycleStartTime, + proposalsForCycle, + evaluatedProposalsForCycle); + CyclesListItem cyclesListItem = new CyclesListItem(cycleResult, bsqFormatter); + itemList.add(cyclesListItem); + } + + private void hideResultDisplay() { + if (resultDisplayInitialized) { + proposalsDisplay.removeAllFields(); + resultDisplayView.setVisible(false); + resultDisplayView.setManaged(false); + } + } + + private void createAllFieldsOnResultDisplay(CyclesListItem cyclesListItem) { + resultDisplayView.setVisible(true); + resultDisplayView.setManaged(true); + + proposalsDisplay.createAllFields(0, cyclesListItem.getCycleResult()); + resultDisplayInitialized = true; + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // TableColumns + /////////////////////////////////////////////////////////////////////////////////////////// + + private void createColumns(TableView tableView) { + TableColumn cycleColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.results.table.header.cycle")); + cycleColumn.setMinWidth(160); + cycleColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + cycleColumn.setCellFactory( + new Callback, TableCell>() { + @Override + public TableCell call( + TableColumn column) { + return new TableCell() { + @Override + public void updateItem(final CyclesListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null) + setText(item.getCycle()); + else + setText(""); + } + }; + } + }); + cycleColumn.setComparator(Comparator.comparing(CyclesListItem::getCycleStartTime)); + tableView.getColumns().add(cycleColumn); + + TableColumn proposalsColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.results.table.header.numProposals")); + proposalsColumn.setMinWidth(90); + proposalsColumn.setMaxWidth(90); + proposalsColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + proposalsColumn.setCellFactory( + new Callback, TableCell>() { + @Override + public TableCell call( + TableColumn column) { + return new TableCell() { + @Override + public void updateItem(final CyclesListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null) + setText(item.getNumProposals()); + else + setText(""); + } + }; + } + }); + proposalsColumn.setComparator(Comparator.comparing(CyclesListItem::getNumProposals)); + tableView.getColumns().add(proposalsColumn); + + TableColumn votesColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.results.table.header.numVotes")); + votesColumn.setMinWidth(70); + votesColumn.setMaxWidth(70); + votesColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + votesColumn.setCellFactory( + new Callback, TableCell>() { + @Override + public TableCell call( + TableColumn column) { + return new TableCell() { + @Override + public void updateItem(final CyclesListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null) + setText(item.getNumVotesAsString()); + else + setText(""); + } + }; + } + }); + votesColumn.setComparator(Comparator.comparing(CyclesListItem::getNumProposals)); + tableView.getColumns().add(votesColumn); + + TableColumn stakeColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.results.table.header.stake")); + stakeColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + stakeColumn.setCellFactory( + new Callback, TableCell>() { + @Override + public TableCell call( + TableColumn column) { + return new TableCell() { + @Override + public void updateItem(final CyclesListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null) + setText(item.getStake()); + else + setText(""); + } + }; + } + }); + stakeColumn.setComparator(Comparator.comparing(CyclesListItem::getNumProposals)); + tableView.getColumns().add(stakeColumn); + + TableColumn issuanceColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.results.table.header.issuance")); + issuanceColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + issuanceColumn.setCellFactory( + new Callback, TableCell>() { + @Override + public TableCell call( + TableColumn column) { + return new TableCell() { + @Override + public void updateItem(final CyclesListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null) + setText(item.getIssuance()); + else + setText(""); + } + }; + } + }); + issuanceColumn.setComparator(Comparator.comparing(CyclesListItem::getNumProposals)); + tableView.getColumns().add(issuanceColumn); + } +} diff --git a/src/main/java/bisq/desktop/main/dao/cycles/cycle/CycleDetailsWindow.java b/src/main/java/bisq/desktop/main/dao/cycles/cycle/CycleDetailsWindow.java new file mode 100644 index 00000000000..54de42d5f7d --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/cycles/cycle/CycleDetailsWindow.java @@ -0,0 +1,88 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.desktop.main.dao.cycles.cycle; + +import bisq.desktop.main.overlays.Overlay; +import bisq.desktop.util.FormBuilder; + +import bisq.core.dao.voting.voteresult.EvaluatedProposal; +import bisq.core.locale.Res; +import bisq.core.util.BsqFormatter; + +import javafx.scene.control.Button; +import javafx.scene.control.TextArea; + +import javafx.geometry.Insets; + +import javafx.beans.value.ChangeListener; + +import static bisq.desktop.util.FormBuilder.addTitledGroupBg; + +public class CycleDetailsWindow extends Overlay { + + private final BsqFormatter bsqFormatter; + private ChangeListener changeListener; + private TextArea textArea; + private EvaluatedProposal evaluatedProposal; + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Public API + /////////////////////////////////////////////////////////////////////////////////////////// + + public CycleDetailsWindow(BsqFormatter bsqFormatter, EvaluatedProposal evaluatedProposal) { + this.bsqFormatter = bsqFormatter; + this.evaluatedProposal = evaluatedProposal; + type = Type.Confirmation; + } + + @Override + public void show() { + rowIndex = -1; + width = 850; + createGridPane(); + addContent(); + display(); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Protected + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + protected void createGridPane() { + super.createGridPane(); + gridPane.setPadding(new Insets(35, 40, 30, 40)); + gridPane.getStyleClass().add("grid-pane"); + } + + private void addContent() { + addTitledGroupBg(gridPane, ++rowIndex, 5, Res.get("dao.results.result.detail.header")); + + //TODO impl + //addLabelTextField(gridPane, rowIndex, Res.get("dao.results.result.detail.header"), evaluatedProposal.getProposal().getName(), Layout.FIRST_ROW_DISTANCE); + + + Button closeButton = FormBuilder.addButtonAfterGroup(gridPane, ++rowIndex, Res.get("shared.close")); + closeButton.setOnAction(e -> { + closeHandlerOptional.ifPresent(Runnable::run); + hide(); + }); + } +} diff --git a/src/main/java/bisq/desktop/main/dao/cycles/cycle/CycleDisplay.java b/src/main/java/bisq/desktop/main/dao/cycles/cycle/CycleDisplay.java new file mode 100644 index 00000000000..c269176f057 --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/cycles/cycle/CycleDisplay.java @@ -0,0 +1,419 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.desktop.main.dao.cycles.cycle; + +import bisq.desktop.components.AutoTooltipLabel; +import bisq.desktop.components.AutoTooltipTableColumn; +import bisq.desktop.components.TableGroupHeadline; +import bisq.desktop.main.dao.cycles.model.CycleResult; +import bisq.desktop.main.dao.proposal.ProposalDetailsWindow; +import bisq.desktop.util.FormBuilder; +import bisq.desktop.util.GUIUtil; + +import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.dao.voting.proposal.ProposalType; +import bisq.core.locale.Res; +import bisq.core.util.BsqFormatter; + +import org.bitcoinj.core.Coin; + +import de.jensd.fx.fontawesome.AwesomeDude; + +import javafx.scene.control.Hyperlink; +import javafx.scene.control.Label; +import javafx.scene.control.ScrollPane; +import javafx.scene.control.TableCell; +import javafx.scene.control.TableColumn; +import javafx.scene.control.TableView; +import javafx.scene.control.Tooltip; +import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.ColumnConstraints; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.Priority; + +import javafx.geometry.HPos; +import javafx.geometry.Insets; + +import javafx.beans.property.ReadOnlyObjectWrapper; + +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.collections.transformation.SortedList; + +import javafx.util.Callback; + +import java.util.Comparator; +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Collectors; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class CycleDisplay { + private final GridPane gridPane; + private final BsqWalletService bsqWalletService; + private final BsqFormatter bsqFormatter; + + private int gridRow; + private int gridRowStartIndex; + private TableView tableView; + + + private final ObservableList itemList = FXCollections.observableArrayList(); + private final SortedList sortedList = new SortedList<>(itemList); + + + public CycleDisplay(GridPane gridPane, BsqWalletService bsqWalletService, BsqFormatter bsqFormatter) { + this.gridPane = gridPane; + this.bsqWalletService = bsqWalletService; + this.bsqFormatter = bsqFormatter; + } + + public void createAllFields(int gridRowStartIndex, CycleResult cycleResult) { + removeAllFields(); + + this.gridRowStartIndex = gridRowStartIndex; + this.gridRow = gridRowStartIndex; + + createTableView(); + + itemList.setAll(cycleResult.getEvaluatedProposals().stream().map(e -> new CycleListItem(e, bsqFormatter)).collect(Collectors.toList())); + + Map requiredThresholdByType = new HashMap<>(); + cycleResult.getEvaluatedProposals().forEach(e -> { + requiredThresholdByType.putIfAbsent(e.getProposal().getType(), e.getRequiredThreshold()); + }); + Map requiredQuorumByType = new HashMap<>(); + cycleResult.getEvaluatedProposals().forEach(e -> { + requiredQuorumByType.putIfAbsent(e.getProposal().getType(), e.getRequiredQuorum()); + }); + + requiredThresholdByType.forEach((key, value) -> { + String title = Res.get("dao.results.result.requiredThreshold." + key.name()); + String requiredThreshold = String.valueOf(value / 100) + "%"; + FormBuilder.addLabelTextField(gridPane, ++gridRow, title, requiredThreshold, 0); + }); + requiredQuorumByType.forEach((key, value) -> { + String title = Res.get("dao.results.result.requiredQuorum." + key.name()); + String requiredQuorum = bsqFormatter.formatCoinWithCode(Coin.valueOf(value)); + FormBuilder.addLabelTextField(gridPane, ++gridRow, title, requiredQuorum); + }); + } + + private void createTableView() { + TableGroupHeadline headline = new TableGroupHeadline(Res.get("dao.results.result.header")); + GridPane.setRowIndex(headline, gridRow); + GridPane.setMargin(headline, new Insets(0, -10, -10, -10)); + GridPane.setColumnSpan(headline, 2); + gridPane.getChildren().add(headline); + + tableView = new TableView<>(); + tableView.setPlaceholder(new AutoTooltipLabel(Res.get("table.placeholder.noData"))); + tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); + tableView.setPrefHeight(200); + + createColumns(tableView); + GridPane.setRowIndex(tableView, gridRow); + GridPane.setMargin(tableView, new Insets(20, -10, 5, -10)); + GridPane.setColumnSpan(tableView, 2); + GridPane.setHgrow(tableView, Priority.ALWAYS); + gridPane.getChildren().add(tableView); + + tableView.setItems(sortedList); + sortedList.comparatorProperty().bind(tableView.comparatorProperty()); + } + + private void createColumns(TableView tableView) { + TableColumn proposalColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.result.table.header.proposalOwnerName")); + proposalColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + proposalColumn.setCellFactory( + new Callback, TableCell>() { + @Override + public TableCell call( + TableColumn column) { + return new TableCell() { + @Override + public void updateItem(final CycleListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null) + setText(item.getProposalOwnerName()); + else + setText(""); + } + }; + } + }); + proposalColumn.setComparator(Comparator.comparing(CycleListItem::getProposalOwnerName)); + tableView.getColumns().add(proposalColumn); + + TableColumn proposalIdColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.result.table.header.proposalId")); + proposalIdColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + + proposalIdColumn.setCellFactory( + new Callback, TableCell>() { + + @Override + public TableCell call(TableColumn column) { + return new TableCell() { + private Hyperlink field; + + @Override + public void updateItem(final CycleListItem item, boolean empty) { + super.updateItem(item, empty); + + // cycleDetailsWindow.show(item.getEvaluatedProposal()) + if (item != null && !empty) { + field = new Hyperlink(item.getProposalId()); + //TODO setId or getStyleClass.add does not apply color... + //field.getStyleClass().add(item.getColorStyleClass()); + //field.setId(item.getColorStyleClass()); + field.setStyle(item.getColorStyle()); + field.setOnAction(event -> new ProposalDetailsWindow(bsqFormatter, + bsqWalletService, + item.getEvaluatedProposal().getProposal()) + .show()); + field.setTooltip(new Tooltip(Res.get("tooltip.openPopupForDetails"))); + setGraphic(field); + } else { + setGraphic(null); + if (field != null) + field.setOnAction(null); + } + } + }; + } + }); + proposalIdColumn.setComparator(Comparator.comparing(CycleListItem::getProposalOwnerName)); + tableView.getColumns().add(proposalIdColumn); + + TableColumn acceptedColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.result.table.header.accepted")); + acceptedColumn.setMinWidth(80); + acceptedColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + acceptedColumn.setCellFactory( + new Callback, TableCell>() { + private Hyperlink field; + + @Override + public TableCell call( + TableColumn column) { + return new TableCell() { + @Override + public void updateItem(final CycleListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null && !empty) { + field = new Hyperlink(item.getAccepted()); + field.setStyle(item.getColorStyle()); + field.setOnAction(event -> new CycleDetailsWindow(bsqFormatter, item.getEvaluatedProposal()).show()); + field.setTooltip(new Tooltip(Res.get("tooltip.openPopupForDetails"))); + setGraphic(field); + } else { + setGraphic(null); + if (field != null) + field.setOnAction(null); + } + } + }; + } + }); + acceptedColumn.setComparator(Comparator.comparing(CycleListItem::getAccepted)); + tableView.getColumns().add(acceptedColumn); + + TableColumn rejectedColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.result.table.header.rejected")); + rejectedColumn.setMinWidth(80); + rejectedColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + rejectedColumn.setCellFactory( + new Callback, TableCell>() { + private Hyperlink field; + + @Override + public TableCell call( + TableColumn column) { + return new TableCell() { + @Override + public void updateItem(final CycleListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null && !empty) { + field = new Hyperlink(item.getRejected()); + field.setStyle(item.getColorStyle()); + field.setOnAction(event -> new CycleDetailsWindow(bsqFormatter, item.getEvaluatedProposal()).show()); + field.setTooltip(new Tooltip(Res.get("tooltip.openPopupForDetails"))); + setGraphic(field); + } else { + setGraphic(null); + if (field != null) + field.setOnAction(null); + } + } + }; + } + }); + rejectedColumn.setComparator(Comparator.comparing(CycleListItem::getRejected)); + tableView.getColumns().add(rejectedColumn); + + TableColumn thresholdColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.result.table.header.threshold")); + thresholdColumn.setMinWidth(100); + thresholdColumn.setMaxWidth(100); + thresholdColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + thresholdColumn.setCellFactory( + new Callback, TableCell>() { + @Override + public TableCell call( + TableColumn column) { + return new TableCell() { + @Override + public void updateItem(final CycleListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null) + setText(item.getThreshold()); + else + setText(""); + } + }; + } + }); + thresholdColumn.setComparator(Comparator.comparing(CycleListItem::getThreshold)); + tableView.getColumns().add(thresholdColumn); + + TableColumn quorumColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.result.table.header.quorum")); + quorumColumn.setMinWidth(130); + quorumColumn.setMaxWidth(130); + quorumColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + quorumColumn.setCellFactory( + new Callback, TableCell>() { + @Override + public TableCell call( + TableColumn column) { + return new TableCell() { + @Override + public void updateItem(final CycleListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null) + setText(item.getQuorum()); + else + setText(""); + } + }; + } + }); + quorumColumn.setComparator(Comparator.comparing(CycleListItem::getThreshold)); + tableView.getColumns().add(quorumColumn); + + TableColumn issuanceColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.result.table.header.issuance")); + issuanceColumn.setMinWidth(130); + issuanceColumn.setMaxWidth(130); + issuanceColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + issuanceColumn.setCellFactory( + new Callback, TableCell>() { + @Override + public TableCell call( + TableColumn column) { + return new TableCell() { + @Override + public void updateItem(final CycleListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null) + setText(item.getIssuance()); + else + setText(""); + } + }; + } + }); + issuanceColumn.setComparator(Comparator.comparing(CycleListItem::getThreshold)); + tableView.getColumns().add(issuanceColumn); + + + TableColumn resultColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.result.table.header.result")); + resultColumn.setMinWidth(60); + resultColumn.setMaxWidth(60); + resultColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + resultColumn.setCellFactory(new Callback, + TableCell>() { + + @Override + public TableCell call(TableColumn column) { + return new TableCell() { + Label icon; + + @Override + public void updateItem(final CycleListItem item, boolean empty) { + super.updateItem(item, empty); + + if (item != null && !empty) { + icon = new Label(); + AwesomeDude.setIcon(icon, item.getIcon()); + icon.getStyleClass().add(item.getColorStyleClass()); + setGraphic(icon); + } else { + setGraphic(null); + if (icon != null) + icon = null; + } + } + }; + } + }); + + + resultColumn.setComparator(Comparator.comparing(CycleListItem::getThreshold)); + tableView.getColumns().add(resultColumn); + } + + public void removeAllFields() { + GUIUtil.removeChildrenFromGridPaneRows(gridPane, gridRowStartIndex, gridRow); + gridRow = gridRowStartIndex; + } + + public ScrollPane getView() { + ScrollPane scrollPane = new ScrollPane(); + scrollPane.setFitToWidth(true); + scrollPane.setFitToHeight(true); + scrollPane.setMinHeight(280); // just enough to display overview at voting without scroller + + AnchorPane anchorPane = new AnchorPane(); + scrollPane.setContent(anchorPane); + + gridPane.setHgap(5); + gridPane.setVgap(5); + ColumnConstraints columnConstraints1 = new ColumnConstraints(); + columnConstraints1.setHalignment(HPos.RIGHT); + columnConstraints1.setHgrow(Priority.SOMETIMES); + columnConstraints1.setMinWidth(140); + ColumnConstraints columnConstraints2 = new ColumnConstraints(); + columnConstraints2.setHgrow(Priority.ALWAYS); + columnConstraints2.setMinWidth(300); + + gridPane.getColumnConstraints().addAll(columnConstraints1, columnConstraints2); + AnchorPane.setBottomAnchor(gridPane, 20d); + AnchorPane.setRightAnchor(gridPane, 10d); + AnchorPane.setLeftAnchor(gridPane, 10d); + AnchorPane.setTopAnchor(gridPane, 20d); + anchorPane.getChildren().add(gridPane); + + return scrollPane; + } +} diff --git a/src/main/java/bisq/desktop/main/dao/cycles/cycle/CycleListItem.java b/src/main/java/bisq/desktop/main/dao/cycles/cycle/CycleListItem.java new file mode 100644 index 00000000000..86da4fd9e2a --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/cycles/cycle/CycleListItem.java @@ -0,0 +1,99 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.desktop.main.dao.cycles.cycle; + +import bisq.core.dao.voting.proposal.compensation.CompensationProposal; +import bisq.core.dao.voting.voteresult.EvaluatedProposal; +import bisq.core.dao.voting.voteresult.ProposalVoteResult; +import bisq.core.locale.Res; +import bisq.core.util.BsqFormatter; + +import org.bitcoinj.core.Coin; + +import de.jensd.fx.fontawesome.AwesomeIcon; + +import lombok.Getter; + +public class CycleListItem { + private final ProposalVoteResult proposalVoteResult; + private BsqFormatter bsqFormatter; + @Getter + private EvaluatedProposal evaluatedProposal; + + public CycleListItem(EvaluatedProposal evaluatedProposal, BsqFormatter bsqFormatter) { + this.evaluatedProposal = evaluatedProposal; + proposalVoteResult = evaluatedProposal.getProposalVoteResult(); + this.bsqFormatter = bsqFormatter; + } + + public String getProposalOwnerName() { + return evaluatedProposal.getProposal().getName(); + } + + public String getProposalId() { + return evaluatedProposal.getProposal().getShortId(); + } + + public String getAccepted() { + return Res.get("dao.results.result.table.item.votes", + bsqFormatter.formatCoinWithCode(Coin.valueOf(proposalVoteResult.getStakeOfAcceptedVotes())), + String.valueOf(proposalVoteResult.getNumAcceptedVotes())); + } + + public String getRejected() { + return Res.get("dao.results.result.table.item.votes", + bsqFormatter.formatCoinWithCode(Coin.valueOf(proposalVoteResult.getStakeOfRejectedVotes())), + String.valueOf(proposalVoteResult.getNumRejectedVotes())); + } + + public String getThreshold() { + return (proposalVoteResult.getThreshold() / 100D) + "%"; + } + + public String getQuorum() { + return bsqFormatter.formatCoinWithCode(Coin.valueOf(proposalVoteResult.getQuorum())); + } + + public AwesomeIcon getIcon() { + return evaluatedProposal.isAccepted() ? AwesomeIcon.OK_SIGN : AwesomeIcon.BAN_CIRCLE; + } + + public String getColorStyleClass() { + return evaluatedProposal.isAccepted() ? "dao-accepted-icon" : "dao-rejected-icon"; + } + + public String getColorStyle() { + return evaluatedProposal.isAccepted() ? "-fx-text-fill: -bs-green" : "-fx-text-fill: -bs-error-red"; + } + + public String getIssuance() { + switch (evaluatedProposal.getProposal().getType()) { + case COMPENSATION_REQUEST: + Coin requestedBsq = evaluatedProposal.isAccepted() ? + ((CompensationProposal) evaluatedProposal.getProposal()).getRequestedBsq() : + Coin.ZERO; + return bsqFormatter.formatCoinWithCode(requestedBsq); + case GENERIC: + case CHANGE_PARAM: + case REMOVE_ALTCOIN: + default: + return ""; + } + + } +} diff --git a/src/main/java/bisq/desktop/main/dao/cycles/model/CycleResult.java b/src/main/java/bisq/desktop/main/dao/cycles/model/CycleResult.java new file mode 100644 index 00000000000..4da420c2318 --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/cycles/model/CycleResult.java @@ -0,0 +1,76 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.desktop.main.dao.cycles.model; + +import bisq.core.dao.state.period.Cycle; +import bisq.core.dao.voting.proposal.Proposal; +import bisq.core.dao.voting.voteresult.EvaluatedProposal; +import bisq.core.util.BsqFormatter; + +import java.util.List; + +import lombok.Data; + +@Data +public class CycleResult { + private final Cycle cycle; + private final int cycleIndex; + private final int numVotes, numAcceptedVotes, numRejectedVotes; + private final long stakeOfAcceptedVotes; + private final long stakeOfRejectedVotes; + private BsqFormatter bsqFormatter; + private long cycleStartTime; + + // All available proposals of cycle + private List proposals; + + // Proposals which ended up in voting + private final List evaluatedProposals; + + public CycleResult(Cycle cycle, + int cycleIndex, + long cycleStartTime, + List proposals, + List evaluatedProposals) { + this.cycle = cycle; + this.cycleIndex = cycleIndex; + this.cycleStartTime = cycleStartTime; + this.proposals = proposals; + this.evaluatedProposals = evaluatedProposals; + + numVotes = evaluatedProposals.stream() + .mapToInt(e -> e.getProposalVoteResult().getNumActiveVotes()) + .sum(); + numAcceptedVotes = evaluatedProposals.stream() + .mapToInt(e -> e.getProposalVoteResult().getNumActiveVotes()) + .sum(); + numRejectedVotes = evaluatedProposals.stream() + .mapToInt(e -> e.getProposalVoteResult().getNumRejectedVotes()) + .sum(); + stakeOfAcceptedVotes = evaluatedProposals.stream() + .mapToLong(e -> e.getProposalVoteResult().getStakeOfAcceptedVotes()) + .sum(); + stakeOfRejectedVotes = evaluatedProposals.stream() + .mapToLong(e -> e.getProposalVoteResult().getStakeOfRejectedVotes()) + .sum(); + } + + public long getTotalStake() { + return stakeOfAcceptedVotes + stakeOfRejectedVotes; + } +} diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java index 5b94cd124e9..1ebb333e212 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java @@ -274,7 +274,7 @@ public void setEditable(boolean isEditable) { public void removeAllFields() { if (gridRow > 0) { clearForm(); - GUIUtil.removeChildrenFromGridPaneRows(gridPane, gridRowStartIndex, gridRow + 1); + GUIUtil.removeChildrenFromGridPaneRows(gridPane, gridRowStartIndex, gridRow); gridRow = gridRowStartIndex; } } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalView.java index 9c3a4a67a7e..7d3eab51dbb 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalView.java @@ -31,8 +31,6 @@ import bisq.desktop.main.dao.proposal.closed.ClosedProposalsView; import bisq.desktop.main.dao.proposal.dashboard.ProposalDashboardView; import bisq.desktop.main.dao.proposal.make.MakeProposalView; -import bisq.desktop.main.dao.proposal.myvotes.MyVotesView; -import bisq.desktop.main.dao.proposal.votes.VotesView; import bisq.core.locale.Res; @@ -55,7 +53,7 @@ public class ProposalView extends ActivatableViewAndModel { private final ViewLoader viewLoader; private final Navigation navigation; - private MenuItem dashboard, make, active, myVotes, votes, closed; + private MenuItem dashboard, make, active, closed; private Navigation.Listener listener; @FXML @@ -89,13 +87,9 @@ public void initialize() { MakeProposalView.class, AwesomeIcon.EDIT, baseNavPath); active = new MenuItem(navigation, toggleGroup, Res.get("dao.proposal.menuItem.active"), ActiveProposalsView.class, AwesomeIcon.LIST_UL, baseNavPath); - myVotes = new MenuItem(navigation, toggleGroup, Res.get("dao.proposal.menuItem.myVotes"), - MyVotesView.class, AwesomeIcon.THUMBS_UP, baseNavPath); - votes = new MenuItem(navigation, toggleGroup, Res.get("dao.proposal.menuItem.votes"), - VotesView.class, AwesomeIcon.THUMBS_UP_ALT, baseNavPath); closed = new MenuItem(navigation, toggleGroup, Res.get("dao.proposal.menuItem.closed"), ClosedProposalsView.class, AwesomeIcon.LIST_ALT, baseNavPath); - leftVBox.getChildren().addAll(dashboard, make, active, myVotes, votes, closed); + leftVBox.getChildren().addAll(dashboard, make, active, closed); } @Override @@ -103,8 +97,6 @@ protected void activate() { dashboard.activate(); make.activate(); active.activate(); - myVotes.activate(); - votes.activate(); closed.activate(); navigation.addListener(listener); @@ -129,8 +121,6 @@ protected void deactivate() { dashboard.deactivate(); make.deactivate(); active.deactivate(); - myVotes.deactivate(); - votes.deactivate(); closed.deactivate(); } @@ -141,8 +131,6 @@ private void loadView(Class viewClass) { if (view instanceof ProposalDashboardView) dashboard.setSelected(true); else if (view instanceof MakeProposalView) make.setSelected(true); else if (view instanceof ActiveProposalsView) active.setSelected(true); - else if (view instanceof MyVotesView) myVotes.setSelected(true); - else if (view instanceof VotesView) votes.setSelected(true); else if (view instanceof ClosedProposalsView) closed.setSelected(true); } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java index 8c75d779670..c8adc885aeb 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java @@ -98,20 +98,6 @@ public void initialize() { addMultilineLabel(root, gridRow, Res.get("dao.cycle.info.details"), Layout.FIRST_ROW_AND_GROUP_DISTANCE); } - - private SeparatedPhaseBars createSeparatedPhaseBars() { - phaseBarsItems = Arrays.asList( - new SeparatedPhaseBars.SeparatedPhaseBarsItem(DaoPhase.Phase.PROPOSAL, true), - new SeparatedPhaseBars.SeparatedPhaseBarsItem(DaoPhase.Phase.BREAK1, false), - new SeparatedPhaseBars.SeparatedPhaseBarsItem(DaoPhase.Phase.BLIND_VOTE, true), - new SeparatedPhaseBars.SeparatedPhaseBarsItem(DaoPhase.Phase.BREAK2, false), - new SeparatedPhaseBars.SeparatedPhaseBarsItem(DaoPhase.Phase.VOTE_REVEAL, true), - new SeparatedPhaseBars.SeparatedPhaseBarsItem(DaoPhase.Phase.BREAK3, false), - new SeparatedPhaseBars.SeparatedPhaseBarsItem(DaoPhase.Phase.RESULT, false), - new SeparatedPhaseBars.SeparatedPhaseBarsItem(DaoPhase.Phase.BREAK4, false)); - return new SeparatedPhaseBars(phaseBarsItems); - } - @Override protected void activate() { super.activate(); @@ -172,6 +158,19 @@ public void onChainHeightChanged(int height) { voteResultTextField.setText(getPhaseDuration(height, DaoPhase.Phase.RESULT)); } + private SeparatedPhaseBars createSeparatedPhaseBars() { + phaseBarsItems = Arrays.asList( + new SeparatedPhaseBars.SeparatedPhaseBarsItem(DaoPhase.Phase.PROPOSAL, true), + new SeparatedPhaseBars.SeparatedPhaseBarsItem(DaoPhase.Phase.BREAK1, false), + new SeparatedPhaseBars.SeparatedPhaseBarsItem(DaoPhase.Phase.BLIND_VOTE, true), + new SeparatedPhaseBars.SeparatedPhaseBarsItem(DaoPhase.Phase.BREAK2, false), + new SeparatedPhaseBars.SeparatedPhaseBarsItem(DaoPhase.Phase.VOTE_REVEAL, true), + new SeparatedPhaseBars.SeparatedPhaseBarsItem(DaoPhase.Phase.BREAK3, false), + new SeparatedPhaseBars.SeparatedPhaseBarsItem(DaoPhase.Phase.RESULT, false), + new SeparatedPhaseBars.SeparatedPhaseBarsItem(DaoPhase.Phase.BREAK4, false)); + return new SeparatedPhaseBars(phaseBarsItems); + } + private String getPhaseDuration(int height, DaoPhase.Phase phase) { final long start = daoFacade.getFirstBlockOfPhase(height, phase); final long end = daoFacade.getLastBlockOfPhase(height, phase); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index ea17468e479..85a16a731f1 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -117,8 +117,8 @@ public void initialize() { Res.getWithCol("dao.proposal.create.proposalType"), Layout.FIRST_ROW_DISTANCE).second; proposalTypeComboBox.setConverter(new StringConverter() { @Override - public String toString(ProposalType object) { - return Res.get(object.name()); + public String toString(ProposalType proposalType) { + return Res.get("dao.proposal.type." + proposalType.name()); } @Override diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java deleted file mode 100644 index def2bbaac1b..00000000000 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java +++ /dev/null @@ -1,363 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.desktop.main.dao.proposal.myvotes; - -import bisq.desktop.common.view.ActivatableView; -import bisq.desktop.common.view.FxmlView; - -import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.DaoFacade; -import bisq.core.user.Preferences; -import bisq.core.util.BSFormatter; -import bisq.core.util.BsqFormatter; - -import javax.inject.Inject; - -import javafx.scene.layout.GridPane; - -@FxmlView -public class MyVotesView extends ActivatableView /*extends BaseProposalView*/ { - private final Preferences preferences; - /* - - private final ObservableList voteListItems = FXCollections.observableArrayList(); - private SortedList sortedList = new SortedList<>(voteListItems); - private TableView votesTableView; - private VoteListItem selectedVoteListItem; - private Subscription selectedVoteSubscription; -*/ - - /////////////////////////////////////////////////////////////////////////////////////////// - // Constructor, lifecycle - /////////////////////////////////////////////////////////////////////////////////////////// - - @Inject - private MyVotesView(DaoFacade daoFacade, - BsqWalletService bsqWalletService, - BsqFormatter bsqFormatter, - BSFormatter btcFormatter, - Preferences preferences) { - - // super(daoFacade, bsqWalletService, bsqFormatter, btcFormatter); - this.preferences = preferences; - } - - /* @Override - public void initialize() { - super.initialize(); - - createVoteTableView(); - createProposalsTableView(Res.get("dao.proposal.myVotes.proposals.header"), Layout.GROUP_DISTANCE - 20); - createProposalDisplay(); - - changeProposalViewItemsVisibility(false); - } - - @Override - protected void activate() { - super.activate(); - - selectedVoteSubscription = EasyBind.subscribe(votesTableView.getSelectionModel().selectedItemProperty(), - this::onSelectVote); - - sortedList.comparatorProperty().bind(votesTableView.comparatorProperty()); - - voteListItems.clear(); - List items = daoFacade.getMyVoteList().stream() - .map(vote -> new VoteListItem(vote, daoFacade, bsqWalletService, bsqFormatter)) - .collect(Collectors.toList()); - voteListItems.addAll(items); - } - - private void onSelectVote(VoteListItem voteListItem) { - selectedVoteListItem = voteListItem; - changeProposalViewItemsVisibility(selectedVoteListItem != null); - updateListItems(); - } - - @Override - protected void deactivate() { - super.deactivate(); - - selectedVoteSubscription.unsubscribe(); - - changeProposalViewItemsVisibility(false); - votesTableView.getSelectionModel().clearSelection(); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Create views - /////////////////////////////////////////////////////////////////////////////////////////// - - private void createVoteTableView() { - TableGroupHeadline proposalsHeadline = new TableGroupHeadline(Res.get("dao.proposal.myVotes.header")); - GridPane.setRowIndex(proposalsHeadline, ++gridRow); - GridPane.setMargin(proposalsHeadline, new Insets(-10, -10, -10, -10)); - GridPane.setColumnSpan(proposalsHeadline, 2); - root.getChildren().add(proposalsHeadline); - - votesTableView = new TableView<>(); - votesTableView.setPlaceholder(new AutoTooltipLabel(Res.get("table.placeholder.noData"))); - votesTableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); - - createVoteColumns(votesTableView); - GridPane.setRowIndex(votesTableView, gridRow); - GridPane.setMargin(votesTableView, new Insets(10, -10, 5, -10)); - GridPane.setColumnSpan(votesTableView, 2); - GridPane.setHgrow(votesTableView, Priority.ALWAYS); - root.getChildren().add(votesTableView); - - votesTableView.setItems(sortedList); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Handler - /////////////////////////////////////////////////////////////////////////////////////////// - - private void onShowProposalList(BallotList ballotList) { - - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Protected - /////////////////////////////////////////////////////////////////////////////////////////// - - *//* @Override - protected void updateProposalList() { - //TODO - //if (selectedVoteListItem != null) - // doUpdateProposalList(selectedVoteListItem.getMyVote().getBallotList().getList()); - }*//* - @Override - protected List getProposalList() { - //TODO - return null;// daoFacade.getActiveOrMyUnconfirmedProposals(); - } - - @Override - protected BaseProposalListItem getListItem(Proposal proposal) { - return new ActiveProposalListItem(proposal, daoFacade, bsqWalletService, bsqFormatter); - } - - /////////////////////////////////////////////////////////////////////////////////////////// - // TableColumns - /////////////////////////////////////////////////////////////////////////////////////////// - - private void createVoteColumns(TableView tableView) { - TableColumn dateColumn = new AutoTooltipTableColumn(Res.get("shared.dateTime")) { - { - setMinWidth(190); - setMaxWidth(190); - } - }; - dateColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - dateColumn.setCellFactory( - new Callback, TableCell>() { - @Override - public TableCell call( - TableColumn column) { - return new TableCell() { - @Override - public void updateItem(final VoteListItem item, boolean empty) { - super.updateItem(item, empty); - if (item != null) - setText(bsqFormatter.formatDateTime(new Date(item.getMyVote() - .getDate()))); - else - setText(""); - } - }; - } - }); - dateColumn.setComparator(Comparator.comparing(o3 -> o3.getMyVote().getDate())); - dateColumn.setSortType(TableColumn.SortType.DESCENDING); - tableView.getColumns().add(dateColumn); - tableView.getSortOrder().add(dateColumn); - - - TableColumn proposalListColumn = new AutoTooltipTableColumn<>(Res.get("dao.proposal.myVotes.proposalList")); - proposalListColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - proposalListColumn.setCellFactory( - new Callback, TableCell>() { - @Override - public TableCell call( - TableColumn column) { - return new TableCell() { - @Override - public void updateItem(final VoteListItem item, boolean empty) { - super.updateItem(item, empty); - - if (item != null && !empty) { - BallotList ballotList = item.getMyVote().getBallotList(); - HyperlinkWithIcon field = new HyperlinkWithIcon(Res.get("dao.proposal.myVotes.showProposalList"), AwesomeIcon.INFO_SIGN); - field.setOnAction(event -> onShowProposalList(ballotList)); - field.setTooltip(new Tooltip(Res.get("dao.proposal.myVotes.tooltip.showProposalList"))); - setGraphic(field); - } else { - setGraphic(null); - } - } - }; - } - }); - proposalListColumn.setSortable(false); - tableView.getColumns().add(proposalListColumn); - - TableColumn stakeColumn = new AutoTooltipTableColumn<>(Res.get("dao.proposal.votes.stake")); - stakeColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - stakeColumn.setCellFactory( - new Callback, TableCell>() { - @Override - public TableCell call( - TableColumn column) { - return new TableCell() { - @Override - public void updateItem(final VoteListItem item, boolean empty) { - super.updateItem(item, empty); - if (item != null && !empty) { - textProperty().bind(item.getStakeAsStringProperty()); - } else { - textProperty().unbind(); - setText(""); - } - } - }; - } - }); - stakeColumn.setComparator(Comparator.comparing(VoteListItem::getStake)); - tableView.getColumns().add(stakeColumn); - - TableColumn txColumn = new AutoTooltipTableColumn<>(Res.get("dao.proposal.myVotes.tx")); - txColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - txColumn.setCellFactory( - new Callback, TableCell>() { - @Override - public TableCell call( - TableColumn column) { - return new TableCell() { - @Override - public void updateItem(final VoteListItem item, boolean empty) { - super.updateItem(item, empty); - - if (item != null && !empty) { - String txId = item.getMyVote().getTxId(); - HyperlinkWithIcon hyperlinkWithIcon = new HyperlinkWithIcon(txId, AwesomeIcon.EXTERNAL_LINK); - hyperlinkWithIcon.setOnAction(event -> { - if (txId != null) - GUIUtil.openWebPage(preferences.getBlockChainExplorer().txUrl + txId); - }); - hyperlinkWithIcon.setTooltip(new Tooltip(Res.get("tooltip.openBlockchainForTx", txId))); - setGraphic(hyperlinkWithIcon); - } else { - setGraphic(null); - } - } - }; - } - }); - txColumn.setComparator(Comparator.comparing(o2 -> o2.getMyVote().getBlindVote().getTxId())); - tableView.getColumns().add(txColumn); - - TableColumn confidenceColumn = new TableColumn<>(Res.get("shared.confirmations")); - confidenceColumn.setMinWidth(130); - confidenceColumn.setMaxWidth(confidenceColumn.getMinWidth()); - - confidenceColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - - confidenceColumn.setCellFactory(new Callback, - TableCell>() { - - @Override - public TableCell call(TableColumn column) { - return new TableCell() { - - @Override - public void updateItem(final VoteListItem item, boolean empty) { - super.updateItem(item, empty); - - if (item != null && !empty) { - setGraphic(item.getTxConfidenceIndicator()); - } else { - setGraphic(null); - } - } - }; - } - }); - confidenceColumn.setComparator(Comparator.comparing(VoteListItem::getConfirmations)); - tableView.getColumns().add(confidenceColumn); - } - - - @Override - protected void createProposalColumns(TableView tableView) { - super.createProposalColumns(tableView); - - TableColumn actionColumn = new TableColumn<>(Res.get("dao.proposal.votes.header")); - actionColumn.setMinWidth(50); - actionColumn.setMaxWidth(actionColumn.getMinWidth()); - - actionColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - - actionColumn.setCellFactory(new Callback, - TableCell>() { - - @Override - public TableCell call(TableColumn column) { - return new TableCell() { - ImageView actionButtonIconView; - - @Override - public void updateItem(final BaseProposalListItem item, boolean empty) { - super.updateItem(item, empty); - - if (item != null && !empty) { - actionButtonIconView = new ImageView(); - //TODO - *//* Vote vote = item.getProposal().getVote(); - if (vote instanceof BooleanVote) { - if (((BooleanVote) vote).isAccepted()) { - actionButtonIconView.setId("accepted"); - } else { - actionButtonIconView.setId("rejected"); - } - } else { - //TODO - }*//* - - setGraphic(actionButtonIconView); - } else { - setGraphic(null); - } - } - }; - } - }); - actionColumn.setComparator(Comparator.comparing(BaseProposalListItem::getConfirmations)); - tableView.getColumns().add(actionColumn); - }*/ -} diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java deleted file mode 100644 index 78486006e64..00000000000 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.desktop.main.dao.proposal.myvotes; - -import bisq.desktop.components.indicator.TxConfidenceIndicator; - -import bisq.core.btc.listeners.TxConfidenceListener; -import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.DaoFacade; -import bisq.core.dao.state.BlockListener; -import bisq.core.dao.state.blockchain.Block; -import bisq.core.dao.state.blockchain.Tx; -import bisq.core.dao.state.blockchain.TxOutput; -import bisq.core.dao.voting.myvote.MyVote; -import bisq.core.locale.Res; -import bisq.core.util.BsqFormatter; - -import org.bitcoinj.core.Coin; -import org.bitcoinj.core.Transaction; -import org.bitcoinj.core.TransactionConfidence; - -import javafx.scene.control.Tooltip; - -import javafx.beans.property.SimpleStringProperty; -import javafx.beans.property.StringProperty; -import javafx.beans.value.ChangeListener; - -import java.util.Optional; - -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; -import lombok.extern.slf4j.Slf4j; - -@ToString -@Slf4j -@EqualsAndHashCode -public class VoteListItem implements BlockListener { - @Getter - private final MyVote myVote; - private final DaoFacade daoFacade; - private final BsqWalletService bsqWalletService; - private final BsqFormatter bsqFormatter; - private final ChangeListener chainHeightListener; - @Getter - private TxConfidenceIndicator txConfidenceIndicator; - @Getter - private Integer confirmations = 0; - - private TxConfidenceListener txConfidenceListener; - private Tooltip tooltip = new Tooltip(Res.get("confidence.unknown")); - private Transaction walletTransaction; - @Setter - private Runnable onRemoveHandler; - @Getter - private long stake = 0; - @Getter - private StringProperty stakeAsStringProperty = new SimpleStringProperty(""); - - VoteListItem(MyVote myVote, - DaoFacade daoFacade, - BsqWalletService bsqWalletService, - BsqFormatter bsqFormatter) { - this.myVote = myVote; - this.daoFacade = daoFacade; - this.bsqWalletService = bsqWalletService; - this.bsqFormatter = bsqFormatter; - - txConfidenceIndicator = new TxConfidenceIndicator(); - txConfidenceIndicator.setId("funds-confidence"); - - txConfidenceIndicator.setProgress(-1); - txConfidenceIndicator.setPrefSize(24, 24); - txConfidenceIndicator.setTooltip(tooltip); - daoFacade.addBlockListener(this); - - chainHeightListener = (observable, oldValue, newValue) -> setupConfidence(); - bsqWalletService.getChainHeightProperty().addListener(chainHeightListener); - setupConfidence(); - calculateStake(); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Listener - /////////////////////////////////////////////////////////////////////////////////////////// - - @Override - public void onBlockAdded(Block block) { - //TODO do we want that here??? - setupConfidence(); - } - - private void setupConfidence() { - calculateStake(); - final String txId = myVote.getBlindVote().getTxId(); - Optional optionalTx = daoFacade.getTx(txId); - if (optionalTx.isPresent()) { - Tx tx = optionalTx.get(); - // We cache the walletTransaction once found - if (walletTransaction == null) { - final Optional transactionOptional = bsqWalletService.isWalletTransaction(txId); - transactionOptional.ifPresent(transaction -> walletTransaction = transaction); - } - - if (walletTransaction != null) { - // It is our tx so we get confidence updates - if (txConfidenceListener == null) { - txConfidenceListener = new TxConfidenceListener(txId) { - @Override - public void onTransactionConfidenceChanged(TransactionConfidence confidence) { - updateConfidence(confidence.getConfidenceType(), confidence.getDepthInBlocks(), confidence.numBroadcastPeers()); - } - }; - bsqWalletService.addTxConfidenceListener(txConfidenceListener); - } - } else { - // tx from other users, we dont get confidence updates but as we have the bsq tx we can calculate it - // we get setupConfidence called at each new block from above listener so no need to register a new listener - int depth = bsqWalletService.getChainHeightProperty().get() - tx.getBlockHeight() + 1; - if (depth > 0) - updateConfidence(TransactionConfidence.ConfidenceType.BUILDING, depth, -1); - } - - final TransactionConfidence confidence = bsqWalletService.getConfidenceForTxId(txId); - if (confidence != null) - updateConfidence(confidence, confidence.getDepthInBlocks()); - } - } - - private void calculateStake() { - if (stake == 0) { - String txId = myVote.getTxId(); - stake = daoFacade.getUnspentBlindVoteStakeTxOutputs().stream() - .filter(txOutput -> txOutput.getTxId().equals(txId)) - .filter(txOutput -> txOutput.getIndex() == 0) - .mapToLong(TxOutput::getValue) - .sum(); - stakeAsStringProperty.set(bsqFormatter.formatCoin(Coin.valueOf(stake))); - } - } - - private void updateConfidence(TransactionConfidence confidence, int depthInBlocks) { - if (confidence != null) { - updateConfidence(confidence.getConfidenceType(), confidence.getDepthInBlocks(), confidence.numBroadcastPeers()); - confirmations = depthInBlocks; - } - } - - public void cleanup() { - bsqWalletService.getChainHeightProperty().removeListener(chainHeightListener); - daoFacade.removeBlockListener(this); - if (txConfidenceListener != null) - bsqWalletService.removeTxConfidenceListener(txConfidenceListener); - } - - private void updateConfidence(TransactionConfidence.ConfidenceType confidenceType, int depthInBlocks, int numBroadcastPeers) { - switch (confidenceType) { - case UNKNOWN: - tooltip.setText(Res.get("confidence.unknown")); - txConfidenceIndicator.setProgress(0); - break; - case PENDING: - tooltip.setText(Res.get("confidence.seen", numBroadcastPeers > -1 ? numBroadcastPeers : Res.get("shared.na"))); - txConfidenceIndicator.setProgress(-1.0); - break; - case BUILDING: - tooltip.setText(Res.get("confidence.confirmed", depthInBlocks)); - txConfidenceIndicator.setProgress(Math.min(1, (double) depthInBlocks / 6.0)); - break; - case DEAD: - tooltip.setText(Res.get("confidence.invalid")); - txConfidenceIndicator.setProgress(0); - break; - } - - txConfidenceIndicator.setPrefSize(24, 24); - } -} - diff --git a/src/main/java/bisq/desktop/main/dao/proposal/votes/VotesView.fxml b/src/main/java/bisq/desktop/main/dao/proposal/votes/VotesView.fxml deleted file mode 100644 index add21b35de1..00000000000 --- a/src/main/java/bisq/desktop/main/dao/proposal/votes/VotesView.fxml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - diff --git a/src/main/java/bisq/desktop/main/dao/proposal/votes/VotesView.java b/src/main/java/bisq/desktop/main/dao/proposal/votes/VotesView.java deleted file mode 100644 index 3aa50c234fb..00000000000 --- a/src/main/java/bisq/desktop/main/dao/proposal/votes/VotesView.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.desktop.main.dao.proposal.votes; - -import bisq.desktop.common.view.ActivatableView; -import bisq.desktop.common.view.FxmlView; - -import javax.inject.Inject; - -import javafx.scene.layout.GridPane; - -@FxmlView -public class VotesView extends ActivatableView { - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Constructor, lifecycle - /////////////////////////////////////////////////////////////////////////////////////////// - - @Inject - private VotesView() { - } - - @Override - public void initialize() { - } - - @Override - protected void activate() { - } - - @Override - protected void deactivate() { - } -} diff --git a/src/main/java/bisq/desktop/util/GUIUtil.java b/src/main/java/bisq/desktop/util/GUIUtil.java index a040730c634..e4fd0bfe09d 100644 --- a/src/main/java/bisq/desktop/util/GUIUtil.java +++ b/src/main/java/bisq/desktop/util/GUIUtil.java @@ -96,6 +96,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.concurrent.TimeUnit; @@ -541,8 +542,14 @@ public static void removeChildrenFromGridPaneRows(GridPane gridPane, int start, childByRowMap.get(rowIndex).add(child); }); - for (int i = Math.min(start, childByRowMap.size()); i < Math.min(end, childByRowMap.size()); i++) { - childByRowMap.get(i).forEach(child -> gridPane.getChildren().remove(child)); + for (int i = Math.min(start, childByRowMap.size()); i < Math.min(end + 1, childByRowMap.size()); i++) { + List nodes = childByRowMap.get(i); + if (nodes != null) { + nodes.stream() + .filter(Objects::nonNull) + .filter(node -> gridPane.getChildren().contains(node)) + .forEach(node -> gridPane.getChildren().remove(node)); + } } } diff --git a/src/test/java/bisq/desktop/AwesomeFontDemo.java b/src/test/java/bisq/desktop/AwesomeFontDemo.java index 30cbf688e14..3f80353e528 100644 --- a/src/test/java/bisq/desktop/AwesomeFontDemo.java +++ b/src/test/java/bisq/desktop/AwesomeFontDemo.java @@ -59,7 +59,7 @@ public void start(Stage primaryStage) { root.getChildren().add(button); } - primaryStage.setScene(new Scene(root, 1200, 950)); + primaryStage.setScene(new Scene(root, 1400, 1200)); primaryStage.show(); } } From 09b6202d0d46cf68ada1dbd2e7a3c3bdf8d9f9bf Mon Sep 17 00:00:00 2001 From: sqrrm Date: Sat, 14 Jul 2018 18:57:23 +0200 Subject: [PATCH 139/197] Remove direct references to stateService in desktop --- .../main/dao/bonding/unlock/LockupTxListItem.java | 11 ++--------- .../desktop/main/dao/bonding/unlock/UnlockView.java | 7 ------- .../dao/proposal/dashboard/ProposalDashboardView.java | 2 +- 3 files changed, 3 insertions(+), 17 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockupTxListItem.java b/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockupTxListItem.java index 1efa5eec582..4a9e77aa211 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockupTxListItem.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockupTxListItem.java @@ -25,7 +25,6 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; import bisq.core.dao.DaoFacade; -import bisq.core.dao.state.StateService; import bisq.core.dao.state.blockchain.TxOutput; import bisq.core.dao.state.blockchain.TxType; import bisq.core.locale.Res; @@ -51,9 +50,6 @@ class LockupTxListItem { private final BtcWalletService btcWalletService; private final DaoFacade daoFacade; - //TODO SQ stateService should not be used outside in desktop - private final StateService stateService; - private final BsqFormatter bsqFormatter; private final Date date; private final String txId; @@ -71,14 +67,12 @@ class LockupTxListItem { BsqWalletService bsqWalletService, BtcWalletService btcWalletService, DaoFacade daoFacade, - StateService stateService, Date date, BsqFormatter bsqFormatter) { this.transaction = transaction; this.bsqWalletService = bsqWalletService; this.btcWalletService = btcWalletService; this.daoFacade = daoFacade; - this.stateService = stateService; this.date = date; this.bsqFormatter = bsqFormatter; @@ -89,8 +83,7 @@ class LockupTxListItem { checkNotNull(transaction, "transaction must not be null as we only have list items from transactions " + "which are available in the wallet"); - //TODO SQ use daoFacade - stateService.getLockupTxOutput(transaction.getHashAsString()) + daoFacade.getLockupTxOutput(transaction.getHashAsString()) .ifPresent(out -> amount = Coin.valueOf(out.getValue())); Optional opLockTime = daoFacade.getLockTime(transaction.getHashAsString()); @@ -138,7 +131,7 @@ public void cleanup() { public boolean isSpent() { Optional optionalTxOutput = daoFacade.getLockupTxOutput(txId); - return optionalTxOutput.map(txOutput -> !stateService.isUnspent(txOutput.getKey())) + return optionalTxOutput.map(txOutput -> !daoFacade.isUnspent(txOutput.getKey())) .orElse(true); } diff --git a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java index 20c197ad384..608f4dcb5b0 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java @@ -36,7 +36,6 @@ import bisq.core.btc.wallet.WalletsSetup; import bisq.core.dao.DaoFacade; import bisq.core.dao.state.BlockListener; -import bisq.core.dao.state.StateService; import bisq.core.dao.state.blockchain.Block; import bisq.core.dao.state.blockchain.TxOutput; import bisq.core.dao.state.blockchain.TxType; @@ -92,9 +91,6 @@ public class UnlockView extends ActivatableView implements BsqBa private final DaoFacade daoFacade; private final Preferences preferences; - //TODO SQ stateService should not be used outside in desktop - private final StateService stateService; - private final WalletsSetup walletsSetup; private final P2PService p2PService; private final Navigation navigation; @@ -122,7 +118,6 @@ private UnlockView(BsqWalletService bsqWalletService, BsqValidator bsqValidator, DaoFacade daoFacade, Preferences preferences, - StateService stateService, WalletsSetup walletsSetup, P2PService p2PService, Navigation navigation) { @@ -133,7 +128,6 @@ private UnlockView(BsqWalletService bsqWalletService, this.bsqValidator = bsqValidator; this.daoFacade = daoFacade; this.preferences = preferences; - this.stateService = stateService; this.walletsSetup = walletsSetup; this.p2PService = p2PService; this.navigation = navigation; @@ -415,7 +409,6 @@ private void updateList() { bsqWalletService, btcWalletService, daoFacade, - stateService, transaction.getUpdateTime(), bsqFormatter); }) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java index c8adc885aeb..a96dd342cf6 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java @@ -50,7 +50,7 @@ // We use here ChainHeightListener because we are interested in period changes not in the result of a completed // block. The event from the ChainHeightListener is sent before parsing starts. -// The event from the StateService.Listener would notify after parsing a new block. +// The event from the ChainHeightListener would notify after parsing a new block. @FxmlView public class ProposalDashboardView extends ActivatableView implements ChainHeightListener { private final DaoFacade daoFacade; From d0cfd619fedafb0ed2d32005b35bf61401a4f366 Mon Sep 17 00:00:00 2001 From: sqrrm Date: Sat, 14 Jul 2018 19:16:45 +0200 Subject: [PATCH 140/197] Remove check for already handled InsufficientMoneyException --- .../main/dao/bonding/unlock/UnlockView.java | 22 +++---------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java index 608f4dcb5b0..da8c6b07635 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java @@ -22,10 +22,7 @@ import bisq.desktop.common.view.FxmlView; import bisq.desktop.components.AutoTooltipTableColumn; import bisq.desktop.components.HyperlinkWithIcon; -import bisq.desktop.main.MainView; import bisq.desktop.main.dao.wallet.BsqBalanceUtil; -import bisq.desktop.main.funds.FundsView; -import bisq.desktop.main.funds.deposit.DepositView; import bisq.desktop.main.overlays.popups.Popup; import bisq.desktop.util.GUIUtil; import bisq.desktop.util.validation.BsqValidator; @@ -46,7 +43,6 @@ import bisq.network.p2p.P2PService; import org.bitcoinj.core.Coin; -import org.bitcoinj.core.InsufficientMoneyException; import org.bitcoinj.core.Transaction; import javax.inject.Inject; @@ -334,21 +330,9 @@ private void onButtonClick() { .closeButtonText(Res.get("shared.cancel")) .show(); } catch (Throwable t) { - //TODO SQ conde analysis of intellij says that the following is always false, but don't understand why... - // but mostly they are right ;-) - if (t instanceof InsufficientMoneyException) { - final Coin missingCoin = ((InsufficientMoneyException) t).missing; - final String missing = missingCoin != null ? missingCoin.toFriendlyString() : "null"; - //noinspection unchecked - new Popup<>().warning(Res.get("popup.warning.insufficientBtcFundsForBsqTx", missing)) - .actionButtonTextWithGoTo("navigation.funds.depositFunds") - .onAction(() -> navigation.navigateTo(MainView.class, FundsView.class, DepositView.class)) - .show(); - } else { - log.error(t.toString()); - t.printStackTrace(); - new Popup<>().warning(t.getMessage()).show(); - } + log.error(t.toString()); + t.printStackTrace(); + new Popup<>().warning(t.getMessage()).show(); } } else { GUIUtil.showNotReadyForTxBroadcastPopups(p2PService, walletsSetup); From e677c1a007cfe3aa4e823cdda7667d816a647681 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Mon, 16 Jul 2018 18:57:20 +0200 Subject: [PATCH 141/197] Don't use recursive parser. UI improvements Don't use recursive parser but raw tx list from bitcoin core. --- src/main/java/bisq/desktop/bisq.css | 38 +++++++++++++------ .../desktop/main/dao/bonding/BondingView.java | 4 +- .../desktop/main/dao/voting/VotingView.java | 2 +- .../main/dao/wallet/BsqWalletView.fxml | 5 +-- .../desktop/main/dao/wallet/tx/BsqTxView.java | 37 ++++++++++++------ 5 files changed, 57 insertions(+), 29 deletions(-) diff --git a/src/main/java/bisq/desktop/bisq.css b/src/main/java/bisq/desktop/bisq.css index e619c38fa3b..0129eb8050b 100644 --- a/src/main/java/bisq/desktop/bisq.css +++ b/src/main/java/bisq/desktop/bisq.css @@ -322,25 +322,29 @@ bg color of non edit textFields: fafafa -fx-text-fill: -bs-red-soft; } -.dao-tx-type-fee-icon, -.dao-tx-type-fee-icon:hover { - -fx-text-fill: #5ab9ea; - -fx-cursor: hand; +.dao-tx-type-trade-fee-icon, +.dao-tx-type-trade-fee-icon:hover { + -fx-text-fill: #689f43; } .dao-tx-type-unverified-icon, .dao-tx-type-unverified-icon:hover { - -fx-text-fill: -bs-yellow; + -fx-text-fill: #ffac00; } .dao-tx-type-invalid-icon, .dao-tx-type-invalid-icon:hover { - -fx-text-fill: -bs-error-red; + -fx-text-fill: #ffac00; } -.dao-tx-type-default-icon, -.dao-tx-type-default-icon:hover { - -fx-text-fill: -bs-grey; +.dao-tx-type-self-icon, +.dao-tx-type-self-icon:hover { + -fx-text-fill: #818181; +} + +.dao-tx-type-proposal-fee-icon, +.dao-tx-type-proposal-fee-icon:hover { + -fx-text-fill: #6c8b3b; } .dao-tx-type-genesis-icon, @@ -360,17 +364,27 @@ bg color of non edit textFields: fafafa .dao-tx-type-vote-icon, .dao-tx-type-vote-icon:hover { - -fx-text-fill: -bs-bg-blue1; + -fx-text-fill: #0a4576; } .dao-tx-type-vote-reveal-icon, .dao-tx-type-vote-reveal-icon:hover { - -fx-text-fill: -bs-bg-green2; + -fx-text-fill: #4AC5FF; } .dao-tx-type-issuance-icon, .dao-tx-type-issuance-icon:hover { - -fx-text-fill: -bs-green; + -fx-text-fill: #04a908; +} + +.dao-tx-type-lockup-icon, +.dao-tx-type-lockup-icon:hover { + -fx-text-fill: #7f2c36; +} + +.dao-tx-type-unlock-icon, +.dao-tx-type-unlock-icon:hover { + -fx-text-fill: #438e6c; } .dao-accepted-icon { diff --git a/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java b/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java index 2c1f4c2585c..0e4670a91de 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java @@ -83,9 +83,9 @@ public void initialize() { dashboard = new MenuItem(navigation, toggleGroup, Res.get("shared.dashboard"), BondingDashboardView.class, AwesomeIcon.DASHBOARD, baseNavPath); lockupBSQ = new MenuItem(navigation, toggleGroup, Res.get("dao.bonding.menuItem.lockupBSQ"), - LockupView.class, AwesomeIcon.LIST_UL, baseNavPath); + LockupView.class, AwesomeIcon.LOCK, baseNavPath); unlockBSQ = new MenuItem(navigation, toggleGroup, Res.get("dao.bonding.menuItem.unlockBSQ"), - UnlockView.class, AwesomeIcon.LIST_UL, baseNavPath); + UnlockView.class, AwesomeIcon.UNLOCK, baseNavPath); leftVBox.getChildren().addAll(dashboard, lockupBSQ, unlockBSQ); } diff --git a/src/main/java/bisq/desktop/main/dao/voting/VotingView.java b/src/main/java/bisq/desktop/main/dao/voting/VotingView.java index 79aa9d5a507..7d697ecfbe8 100644 --- a/src/main/java/bisq/desktop/main/dao/voting/VotingView.java +++ b/src/main/java/bisq/desktop/main/dao/voting/VotingView.java @@ -85,7 +85,7 @@ public void initialize() { activeBallots = new MenuItem(navigation, toggleGroup, Res.get("dao.voting.menuItem.activeBallots"), ActiveBallotsView.class, AwesomeIcon.LIST_UL, baseNavPath); closedBallots = new MenuItem(navigation, toggleGroup, Res.get("dao.voting.menuItem.closedBallots"), - ClosedBallotsView.class, AwesomeIcon.LIST_UL, baseNavPath); + ClosedBallotsView.class, AwesomeIcon.LIST_ALT, baseNavPath); leftVBox.getChildren().addAll(dashboard, activeBallots, closedBallots); } diff --git a/src/main/java/bisq/desktop/main/dao/wallet/BsqWalletView.fxml b/src/main/java/bisq/desktop/main/dao/wallet/BsqWalletView.fxml index 701da401d42..58b049dba13 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/BsqWalletView.fxml +++ b/src/main/java/bisq/desktop/main/dao/wallet/BsqWalletView.fxml @@ -28,11 +28,10 @@ AnchorPane.topAnchor="20"/> - + diff --git a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java index fcbc943a49e..80179fe878e 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java @@ -56,6 +56,7 @@ import javafx.scene.layout.GridPane; import javafx.scene.layout.HBox; import javafx.scene.layout.Pane; +import javafx.scene.layout.Priority; import javafx.scene.layout.VBox; import javafx.geometry.Insets; @@ -150,10 +151,12 @@ public void initialize() { VBox vBox = new VBox(); vBox.setSpacing(10); + GridPane.setVgrow(vBox, Priority.ALWAYS); GridPane.setRowIndex(vBox, ++gridRow); GridPane.setColumnSpan(vBox, 2); GridPane.setMargin(vBox, new Insets(40, -10, 5, -10)); vBox.getChildren().addAll(tableView, hBox); + VBox.setVgrow(tableView, Priority.ALWAYS); root.getChildren().add(vBox); walletBsqTransactionsListener = change -> updateList(); @@ -362,9 +365,10 @@ public void updateItem(final BsqTxListItem item, boolean empty) { if (field != null) field.setOnAction(null); - if (txType == TxType.TRANSFER_BSQ) { - if (item.getAmount().isZero()) - labelString = Res.get("funds.tx.direction.self"); + if (txType == TxType.TRANSFER_BSQ && + item.getAmount().isZero() && + item.getTxType() != TxType.UNLOCK) { + labelString = Res.get("funds.tx.direction.self"); } label = new AutoTooltipLabel(labelString); @@ -481,6 +485,9 @@ public void updateItem(final BsqTxListItem item, boolean empty) { boolean doRotate = false; switch (txType) { case UNDEFINED_TX_TYPE: + awesomeIcon = AwesomeIcon.REMOVE_CIRCLE; + style = "dao-tx-type-unverified-icon"; + break; case UNVERIFIED: awesomeIcon = AwesomeIcon.QUESTION_SIGN; style = "dao-tx-type-unverified-icon"; @@ -495,8 +502,8 @@ public void updateItem(final BsqTxListItem item, boolean empty) { break; case TRANSFER_BSQ: if (item.getAmount().isZero()) { - awesomeIcon = AwesomeIcon.EXCHANGE; - style = "dao-tx-type-default-icon"; + awesomeIcon = AwesomeIcon.RETWEET; + style = "dao-tx-type-self-icon"; } else { awesomeIcon = item.isReceived() ? AwesomeIcon.SIGNIN : AwesomeIcon.SIGNOUT; doRotate = item.isReceived(); @@ -507,8 +514,8 @@ public void updateItem(final BsqTxListItem item, boolean empty) { } break; case PAY_TRADE_FEE: - awesomeIcon = AwesomeIcon.TICKET; - style = "dao-tx-type-default-icon"; + awesomeIcon = AwesomeIcon.LEAF; + style = "dao-tx-type-trade-fee-icon"; break; case PROPOSAL: case COMPENSATION_REQUEST: @@ -521,18 +528,26 @@ public void updateItem(final BsqTxListItem item, boolean empty) { final String formattedDate = bsqFormatter.formatDateTime(new Date(blockTimeInSec * 1000)); toolTipText = Res.get("dao.tx.issuance.tooltip", formattedDate); } else { - awesomeIcon = AwesomeIcon.FILE; - style = "dao-tx-type-fee-icon"; + awesomeIcon = AwesomeIcon.SHARE; + style = "dao-tx-type-proposal-fee-icon"; } break; case BLIND_VOTE: - awesomeIcon = AwesomeIcon.THUMBS_UP; + awesomeIcon = AwesomeIcon.EYE_CLOSE; style = "dao-tx-type-vote-icon"; break; case VOTE_REVEAL: - awesomeIcon = AwesomeIcon.LIGHTBULB; + awesomeIcon = AwesomeIcon.EYE_OPEN; style = "dao-tx-type-vote-reveal-icon"; break; + case LOCKUP: + awesomeIcon = AwesomeIcon.LOCK; + style = "dao-tx-type-lockup-icon"; + break; + case UNLOCK: + awesomeIcon = AwesomeIcon.UNLOCK; + style = "dao-tx-type-unlock-icon"; + break; default: awesomeIcon = AwesomeIcon.QUESTION_SIGN; style = "dao-tx-type-unverified-icon"; From eeb900645224301f059ca2b7b4e87cb8ca094a04 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Tue, 17 Jul 2018 17:44:35 +0200 Subject: [PATCH 142/197] Fix UI bug with dashboard view --- .../components/SeparatedPhaseBars.java | 22 +++++++++---------- .../dashboard/ProposalDashboardView.java | 7 ++---- .../desktop/main/dao/wallet/tx/BsqTxView.java | 6 ++--- 3 files changed, 15 insertions(+), 20 deletions(-) diff --git a/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java b/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java index 3aed082be1d..4d9e5ddf262 100644 --- a/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java +++ b/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java @@ -20,8 +20,6 @@ import bisq.core.dao.state.period.DaoPhase; import bisq.core.locale.Res; -import bisq.common.UserThread; - import javafx.scene.control.Label; import javafx.scene.control.ProgressBar; import javafx.scene.layout.AnchorPane; @@ -83,7 +81,6 @@ public SeparatedPhaseBars(List items) { widthProperty().addListener((observable, oldValue, newValue) -> { updateWidth((double) newValue); }); - UserThread.execute(() -> updateWidth(getWidth())); } public void updateWidth() { @@ -117,15 +114,16 @@ private void addLabels() { } private void updateWidth(double availableWidth) { - totalDuration = items.stream().mapToInt(SeparatedPhaseBarsItem::getDuration).sum(); - // availableWidth -= vBoxLabels.getWidth(); - if (availableWidth > 0 && totalDuration > 0) { - final double finalAvailableWidth = availableWidth; - items.forEach(item -> { - final double width = (double) item.duration / (double) totalDuration * finalAvailableWidth; - item.getProgressBar().setPrefWidth(width); - item.getTitleLabel().setPrefWidth(width); - }); + if (availableWidth > 0) { + totalDuration = items.stream().mapToInt(SeparatedPhaseBarsItem::getDuration).sum(); + if (totalDuration > 0) { + final double finalAvailableWidth = availableWidth; + items.forEach(item -> { + final double width = (double) item.duration / (double) totalDuration * finalAvailableWidth; + item.getProgressBar().setPrefWidth(width); + item.getTitleLabel().setPrefWidth(width); + }); + } } } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java index a96dd342cf6..1e021715cb9 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java @@ -28,8 +28,6 @@ import bisq.core.locale.Res; import bisq.core.util.BSFormatter; -import bisq.common.UserThread; - import javax.inject.Inject; import javafx.scene.control.TextField; @@ -117,8 +115,7 @@ protected void activate() { }); daoFacade.addChainHeightListener(this); - // We need to delay as otherwise the periodService has not been updated yet. - UserThread.execute(() -> onChainHeightChanged(daoFacade.getChainHeight())); + onChainHeightChanged(daoFacade.getChainHeight()); } @Override @@ -132,7 +129,6 @@ protected void deactivate() { @Override public void onChainHeightChanged(int height) { if (height > 0) { - separatedPhaseBars.updateWidth(); phaseBarsItems.forEach(item -> { int firstBlock = daoFacade.getFirstBlockOfPhase(height, item.getPhase()); int lastBlock = daoFacade.getLastBlockOfPhase(height, item.getPhase()); @@ -148,6 +144,7 @@ public void onChainHeightChanged(int height) { } item.getProgressProperty().set(progress); }); + separatedPhaseBars.updateWidth(); } currentBlockHeightTextField.setText(String.valueOf(daoFacade.getChainHeight())); diff --git a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java index 80179fe878e..0efd8e9f22e 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java @@ -519,13 +519,13 @@ public void updateItem(final BsqTxListItem item, boolean empty) { break; case PROPOSAL: case COMPENSATION_REQUEST: - final String txId = item.getTxId(); + String txId = item.getTxId(); if (daoFacade.isIssuanceTx(txId)) { awesomeIcon = AwesomeIcon.MONEY; style = "dao-tx-type-issuance-icon"; - final int issuanceBlockHeight = daoFacade.getIssuanceBlockHeight(txId); + int issuanceBlockHeight = daoFacade.getIssuanceBlockHeight(txId); long blockTimeInSec = daoFacade.getBlockTime(issuanceBlockHeight); - final String formattedDate = bsqFormatter.formatDateTime(new Date(blockTimeInSec * 1000)); + String formattedDate = bsqFormatter.formatDateTime(new Date(blockTimeInSec * 1000)); toolTipText = Res.get("dao.tx.issuance.tooltip", formattedDate); } else { awesomeIcon = AwesomeIcon.SHARE; From 29d95c2bd9c3933b2c1fa7473775e31d644de922 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Tue, 17 Jul 2018 18:20:52 +0200 Subject: [PATCH 143/197] Improve UI --- src/main/java/bisq/desktop/bisq.css | 4 +- .../main/dao/bonding/lockup/LockupView.java | 136 ++++++++++-------- .../main/dao/wallet/send/BsqSendView.java | 37 +++-- 3 files changed, 100 insertions(+), 77 deletions(-) diff --git a/src/main/java/bisq/desktop/bisq.css b/src/main/java/bisq/desktop/bisq.css index 0129eb8050b..ab34bbd487d 100644 --- a/src/main/java/bisq/desktop/bisq.css +++ b/src/main/java/bisq/desktop/bisq.css @@ -334,7 +334,7 @@ bg color of non edit textFields: fafafa .dao-tx-type-invalid-icon, .dao-tx-type-invalid-icon:hover { - -fx-text-fill: #ffac00; + -fx-text-fill: #ff4500; } .dao-tx-type-self-icon, @@ -379,7 +379,7 @@ bg color of non edit textFields: fafafa .dao-tx-type-lockup-icon, .dao-tx-type-lockup-icon:hover { - -fx-text-fill: #7f2c36; + -fx-text-fill: #203e7f; } .dao-tx-type-unlock-icon, diff --git a/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java b/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java index 2e26def51da..007c59e8a1f 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java @@ -66,13 +66,14 @@ public class LockupView extends ActivatableView implements BsqBa private final BsqBalanceUtil bsqBalanceUtil; private final BsqValidator bsqValidator; private final DaoFacade daoFacade; - private final IntegerValidator integerValidator; + private final IntegerValidator timeInputTextFieldValidator; private int gridRow = 0; private InputTextField amountInputTextField; private InputTextField timeInputTextField; private Button lockupButton; private ChangeListener focusOutListener; + private ChangeListener inputTextFieldListener; /////////////////////////////////////////////////////////////////////////////////////////// @@ -97,14 +98,9 @@ private LockupView(BsqWalletService bsqWalletService, this.bsqValidator = bsqValidator; this.daoFacade = daoFacade; - - integerValidator = new IntegerValidator(); - // In the UI we don't allow 0 as that would mean that the tx gets spent - // in the same block as the unspent tx and we don't support unconfirmed txs in the DAO. Technically though 0 - // works as well. - integerValidator.setMinValue(BondingConsensus.getMinLockTime()); - // Max value is max of a short int as we use only 2 bytes in the opReturn for the lockTime - integerValidator.setMaxValue(BondingConsensus.getMaxLockTime()); + timeInputTextFieldValidator = new IntegerValidator(); + timeInputTextFieldValidator.setMinValue(BondingConsensus.getMinLockTime()); + timeInputTextFieldValidator.setMaxValue(BondingConsensus.getMaxLockTime()); } @Override @@ -117,85 +113,71 @@ public void initialize() { Layout.FIRST_ROW_AND_GROUP_DISTANCE).second; amountInputTextField.setPromptText(Res.get("dao.bonding.lock.setAmount", bsqFormatter.formatCoinWithCode(Restrictions.getMinNonDustOutput()))); amountInputTextField.setValidator(bsqValidator); + timeInputTextField = addLabelInputTextField(root, ++gridRow, Res.get("dao.bonding.lock.time"), Layout.GRID_GAP).second; timeInputTextField.setPromptText(Res.get("dao.bonding.lock.setTime", String.valueOf(BondingConsensus.getMinLockTime()), String.valueOf(BondingConsensus.getMaxLockTime()))); - timeInputTextField.setValidator(integerValidator); - - focusOutListener = (observable, oldValue, newValue) -> { - if (!newValue) - onUpdateBalances(bsqWalletService.getAvailableBalance(), - bsqWalletService.getAvailableNonBsqBalance(), - bsqWalletService.getUnverifiedBalance(), - bsqWalletService.getLockedForVotingBalance(), - bsqWalletService.getLockupBondsBalance(), - bsqWalletService.getUnlockingBondsBalance()); - }; + timeInputTextField.setValidator(timeInputTextFieldValidator); lockupButton = addButtonAfterGroup(root, ++gridRow, Res.get("dao.bonding.lock.lockupButton")); - lockupButton.setOnAction((event) -> { if (GUIUtil.isReadyForTxBroadcast(p2PService, walletsSetup)) { Coin lockupAmount = bsqFormatter.parseToCoin(amountInputTextField.getText()); int lockupTime = Integer.parseInt(timeInputTextField.getText()); - try { - new Popup<>().headLine(Res.get("dao.bonding.lock.sendFunds.headline")) - .confirmation(Res.get("dao.bonding.lock.sendFunds.details", - bsqFormatter.formatCoinWithCode(lockupAmount), - lockupTime - )) - .actionButtonText(Res.get("shared.yes")) - .onAction(() -> { - daoFacade.publishLockupTx(lockupAmount, - lockupTime, - () -> { - new Popup<>().confirmation(Res.get("dao.tx.published.success")).show(); - }, - errorMessage -> new Popup<>().warning(errorMessage.toString()).show() - ); - amountInputTextField.setText(""); - timeInputTextField.setText(""); - }) - .closeButtonText(Res.get("shared.cancel")) - .show(); - } catch (Throwable t) { - if (t instanceof InsufficientMoneyException) { - final Coin missingCoin = ((InsufficientMoneyException) t).missing; - final String missing = missingCoin != null ? missingCoin.toFriendlyString() : "null"; - //noinspection unchecked - new Popup<>().warning(Res.get("popup.warning.insufficientBtcFundsForBsqTx", missing)) - .actionButtonTextWithGoTo("navigation.funds.depositFunds") - .onAction(() -> navigation.navigateTo(MainView.class, FundsView.class, DepositView.class)) - .show(); - } else { - log.error(t.toString()); - t.printStackTrace(); - new Popup<>().warning(t.getMessage()).show(); - } - } + new Popup<>().headLine(Res.get("dao.bonding.lock.sendFunds.headline")) + .confirmation(Res.get("dao.bonding.lock.sendFunds.details", + bsqFormatter.formatCoinWithCode(lockupAmount), + lockupTime + )) + .actionButtonText(Res.get("shared.yes")) + .onAction(() -> { + daoFacade.publishLockupTx(lockupAmount, + lockupTime, + () -> { + new Popup<>().feedback(Res.get("dao.tx.published.success")).show(); + }, + this::handleError + ); + amountInputTextField.setText(""); + timeInputTextField.setText(""); + }) + .closeButtonText(Res.get("shared.cancel")) + .show(); } else { GUIUtil.showNotReadyForTxBroadcastPopups(p2PService, walletsSetup); } }); + + focusOutListener = (observable, oldValue, newValue) -> { + if (!newValue) { + updateButtonState(); + onUpdateBalances(); + } + }; + inputTextFieldListener = (observable, oldValue, newValue) -> updateButtonState(); } @Override protected void activate() { bsqBalanceUtil.activate(); + + amountInputTextField.textProperty().addListener(inputTextFieldListener); + timeInputTextField.textProperty().addListener(inputTextFieldListener); amountInputTextField.focusedProperty().addListener(focusOutListener); + bsqWalletService.addBsqBalanceListener(this); - onUpdateBalances(bsqWalletService.getAvailableBalance(), - bsqWalletService.getAvailableNonBsqBalance(), - bsqWalletService.getUnverifiedBalance(), - bsqWalletService.getLockedForVotingBalance(), - bsqWalletService.getLockupBondsBalance(), - bsqWalletService.getUnlockingBondsBalance()); + + onUpdateBalances(); } @Override protected void deactivate() { bsqBalanceUtil.deactivate(); + + amountInputTextField.textProperty().removeListener(inputTextFieldListener); + timeInputTextField.textProperty().removeListener(inputTextFieldListener); amountInputTextField.focusedProperty().removeListener(focusOutListener); + bsqWalletService.removeBsqBalanceListener(this); } @@ -210,4 +192,34 @@ public void onUpdateBalances(Coin confirmedBalance, boolean isValid = bsqValidator.validate(amountInputTextField.getText()).isValid; lockupButton.setDisable(!isValid); } + + private void onUpdateBalances() { + onUpdateBalances(bsqWalletService.getAvailableBalance(), + bsqWalletService.getAvailableNonBsqBalance(), + bsqWalletService.getUnverifiedBalance(), + bsqWalletService.getLockedForVotingBalance(), + bsqWalletService.getLockupBondsBalance(), + bsqWalletService.getUnlockingBondsBalance()); + } + + private void updateButtonState() { + lockupButton.setDisable(!bsqValidator.validate(amountInputTextField.getText()).isValid || + !timeInputTextFieldValidator.validate(timeInputTextField.getText()).isValid); + } + + private void handleError(Throwable throwable) { + if (throwable instanceof InsufficientMoneyException) { + final Coin missingCoin = ((InsufficientMoneyException) throwable).missing; + final String missing = missingCoin != null ? missingCoin.toFriendlyString() : "null"; + //noinspection unchecked + new Popup<>().warning(Res.get("popup.warning.insufficientBtcFundsForBsqTx", missing)) + .actionButtonTextWithGoTo("navigation.funds.depositFunds") + .onAction(() -> navigation.navigateTo(MainView.class, FundsView.class, DepositView.class)) + .show(); + } else { + log.error(throwable.toString()); + throwable.printStackTrace(); + new Popup<>().warning(throwable.toString()).show(); + } + } } diff --git a/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java b/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java index 693fd9ebcaf..6387ff83922 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java @@ -94,6 +94,7 @@ public class BsqSendView extends ActivatableView implements BsqB private TitledGroupBg btcTitledGroupBg; private Label receiversBtcAddressLabel; private Label btcAmountLabel; + private ChangeListener inputTextFieldListener; /////////////////////////////////////////////////////////////////////////////////////////// @@ -138,13 +139,9 @@ public void initialize() { focusOutListener = (observable, oldValue, newValue) -> { if (!newValue) - onUpdateBalances(bsqWalletService.getAvailableBalance(), - bsqWalletService.getAvailableNonBsqBalance(), - bsqWalletService.getUnverifiedBalance(), - bsqWalletService.getLockedForVotingBalance(), - bsqWalletService.getLockupBondsBalance(), - bsqWalletService.getUnlockingBondsBalance()); + onUpdateBalances(); }; + inputTextFieldListener = (observable, oldValue, newValue) -> onUpdateBalances(); setSendBtcGroupVisibleState(false); } @@ -153,13 +150,23 @@ public void initialize() { protected void activate() { setSendBtcGroupVisibleState(false); bsqBalanceUtil.activate(); + receiversAddressInputTextField.focusedProperty().addListener(focusOutListener); amountInputTextField.focusedProperty().addListener(focusOutListener); - receiversBtcAddressInputTextField.focusedProperty().addListener(focusOutListener); btcAmountInputTextField.focusedProperty().addListener(focusOutListener); + receiversAddressInputTextField.textProperty().addListener(inputTextFieldListener); + amountInputTextField.textProperty().addListener(inputTextFieldListener); + receiversBtcAddressInputTextField.textProperty().addListener(inputTextFieldListener); + btcAmountInputTextField.textProperty().addListener(inputTextFieldListener); + bsqWalletService.addBsqBalanceListener(this); + + onUpdateBalances(); + } + + private void onUpdateBalances() { onUpdateBalances(bsqWalletService.getAvailableBalance(), bsqWalletService.getAvailableNonBsqBalance(), bsqWalletService.getUnverifiedBalance(), @@ -172,8 +179,17 @@ protected void activate() { @Override protected void deactivate() { bsqBalanceUtil.deactivate(); + receiversAddressInputTextField.focusedProperty().removeListener(focusOutListener); amountInputTextField.focusedProperty().removeListener(focusOutListener); + receiversBtcAddressInputTextField.focusedProperty().removeListener(focusOutListener); + btcAmountInputTextField.focusedProperty().removeListener(focusOutListener); + + receiversAddressInputTextField.textProperty().removeListener(inputTextFieldListener); + amountInputTextField.textProperty().removeListener(inputTextFieldListener); + receiversBtcAddressInputTextField.textProperty().removeListener(inputTextFieldListener); + btcAmountInputTextField.textProperty().removeListener(inputTextFieldListener); + bsqWalletService.removeBsqBalanceListener(this); } @@ -211,12 +227,7 @@ private void addSendBsqGroup() { focusOutListener = (observable, oldValue, newValue) -> { if (!newValue) - onUpdateBalances(bsqWalletService.getAvailableBalance(), - bsqWalletService.getAvailableNonBsqBalance(), - bsqWalletService.getUnverifiedBalance(), - bsqWalletService.getLockedForVotingBalance(), - bsqWalletService.getLockupBondsBalance(), - bsqWalletService.getUnlockingBondsBalance()); + onUpdateBalances(); }; sendButton = addButtonAfterGroup(root, ++gridRow, Res.get("dao.wallet.send.send")); From 513350ff67b0928ce4fdac8eab7ef0bc790c4935 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Wed, 18 Jul 2018 19:23:24 +0200 Subject: [PATCH 144/197] Refactor state listeners --- .../main/dao/BaseProposalListItem.java | 26 +++- .../main/dao/bonding/unlock/UnlockView.java | 141 ++++++++++-------- .../desktop/main/dao/cycles/CyclesView.java | 23 ++- .../dashboard/ProposalDashboardView.java | 40 ++++- .../dao/proposal/make/MakeProposalView.java | 27 +++- .../dao/voting/active/ActiveBallotsView.java | 24 ++- .../wallet/dashboard/BsqDashboardView.java | 29 +++- .../desktop/main/dao/wallet/tx/BsqTxView.java | 35 ++++- 8 files changed, 241 insertions(+), 104 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/BaseProposalListItem.java b/src/main/java/bisq/desktop/main/dao/BaseProposalListItem.java index d62cda396f7..fc418a22a7b 100644 --- a/src/main/java/bisq/desktop/main/dao/BaseProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/BaseProposalListItem.java @@ -22,7 +22,7 @@ import bisq.core.btc.listeners.TxConfidenceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; -import bisq.core.dao.state.BlockListener; +import bisq.core.dao.state.BsqStateListener; import bisq.core.dao.state.blockchain.Block; import bisq.core.dao.state.blockchain.Tx; import bisq.core.dao.state.period.DaoPhase; @@ -48,7 +48,7 @@ @ToString @Slf4j @EqualsAndHashCode -public abstract class BaseProposalListItem implements BlockListener { +public abstract class BaseProposalListItem implements BsqStateListener { @Getter protected final DaoFacade daoFacade; protected final BsqWalletService bsqWalletService; @@ -82,24 +82,36 @@ protected BaseProposalListItem(DaoFacade daoFacade, /////////////////////////////////////////////////////////////////////////////////////////// - // BlockListener + // BsqStateListener /////////////////////////////////////////////////////////////////////////////////////////// @Override - public void onBlockAdded(Block block) { + public void onNewBlockHeight(int blockHeight) { + } + + @Override + public void onEmptyBlockAdded(Block block) { + } + + @Override + public void onParseTxsComplete(Block block) { setupConfidence(); } + @Override + public void onParseBlockChainComplete() { + } + /////////////////////////////////////////////////////////////////////////////////////////// - // Public + // API /////////////////////////////////////////////////////////////////////////////////////////// public void onPhaseChanged(DaoPhase.Phase phase) { } public void cleanup() { - daoFacade.removeBlockListener(this); + daoFacade.removeBsqStateListener(this); bsqWalletService.getChainHeightProperty().removeListener(chainHeightListener); if (txConfidenceListener != null) bsqWalletService.removeTxConfidenceListener(txConfidenceListener); @@ -129,7 +141,7 @@ protected void init() { bsqWalletService.getChainHeightProperty().addListener(chainHeightListener); setupConfidence(); - daoFacade.addBlockListener(this); + daoFacade.addBsqStateListener(this); phaseChangeListener = (observable, oldValue, newValue) -> onPhaseChanged(newValue); diff --git a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java index da8c6b07635..9a68c7d104c 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java @@ -17,7 +17,6 @@ package bisq.desktop.main.dao.bonding.unlock; -import bisq.desktop.Navigation; import bisq.desktop.common.view.ActivatableView; import bisq.desktop.common.view.FxmlView; import bisq.desktop.components.AutoTooltipTableColumn; @@ -32,7 +31,7 @@ import bisq.core.btc.wallet.BtcWalletService; import bisq.core.btc.wallet.WalletsSetup; import bisq.core.dao.DaoFacade; -import bisq.core.dao.state.BlockListener; +import bisq.core.dao.state.BsqStateListener; import bisq.core.dao.state.blockchain.Block; import bisq.core.dao.state.blockchain.TxOutput; import bisq.core.dao.state.blockchain.TxType; @@ -76,7 +75,7 @@ import java.util.stream.Collectors; @FxmlView -public class UnlockView extends ActivatableView implements BsqBalanceListener, BlockListener { +public class UnlockView extends ActivatableView implements BsqBalanceListener, BsqStateListener { private TableView tableView; private final BsqWalletService bsqWalletService; @@ -89,7 +88,6 @@ public class UnlockView extends ActivatableView implements BsqBa private final WalletsSetup walletsSetup; private final P2PService p2PService; - private final Navigation navigation; private int gridRow = 0; private boolean synced; @@ -115,8 +113,7 @@ private UnlockView(BsqWalletService bsqWalletService, DaoFacade daoFacade, Preferences preferences, WalletsSetup walletsSetup, - P2PService p2PService, - Navigation navigation) { + P2PService p2PService) { this.bsqWalletService = bsqWalletService; this.btcWalletService = btcWalletService; this.bsqFormatter = bsqFormatter; @@ -126,9 +123,9 @@ private UnlockView(BsqWalletService bsqWalletService, this.preferences = preferences; this.walletsSetup = walletsSetup; this.p2PService = p2PService; - this.navigation = navigation; } + @Override public void initialize() { gridRow = bsqBalanceUtil.addGroup(root, gridRow); @@ -152,9 +149,87 @@ public void initialize() { GridPane.setMargin(vBox, new Insets(40, -10, 5, -10)); vBox.getChildren().addAll(tableView); root.getChildren().add(vBox); + } + + @Override + protected void activate() { + bsqBalanceUtil.activate(); + bsqWalletService.addBsqBalanceListener(this); + onUpdateBalances(bsqWalletService.getAvailableBalance(), + bsqWalletService.getAvailableNonBsqBalance(), + bsqWalletService.getUnverifiedBalance(), + bsqWalletService.getLockedForVotingBalance(), + bsqWalletService.getLockupBondsBalance(), + bsqWalletService.getUnlockingBondsBalance()); + + bsqWalletService.getWalletTransactions().addListener(walletBsqTransactionsListener); + bsqWalletService.addBsqBalanceListener(this); + btcWalletService.getChainHeightProperty().addListener(walletChainHeightListener); + + tableView.setItems(lockupTxs); + + daoFacade.addBsqStateListener(this); + + updateList(); + onUpdateAnyChainHeight(); + } + + @Override + protected void deactivate() { + bsqBalanceUtil.deactivate(); + bsqWalletService.removeBsqBalanceListener(this); + + lockupTxs.predicateProperty().unbind(); + bsqWalletService.getWalletTransactions().removeListener(walletBsqTransactionsListener); + bsqWalletService.removeBsqBalanceListener(this); + btcWalletService.getChainHeightProperty().removeListener(walletChainHeightListener); + daoFacade.removeBsqStateListener(this); + + observableList.forEach(LockupTxListItem::cleanup); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // BsqBalanceListener + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public void onUpdateBalances(Coin confirmedBalance, + Coin availableNonBsqBalance, + Coin pendingBalance, + Coin lockedForVotingBalance, + Coin lockupBondsBalance, + Coin unlockingBondsBalance) { + bsqValidator.setAvailableBalance(confirmedBalance); + } + + /////////////////////////////////////////////////////////////////////////////////////////// + // BsqStateListener + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public void onNewBlockHeight(int blockHeight) { } + @Override + public void onEmptyBlockAdded(Block block) { + } + + @Override + public void onParseTxsComplete(Block block) { + onUpdateAnyChainHeight(); + } + + @Override + public void onParseBlockChainComplete() { + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Private + /////////////////////////////////////////////////////////////////////////////////////////// + private void addTxIdColumn() { TableColumn column = new AutoTooltipTableColumn<>(Res.get("shared.txId")); @@ -345,34 +420,6 @@ private void openTxInBlockExplorer(LockupTxListItem item) { GUIUtil.openWebPage(preferences.getBsqBlockChainExplorer().txUrl + item.getTxId()); } - @Override - protected void activate() { - bsqBalanceUtil.activate(); - bsqWalletService.addBsqBalanceListener(this); - onUpdateBalances(bsqWalletService.getAvailableBalance(), - bsqWalletService.getAvailableNonBsqBalance(), - bsqWalletService.getUnverifiedBalance(), - bsqWalletService.getLockedForVotingBalance(), - bsqWalletService.getLockupBondsBalance(), - bsqWalletService.getUnlockingBondsBalance()); - - bsqWalletService.getWalletTransactions().addListener(walletBsqTransactionsListener); - bsqWalletService.addBsqBalanceListener(this); - btcWalletService.getChainHeightProperty().addListener(walletChainHeightListener); - - tableView.setItems(lockupTxs); - - daoFacade.addBlockListener(this); - - updateList(); - onUpdateAnyChainHeight(); - } - - @Override - public void onBlockAdded(Block block) { - onUpdateAnyChainHeight(); - } - private void onUpdateAnyChainHeight() { final int bsqBlockChainHeight = daoFacade.getChainHeight(); final int bsqWalletChainHeight = bsqWalletService.getBestChainHeight(); @@ -399,28 +446,4 @@ private void updateList() { .collect(Collectors.toList()); observableList.setAll(items); } - - @Override - protected void deactivate() { - bsqBalanceUtil.deactivate(); - bsqWalletService.removeBsqBalanceListener(this); - - lockupTxs.predicateProperty().unbind(); - bsqWalletService.getWalletTransactions().removeListener(walletBsqTransactionsListener); - bsqWalletService.removeBsqBalanceListener(this); - btcWalletService.getChainHeightProperty().removeListener(walletChainHeightListener); - daoFacade.removeBlockListener(this); - - observableList.forEach(LockupTxListItem::cleanup); - } - - @Override - public void onUpdateBalances(Coin confirmedBalance, - Coin availableNonBsqBalance, - Coin pendingBalance, - Coin lockedForVotingBalance, - Coin lockupBondsBalance, - Coin unlockingBondsBalance) { - bsqValidator.setAvailableBalance(confirmedBalance); - } } diff --git a/src/main/java/bisq/desktop/main/dao/cycles/CyclesView.java b/src/main/java/bisq/desktop/main/dao/cycles/CyclesView.java index e68c8a3d90f..25f6a5e7462 100644 --- a/src/main/java/bisq/desktop/main/dao/cycles/CyclesView.java +++ b/src/main/java/bisq/desktop/main/dao/cycles/CyclesView.java @@ -29,8 +29,9 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; -import bisq.core.dao.state.ChainHeightListener; +import bisq.core.dao.state.BsqStateListener; import bisq.core.dao.state.StateService; +import bisq.core.dao.state.blockchain.Block; import bisq.core.dao.state.period.Cycle; import bisq.core.dao.state.period.CycleService; import bisq.core.dao.voting.proposal.Proposal; @@ -67,7 +68,7 @@ import java.util.stream.Collectors; @FxmlView -public class CyclesView extends ActivatableViewAndModel implements ChainHeightListener { +public class CyclesView extends ActivatableViewAndModel implements BsqStateListener { private final DaoFacade daoFacade; // TODO use daoFacade once dev work completed private final StateService stateService; @@ -114,7 +115,7 @@ private CyclesView(DaoFacade daoFacade, @Override public void initialize() { - daoFacade.addChainHeightListener(this); + daoFacade.addBsqStateListener(this); resultGridPane = new GridPane(); createResultsTable(); @@ -136,14 +137,26 @@ protected void deactivate() { /////////////////////////////////////////////////////////////////////////////////////////// - // ChainHeightListener + // BsqStateListener /////////////////////////////////////////////////////////////////////////////////////////// @Override - public void onChainHeightChanged(int blockHeight) { + public void onNewBlockHeight(int blockHeight) { fillCycleList(); } + @Override + public void onEmptyBlockAdded(Block block) { + } + + @Override + public void onParseTxsComplete(Block block) { + } + + @Override + public void onParseBlockChainComplete() { + } + /////////////////////////////////////////////////////////////////////////////////////////// // UI handlers diff --git a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java index 1e021715cb9..f9d7ccec550 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java @@ -23,7 +23,8 @@ import bisq.desktop.util.Layout; import bisq.core.dao.DaoFacade; -import bisq.core.dao.state.ChainHeightListener; +import bisq.core.dao.state.BsqStateListener; +import bisq.core.dao.state.blockchain.Block; import bisq.core.dao.state.period.DaoPhase; import bisq.core.locale.Res; import bisq.core.util.BSFormatter; @@ -50,7 +51,7 @@ // block. The event from the ChainHeightListener is sent before parsing starts. // The event from the ChainHeightListener would notify after parsing a new block. @FxmlView -public class ProposalDashboardView extends ActivatableView implements ChainHeightListener { +public class ProposalDashboardView extends ActivatableView implements BsqStateListener { private final DaoFacade daoFacade; private final BSFormatter formatter; @@ -113,21 +114,46 @@ protected void activate() { }); }); - daoFacade.addChainHeightListener(this); + daoFacade.addBsqStateListener(this); - onChainHeightChanged(daoFacade.getChainHeight()); + applyData(daoFacade.getChainHeight()); } @Override protected void deactivate() { super.deactivate(); - daoFacade.removeChainHeightListener(this); + daoFacade.removeBsqStateListener(this); phaseSubscription.unsubscribe(); } - // ChainHeightListener + + /////////////////////////////////////////////////////////////////////////////////////////// + // BsqStateListener + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public void onNewBlockHeight(int height) { + applyData(height); + } + + @Override + public void onEmptyBlockAdded(Block block) { + } + @Override - public void onChainHeightChanged(int height) { + public void onParseTxsComplete(Block block) { + } + + @Override + public void onParseBlockChainComplete() { + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Private + /////////////////////////////////////////////////////////////////////////////////////////// + + private void applyData(int height) { if (height > 0) { phaseBarsItems.forEach(item -> { int firstBlock = daoFacade.getFirstBlockOfPhase(height, item.getPhase()); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index 85a16a731f1..02216648d1b 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -30,7 +30,8 @@ import bisq.core.btc.wallet.InsufficientBsqException; import bisq.core.btc.wallet.WalletsSetup; import bisq.core.dao.DaoFacade; -import bisq.core.dao.state.ChainHeightListener; +import bisq.core.dao.state.BsqStateListener; +import bisq.core.dao.state.blockchain.Block; import bisq.core.dao.state.ext.Param; import bisq.core.dao.state.period.DaoPhase; import bisq.core.dao.voting.ValidationException; @@ -72,7 +73,7 @@ import static com.google.common.base.Preconditions.checkNotNull; @FxmlView -public class MakeProposalView extends ActivatableView implements ChainHeightListener { +public class MakeProposalView extends ActivatableView implements BsqStateListener { private final DaoFacade daoFacade; private final BsqWalletService bsqWalletService; private final WalletsSetup walletsSetup; @@ -137,8 +138,8 @@ public ProposalType fromString(String string) { @Override protected void activate() { - daoFacade.addChainHeightListener(this); - onChainHeightChanged(daoFacade.getChainHeight()); + daoFacade.addBsqStateListener(this); + onNewBlockHeight(daoFacade.getChainHeight()); proposalTypeComboBox.getSelectionModel().selectedItemProperty().addListener(proposalTypeChangeListener); @@ -148,7 +149,7 @@ protected void activate() { @Override protected void deactivate() { - daoFacade.removeChainHeightListener(this); + daoFacade.removeBsqStateListener(this); proposalTypeComboBox.getSelectionModel().selectedItemProperty().removeListener(proposalTypeChangeListener); if (createButton != null) createButton.setOnAction(null); @@ -156,14 +157,26 @@ protected void deactivate() { /////////////////////////////////////////////////////////////////////////////////////////// - // ChainHeightListener + // BsqStateListener /////////////////////////////////////////////////////////////////////////////////////////// @Override - public void onChainHeightChanged(int blockHeight) { + public void onNewBlockHeight(int height) { proposalTypeComboBox.setDisable(!daoFacade.isInPhaseButNotLastBlock(DaoPhase.Phase.PROPOSAL)); } + @Override + public void onEmptyBlockAdded(Block block) { + } + + @Override + public void onParseTxsComplete(Block block) { + } + + @Override + public void onParseBlockChainComplete() { + } + /////////////////////////////////////////////////////////////////////////////////////////// // Private diff --git a/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.java b/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.java index 1bf63b9210b..02d095242f7 100644 --- a/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.java +++ b/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.java @@ -31,7 +31,7 @@ import bisq.core.btc.wallet.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; -import bisq.core.dao.state.BlockListener; +import bisq.core.dao.state.BsqStateListener; import bisq.core.dao.state.blockchain.Block; import bisq.core.dao.state.period.DaoPhase; import bisq.core.dao.voting.ballot.Ballot; @@ -73,13 +73,14 @@ import static bisq.desktop.util.FormBuilder.addTitledGroupBg; @FxmlView -public class ActiveBallotsView extends BaseProposalView implements BsqBalanceListener, BlockListener { +public class ActiveBallotsView extends BaseProposalView implements BsqBalanceListener, BsqStateListener { private Button acceptButton, rejectButton, removeMyVoteButton, voteButton; private InputTextField stakeInputTextField; private BusyAnimation voteButtonBusyAnimation; private Label voteButtonInfoLabel; private ListChangeListener listChangeListener; + /////////////////////////////////////////////////////////////////////////////////////////// // Constructor, lifecycle /////////////////////////////////////////////////////////////////////////////////////////// @@ -120,7 +121,7 @@ protected void activate() { voteButton.setOnAction(e -> onVote()); - daoFacade.addBlockListener(this); + daoFacade.addBsqStateListener(this); updateButtons(); } @@ -150,15 +151,28 @@ public void onUpdateBalances(Coin confirmedBalance, bsqFormatter.formatCoinWithCode(confirmedBalance))); } + /////////////////////////////////////////////////////////////////////////////////////////// - // BlockListener + // BsqStateListener /////////////////////////////////////////////////////////////////////////////////////////// @Override - public void onBlockAdded(Block block) { + public void onNewBlockHeight(int blockHeight) { + } + + @Override + public void onEmptyBlockAdded(Block block) { + } + + @Override + public void onParseTxsComplete(Block block) { updateButtons(); } + @Override + public void onParseBlockChainComplete() { + } + /////////////////////////////////////////////////////////////////////////////////////////// // Protected diff --git a/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java b/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java index 2f3a5e39102..68f418c9908 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java @@ -26,7 +26,7 @@ import bisq.desktop.util.Layout; import bisq.core.dao.DaoFacade; -import bisq.core.dao.state.BlockListener; +import bisq.core.dao.state.BsqStateListener; import bisq.core.dao.state.blockchain.Block; import bisq.core.locale.Res; import bisq.core.monetary.Altcoin; @@ -57,7 +57,7 @@ import static bisq.desktop.util.FormBuilder.addTitledGroupBg; @FxmlView -public class BsqDashboardView extends ActivatableView implements BlockListener { +public class BsqDashboardView extends ActivatableView implements BsqStateListener { private final BsqBalanceUtil bsqBalanceUtil; private final DaoFacade daoFacade; @@ -132,7 +132,7 @@ public void initialize() { protected void activate() { bsqBalanceUtil.activate(); - daoFacade.addBlockListener(this); + daoFacade.addBsqStateListener(this); priceFeedService.updateCounterProperty().addListener(priceChangeListener); hyperlinkWithIcon.setOnAction(event -> GUIUtil.openWebPage(preferences.getBsqBlockChainExplorer().txUrl + daoFacade.getGenesisTxId())); @@ -144,21 +144,38 @@ protected void activate() { @Override protected void deactivate() { bsqBalanceUtil.deactivate(); - daoFacade.removeBlockListener(this); + daoFacade.removeBsqStateListener(this); priceFeedService.updateCounterProperty().removeListener(priceChangeListener); hyperlinkWithIcon.setOnAction(null); } /////////////////////////////////////////////////////////////////////////////////////////// - // BlockListener + // BsqStateListener /////////////////////////////////////////////////////////////////////////////////////////// @Override - public void onBlockAdded(Block block) { + public void onNewBlockHeight(int blockHeight) { + } + + @Override + public void onEmptyBlockAdded(Block block) { + } + + @Override + public void onParseTxsComplete(Block block) { updateWithBsqBlockChainData(); } + @Override + public void onParseBlockChainComplete() { + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Private + /////////////////////////////////////////////////////////////////////////////////////////// + private void updateWithBsqBlockChainData() { Coin issuedAmountFromGenesis = daoFacade.getGenesisTotalSupply(); genesisIssueAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(issuedAmountFromGenesis)); diff --git a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java index 0efd8e9f22e..83e39cf4952 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java @@ -32,7 +32,7 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; import bisq.core.dao.DaoFacade; -import bisq.core.dao.state.BlockListener; +import bisq.core.dao.state.BsqStateListener; import bisq.core.dao.state.blockchain.Block; import bisq.core.dao.state.blockchain.TxType; import bisq.core.locale.Res; @@ -55,7 +55,6 @@ import javafx.scene.control.Tooltip; import javafx.scene.layout.GridPane; import javafx.scene.layout.HBox; -import javafx.scene.layout.Pane; import javafx.scene.layout.Priority; import javafx.scene.layout.VBox; @@ -78,10 +77,9 @@ import java.util.stream.Collectors; @FxmlView -public class BsqTxView extends ActivatableView implements BsqBalanceListener, BlockListener { +public class BsqTxView extends ActivatableView implements BsqBalanceListener, BsqStateListener { private TableView tableView; - private Pane rootParent; private final DaoFacade daoFacade; private final BsqFormatter bsqFormatter; @@ -174,7 +172,7 @@ protected void activate() { sortedList.comparatorProperty().bind(tableView.comparatorProperty()); tableView.setItems(sortedList); - daoFacade.addBlockListener(this); + daoFacade.addBsqStateListener(this); updateList(); onUpdateAnyChainHeight(); @@ -187,12 +185,16 @@ protected void deactivate() { bsqWalletService.getWalletTransactions().removeListener(walletBsqTransactionsListener); bsqWalletService.removeBsqBalanceListener(this); btcWalletService.getChainHeightProperty().removeListener(walletChainHeightListener); - daoFacade.removeBlockListener(this); + daoFacade.removeBsqStateListener(this); observableList.forEach(BsqTxListItem::cleanup); } + /////////////////////////////////////////////////////////////////////////////////////////// + // BsqBalanceListener + /////////////////////////////////////////////////////////////////////////////////////////// + @Override public void onUpdateBalances(Coin confirmedBalance, Coin availableNonBsqBalance, @@ -205,14 +207,31 @@ public void onUpdateBalances(Coin confirmedBalance, /////////////////////////////////////////////////////////////////////////////////////////// - // Listener + // BsqStateListener /////////////////////////////////////////////////////////////////////////////////////////// @Override - public void onBlockAdded(Block block) { + public void onNewBlockHeight(int blockHeight) { + } + + @Override + public void onEmptyBlockAdded(Block block) { + } + + @Override + public void onParseTxsComplete(Block block) { onUpdateAnyChainHeight(); } + @Override + public void onParseBlockChainComplete() { + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Private + /////////////////////////////////////////////////////////////////////////////////////////// + // If chain height from wallet of from the BSQ blockchain parsing changed we update our state. private void onUpdateAnyChainHeight() { final int bsqBlockChainHeight = daoFacade.getChainHeight(); From 18163b799124593c2070899dee1d5eefdcc7daa0 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Wed, 18 Jul 2018 19:43:41 +0200 Subject: [PATCH 145/197] Rename StateService to BsqStateService --- .../bisq/desktop/main/dao/cycles/CyclesView.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/cycles/CyclesView.java b/src/main/java/bisq/desktop/main/dao/cycles/CyclesView.java index 25f6a5e7462..e27ce57e383 100644 --- a/src/main/java/bisq/desktop/main/dao/cycles/CyclesView.java +++ b/src/main/java/bisq/desktop/main/dao/cycles/CyclesView.java @@ -30,7 +30,7 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; import bisq.core.dao.state.BsqStateListener; -import bisq.core.dao.state.StateService; +import bisq.core.dao.state.BsqStateService; import bisq.core.dao.state.blockchain.Block; import bisq.core.dao.state.period.Cycle; import bisq.core.dao.state.period.CycleService; @@ -71,7 +71,7 @@ public class CyclesView extends ActivatableViewAndModel implements BsqStateListener { private final DaoFacade daoFacade; // TODO use daoFacade once dev work completed - private final StateService stateService; + private final BsqStateService bsqStateService; private final CycleService cycleService; private final VoteResultService voteResultService; private final ProposalService proposalService; @@ -98,14 +98,14 @@ public class CyclesView extends ActivatableViewAndModel i @Inject private CyclesView(DaoFacade daoFacade, - StateService stateService, + BsqStateService bsqStateService, CycleService cycleService, VoteResultService voteResultService, ProposalService proposalService, BsqWalletService bsqWalletService, BsqFormatter bsqFormatter) { this.daoFacade = daoFacade; - this.stateService = stateService; + this.bsqStateService = bsqStateService; this.cycleService = cycleService; this.voteResultService = voteResultService; this.proposalService = proposalService; @@ -215,7 +215,7 @@ private void createResultDisplay() { private void fillCycleList() { itemList.clear(); - stateService.getCycles().forEach(this::addCycleListItem); + bsqStateService.getCycles().forEach(this::addCycleListItem); Collections.reverse(itemList); } @@ -229,7 +229,7 @@ private void addCycleListItem(Cycle cycle) { .filter(evaluatedProposal -> cycleService.isTxInCycle(cycle, evaluatedProposal.getProposal().getTxId())) .collect(Collectors.toList()); - long cycleStartTime = stateService.getBlockAtHeight(cycle.getHeightOfFirstBlock()) + long cycleStartTime = bsqStateService.getBlockAtHeight(cycle.getHeightOfFirstBlock()) .map(e -> e.getTime() * 1000) .orElse(0L); int cycleIndex = cycleService.getCycleIndex(cycle); From 547fb2f070581c1880ba74887d98dc1325a2d385 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Wed, 18 Jul 2018 21:05:38 +0200 Subject: [PATCH 146/197] Apply code analysis, cleanups --- .../desktop/main/dao/BaseBsqTxListItem.java | 80 ++++++++++++++++ .../main/dao/BaseProposalListItem.java | 7 +- .../desktop/main/dao/BaseProposalView.java | 8 +- .../java/bisq/desktop/main/dao/DaoView.java | 11 ++- .../desktop/main/dao/bonding/BondingView.fxml | 3 +- .../dao/bonding/unlock/LockupTxListItem.java | 55 ++--------- .../main/dao/bonding/unlock/UnlockView.java | 16 +--- .../main/dao/cycles/CyclesListItem.java | 2 +- .../desktop/main/dao/cycles/CyclesView.java | 6 +- .../dao/cycles/cycle/CycleDetailsWindow.java | 9 +- .../main/dao/cycles/cycle/CycleDisplay.java | 4 +- .../main/dao/cycles/cycle/CycleListItem.java | 2 +- .../dao/proposal/ProposalDetailsWindow.java | 6 +- .../main/dao/proposal/ProposalDisplay.java | 25 +++-- .../main/dao/proposal/ProposalItemsView.java | 2 +- .../main/dao/proposal/ProposalView.fxml | 3 +- .../main/dao/proposal/ProposalView.java | 5 +- .../active/ActiveProposalListItem.java | 1 + .../proposal/active/ActiveProposalsView.java | 3 +- .../closed/ClosedProposalListItem.java | 2 +- .../dao/proposal/make/MakeProposalView.java | 2 + .../main/dao/voting/BaseBallotListItem.java | 96 +++++++++++++++++++ .../desktop/main/dao/voting/VotingView.fxml | 3 +- .../desktop/main/dao/voting/VotingView.java | 4 - .../voting/active/ActiveBallotListItem.java | 63 ++---------- .../voting/closed/ClosedBallotListItem.java | 54 +---------- .../dao/voting/closed/ClosedBallotsView.java | 5 - .../main/dao/wallet/BsqBalanceUtil.java | 2 +- .../main/dao/wallet/BsqWalletView.fxml | 3 +- .../main/dao/wallet/BsqWalletView.java | 1 + .../main/dao/wallet/send/BsqSendView.java | 6 +- .../main/dao/wallet/tx/BsqTxListItem.java | 54 ++--------- .../desktop/main/dao/wallet/tx/BsqTxView.java | 1 + .../funds/transactions/TransactionsView.java | 1 + 34 files changed, 268 insertions(+), 277 deletions(-) create mode 100644 src/main/java/bisq/desktop/main/dao/BaseBsqTxListItem.java create mode 100644 src/main/java/bisq/desktop/main/dao/voting/BaseBallotListItem.java diff --git a/src/main/java/bisq/desktop/main/dao/BaseBsqTxListItem.java b/src/main/java/bisq/desktop/main/dao/BaseBsqTxListItem.java new file mode 100644 index 00000000000..802ba54c22a --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/BaseBsqTxListItem.java @@ -0,0 +1,80 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.desktop.main.dao; + +import bisq.desktop.components.indicator.TxConfidenceIndicator; +import bisq.desktop.util.GUIUtil; + +import bisq.core.btc.listeners.TxConfidenceListener; +import bisq.core.btc.wallet.BsqWalletService; + +import org.bitcoinj.core.Transaction; +import org.bitcoinj.core.TransactionConfidence; + +import javafx.scene.control.Tooltip; + +import lombok.Data; + + +@Data +public class BaseBsqTxListItem { + protected final BsqWalletService bsqWalletService; + protected final String txId; + protected int confirmations = 0; + protected TxConfidenceIndicator txConfidenceIndicator; + protected TxConfidenceListener txConfidenceListener; + + protected BaseBsqTxListItem(Transaction transaction, + BsqWalletService bsqWalletService) { + this.bsqWalletService = bsqWalletService; + + txId = transaction.getHashAsString(); + + setupConfidence(bsqWalletService); + } + + private void setupConfidence(BsqWalletService bsqWalletService) { + txConfidenceIndicator = new TxConfidenceIndicator(); + txConfidenceIndicator.setId("funds-confidence"); + Tooltip tooltip = new Tooltip(); + txConfidenceIndicator.setProgress(0); + txConfidenceIndicator.setPrefSize(24, 24); + txConfidenceIndicator.setTooltip(tooltip); + + txConfidenceListener = new TxConfidenceListener(txId) { + @Override + public void onTransactionConfidenceChanged(TransactionConfidence confidence) { + updateConfidence(confidence, tooltip); + } + }; + bsqWalletService.addTxConfidenceListener(txConfidenceListener); + updateConfidence(bsqWalletService.getConfidenceForTxId(txId), tooltip); + } + + private void updateConfidence(TransactionConfidence confidence, Tooltip tooltip) { + if (confidence != null) { + GUIUtil.updateConfidence(confidence, tooltip, txConfidenceIndicator); + confirmations = confidence.getDepthInBlocks(); + } + } + + public void cleanup() { + bsqWalletService.removeTxConfidenceListener(txConfidenceListener); + } +} + diff --git a/src/main/java/bisq/desktop/main/dao/BaseProposalListItem.java b/src/main/java/bisq/desktop/main/dao/BaseProposalListItem.java index fc418a22a7b..5a4da38f7a4 100644 --- a/src/main/java/bisq/desktop/main/dao/BaseProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/BaseProposalListItem.java @@ -157,8 +157,7 @@ protected void init() { private void setupConfidence() { final String txId = getProposal().getTxId(); Optional optionalTx = daoFacade.getTx(txId); - if (optionalTx.isPresent()) { - Tx tx = optionalTx.get(); + optionalTx.ifPresent(tx -> { // We cache the walletTransaction once found if (walletTransaction == null) { final Optional transactionOptional = bsqWalletService.isWalletTransaction(txId); @@ -177,7 +176,7 @@ public void onTransactionConfidenceChanged(TransactionConfidence confidence) { bsqWalletService.addTxConfidenceListener(txConfidenceListener); } } else { - // tx from other users, we dont get confidence updates but as we have the bsq tx we can calculate it + // tx from other users, we don't get confidence updates but as we have the bsq tx we can calculate it // we get setupConfidence called at each new block from above listener so no need to register a new listener int depth = bsqWalletService.getChainHeightProperty().get() - tx.getBlockHeight() + 1; if (depth > 0) @@ -187,7 +186,7 @@ public void onTransactionConfidenceChanged(TransactionConfidence confidence) { final TransactionConfidence confidence = bsqWalletService.getConfidenceForTxId(txId); if (confidence != null) updateConfidence(confidence, confidence.getDepthInBlocks()); - } + }); } private void updateConfidence(TransactionConfidence confidence, int depthInBlocks) { diff --git a/src/main/java/bisq/desktop/main/dao/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/BaseProposalView.java index 33cd915cfa7..a6d4fc0eff9 100644 --- a/src/main/java/bisq/desktop/main/dao/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/BaseProposalView.java @@ -68,16 +68,16 @@ public abstract class BaseProposalView extends ActivatableView { protected final BSFormatter btcFormatter; protected final ObservableList proposalBaseProposalListItems = FXCollections.observableArrayList(); - protected final SortedList sortedList = new SortedList<>(proposalBaseProposalListItems); + private final SortedList sortedList = new SortedList<>(proposalBaseProposalListItems); protected TableView proposalTableView; - protected Subscription selectedProposalSubscription; + private Subscription selectedProposalSubscription; protected ProposalDisplay proposalDisplay; protected int gridRow = 0; protected GridPane detailsGridPane, gridPane; protected BaseProposalListItem selectedBaseProposalListItem; protected DaoPhase.Phase currentPhase; - protected Subscription phaseSubscription; + private Subscription phaseSubscription; private ScrollPane proposalDisplayView; private boolean proposalDisplayInitialized; @@ -137,7 +137,7 @@ protected void createProposalsTableView() { createProposalsTableView(Res.get("dao.proposal.active.header"), -10); } - protected void createProposalsTableView(String header, double top) { + private void createProposalsTableView(String header, double top) { TableGroupHeadline proposalsHeadline = new TableGroupHeadline(header); GridPane.setRowIndex(proposalsHeadline, ++gridRow); GridPane.setMargin(proposalsHeadline, new Insets(top, -10, -10, -10)); diff --git a/src/main/java/bisq/desktop/main/dao/DaoView.java b/src/main/java/bisq/desktop/main/dao/DaoView.java index 73f18eef6d1..ae9683c9562 100644 --- a/src/main/java/bisq/desktop/main/dao/DaoView.java +++ b/src/main/java/bisq/desktop/main/dao/DaoView.java @@ -50,7 +50,16 @@ public class DaoView extends ActivatableViewAndModel { @FXML - Tab bsqWalletTab, proposalsTab, votingTab, resultsTab, bondingTab; + private + Tab bsqWalletTab; + @FXML + private Tab proposalsTab; + @FXML + private Tab votingTab; + @FXML + private Tab resultsTab; + @FXML + private Tab bondingTab; private Navigation.Listener navigationListener; private ChangeListener tabChangeListener; diff --git a/src/main/java/bisq/desktop/main/dao/bonding/BondingView.fxml b/src/main/java/bisq/desktop/main/dao/bonding/BondingView.fxml index 84b322ce5af..a8ac7a57741 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/BondingView.fxml +++ b/src/main/java/bisq/desktop/main/dao/bonding/BondingView.fxml @@ -26,8 +26,7 @@ - optionalTxOutput = daoFacade.getLockupTxOutput(txId); return optionalTxOutput.map(txOutput -> !daoFacade.isUnspent(txOutput.getKey())) .orElse(true); @@ -141,8 +104,4 @@ public TxType getTxType() { .flatMap(tx -> daoFacade.getOptionalTxType(tx.getId())) .orElse(confirmations == 0 ? TxType.UNVERIFIED : TxType.UNDEFINED_TX_TYPE); } - - public void setAmount(Coin amount) { - this.amount = amount; - } } diff --git a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java index 9a68c7d104c..7c5cd460039 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java @@ -90,7 +90,6 @@ public class UnlockView extends ActivatableView implements BsqBa private final P2PService p2PService; private int gridRow = 0; - private boolean synced; private LockupTxListItem selectedItem; private final ObservableList observableList = FXCollections.observableArrayList(); @@ -140,7 +139,7 @@ public void initialize() { lockupTxs.setPredicate(LockupTxListItem::isLockupAndUnspent); walletBsqTransactionsListener = change -> updateList(); - walletChainHeightListener = (observable, oldValue, newValue) -> onUpdateAnyChainHeight(); + walletChainHeightListener = (observable, oldValue, newValue) -> updateList(); VBox vBox = new VBox(); vBox.setSpacing(10); @@ -171,7 +170,6 @@ protected void activate() { daoFacade.addBsqStateListener(this); updateList(); - onUpdateAnyChainHeight(); } @Override @@ -218,7 +216,7 @@ public void onEmptyBlockAdded(Block block) { @Override public void onParseTxsComplete(Block block) { - onUpdateAnyChainHeight(); + updateList(); } @Override @@ -249,6 +247,7 @@ public TableCell call(TableColumn 0) { - synced = bsqWalletChainHeight == bsqBlockChainHeight; - } - updateList(); - } - private void updateList() { observableList.forEach(LockupTxListItem::cleanup); diff --git a/src/main/java/bisq/desktop/main/dao/cycles/CyclesListItem.java b/src/main/java/bisq/desktop/main/dao/cycles/CyclesListItem.java index f7b1cf13734..e16bbad440a 100644 --- a/src/main/java/bisq/desktop/main/dao/cycles/CyclesListItem.java +++ b/src/main/java/bisq/desktop/main/dao/cycles/CyclesListItem.java @@ -30,7 +30,7 @@ import lombok.Getter; public class CyclesListItem { - private BsqFormatter bsqFormatter; + private final BsqFormatter bsqFormatter; @Getter private CycleResult cycleResult; diff --git a/src/main/java/bisq/desktop/main/dao/cycles/CyclesView.java b/src/main/java/bisq/desktop/main/dao/cycles/CyclesView.java index e27ce57e383..41eaad4e07b 100644 --- a/src/main/java/bisq/desktop/main/dao/cycles/CyclesView.java +++ b/src/main/java/bisq/desktop/main/dao/cycles/CyclesView.java @@ -84,7 +84,6 @@ public class CyclesView extends ActivatableViewAndModel i private final ObservableList itemList = FXCollections.observableArrayList(); private final SortedList sortedList = new SortedList<>(itemList); private ChangeListener selectedItemListener; - private CyclesListItem selectedItem; private GridPane resultGridPane; private CycleDisplay proposalsDisplay; @@ -163,9 +162,8 @@ public void onParseBlockChainComplete() { /////////////////////////////////////////////////////////////////////////////////////////// private void onCycleListItemSelected(CyclesListItem item) { - selectedItem = item; - if (selectedItem != null) - createAllFieldsOnResultDisplay(selectedItem); + if (item != null) + createAllFieldsOnResultDisplay(item); else hideResultDisplay(); diff --git a/src/main/java/bisq/desktop/main/dao/cycles/cycle/CycleDetailsWindow.java b/src/main/java/bisq/desktop/main/dao/cycles/cycle/CycleDetailsWindow.java index 54de42d5f7d..1d05be18e8b 100644 --- a/src/main/java/bisq/desktop/main/dao/cycles/cycle/CycleDetailsWindow.java +++ b/src/main/java/bisq/desktop/main/dao/cycles/cycle/CycleDetailsWindow.java @@ -25,20 +25,15 @@ import bisq.core.util.BsqFormatter; import javafx.scene.control.Button; -import javafx.scene.control.TextArea; import javafx.geometry.Insets; -import javafx.beans.value.ChangeListener; - import static bisq.desktop.util.FormBuilder.addTitledGroupBg; -public class CycleDetailsWindow extends Overlay { +class CycleDetailsWindow extends Overlay { private final BsqFormatter bsqFormatter; - private ChangeListener changeListener; - private TextArea textArea; - private EvaluatedProposal evaluatedProposal; + private final EvaluatedProposal evaluatedProposal; /////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/main/java/bisq/desktop/main/dao/cycles/cycle/CycleDisplay.java b/src/main/java/bisq/desktop/main/dao/cycles/cycle/CycleDisplay.java index c269176f057..ccf0831f0b5 100644 --- a/src/main/java/bisq/desktop/main/dao/cycles/cycle/CycleDisplay.java +++ b/src/main/java/bisq/desktop/main/dao/cycles/cycle/CycleDisplay.java @@ -72,7 +72,6 @@ public class CycleDisplay { private int gridRow; private int gridRowStartIndex; - private TableView tableView; private final ObservableList itemList = FXCollections.observableArrayList(); @@ -123,7 +122,7 @@ private void createTableView() { GridPane.setColumnSpan(headline, 2); gridPane.getChildren().add(headline); - tableView = new TableView<>(); + TableView tableView = new TableView<>(); tableView.setPlaceholder(new AutoTooltipLabel(Res.get("table.placeholder.noData"))); tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); tableView.setPrefHeight(200); @@ -388,6 +387,7 @@ public void removeAllFields() { gridRow = gridRowStartIndex; } + @SuppressWarnings("Duplicates") public ScrollPane getView() { ScrollPane scrollPane = new ScrollPane(); scrollPane.setFitToWidth(true); diff --git a/src/main/java/bisq/desktop/main/dao/cycles/cycle/CycleListItem.java b/src/main/java/bisq/desktop/main/dao/cycles/cycle/CycleListItem.java index 86da4fd9e2a..e71e4e7fd8d 100644 --- a/src/main/java/bisq/desktop/main/dao/cycles/cycle/CycleListItem.java +++ b/src/main/java/bisq/desktop/main/dao/cycles/cycle/CycleListItem.java @@ -31,7 +31,7 @@ public class CycleListItem { private final ProposalVoteResult proposalVoteResult; - private BsqFormatter bsqFormatter; + private final BsqFormatter bsqFormatter; @Getter private EvaluatedProposal evaluatedProposal; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java index 3d9a2a711a0..6a6d9d85b37 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java @@ -27,16 +27,12 @@ import javafx.geometry.Insets; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import static bisq.desktop.util.FormBuilder.addButtonAfterGroup; public class ProposalDetailsWindow extends Overlay { - protected static final Logger log = LoggerFactory.getLogger(ProposalDetailsWindow.class); private final BsqFormatter bsqFormatter; private final BsqWalletService bsqWalletService; - private Proposal proposal; + private final Proposal proposal; private ProposalDisplay proposalDisplay; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java index 1ebb333e212..c4a8ec484b9 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java @@ -61,14 +61,18 @@ import javax.annotation.Nullable; import static bisq.desktop.util.FormBuilder.*; +import static com.google.common.base.Preconditions.checkNotNull; @Slf4j public class ProposalDisplay { private final GridPane gridPane; private final int maxLengthDescriptionText; - private BsqFormatter bsqFormatter; - private BsqWalletService bsqWalletService; - public InputTextField uidTextField, nameTextField, titleTextField, linkInputTextField; + private final BsqFormatter bsqFormatter; + private final BsqWalletService bsqWalletService; + private InputTextField uidTextField; + public InputTextField nameTextField; + public InputTextField titleTextField; + public InputTextField linkInputTextField; @Nullable public InputTextField requestedBsqTextField, bsqAddressTextField, paramValueTextField; @Nullable @@ -78,8 +82,8 @@ public class ProposalDisplay { private HyperlinkWithIcon linkHyperlinkWithIcon; @Nullable private TxIdTextField txIdTextField; - private FeeService feeService; - private ChangeListener descriptionTextAreaListener; + private final FeeService feeService; + private final ChangeListener descriptionTextAreaListener; private int gridRowStartIndex; public ProposalDisplay(GridPane gridPane, BsqFormatter bsqFormatter, BsqWalletService bsqWalletService, @Nullable FeeService feeService) { @@ -112,6 +116,7 @@ public void createAllFields(String title, int gridRowStartIndex, double top, Pro } else if (showDetails) { rowSpan = hasAddedFields ? 8 : 6; } else { + //noinspection IfCanBeSwitch if (proposalType == ProposalType.COMPENSATION_REQUEST) rowSpan = 5; else if (proposalType == ProposalType.CHANGE_PARAM) @@ -148,18 +153,21 @@ else if (proposalType == ProposalType.CHANGE_PARAM) switch (proposalType) { case COMPENSATION_REQUEST: + requestedBsqTextField = addLabelInputTextField(gridPane, ++gridRow, Res.get("dao.proposal.display.requestedBsq")).second; if (feeService != null) { BsqValidator bsqValidator = new BsqValidator(bsqFormatter); //TODO should we use the BSQ or a BTC validator? Technically it is BTC at that stage... //bsqValidator.setMinValue(feeService.getCreateCompensationRequestFee()); bsqValidator.setMinValue(CompensationConsensus.getMinCompensationRequestAmount()); + checkNotNull(requestedBsqTextField, "requestedBsqTextField must no tbe null"); requestedBsqTextField.setValidator(bsqValidator); } // TODO validator, addressTF if (showDetails) { bsqAddressTextField = addLabelInputTextField(gridPane, ++gridRow, Res.get("dao.proposal.display.bsqAddress")).second; + checkNotNull(bsqAddressTextField, "bsqAddressTextField must no tbe null"); bsqAddressTextField.setText("B" + bsqWalletService.getUnusedAddress().toBase58()); bsqAddressTextField.setValidator(new BsqAddressValidator(bsqFormatter)); } @@ -167,7 +175,9 @@ else if (proposalType == ProposalType.CHANGE_PARAM) case GENERIC: break; case CHANGE_PARAM: + checkNotNull(gridPane, "gridPane must no tbe null"); paramComboBox = addLabelComboBox(gridPane, ++gridRow, Res.get("dao.proposal.display.paramComboBox.label")).second; + checkNotNull(paramComboBox, "paramComboBox must no tbe null"); paramComboBox.setItems(FXCollections.observableArrayList(Param.values())); paramComboBox.setConverter(new StringConverter() { @Override @@ -205,12 +215,15 @@ public void applyProposalPayload(Proposal proposal) { linkHyperlinkWithIcon.setOnAction(e -> GUIUtil.openWebPage(proposal.getLink())); if (proposal instanceof CompensationProposal) { CompensationProposal compensationProposal = (CompensationProposal) proposal; + checkNotNull(requestedBsqTextField, "requestedBsqTextField must no tbe null"); requestedBsqTextField.setText(bsqFormatter.formatCoinWithCode(compensationProposal.getRequestedBsq())); if (bsqAddressTextField != null) bsqAddressTextField.setText(compensationProposal.getBsqAddress()); } else if (proposal instanceof ChangeParamProposal) { ChangeParamProposal changeParamProposal = (ChangeParamProposal) proposal; + checkNotNull(paramComboBox, "paramComboBox must no tbe null"); paramComboBox.getSelectionModel().select(changeParamProposal.getParam()); + checkNotNull(paramValueTextField, "paramValueTextField must no tbe null"); paramValueTextField.setText(String.valueOf(changeParamProposal.getParamValue())); } if (txIdTextField != null) @@ -283,7 +296,7 @@ public int incrementAndGetGridRow() { return ++gridRow; } - + @SuppressWarnings("Duplicates") public ScrollPane getView() { ScrollPane scrollPane = new ScrollPane(); scrollPane.setFitToWidth(true); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalItemsView.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalItemsView.java index 7bf96b91d25..13be20e7552 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalItemsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalItemsView.java @@ -33,7 +33,7 @@ @FxmlView public abstract class ProposalItemsView extends BaseProposalView { - protected ListChangeListener listChangeListener; + private ListChangeListener listChangeListener; /////////////////////////////////////////////////////////////////////////////////////////// // Constructor, lifecycle diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalView.fxml b/src/main/java/bisq/desktop/main/dao/proposal/ProposalView.fxml index a4518328f8b..519b1e053b5 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalView.fxml +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalView.fxml @@ -26,8 +26,7 @@ - viewClass) { else if (view instanceof ActiveProposalsView) active.setSelected(true); else if (view instanceof ClosedProposalsView) closed.setSelected(true); } - - public Class getSelectedViewClass() { - return selectedViewClass; - } } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalListItem.java index cd7362e4e60..ea20b80b81b 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalListItem.java @@ -72,6 +72,7 @@ protected void init() { public void onPhaseChanged(DaoPhase.Phase phase) { super.onPhaseChanged(phase); + //noinspection IfCanBeSwitch if (phase == DaoPhase.Phase.PROPOSAL) { imageView.setId("image-remove"); button.setGraphic(imageView); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index b5862f302ef..5734eb4af2c 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -116,10 +116,11 @@ protected void fillListItems() { @Override - public void onPhaseChanged(DaoPhase.Phase phase) { + protected void onPhaseChanged(DaoPhase.Phase phase) { super.onPhaseChanged(phase); if (button != null) { + //noinspection IfCanBeSwitch,IfCanBeSwitch,IfCanBeSwitch if (phase == DaoPhase.Phase.PROPOSAL) { if (selectedBaseProposalListItem != null && selectedBaseProposalListItem.getProposal() != null) { button.setText(Res.get("dao.proposal.active.remove")); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalListItem.java index 3720e42b933..88971a05b77 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalListItem.java @@ -31,7 +31,7 @@ @ToString @Slf4j @EqualsAndHashCode(callSuper = true) -public class ClosedProposalListItem extends ProposalListItem { +class ClosedProposalListItem extends ProposalListItem { /////////////////////////////////////////////////////////////////////////////////////////// // Constructor, lifecycle diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index 02216648d1b..72deb82362f 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -252,6 +252,8 @@ private ProposalWithTransaction getProposalWithTransaction(ProposalType type) proposalDisplay.descriptionTextArea.getText(), proposalDisplay.linkInputTextField.getText());*/ case CHANGE_PARAM: + checkNotNull(proposalDisplay.paramComboBox, "proposalDisplay.paramComboBox must no tbe null"); + checkNotNull(proposalDisplay.paramValueTextField, "proposalDisplay.paramValueTextField must no tbe null"); Param selectedParam = proposalDisplay.paramComboBox.getSelectionModel().getSelectedItem(); if (selectedParam == null) throw new ValidationException("selectedParam is null"); diff --git a/src/main/java/bisq/desktop/main/dao/voting/BaseBallotListItem.java b/src/main/java/bisq/desktop/main/dao/voting/BaseBallotListItem.java new file mode 100644 index 00000000000..37ec10675d4 --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/voting/BaseBallotListItem.java @@ -0,0 +1,96 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.desktop.main.dao.voting; + +import bisq.desktop.main.dao.BaseProposalListItem; + +import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.dao.DaoFacade; +import bisq.core.dao.state.period.DaoPhase; +import bisq.core.dao.voting.ballot.Ballot; +import bisq.core.dao.voting.ballot.vote.BooleanVote; +import bisq.core.dao.voting.ballot.vote.Vote; +import bisq.core.dao.voting.proposal.Proposal; +import bisq.core.util.BsqFormatter; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.ToString; +import lombok.extern.slf4j.Slf4j; + +@ToString +@Slf4j +@EqualsAndHashCode(callSuper = true) +public class BaseBallotListItem extends BaseProposalListItem { + @Getter + private final Ballot ballot; + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Constructor, lifecycle + /////////////////////////////////////////////////////////////////////////////////////////// + + protected BaseBallotListItem(Ballot ballot, + DaoFacade daoFacade, + BsqWalletService bsqWalletService, + BsqFormatter bsqFormatter) { + super(daoFacade, + bsqWalletService, + bsqFormatter); + + this.ballot = ballot; + + init(); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Protected + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + protected void init() { + super.init(); + } + + @Override + public void onPhaseChanged(DaoPhase.Phase phase) { + super.onPhaseChanged(phase); + + final Vote vote = ballot.getVote(); + if (vote != null) { + imageView.setVisible(true); + if (vote instanceof BooleanVote) { + if (((BooleanVote) vote).isAccepted()) { + imageView.setId("accepted"); + } else { + imageView.setId("rejected"); + } + }/* else { + // not impl. + }*/ + } else { + imageView.setVisible(false); + } + } + + @Override + public Proposal getProposal() { + return ballot.getProposal(); + } +} diff --git a/src/main/java/bisq/desktop/main/dao/voting/VotingView.fxml b/src/main/java/bisq/desktop/main/dao/voting/VotingView.fxml index 65f16c9d2dd..a5bf85f199a 100644 --- a/src/main/java/bisq/desktop/main/dao/voting/VotingView.fxml +++ b/src/main/java/bisq/desktop/main/dao/voting/VotingView.fxml @@ -26,8 +26,7 @@ - viewClass) { else if (view instanceof ActiveBallotsView) activeBallots.setSelected(true); else if (view instanceof ClosedBallotsView) closedBallots.setSelected(true); } - - public Class getSelectedViewClass() { - return selectedViewClass; - } } diff --git a/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotListItem.java b/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotListItem.java index 4c080e354f2..f421a621274 100644 --- a/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotListItem.java +++ b/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotListItem.java @@ -17,80 +17,33 @@ package bisq.desktop.main.dao.voting.active; -import bisq.desktop.main.dao.BaseProposalListItem; +import bisq.desktop.main.dao.voting.BaseBallotListItem; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; -import bisq.core.dao.state.period.DaoPhase; import bisq.core.dao.voting.ballot.Ballot; -import bisq.core.dao.voting.ballot.vote.BooleanVote; -import bisq.core.dao.voting.ballot.vote.Vote; -import bisq.core.dao.voting.proposal.Proposal; import bisq.core.util.BsqFormatter; import lombok.EqualsAndHashCode; -import lombok.Getter; import lombok.ToString; import lombok.extern.slf4j.Slf4j; @ToString @Slf4j @EqualsAndHashCode(callSuper = true) -public class ActiveBallotListItem extends BaseProposalListItem { - @Getter - private final Ballot ballot; - +class ActiveBallotListItem extends BaseBallotListItem { /////////////////////////////////////////////////////////////////////////////////////////// // Constructor, lifecycle /////////////////////////////////////////////////////////////////////////////////////////// - public ActiveBallotListItem(Ballot ballot, - DaoFacade daoFacade, - BsqWalletService bsqWalletService, - BsqFormatter bsqFormatter) { - super(daoFacade, + ActiveBallotListItem(Ballot ballot, + DaoFacade daoFacade, + BsqWalletService bsqWalletService, + BsqFormatter bsqFormatter) { + super(ballot, + daoFacade, bsqWalletService, bsqFormatter); - - this.ballot = ballot; - - init(); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Protected - /////////////////////////////////////////////////////////////////////////////////////////// - - @Override - protected void init() { - super.init(); - } - - @Override - public void onPhaseChanged(DaoPhase.Phase phase) { - super.onPhaseChanged(phase); - - final Vote vote = ballot.getVote(); - if (vote != null) { - imageView.setVisible(true); - if (vote instanceof BooleanVote) { - if (((BooleanVote) vote).isAccepted()) { - imageView.setId("accepted"); - } else { - imageView.setId("rejected"); - } - } else { - //TODO - } - } else { - imageView.setVisible(false); - } - } - - @Override - public Proposal getProposal() { - return ballot.getProposal(); } } diff --git a/src/main/java/bisq/desktop/main/dao/voting/closed/ClosedBallotListItem.java b/src/main/java/bisq/desktop/main/dao/voting/closed/ClosedBallotListItem.java index 1aac2fa0067..a1c4c38f425 100644 --- a/src/main/java/bisq/desktop/main/dao/voting/closed/ClosedBallotListItem.java +++ b/src/main/java/bisq/desktop/main/dao/voting/closed/ClosedBallotListItem.java @@ -17,28 +17,21 @@ package bisq.desktop.main.dao.voting.closed; -import bisq.desktop.main.dao.BaseProposalListItem; +import bisq.desktop.main.dao.voting.BaseBallotListItem; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; -import bisq.core.dao.state.period.DaoPhase; import bisq.core.dao.voting.ballot.Ballot; -import bisq.core.dao.voting.ballot.vote.BooleanVote; -import bisq.core.dao.voting.ballot.vote.Vote; -import bisq.core.dao.voting.proposal.Proposal; import bisq.core.util.BsqFormatter; import lombok.EqualsAndHashCode; -import lombok.Getter; import lombok.ToString; import lombok.extern.slf4j.Slf4j; @ToString @Slf4j @EqualsAndHashCode(callSuper = true) -public class ClosedBallotListItem extends BaseProposalListItem { - @Getter - private final Ballot ballot; +class ClosedBallotListItem extends BaseBallotListItem { /////////////////////////////////////////////////////////////////////////////////////////// @@ -49,48 +42,9 @@ public ClosedBallotListItem(Ballot ballot, DaoFacade daoFacade, BsqWalletService bsqWalletService, BsqFormatter bsqFormatter) { - super(daoFacade, + super(ballot, + daoFacade, bsqWalletService, bsqFormatter); - - this.ballot = ballot; - - init(); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Protected - /////////////////////////////////////////////////////////////////////////////////////////// - - @Override - protected void init() { - super.init(); - } - - @Override - public void onPhaseChanged(DaoPhase.Phase phase) { - super.onPhaseChanged(phase); - - final Vote vote = ballot.getVote(); - if (vote != null) { - imageView.setVisible(true); - if (vote instanceof BooleanVote) { - if (((BooleanVote) vote).isAccepted()) { - imageView.setId("accepted"); - } else { - imageView.setId("rejected"); - } - } else { - //TODO - } - } else { - imageView.setVisible(false); - } - } - - @Override - public Proposal getProposal() { - return ballot.getProposal(); } } diff --git a/src/main/java/bisq/desktop/main/dao/voting/closed/ClosedBallotsView.java b/src/main/java/bisq/desktop/main/dao/voting/closed/ClosedBallotsView.java index 016208d46d8..adacb084380 100644 --- a/src/main/java/bisq/desktop/main/dao/voting/closed/ClosedBallotsView.java +++ b/src/main/java/bisq/desktop/main/dao/voting/closed/ClosedBallotsView.java @@ -105,11 +105,6 @@ protected void fillListItems() { /////////////////////////////////////////////////////////////////////////////////////////// - private ClosedBallotListItem getBallotListItem() { - return (ClosedBallotListItem) selectedBaseProposalListItem; - } - - /////////////////////////////////////////////////////////////////////////////////////////// // TableColumns /////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/main/java/bisq/desktop/main/dao/wallet/BsqBalanceUtil.java b/src/main/java/bisq/desktop/main/dao/wallet/BsqBalanceUtil.java index 3014f451d65..36c7de4a9b9 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/BsqBalanceUtil.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/BsqBalanceUtil.java @@ -75,7 +75,7 @@ public int addGroup(GridPane gridPane, int gridRow) { "shared.lockedInBonds")).second; lockedInBondsBalanceTextField.setMouseTransparent(false); - // TODO add unlockinBondsBalanceTextField + // TODO add unlockingBondsBalanceTextField totalBalanceTextField = addLabelTextField(gridPane, ++gridRow, Res.getWithCol("shared.totalBsqBalance")).second; totalBalanceTextField.setMouseTransparent(false); diff --git a/src/main/java/bisq/desktop/main/dao/wallet/BsqWalletView.fxml b/src/main/java/bisq/desktop/main/dao/wallet/BsqWalletView.fxml index 58b049dba13..a678031be87 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/BsqWalletView.fxml +++ b/src/main/java/bisq/desktop/main/dao/wallet/BsqWalletView.fxml @@ -27,8 +27,7 @@ - diff --git a/src/main/java/bisq/desktop/main/dao/wallet/BsqWalletView.java b/src/main/java/bisq/desktop/main/dao/wallet/BsqWalletView.java index 97b7b9d0dfc..33e47aeca2a 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/BsqWalletView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/BsqWalletView.java @@ -126,6 +126,7 @@ protected void activate() { } } + @SuppressWarnings("Duplicates") @Override protected void deactivate() { navigation.removeListener(listener); diff --git a/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java b/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java index 6387ff83922..41df1372bf6 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java @@ -254,7 +254,7 @@ private void addSendBsqGroup() { amountInputTextField.setText(""); }); } catch (Throwable t) { - hanldeError(t); + handleError(t); } } else { GUIUtil.showNotReadyForTxBroadcastPopups(p2PService, walletsSetup); @@ -317,7 +317,7 @@ private void addSendBtcGroup() { btcAmountInputTextField.setText(""); }); } catch (Throwable t) { - hanldeError(t); + handleError(t); } } else { GUIUtil.showNotReadyForTxBroadcastPopups(p2PService, walletsSetup); @@ -325,7 +325,7 @@ private void addSendBtcGroup() { }); } - private void hanldeError(Throwable t) { + private void handleError(Throwable t) { if (t instanceof InsufficientMoneyException) { final Coin missingCoin = ((InsufficientMoneyException) t).missing; final String missing = missingCoin != null ? missingCoin.toFriendlyString() : "null"; diff --git a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java index 1c07ff2efe1..9a63052eef6 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java @@ -18,7 +18,7 @@ package bisq.desktop.main.dao.wallet.tx; import bisq.desktop.components.indicator.TxConfidenceIndicator; -import bisq.desktop.util.GUIUtil; +import bisq.desktop.main.dao.BaseBsqTxListItem; import bisq.core.btc.listeners.TxConfidenceListener; import bisq.core.btc.wallet.BsqWalletService; @@ -31,27 +31,22 @@ import org.bitcoinj.core.Coin; import org.bitcoinj.core.Transaction; -import org.bitcoinj.core.TransactionConfidence; import org.bitcoinj.core.TransactionOutput; -import javafx.scene.control.Tooltip; - import java.util.Date; import lombok.Data; +import lombok.EqualsAndHashCode; import static com.google.common.base.Preconditions.checkNotNull; - +@EqualsAndHashCode(callSuper = true) @Data -class BsqTxListItem { - private final Transaction transaction; - private final BsqWalletService bsqWalletService; +class BsqTxListItem extends BaseBsqTxListItem { private final BtcWalletService btcWalletService; private final DaoFacade daoFacade; private final BsqFormatter bsqFormatter; private final Date date; - private final String txId; private final boolean isBurnedBsqTx; private int confirmations = 0; @@ -70,18 +65,14 @@ class BsqTxListItem { DaoFacade daoFacade, Date date, BsqFormatter bsqFormatter) { - this.transaction = transaction; - this.bsqWalletService = bsqWalletService; + super(transaction, bsqWalletService); + this.btcWalletService = btcWalletService; this.daoFacade = daoFacade; this.isBurnedBsqTx = daoFacade.hasTxBurntFee(transaction.getHashAsString()); this.date = date; this.bsqFormatter = bsqFormatter; - txId = transaction.getHashAsString(); - - setupConfidence(bsqWalletService); - checkNotNull(transaction, "transaction must not be null as we only have list items from transactions " + "which are available in the wallet"); @@ -129,43 +120,10 @@ class BsqTxListItem { address = ""; } - private void setupConfidence(BsqWalletService bsqWalletService) { - txConfidenceIndicator = new TxConfidenceIndicator(); - txConfidenceIndicator.setId("funds-confidence"); - Tooltip tooltip = new Tooltip(); - txConfidenceIndicator.setProgress(0); - txConfidenceIndicator.setPrefSize(24, 24); - txConfidenceIndicator.setTooltip(tooltip); - - txConfidenceListener = new TxConfidenceListener(txId) { - @Override - public void onTransactionConfidenceChanged(TransactionConfidence confidence) { - updateConfidence(confidence, tooltip); - } - }; - bsqWalletService.addTxConfidenceListener(txConfidenceListener); - updateConfidence(bsqWalletService.getConfidenceForTxId(txId), tooltip); - } - - private void updateConfidence(TransactionConfidence confidence, Tooltip tooltip) { - if (confidence != null) { - GUIUtil.updateConfidence(confidence, tooltip, txConfidenceIndicator); - confirmations = confidence.getDepthInBlocks(); - } - } - - public void cleanup() { - bsqWalletService.removeTxConfidenceListener(txConfidenceListener); - } - public TxType getTxType() { return daoFacade.getTx(txId) .flatMap(tx -> daoFacade.getOptionalTxType(tx.getId())) .orElse(confirmations == 0 ? TxType.UNVERIFIED : TxType.UNDEFINED_TX_TYPE); } - - public void setAmount(Coin amount) { - this.amount = amount; - } } diff --git a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java index 83e39cf4952..f1d9952934e 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java @@ -331,6 +331,7 @@ public TableCell call(TableColumn call(TableColumn Date: Wed, 18 Jul 2018 21:14:31 +0200 Subject: [PATCH 147/197] Fix confirmations list view --- ...istItem.java => TxConfidenceListItem.java} | 7 +- .../dao/bonding/unlock/LockupTxListItem.java | 5 +- .../main/dao/bonding/unlock/UnlockView.java | 131 +++++++++--------- .../main/dao/wallet/tx/BsqTxListItem.java | 7 +- 4 files changed, 77 insertions(+), 73 deletions(-) rename src/main/java/bisq/desktop/main/dao/{BaseBsqTxListItem.java => TxConfidenceListItem.java} (94%) diff --git a/src/main/java/bisq/desktop/main/dao/BaseBsqTxListItem.java b/src/main/java/bisq/desktop/main/dao/TxConfidenceListItem.java similarity index 94% rename from src/main/java/bisq/desktop/main/dao/BaseBsqTxListItem.java rename to src/main/java/bisq/desktop/main/dao/TxConfidenceListItem.java index 802ba54c22a..ab635d2b281 100644 --- a/src/main/java/bisq/desktop/main/dao/BaseBsqTxListItem.java +++ b/src/main/java/bisq/desktop/main/dao/TxConfidenceListItem.java @@ -32,19 +32,18 @@ @Data -public class BaseBsqTxListItem { +public class TxConfidenceListItem { protected final BsqWalletService bsqWalletService; protected final String txId; protected int confirmations = 0; protected TxConfidenceIndicator txConfidenceIndicator; protected TxConfidenceListener txConfidenceListener; - protected BaseBsqTxListItem(Transaction transaction, - BsqWalletService bsqWalletService) { + protected TxConfidenceListItem(Transaction transaction, + BsqWalletService bsqWalletService) { this.bsqWalletService = bsqWalletService; txId = transaction.getHashAsString(); - setupConfidence(bsqWalletService); } diff --git a/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockupTxListItem.java b/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockupTxListItem.java index 918da837a09..f5ded35d30a 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockupTxListItem.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockupTxListItem.java @@ -19,7 +19,7 @@ import bisq.desktop.components.AutoTooltipButton; import bisq.desktop.components.indicator.TxConfidenceIndicator; -import bisq.desktop.main.dao.BaseBsqTxListItem; +import bisq.desktop.main.dao.TxConfidenceListItem; import bisq.core.btc.listeners.TxConfidenceListener; import bisq.core.btc.wallet.BsqWalletService; @@ -43,14 +43,13 @@ @EqualsAndHashCode(callSuper = true) @Data -class LockupTxListItem extends BaseBsqTxListItem { +class LockupTxListItem extends TxConfidenceListItem { private final BtcWalletService btcWalletService; private final DaoFacade daoFacade; private final BsqFormatter bsqFormatter; private final Date date; - private int confirmations = 0; private Coin amount = Coin.ZERO; private int lockTime; private AutoTooltipButton button; diff --git a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java index 7c5cd460039..1d0d01587fe 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java @@ -228,6 +228,74 @@ public void onParseBlockChainComplete() { // Private /////////////////////////////////////////////////////////////////////////////////////////// + private void onButtonClick() { + if (GUIUtil.isReadyForTxBroadcast(p2PService, walletsSetup)) { + Optional lockupTxOutput = daoFacade.getLockupTxOutput(selectedItem.getTxId()); + if (!lockupTxOutput.isPresent()) { + log.warn("Lockup output not found, txId = ", selectedItem.getTxId()); + return; + } + + Coin unlockAmount = Coin.valueOf(lockupTxOutput.get().getValue()); + Optional opLockTime = daoFacade.getLockTime(selectedItem.getTxId()); + int lockTime = opLockTime.orElse(-1); + + try { + new Popup<>().headLine(Res.get("dao.bonding.unlock.sendTx.headline")) + .confirmation(Res.get("dao.bonding.unlock.sendTx.details", + bsqFormatter.formatCoinWithCode(unlockAmount), + lockTime + )) + .actionButtonText(Res.get("shared.yes")) + .onAction(() -> { + daoFacade.publishUnlockTx(selectedItem.getTxId(), + () -> { + new Popup<>().confirmation(Res.get("dao.tx.published.success")).show(); + }, + errorMessage -> new Popup<>().warning(errorMessage.toString()).show() + ); + }) + .closeButtonText(Res.get("shared.cancel")) + .show(); + } catch (Throwable t) { + log.error(t.toString()); + t.printStackTrace(); + new Popup<>().warning(t.getMessage()).show(); + } + } else { + GUIUtil.showNotReadyForTxBroadcastPopups(p2PService, walletsSetup); + } + log.info("unlock tx: {}", selectedItem.getTxId()); + } + + private void openTxInBlockExplorer(LockupTxListItem item) { + if (item.getTxId() != null) + GUIUtil.openWebPage(preferences.getBsqBlockChainExplorer().txUrl + item.getTxId()); + } + + private void updateList() { + observableList.forEach(LockupTxListItem::cleanup); + + // copy list to avoid ConcurrentModificationException + final List walletTransactions = new ArrayList<>(bsqWalletService.getWalletTransactions()); + List items = walletTransactions.stream() + .map(transaction -> { + return new LockupTxListItem(transaction, + bsqWalletService, + btcWalletService, + daoFacade, + transaction.getUpdateTime(), + bsqFormatter); + }) + .collect(Collectors.toList()); + observableList.setAll(items); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Table columns + /////////////////////////////////////////////////////////////////////////////////////////// + private void addTxIdColumn() { TableColumn column = new AutoTooltipTableColumn<>(Res.get("shared.txId")); @@ -373,67 +441,4 @@ public void updateItem(final LockupTxListItem item, boolean empty) { unlockColumn.setComparator(Comparator.comparing(LockupTxListItem::getConfirmations)); tableView.getColumns().add(unlockColumn); } - - private void onButtonClick() { - if (GUIUtil.isReadyForTxBroadcast(p2PService, walletsSetup)) { - Optional lockupTxOutput = daoFacade.getLockupTxOutput(selectedItem.getTxId()); - if (!lockupTxOutput.isPresent()) { - log.warn("Lockup output not found, txId = ", selectedItem.getTxId()); - return; - } - - Coin unlockAmount = Coin.valueOf(lockupTxOutput.get().getValue()); - Optional opLockTime = daoFacade.getLockTime(selectedItem.getTxId()); - int lockTime = opLockTime.orElse(-1); - - try { - new Popup<>().headLine(Res.get("dao.bonding.unlock.sendTx.headline")) - .confirmation(Res.get("dao.bonding.unlock.sendTx.details", - bsqFormatter.formatCoinWithCode(unlockAmount), - lockTime - )) - .actionButtonText(Res.get("shared.yes")) - .onAction(() -> { - daoFacade.publishUnlockTx(selectedItem.getTxId(), - () -> { - new Popup<>().confirmation(Res.get("dao.tx.published.success")).show(); - }, - errorMessage -> new Popup<>().warning(errorMessage.toString()).show() - ); - }) - .closeButtonText(Res.get("shared.cancel")) - .show(); - } catch (Throwable t) { - log.error(t.toString()); - t.printStackTrace(); - new Popup<>().warning(t.getMessage()).show(); - } - } else { - GUIUtil.showNotReadyForTxBroadcastPopups(p2PService, walletsSetup); - } - log.info("unlock tx: {}", selectedItem.getTxId()); - } - - private void openTxInBlockExplorer(LockupTxListItem item) { - if (item.getTxId() != null) - GUIUtil.openWebPage(preferences.getBsqBlockChainExplorer().txUrl + item.getTxId()); - } - - private void updateList() { - observableList.forEach(LockupTxListItem::cleanup); - - // copy list to avoid ConcurrentModificationException - final List walletTransactions = new ArrayList<>(bsqWalletService.getWalletTransactions()); - List items = walletTransactions.stream() - .map(transaction -> { - return new LockupTxListItem(transaction, - bsqWalletService, - btcWalletService, - daoFacade, - transaction.getUpdateTime(), - bsqFormatter); - }) - .collect(Collectors.toList()); - observableList.setAll(items); - } } diff --git a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java index 9a63052eef6..7eba0c478e1 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java @@ -18,7 +18,7 @@ package bisq.desktop.main.dao.wallet.tx; import bisq.desktop.components.indicator.TxConfidenceIndicator; -import bisq.desktop.main.dao.BaseBsqTxListItem; +import bisq.desktop.main.dao.TxConfidenceListItem; import bisq.core.btc.listeners.TxConfidenceListener; import bisq.core.btc.wallet.BsqWalletService; @@ -37,19 +37,20 @@ import lombok.Data; import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; import static com.google.common.base.Preconditions.checkNotNull; +@Slf4j @EqualsAndHashCode(callSuper = true) @Data -class BsqTxListItem extends BaseBsqTxListItem { +class BsqTxListItem extends TxConfidenceListItem { private final BtcWalletService btcWalletService; private final DaoFacade daoFacade; private final BsqFormatter bsqFormatter; private final Date date; private final boolean isBurnedBsqTx; - private int confirmations = 0; private final String address; private final String direction; private Coin amount; From cf9b51a0d5e97d55c5489ca59f4aaed63c628767 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Wed, 18 Jul 2018 21:41:56 +0200 Subject: [PATCH 148/197] Add proposalFee text field --- .../desktop/main/dao/BaseProposalView.java | 4 +-- .../desktop/main/dao/cycles/CyclesView.java | 2 +- .../main/dao/cycles/cycle/CycleDisplay.java | 8 +++-- .../dao/proposal/ProposalDetailsWindow.java | 9 +++-- .../main/dao/proposal/ProposalDisplay.java | 36 ++++++++++--------- .../active/ActiveProposalListItem.java | 2 +- .../dao/proposal/make/MakeProposalView.java | 4 +-- 7 files changed, 37 insertions(+), 28 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/BaseProposalView.java index a6d4fc0eff9..17bffb94749 100644 --- a/src/main/java/bisq/desktop/main/dao/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/BaseProposalView.java @@ -160,7 +160,7 @@ private void createProposalsTableView(String header, double top) { } protected void createEmptyProposalDisplay() { - proposalDisplay = new ProposalDisplay(detailsGridPane, bsqFormatter, bsqWalletService, null); + proposalDisplay = new ProposalDisplay(detailsGridPane, bsqFormatter, bsqWalletService, daoFacade); proposalDisplayView = proposalDisplay.getView(); GridPane.setMargin(proposalDisplayView, new Insets(10, -10, 0, -10)); GridPane.setRowIndex(proposalDisplayView, ++gridRow); @@ -328,7 +328,7 @@ public void updateItem(final BaseProposalListItem item, boolean empty) { final Proposal proposal = item.getProposal(); field = new HyperlinkWithIcon(proposal.getShortId()); field.setOnAction(event -> { - new ProposalDetailsWindow(bsqFormatter, bsqWalletService, proposal).show(); + new ProposalDetailsWindow(bsqFormatter, bsqWalletService, proposal, daoFacade).show(); }); field.setTooltip(new Tooltip(Res.get("tooltip.openPopupForDetails"))); setGraphic(field); diff --git a/src/main/java/bisq/desktop/main/dao/cycles/CyclesView.java b/src/main/java/bisq/desktop/main/dao/cycles/CyclesView.java index 41eaad4e07b..84d1827bbde 100644 --- a/src/main/java/bisq/desktop/main/dao/cycles/CyclesView.java +++ b/src/main/java/bisq/desktop/main/dao/cycles/CyclesView.java @@ -198,7 +198,7 @@ private void createResultsTable() { } private void createResultDisplay() { - proposalsDisplay = new CycleDisplay(resultGridPane, bsqWalletService, bsqFormatter); + proposalsDisplay = new CycleDisplay(resultGridPane, bsqWalletService, daoFacade, bsqFormatter); resultDisplayView = proposalsDisplay.getView(); GridPane.setMargin(resultDisplayView, new Insets(10, -10, 0, -10)); GridPane.setRowIndex(resultDisplayView, ++gridRow); diff --git a/src/main/java/bisq/desktop/main/dao/cycles/cycle/CycleDisplay.java b/src/main/java/bisq/desktop/main/dao/cycles/cycle/CycleDisplay.java index ccf0831f0b5..23b9941bcf8 100644 --- a/src/main/java/bisq/desktop/main/dao/cycles/cycle/CycleDisplay.java +++ b/src/main/java/bisq/desktop/main/dao/cycles/cycle/CycleDisplay.java @@ -26,6 +26,7 @@ import bisq.desktop.util.GUIUtil; import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.dao.DaoFacade; import bisq.core.dao.voting.proposal.ProposalType; import bisq.core.locale.Res; import bisq.core.util.BsqFormatter; @@ -68,6 +69,7 @@ public class CycleDisplay { private final GridPane gridPane; private final BsqWalletService bsqWalletService; + private final DaoFacade daoFacade; private final BsqFormatter bsqFormatter; private int gridRow; @@ -78,9 +80,10 @@ public class CycleDisplay { private final SortedList sortedList = new SortedList<>(itemList); - public CycleDisplay(GridPane gridPane, BsqWalletService bsqWalletService, BsqFormatter bsqFormatter) { + public CycleDisplay(GridPane gridPane, BsqWalletService bsqWalletService, DaoFacade daoFacade, BsqFormatter bsqFormatter) { this.gridPane = gridPane; this.bsqWalletService = bsqWalletService; + this.daoFacade = daoFacade; this.bsqFormatter = bsqFormatter; } @@ -187,7 +190,8 @@ public void updateItem(final CycleListItem item, boolean empty) { field.setStyle(item.getColorStyle()); field.setOnAction(event -> new ProposalDetailsWindow(bsqFormatter, bsqWalletService, - item.getEvaluatedProposal().getProposal()) + item.getEvaluatedProposal().getProposal(), + daoFacade) .show()); field.setTooltip(new Tooltip(Res.get("tooltip.openPopupForDetails"))); setGraphic(field); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java index 6a6d9d85b37..f9afafaaa1f 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java @@ -21,6 +21,7 @@ import bisq.desktop.util.Layout; import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.dao.DaoFacade; import bisq.core.dao.voting.proposal.Proposal; import bisq.core.locale.Res; import bisq.core.util.BsqFormatter; @@ -33,6 +34,8 @@ public class ProposalDetailsWindow extends Overlay { private final BsqFormatter bsqFormatter; private final BsqWalletService bsqWalletService; private final Proposal proposal; + private final DaoFacade daoFacade; + private ProposalDisplay proposalDisplay; @@ -40,10 +43,12 @@ public class ProposalDetailsWindow extends Overlay { // Public API /////////////////////////////////////////////////////////////////////////////////////////// - public ProposalDetailsWindow(BsqFormatter bsqFormatter, BsqWalletService bsqWalletService, Proposal proposal) { + public ProposalDetailsWindow(BsqFormatter bsqFormatter, BsqWalletService bsqWalletService, Proposal proposal, + DaoFacade daoFacade) { this.bsqFormatter = bsqFormatter; this.bsqWalletService = bsqWalletService; this.proposal = proposal; + this.daoFacade = daoFacade; type = Type.Confirmation; width = 950; @@ -52,7 +57,7 @@ public ProposalDetailsWindow(BsqFormatter bsqFormatter, BsqWalletService bsqWall public void show() { createGridPane(); - proposalDisplay = new ProposalDisplay(gridPane, bsqFormatter, bsqWalletService, null); + proposalDisplay = new ProposalDisplay(gridPane, bsqFormatter, bsqWalletService, daoFacade); proposalDisplay.createAllFields(Res.get("dao.proposal.details"), 1, Layout.GROUP_DISTANCE, proposal.getType(), false, true); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java index c4a8ec484b9..d883bb4d2b0 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java @@ -27,6 +27,7 @@ import bisq.desktop.util.validation.BsqValidator; import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.dao.DaoFacade; import bisq.core.dao.state.ext.Param; import bisq.core.dao.voting.proposal.Proposal; import bisq.core.dao.voting.proposal.ProposalConsensus; @@ -35,12 +36,12 @@ import bisq.core.dao.voting.proposal.compensation.CompensationProposal; import bisq.core.dao.voting.proposal.param.ChangeParamProposal; import bisq.core.locale.Res; -import bisq.core.provider.fee.FeeService; import bisq.core.util.BsqFormatter; import javafx.scene.control.ComboBox; import javafx.scene.control.ScrollPane; import javafx.scene.control.TextArea; +import javafx.scene.control.TextField; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.ColumnConstraints; import javafx.scene.layout.GridPane; @@ -69,7 +70,9 @@ public class ProposalDisplay { private final int maxLengthDescriptionText; private final BsqFormatter bsqFormatter; private final BsqWalletService bsqWalletService; + private DaoFacade daoFacade; private InputTextField uidTextField; + private TextField proposalFeeTextField; public InputTextField nameTextField; public InputTextField titleTextField; public InputTextField linkInputTextField; @@ -82,15 +85,15 @@ public class ProposalDisplay { private HyperlinkWithIcon linkHyperlinkWithIcon; @Nullable private TxIdTextField txIdTextField; - private final FeeService feeService; private final ChangeListener descriptionTextAreaListener; private int gridRowStartIndex; - public ProposalDisplay(GridPane gridPane, BsqFormatter bsqFormatter, BsqWalletService bsqWalletService, @Nullable FeeService feeService) { + public ProposalDisplay(GridPane gridPane, BsqFormatter bsqFormatter, BsqWalletService bsqWalletService, + DaoFacade daoFacade) { this.gridPane = gridPane; this.bsqFormatter = bsqFormatter; this.bsqWalletService = bsqWalletService; - this.feeService = feeService; + this.daoFacade = daoFacade; maxLengthDescriptionText = ProposalConsensus.getMaxLengthDescriptionText(); @@ -112,17 +115,17 @@ public void createAllFields(String title, int gridRowStartIndex, double top, Pro boolean hasAddedFields = proposalType == ProposalType.COMPENSATION_REQUEST || proposalType == ProposalType.CHANGE_PARAM; if (isMakeProposalScreen) { - rowSpan = hasAddedFields ? 7 : 5; - } else if (showDetails) { rowSpan = hasAddedFields ? 8 : 6; + } else if (showDetails) { + rowSpan = hasAddedFields ? 9 : 7; } else { //noinspection IfCanBeSwitch if (proposalType == ProposalType.COMPENSATION_REQUEST) - rowSpan = 5; - else if (proposalType == ProposalType.CHANGE_PARAM) rowSpan = 6; + else if (proposalType == ProposalType.CHANGE_PARAM) + rowSpan = 7; else - rowSpan = 4; + rowSpan = 5; } addTitledGroupBg(gridPane, gridRow, rowSpan, title, top); @@ -155,14 +158,10 @@ else if (proposalType == ProposalType.CHANGE_PARAM) case COMPENSATION_REQUEST: requestedBsqTextField = addLabelInputTextField(gridPane, ++gridRow, Res.get("dao.proposal.display.requestedBsq")).second; - if (feeService != null) { - BsqValidator bsqValidator = new BsqValidator(bsqFormatter); - //TODO should we use the BSQ or a BTC validator? Technically it is BTC at that stage... - //bsqValidator.setMinValue(feeService.getCreateCompensationRequestFee()); - bsqValidator.setMinValue(CompensationConsensus.getMinCompensationRequestAmount()); - checkNotNull(requestedBsqTextField, "requestedBsqTextField must no tbe null"); - requestedBsqTextField.setValidator(bsqValidator); - } + BsqValidator bsqValidator = new BsqValidator(bsqFormatter); + bsqValidator.setMinValue(CompensationConsensus.getMinCompensationRequestAmount()); + checkNotNull(requestedBsqTextField, "requestedBsqTextField must no tbe null"); + requestedBsqTextField.setValidator(bsqValidator); // TODO validator, addressTF if (showDetails) { bsqAddressTextField = addLabelInputTextField(gridPane, ++gridRow, @@ -199,6 +198,9 @@ public Param fromString(String string) { if (!isMakeProposalScreen && showDetails) txIdTextField = addLabelTxIdTextField(gridPane, ++gridRow, Res.get("dao.proposal.display.txId"), "").second; + + proposalFeeTextField = addLabelTextField(gridPane, ++gridRow, Res.get("dao.proposal.display.proposalFee")).second; + proposalFeeTextField.setText(bsqFormatter.formatCoinWithCode(daoFacade.getProposalFee())); } public void applyProposalPayload(Proposal proposal) { diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalListItem.java index ea20b80b81b..887436fe3e0 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalListItem.java @@ -76,7 +76,7 @@ public void onPhaseChanged(DaoPhase.Phase phase) { if (phase == DaoPhase.Phase.PROPOSAL) { imageView.setId("image-remove"); button.setGraphic(imageView); - button.setText(Res.get("dao.proposal.active.remove")); + button.setText(Res.get("shared.remove")); final boolean isMyProposal = daoFacade.isMyProposal(proposal); button.setVisible(isMyProposal); button.setManaged(isMyProposal); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index 72deb82362f..00f856668d6 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -78,7 +78,6 @@ public class MakeProposalView extends ActivatableView implements private final BsqWalletService bsqWalletService; private final WalletsSetup walletsSetup; private final P2PService p2PService; - private final FeeService feeService; private final BSFormatter btcFormatter; private final BsqFormatter bsqFormatter; @@ -105,7 +104,6 @@ private MakeProposalView(DaoFacade daoFacade, this.bsqWalletService = bsqWalletService; this.walletsSetup = walletsSetup; this.p2PService = p2PService; - this.feeService = feeService; this.btcFormatter = btcFormatter; this.bsqFormatter = bsqFormatter; } @@ -291,7 +289,7 @@ private void addProposalDisplay() { proposalDisplay = null; } if (selectedProposalType != null) { - proposalDisplay = new ProposalDisplay(root, bsqFormatter, bsqWalletService, feeService); + proposalDisplay = new ProposalDisplay(root, bsqFormatter, bsqWalletService, daoFacade); proposalDisplay.createAllFields(Res.get("dao.proposal.create.createNew"), 1, Layout.GROUP_DISTANCE, selectedProposalType, true, true); proposalDisplay.fillWithMock(); From 7dd28e915669be9214162cf0d0398efc52ecd8f7 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Wed, 18 Jul 2018 22:51:29 +0200 Subject: [PATCH 149/197] Fix wrong removal of listener --- .../main/dao/cycles/cycle/CycleDisplay.java | 12 ++++++++---- .../main/dao/cycles/cycle/CycleListItem.java | 2 +- .../main/dao/proposal/ProposalDisplay.java | 16 ++++++++++++++-- .../dao/proposal/make/MakeProposalView.java | 2 +- .../dao/voting/active/ActiveBallotsView.java | 17 +++++++++++++---- 5 files changed, 37 insertions(+), 12 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/cycles/cycle/CycleDisplay.java b/src/main/java/bisq/desktop/main/dao/cycles/cycle/CycleDisplay.java index 23b9941bcf8..6587762baed 100644 --- a/src/main/java/bisq/desktop/main/dao/cycles/cycle/CycleDisplay.java +++ b/src/main/java/bisq/desktop/main/dao/cycles/cycle/CycleDisplay.java @@ -184,6 +184,7 @@ public void updateItem(final CycleListItem item, boolean empty) { // cycleDetailsWindow.show(item.getEvaluatedProposal()) if (item != null && !empty) { field = new Hyperlink(item.getProposalId()); + //TODO setId or getStyleClass.add does not apply color... //field.getStyleClass().add(item.getColorStyleClass()); //field.setId(item.getColorStyleClass()); @@ -230,8 +231,10 @@ public void updateItem(final CycleListItem item, boolean empty) { setGraphic(field); } else { setGraphic(null); - if (field != null) - field.setOnAction(null); + + //TODO does get called on active items somehow... + //if (field != null) + // field.setOnAction(null); } } }; @@ -263,8 +266,9 @@ public void updateItem(final CycleListItem item, boolean empty) { setGraphic(field); } else { setGraphic(null); - if (field != null) - field.setOnAction(null); + //TODO does get called on active items somehow... + //if (field != null) + // field.setOnAction(null); } } }; diff --git a/src/main/java/bisq/desktop/main/dao/cycles/cycle/CycleListItem.java b/src/main/java/bisq/desktop/main/dao/cycles/cycle/CycleListItem.java index e71e4e7fd8d..de87fed8e57 100644 --- a/src/main/java/bisq/desktop/main/dao/cycles/cycle/CycleListItem.java +++ b/src/main/java/bisq/desktop/main/dao/cycles/cycle/CycleListItem.java @@ -78,7 +78,7 @@ public String getColorStyleClass() { } public String getColorStyle() { - return evaluatedProposal.isAccepted() ? "-fx-text-fill: -bs-green" : "-fx-text-fill: -bs-error-red"; + return evaluatedProposal.isAccepted() ? "-fx-text-fill: -bs-green;" : "-fx-text-fill: -bs-error-red;"; } public String getIssuance() { diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java index d883bb4d2b0..770d80bf9aa 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java @@ -28,6 +28,7 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; +import bisq.core.dao.state.blockchain.Tx; import bisq.core.dao.state.ext.Param; import bisq.core.dao.voting.proposal.Proposal; import bisq.core.dao.voting.proposal.ProposalConsensus; @@ -88,6 +89,11 @@ public class ProposalDisplay { private final ChangeListener descriptionTextAreaListener; private int gridRowStartIndex; + + // TODO get that warning at closing the window... + // javafx.scene.CssStyleHelper calculateValue + // WARNING: Could not resolve '-fx-accent' while resolving lookups for '-fx-text-fill' from rule '*.hyperlink' in stylesheet file:/Users/dev/idea/bisq/desktop/out/production/resources/bisq/desktop/bisq.css + public ProposalDisplay(GridPane gridPane, BsqFormatter bsqFormatter, BsqWalletService bsqWalletService, DaoFacade daoFacade) { this.gridPane = gridPane; @@ -200,7 +206,6 @@ public Param fromString(String string) { Res.get("dao.proposal.display.txId"), "").second; proposalFeeTextField = addLabelTextField(gridPane, ++gridRow, Res.get("dao.proposal.display.proposalFee")).second; - proposalFeeTextField.setText(bsqFormatter.formatCoinWithCode(daoFacade.getProposalFee())); } public void applyProposalPayload(Proposal proposal) { @@ -228,8 +233,15 @@ public void applyProposalPayload(Proposal proposal) { checkNotNull(paramValueTextField, "paramValueTextField must no tbe null"); paramValueTextField.setText(String.valueOf(changeParamProposal.getParamValue())); } - if (txIdTextField != null) + int chainHeight; + if (txIdTextField != null) { txIdTextField.setup(proposal.getTxId()); + + chainHeight = daoFacade.getChainHeight(); + } else { + chainHeight = daoFacade.getTx(proposal.getTxId()).map(Tx::getBlockHeight).orElse(0); + } + proposalFeeTextField.setText(bsqFormatter.formatCoinWithCode(daoFacade.getProposalFee(chainHeight))); } public void clearForm() { diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index 00f856668d6..879d4550fbf 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -187,7 +187,7 @@ private void publishMyProposal(ProposalType type) { Transaction transaction = proposalWithTransaction.getTransaction(); Coin miningFee = transaction.getFee(); int txSize = transaction.bitcoinSerialize().length; - final Coin fee = daoFacade.getProposalFee(); + final Coin fee = daoFacade.getProposalFee(daoFacade.getChainHeight()); GUIUtil.showBsqFeeInfoPopup(fee, miningFee, txSize, bsqFormatter, btcFormatter, Res.get("dao.proposal"), () -> doPublishMyProposal(proposal, transaction)); diff --git a/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.java b/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.java index 02d095242f7..1ed1913cf9a 100644 --- a/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.java +++ b/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.java @@ -25,6 +25,7 @@ import bisq.desktop.main.overlays.popups.Popup; import bisq.desktop.util.GUIUtil; import bisq.desktop.util.Layout; +import bisq.desktop.util.validation.BsqValidator; import bisq.core.btc.exceptions.TransactionVerificationException; import bisq.core.btc.exceptions.WalletException; @@ -58,6 +59,7 @@ import javafx.scene.image.ImageView; import javafx.beans.property.ReadOnlyObjectWrapper; +import javafx.beans.value.ChangeListener; import javafx.collections.ListChangeListener; @@ -79,6 +81,7 @@ public class ActiveBallotsView extends BaseProposalView implements BsqBalanceLis private BusyAnimation voteButtonBusyAnimation; private Label voteButtonInfoLabel; private ListChangeListener listChangeListener; + private ChangeListener stakeListener; /////////////////////////////////////////////////////////////////////////////////////////// @@ -102,6 +105,7 @@ public void initialize() { createVoteView(); createEmptyProposalDisplay(); + stakeListener = (observable, oldValue, newValue) -> updateButtons(); listChangeListener = c -> updateListItems(); } @@ -109,8 +113,9 @@ public void initialize() { protected void activate() { super.activate(); + stakeInputTextField.textProperty().addListener(stakeListener); + daoFacade.getValidAndConfirmedBallots().addListener(listChangeListener); bsqWalletService.addBsqBalanceListener(this); - daoFacade.getActiveOrMyUnconfirmedBallots().addListener(listChangeListener); onUpdateBalances(bsqWalletService.getAvailableBalance(), bsqWalletService.getAvailableNonBsqBalance(), @@ -131,7 +136,8 @@ protected void activate() { protected void deactivate() { super.deactivate(); - daoFacade.getActiveOrMyUnconfirmedBallots().removeListener(listChangeListener); + stakeInputTextField.textProperty().removeListener(stakeListener); + daoFacade.getValidAndConfirmedBallots().removeListener(listChangeListener); bsqWalletService.removeBsqBalanceListener(this); } @@ -180,7 +186,7 @@ public void onParseBlockChainComplete() { @Override protected void fillListItems() { - List list = daoFacade.getActiveOrMyUnconfirmedBallots(); + List list = daoFacade.getValidAndConfirmedBallots(); proposalBaseProposalListItems.setAll(list.stream() .map(ballot -> new ActiveBallotListItem(ballot, daoFacade, bsqWalletService, bsqFormatter)) .collect(Collectors.toSet())); @@ -312,7 +318,8 @@ private ActiveBallotListItem getBallotListItem() { private void updateButtons() { final boolean isBlindVotePhase = daoFacade.phaseProperty().get() == DaoPhase.Phase.BLIND_VOTE; stakeInputTextField.setDisable(!isBlindVotePhase); - voteButton.setDisable(!isBlindVotePhase); + voteButton.setDisable(!isBlindVotePhase && + stakeInputTextField.getValidator().validate(stakeInputTextField.getText()).isValid); if (acceptButton != null) acceptButton.setDisable(!isBlindVotePhase); if (rejectButton != null) rejectButton.setDisable(!isBlindVotePhase); @@ -330,6 +337,8 @@ private void createVoteView() { final Tuple2 tuple2 = addLabelInputTextField(root, gridRow, Res.getWithCol("dao.proposal.myVote.stake"), Layout.FIRST_ROW_AND_GROUP_DISTANCE - 20); stakeInputTextField = tuple2.second; + stakeInputTextField.setValidator(new BsqValidator(bsqFormatter)); + Tuple3 tuple = addButtonBusyAnimationLabelAfterGroup(root, ++gridRow, Res.get("dao.proposal.myVote.button")); voteButton = tuple.first; From 288f4a7d89ebdb6331125aeb6440c1175f584af8 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Wed, 18 Jul 2018 23:16:09 +0200 Subject: [PATCH 150/197] Update proposal view on height change --- .../main/dao/proposal/ProposalDisplay.java | 5 ++++- .../dao/proposal/make/MakeProposalView.java | 22 ++++++++++++++----- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java index 770d80bf9aa..fbd909d4a98 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java @@ -58,6 +58,7 @@ import java.util.UUID; +import lombok.Getter; import lombok.extern.slf4j.Slf4j; import javax.annotation.Nullable; @@ -81,6 +82,7 @@ public class ProposalDisplay { public InputTextField requestedBsqTextField, bsqAddressTextField, paramValueTextField; @Nullable public ComboBox paramComboBox; + @Getter private int gridRow; public TextArea descriptionTextArea; private HyperlinkWithIcon linkHyperlinkWithIcon; @@ -206,6 +208,8 @@ public Param fromString(String string) { Res.get("dao.proposal.display.txId"), "").second; proposalFeeTextField = addLabelTextField(gridPane, ++gridRow, Res.get("dao.proposal.display.proposalFee")).second; + if (isMakeProposalScreen) + proposalFeeTextField.setText(bsqFormatter.formatCoinWithCode(daoFacade.getProposalFee(daoFacade.getChainHeight()))); } public void applyProposalPayload(Proposal proposal) { @@ -236,7 +240,6 @@ public void applyProposalPayload(Proposal proposal) { int chainHeight; if (txIdTextField != null) { txIdTextField.setup(proposal.getTxId()); - chainHeight = daoFacade.getChainHeight(); } else { chainHeight = daoFacade.getTx(proposal.getTxId()).map(Tx::getBlockHeight).orElse(0); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index 879d4550fbf..68009e61692 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -66,6 +66,8 @@ import java.util.Arrays; +import javax.annotation.Nullable; + import static bisq.desktop.util.FormBuilder.addButtonAfterGroup; import static bisq.desktop.util.FormBuilder.addLabelComboBox; import static bisq.desktop.util.FormBuilder.addTitledGroupBg; @@ -85,6 +87,7 @@ public class MakeProposalView extends ActivatableView implements private Button createButton; private ComboBox proposalTypeComboBox; private ChangeListener proposalTypeChangeListener; + @Nullable private ProposalType selectedProposalType; @@ -128,6 +131,7 @@ public ProposalType fromString(String string) { proposalTypeComboBox.setPromptText(Res.get("shared.select")); proposalTypeChangeListener = (observable, oldValue, newValue) -> { selectedProposalType = newValue; + removeProposalDisplay(); addProposalDisplay(); }; @@ -160,7 +164,10 @@ protected void deactivate() { @Override public void onNewBlockHeight(int height) { - proposalTypeComboBox.setDisable(!daoFacade.isInPhaseButNotLastBlock(DaoPhase.Phase.PROPOSAL)); + boolean isProposalPhase = daoFacade.isInPhaseButNotLastBlock(DaoPhase.Phase.PROPOSAL); + proposalTypeComboBox.setDisable(!isProposalPhase); + if (!isProposalPhase) + proposalTypeComboBox.getSelectionModel().clearSelection(); } @Override @@ -283,11 +290,6 @@ private ProposalWithTransaction getProposalWithTransaction(ProposalType type) } private void addProposalDisplay() { - // TODO need to update removed fields when switching. - if (proposalDisplay != null) { - proposalDisplay.removeAllFields(); - proposalDisplay = null; - } if (selectedProposalType != null) { proposalDisplay = new ProposalDisplay(root, bsqFormatter, bsqWalletService, daoFacade); proposalDisplay.createAllFields(Res.get("dao.proposal.create.createNew"), 1, Layout.GROUP_DISTANCE, @@ -299,6 +301,14 @@ private void addProposalDisplay() { } } + private void removeProposalDisplay() { + if (proposalDisplay != null) { + proposalDisplay.removeAllFields(); + GUIUtil.removeChildrenFromGridPaneRows(root, 1, proposalDisplay.getGridRow()); + proposalDisplay = null; + } + } + private void setCreateButtonHandler() { createButton.setOnAction(event -> { // TODO break up in methods From f27a7461c83c5f09fc7845d4703b7d64f15767eb Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Wed, 18 Jul 2018 23:19:53 +0200 Subject: [PATCH 151/197] Rename classes --- .../java/bisq/desktop/main/dao/DaoView.java | 8 +- .../ResultsListItem.java} | 28 ++-- .../ResultsView.fxml} | 2 +- .../ResultsView.java} | 128 +++++++-------- .../model/ResultsOfCycle.java} | 14 +- .../ProposalResultDetailsWindow.java} | 6 +- .../proposal/ProposalResultDisplay.java} | 154 +++++++++--------- .../proposal/ProposalResultListItem.java} | 6 +- 8 files changed, 173 insertions(+), 173 deletions(-) rename src/main/java/bisq/desktop/main/dao/{cycles/CyclesListItem.java => results/ResultsListItem.java} (65%) rename src/main/java/bisq/desktop/main/dao/{cycles/CyclesView.fxml => results/ResultsView.fxml} (94%) rename src/main/java/bisq/desktop/main/dao/{cycles/CyclesView.java => results/ResultsView.java} (69%) rename src/main/java/bisq/desktop/main/dao/{cycles/model/CycleResult.java => results/model/ResultsOfCycle.java} (88%) rename src/main/java/bisq/desktop/main/dao/{cycles/cycle/CycleDetailsWindow.java => results/proposal/ProposalResultDetailsWindow.java} (91%) rename src/main/java/bisq/desktop/main/dao/{cycles/cycle/CycleDisplay.java => results/proposal/ProposalResultDisplay.java} (64%) rename src/main/java/bisq/desktop/main/dao/{cycles/cycle/CycleListItem.java => results/proposal/ProposalResultListItem.java} (94%) diff --git a/src/main/java/bisq/desktop/main/dao/DaoView.java b/src/main/java/bisq/desktop/main/dao/DaoView.java index ae9683c9562..be9261217b5 100644 --- a/src/main/java/bisq/desktop/main/dao/DaoView.java +++ b/src/main/java/bisq/desktop/main/dao/DaoView.java @@ -26,8 +26,8 @@ import bisq.desktop.common.view.ViewLoader; import bisq.desktop.main.MainView; import bisq.desktop.main.dao.bonding.BondingView; -import bisq.desktop.main.dao.cycles.CyclesView; import bisq.desktop.main.dao.proposal.ProposalView; +import bisq.desktop.main.dao.results.ResultsView; import bisq.desktop.main.dao.voting.VotingView; import bisq.desktop.main.dao.wallet.BsqWalletView; import bisq.desktop.main.dao.wallet.dashboard.BsqDashboardView; @@ -126,7 +126,7 @@ public void initialize() { navigation.navigateTo(MainView.class, DaoView.class, VotingView.class); } else if (newValue == resultsTab) { //noinspection unchecked - navigation.navigateTo(MainView.class, DaoView.class, CyclesView.class); + navigation.navigateTo(MainView.class, DaoView.class, ResultsView.class); } else if (newValue == bondingTab) { //noinspection unchecked navigation.navigateTo(MainView.class, DaoView.class, BondingView.class); @@ -152,7 +152,7 @@ else if (selectedItem == votingTab) navigation.navigateTo(MainView.class, DaoView.class, VotingView.class); else if (selectedItem == resultsTab) //noinspection unchecked - navigation.navigateTo(MainView.class, DaoView.class, CyclesView.class); + navigation.navigateTo(MainView.class, DaoView.class, ResultsView.class); else if (selectedItem == bondingTab) //noinspection unchecked navigation.navigateTo(MainView.class, DaoView.class, BondingView.class); @@ -174,7 +174,7 @@ private void loadView(Class viewClass) { selectedTab = proposalsTab; } else if (view instanceof VotingView) { selectedTab = votingTab; - } else if (view instanceof CyclesView) { + } else if (view instanceof ResultsView) { selectedTab = resultsTab; } else if (view instanceof BondingView) { selectedTab = bondingTab; diff --git a/src/main/java/bisq/desktop/main/dao/cycles/CyclesListItem.java b/src/main/java/bisq/desktop/main/dao/results/ResultsListItem.java similarity index 65% rename from src/main/java/bisq/desktop/main/dao/cycles/CyclesListItem.java rename to src/main/java/bisq/desktop/main/dao/results/ResultsListItem.java index e16bbad440a..0d0e3e6220e 100644 --- a/src/main/java/bisq/desktop/main/dao/cycles/CyclesListItem.java +++ b/src/main/java/bisq/desktop/main/dao/results/ResultsListItem.java @@ -15,9 +15,9 @@ * along with Bisq. If not, see . */ -package bisq.desktop.main.dao.cycles; +package bisq.desktop.main.dao.results; -import bisq.desktop.main.dao.cycles.model.CycleResult; +import bisq.desktop.main.dao.results.model.ResultsOfCycle; import bisq.core.dao.voting.proposal.compensation.CompensationProposal; import bisq.core.locale.Res; @@ -29,37 +29,37 @@ import lombok.Getter; -public class CyclesListItem { +public class ResultsListItem { private final BsqFormatter bsqFormatter; @Getter - private CycleResult cycleResult; + private ResultsOfCycle resultsOfCycle; - public CyclesListItem(CycleResult cycleResult, - BsqFormatter bsqFormatter) { - this.cycleResult = cycleResult; + public ResultsListItem(ResultsOfCycle resultsOfCycle, + BsqFormatter bsqFormatter) { + this.resultsOfCycle = resultsOfCycle; this.bsqFormatter = bsqFormatter; } public String getCycle() { - int displayIndex = cycleResult.getCycleIndex() + 1; - String dateTime = bsqFormatter.formatDateTime(new Date(cycleResult.getCycleStartTime())); + int displayIndex = resultsOfCycle.getCycleIndex() + 1; + String dateTime = bsqFormatter.formatDateTime(new Date(resultsOfCycle.getCycleStartTime())); return Res.get("dao.results.results.table.item.cycle", displayIndex, dateTime); } public String getNumProposals() { - return String.valueOf(cycleResult.getEvaluatedProposals().size()); + return String.valueOf(resultsOfCycle.getEvaluatedProposals().size()); } public String getNumVotesAsString() { - return String.valueOf(cycleResult.getNumVotes()); + return String.valueOf(resultsOfCycle.getNumVotes()); } public String getStake() { - return bsqFormatter.formatCoinWithCode(Coin.valueOf(cycleResult.getTotalStake())); + return bsqFormatter.formatCoinWithCode(Coin.valueOf(resultsOfCycle.getTotalStake())); } public String getIssuance() { - long totalIssuance = cycleResult.getEvaluatedProposals().stream() + long totalIssuance = resultsOfCycle.getEvaluatedProposals().stream() .filter(e -> e.getProposal() instanceof CompensationProposal) .map(e -> (CompensationProposal) e.getProposal()) .mapToLong(e -> e.getRequestedBsq().value) @@ -68,6 +68,6 @@ public String getIssuance() { } public Long getCycleStartTime() { - return cycleResult.getCycleStartTime(); + return resultsOfCycle.getCycleStartTime(); } } diff --git a/src/main/java/bisq/desktop/main/dao/cycles/CyclesView.fxml b/src/main/java/bisq/desktop/main/dao/results/ResultsView.fxml similarity index 94% rename from src/main/java/bisq/desktop/main/dao/cycles/CyclesView.fxml rename to src/main/java/bisq/desktop/main/dao/results/ResultsView.fxml index ef067e5f4fd..4b19a62a649 100644 --- a/src/main/java/bisq/desktop/main/dao/cycles/CyclesView.fxml +++ b/src/main/java/bisq/desktop/main/dao/results/ResultsView.fxml @@ -21,7 +21,7 @@ -. */ -package bisq.desktop.main.dao.cycles; +package bisq.desktop.main.dao.results; import bisq.desktop.common.model.Activatable; @@ -24,8 +24,8 @@ import bisq.desktop.components.AutoTooltipLabel; import bisq.desktop.components.AutoTooltipTableColumn; import bisq.desktop.components.TableGroupHeadline; -import bisq.desktop.main.dao.cycles.cycle.CycleDisplay; -import bisq.desktop.main.dao.cycles.model.CycleResult; +import bisq.desktop.main.dao.results.model.ResultsOfCycle; +import bisq.desktop.main.dao.results.proposal.ProposalResultDisplay; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; @@ -68,7 +68,7 @@ import java.util.stream.Collectors; @FxmlView -public class CyclesView extends ActivatableViewAndModel implements BsqStateListener { +public class ResultsView extends ActivatableViewAndModel implements BsqStateListener { private final DaoFacade daoFacade; // TODO use daoFacade once dev work completed private final BsqStateService bsqStateService; @@ -79,14 +79,14 @@ public class CyclesView extends ActivatableViewAndModel i private final BsqFormatter bsqFormatter; private int gridRow = 0; - private TableView tableView; + private TableView tableView; - private final ObservableList itemList = FXCollections.observableArrayList(); - private final SortedList sortedList = new SortedList<>(itemList); - private ChangeListener selectedItemListener; + private final ObservableList itemList = FXCollections.observableArrayList(); + private final SortedList sortedList = new SortedList<>(itemList); + private ChangeListener selectedItemListener; private GridPane resultGridPane; - private CycleDisplay proposalsDisplay; + private ProposalResultDisplay proposalsDisplay; private ScrollPane resultDisplayView; private boolean resultDisplayInitialized; @@ -96,13 +96,13 @@ public class CyclesView extends ActivatableViewAndModel i /////////////////////////////////////////////////////////////////////////////////////////// @Inject - private CyclesView(DaoFacade daoFacade, - BsqStateService bsqStateService, - CycleService cycleService, - VoteResultService voteResultService, - ProposalService proposalService, - BsqWalletService bsqWalletService, - BsqFormatter bsqFormatter) { + private ResultsView(DaoFacade daoFacade, + BsqStateService bsqStateService, + CycleService cycleService, + VoteResultService voteResultService, + ProposalService proposalService, + BsqWalletService bsqWalletService, + BsqFormatter bsqFormatter) { this.daoFacade = daoFacade; this.bsqStateService = bsqStateService; this.cycleService = cycleService; @@ -161,7 +161,7 @@ public void onParseBlockChainComplete() { // UI handlers /////////////////////////////////////////////////////////////////////////////////////////// - private void onCycleListItemSelected(CyclesListItem item) { + private void onCycleListItemSelected(ResultsListItem item) { if (item != null) createAllFieldsOnResultDisplay(item); else @@ -198,7 +198,7 @@ private void createResultsTable() { } private void createResultDisplay() { - proposalsDisplay = new CycleDisplay(resultGridPane, bsqWalletService, daoFacade, bsqFormatter); + proposalsDisplay = new ProposalResultDisplay(resultGridPane, bsqWalletService, daoFacade, bsqFormatter); resultDisplayView = proposalsDisplay.getView(); GridPane.setMargin(resultDisplayView, new Insets(10, -10, 0, -10)); GridPane.setRowIndex(resultDisplayView, ++gridRow); @@ -231,13 +231,13 @@ private void addCycleListItem(Cycle cycle) { .map(e -> e.getTime() * 1000) .orElse(0L); int cycleIndex = cycleService.getCycleIndex(cycle); - CycleResult cycleResult = new CycleResult(cycle, + ResultsOfCycle resultsOfCycle = new ResultsOfCycle(cycle, cycleIndex, cycleStartTime, proposalsForCycle, evaluatedProposalsForCycle); - CyclesListItem cyclesListItem = new CyclesListItem(cycleResult, bsqFormatter); - itemList.add(cyclesListItem); + ResultsListItem resultsListItem = new ResultsListItem(resultsOfCycle, bsqFormatter); + itemList.add(resultsListItem); } private void hideResultDisplay() { @@ -248,11 +248,11 @@ private void hideResultDisplay() { } } - private void createAllFieldsOnResultDisplay(CyclesListItem cyclesListItem) { + private void createAllFieldsOnResultDisplay(ResultsListItem resultsListItem) { resultDisplayView.setVisible(true); resultDisplayView.setManaged(true); - proposalsDisplay.createAllFields(0, cyclesListItem.getCycleResult()); + proposalsDisplay.createAllFields(0, resultsListItem.getResultsOfCycle()); resultDisplayInitialized = true; } @@ -261,19 +261,19 @@ private void createAllFieldsOnResultDisplay(CyclesListItem cyclesListItem) { // TableColumns /////////////////////////////////////////////////////////////////////////////////////////// - private void createColumns(TableView tableView) { - TableColumn cycleColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.results.table.header.cycle")); + private void createColumns(TableView tableView) { + TableColumn cycleColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.results.table.header.cycle")); cycleColumn.setMinWidth(160); cycleColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); cycleColumn.setCellFactory( - new Callback, TableCell>() { + new Callback, TableCell>() { @Override - public TableCell call( - TableColumn column) { - return new TableCell() { + public TableCell call( + TableColumn column) { + return new TableCell() { @Override - public void updateItem(final CyclesListItem item, boolean empty) { + public void updateItem(final ResultsListItem item, boolean empty) { super.updateItem(item, empty); if (item != null) setText(item.getCycle()); @@ -283,22 +283,22 @@ public void updateItem(final CyclesListItem item, boolean empty) { }; } }); - cycleColumn.setComparator(Comparator.comparing(CyclesListItem::getCycleStartTime)); + cycleColumn.setComparator(Comparator.comparing(ResultsListItem::getCycleStartTime)); tableView.getColumns().add(cycleColumn); - TableColumn proposalsColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.results.table.header.numProposals")); + TableColumn proposalsColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.results.table.header.numProposals")); proposalsColumn.setMinWidth(90); proposalsColumn.setMaxWidth(90); proposalsColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); proposalsColumn.setCellFactory( - new Callback, TableCell>() { + new Callback, TableCell>() { @Override - public TableCell call( - TableColumn column) { - return new TableCell() { + public TableCell call( + TableColumn column) { + return new TableCell() { @Override - public void updateItem(final CyclesListItem item, boolean empty) { + public void updateItem(final ResultsListItem item, boolean empty) { super.updateItem(item, empty); if (item != null) setText(item.getNumProposals()); @@ -308,22 +308,22 @@ public void updateItem(final CyclesListItem item, boolean empty) { }; } }); - proposalsColumn.setComparator(Comparator.comparing(CyclesListItem::getNumProposals)); + proposalsColumn.setComparator(Comparator.comparing(ResultsListItem::getNumProposals)); tableView.getColumns().add(proposalsColumn); - TableColumn votesColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.results.table.header.numVotes")); + TableColumn votesColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.results.table.header.numVotes")); votesColumn.setMinWidth(70); votesColumn.setMaxWidth(70); votesColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); votesColumn.setCellFactory( - new Callback, TableCell>() { + new Callback, TableCell>() { @Override - public TableCell call( - TableColumn column) { - return new TableCell() { + public TableCell call( + TableColumn column) { + return new TableCell() { @Override - public void updateItem(final CyclesListItem item, boolean empty) { + public void updateItem(final ResultsListItem item, boolean empty) { super.updateItem(item, empty); if (item != null) setText(item.getNumVotesAsString()); @@ -333,20 +333,20 @@ public void updateItem(final CyclesListItem item, boolean empty) { }; } }); - votesColumn.setComparator(Comparator.comparing(CyclesListItem::getNumProposals)); + votesColumn.setComparator(Comparator.comparing(ResultsListItem::getNumProposals)); tableView.getColumns().add(votesColumn); - TableColumn stakeColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.results.table.header.stake")); + TableColumn stakeColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.results.table.header.stake")); stakeColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); stakeColumn.setCellFactory( - new Callback, TableCell>() { + new Callback, TableCell>() { @Override - public TableCell call( - TableColumn column) { - return new TableCell() { + public TableCell call( + TableColumn column) { + return new TableCell() { @Override - public void updateItem(final CyclesListItem item, boolean empty) { + public void updateItem(final ResultsListItem item, boolean empty) { super.updateItem(item, empty); if (item != null) setText(item.getStake()); @@ -356,20 +356,20 @@ public void updateItem(final CyclesListItem item, boolean empty) { }; } }); - stakeColumn.setComparator(Comparator.comparing(CyclesListItem::getNumProposals)); + stakeColumn.setComparator(Comparator.comparing(ResultsListItem::getNumProposals)); tableView.getColumns().add(stakeColumn); - TableColumn issuanceColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.results.table.header.issuance")); + TableColumn issuanceColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.results.table.header.issuance")); issuanceColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); issuanceColumn.setCellFactory( - new Callback, TableCell>() { + new Callback, TableCell>() { @Override - public TableCell call( - TableColumn column) { - return new TableCell() { + public TableCell call( + TableColumn column) { + return new TableCell() { @Override - public void updateItem(final CyclesListItem item, boolean empty) { + public void updateItem(final ResultsListItem item, boolean empty) { super.updateItem(item, empty); if (item != null) setText(item.getIssuance()); @@ -379,7 +379,7 @@ public void updateItem(final CyclesListItem item, boolean empty) { }; } }); - issuanceColumn.setComparator(Comparator.comparing(CyclesListItem::getNumProposals)); + issuanceColumn.setComparator(Comparator.comparing(ResultsListItem::getNumProposals)); tableView.getColumns().add(issuanceColumn); } } diff --git a/src/main/java/bisq/desktop/main/dao/cycles/model/CycleResult.java b/src/main/java/bisq/desktop/main/dao/results/model/ResultsOfCycle.java similarity index 88% rename from src/main/java/bisq/desktop/main/dao/cycles/model/CycleResult.java rename to src/main/java/bisq/desktop/main/dao/results/model/ResultsOfCycle.java index 4da420c2318..5c67cdef68d 100644 --- a/src/main/java/bisq/desktop/main/dao/cycles/model/CycleResult.java +++ b/src/main/java/bisq/desktop/main/dao/results/model/ResultsOfCycle.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.desktop.main.dao.cycles.model; +package bisq.desktop.main.dao.results.model; import bisq.core.dao.state.period.Cycle; import bisq.core.dao.voting.proposal.Proposal; @@ -27,7 +27,7 @@ import lombok.Data; @Data -public class CycleResult { +public class ResultsOfCycle { private final Cycle cycle; private final int cycleIndex; private final int numVotes, numAcceptedVotes, numRejectedVotes; @@ -42,11 +42,11 @@ public class CycleResult { // Proposals which ended up in voting private final List evaluatedProposals; - public CycleResult(Cycle cycle, - int cycleIndex, - long cycleStartTime, - List proposals, - List evaluatedProposals) { + public ResultsOfCycle(Cycle cycle, + int cycleIndex, + long cycleStartTime, + List proposals, + List evaluatedProposals) { this.cycle = cycle; this.cycleIndex = cycleIndex; this.cycleStartTime = cycleStartTime; diff --git a/src/main/java/bisq/desktop/main/dao/cycles/cycle/CycleDetailsWindow.java b/src/main/java/bisq/desktop/main/dao/results/proposal/ProposalResultDetailsWindow.java similarity index 91% rename from src/main/java/bisq/desktop/main/dao/cycles/cycle/CycleDetailsWindow.java rename to src/main/java/bisq/desktop/main/dao/results/proposal/ProposalResultDetailsWindow.java index 1d05be18e8b..f50078b104b 100644 --- a/src/main/java/bisq/desktop/main/dao/cycles/cycle/CycleDetailsWindow.java +++ b/src/main/java/bisq/desktop/main/dao/results/proposal/ProposalResultDetailsWindow.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.desktop.main.dao.cycles.cycle; +package bisq.desktop.main.dao.results.proposal; import bisq.desktop.main.overlays.Overlay; import bisq.desktop.util.FormBuilder; @@ -30,7 +30,7 @@ import static bisq.desktop.util.FormBuilder.addTitledGroupBg; -class CycleDetailsWindow extends Overlay { +class ProposalResultDetailsWindow extends Overlay { private final BsqFormatter bsqFormatter; private final EvaluatedProposal evaluatedProposal; @@ -40,7 +40,7 @@ class CycleDetailsWindow extends Overlay { // Public API /////////////////////////////////////////////////////////////////////////////////////////// - public CycleDetailsWindow(BsqFormatter bsqFormatter, EvaluatedProposal evaluatedProposal) { + public ProposalResultDetailsWindow(BsqFormatter bsqFormatter, EvaluatedProposal evaluatedProposal) { this.bsqFormatter = bsqFormatter; this.evaluatedProposal = evaluatedProposal; type = Type.Confirmation; diff --git a/src/main/java/bisq/desktop/main/dao/cycles/cycle/CycleDisplay.java b/src/main/java/bisq/desktop/main/dao/results/proposal/ProposalResultDisplay.java similarity index 64% rename from src/main/java/bisq/desktop/main/dao/cycles/cycle/CycleDisplay.java rename to src/main/java/bisq/desktop/main/dao/results/proposal/ProposalResultDisplay.java index 6587762baed..dd8e7b96475 100644 --- a/src/main/java/bisq/desktop/main/dao/cycles/cycle/CycleDisplay.java +++ b/src/main/java/bisq/desktop/main/dao/results/proposal/ProposalResultDisplay.java @@ -15,13 +15,13 @@ * along with Bisq. If not, see . */ -package bisq.desktop.main.dao.cycles.cycle; +package bisq.desktop.main.dao.results.proposal; import bisq.desktop.components.AutoTooltipLabel; import bisq.desktop.components.AutoTooltipTableColumn; import bisq.desktop.components.TableGroupHeadline; -import bisq.desktop.main.dao.cycles.model.CycleResult; import bisq.desktop.main.dao.proposal.ProposalDetailsWindow; +import bisq.desktop.main.dao.results.model.ResultsOfCycle; import bisq.desktop.util.FormBuilder; import bisq.desktop.util.GUIUtil; @@ -66,7 +66,7 @@ import lombok.extern.slf4j.Slf4j; @Slf4j -public class CycleDisplay { +public class ProposalResultDisplay { private final GridPane gridPane; private final BsqWalletService bsqWalletService; private final DaoFacade daoFacade; @@ -76,18 +76,18 @@ public class CycleDisplay { private int gridRowStartIndex; - private final ObservableList itemList = FXCollections.observableArrayList(); - private final SortedList sortedList = new SortedList<>(itemList); + private final ObservableList itemList = FXCollections.observableArrayList(); + private final SortedList sortedList = new SortedList<>(itemList); - public CycleDisplay(GridPane gridPane, BsqWalletService bsqWalletService, DaoFacade daoFacade, BsqFormatter bsqFormatter) { + public ProposalResultDisplay(GridPane gridPane, BsqWalletService bsqWalletService, DaoFacade daoFacade, BsqFormatter bsqFormatter) { this.gridPane = gridPane; this.bsqWalletService = bsqWalletService; this.daoFacade = daoFacade; this.bsqFormatter = bsqFormatter; } - public void createAllFields(int gridRowStartIndex, CycleResult cycleResult) { + public void createAllFields(int gridRowStartIndex, ResultsOfCycle resultsOfCycle) { removeAllFields(); this.gridRowStartIndex = gridRowStartIndex; @@ -95,14 +95,14 @@ public void createAllFields(int gridRowStartIndex, CycleResult cycleResult) { createTableView(); - itemList.setAll(cycleResult.getEvaluatedProposals().stream().map(e -> new CycleListItem(e, bsqFormatter)).collect(Collectors.toList())); + itemList.setAll(resultsOfCycle.getEvaluatedProposals().stream().map(e -> new ProposalResultListItem(e, bsqFormatter)).collect(Collectors.toList())); Map requiredThresholdByType = new HashMap<>(); - cycleResult.getEvaluatedProposals().forEach(e -> { + resultsOfCycle.getEvaluatedProposals().forEach(e -> { requiredThresholdByType.putIfAbsent(e.getProposal().getType(), e.getRequiredThreshold()); }); Map requiredQuorumByType = new HashMap<>(); - cycleResult.getEvaluatedProposals().forEach(e -> { + resultsOfCycle.getEvaluatedProposals().forEach(e -> { requiredQuorumByType.putIfAbsent(e.getProposal().getType(), e.getRequiredQuorum()); }); @@ -125,7 +125,7 @@ private void createTableView() { GridPane.setColumnSpan(headline, 2); gridPane.getChildren().add(headline); - TableView tableView = new TableView<>(); + TableView tableView = new TableView<>(); tableView.setPlaceholder(new AutoTooltipLabel(Res.get("table.placeholder.noData"))); tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); tableView.setPrefHeight(200); @@ -141,18 +141,18 @@ private void createTableView() { sortedList.comparatorProperty().bind(tableView.comparatorProperty()); } - private void createColumns(TableView tableView) { - TableColumn proposalColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.result.table.header.proposalOwnerName")); + private void createColumns(TableView tableView) { + TableColumn proposalColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.result.table.header.proposalOwnerName")); proposalColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); proposalColumn.setCellFactory( - new Callback, TableCell>() { + new Callback, TableCell>() { @Override - public TableCell call( - TableColumn column) { - return new TableCell() { + public TableCell call( + TableColumn column) { + return new TableCell() { @Override - public void updateItem(final CycleListItem item, boolean empty) { + public void updateItem(final ProposalResultListItem item, boolean empty) { super.updateItem(item, empty); if (item != null) setText(item.getProposalOwnerName()); @@ -162,23 +162,23 @@ public void updateItem(final CycleListItem item, boolean empty) { }; } }); - proposalColumn.setComparator(Comparator.comparing(CycleListItem::getProposalOwnerName)); + proposalColumn.setComparator(Comparator.comparing(ProposalResultListItem::getProposalOwnerName)); tableView.getColumns().add(proposalColumn); - TableColumn proposalIdColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.result.table.header.proposalId")); + TableColumn proposalIdColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.result.table.header.proposalId")); proposalIdColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); proposalIdColumn.setCellFactory( - new Callback, TableCell>() { + new Callback, TableCell>() { @Override - public TableCell call(TableColumn column) { - return new TableCell() { + public TableCell call(TableColumn column) { + return new TableCell() { private Hyperlink field; @Override - public void updateItem(final CycleListItem item, boolean empty) { + public void updateItem(final ProposalResultListItem item, boolean empty) { super.updateItem(item, empty); // cycleDetailsWindow.show(item.getEvaluatedProposal()) @@ -205,28 +205,28 @@ public void updateItem(final CycleListItem item, boolean empty) { }; } }); - proposalIdColumn.setComparator(Comparator.comparing(CycleListItem::getProposalOwnerName)); + proposalIdColumn.setComparator(Comparator.comparing(ProposalResultListItem::getProposalOwnerName)); tableView.getColumns().add(proposalIdColumn); - TableColumn acceptedColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.result.table.header.accepted")); + TableColumn acceptedColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.result.table.header.accepted")); acceptedColumn.setMinWidth(80); acceptedColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); acceptedColumn.setCellFactory( - new Callback, TableCell>() { + new Callback, TableCell>() { private Hyperlink field; @Override - public TableCell call( - TableColumn column) { - return new TableCell() { + public TableCell call( + TableColumn column) { + return new TableCell() { @Override - public void updateItem(final CycleListItem item, boolean empty) { + public void updateItem(final ProposalResultListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { field = new Hyperlink(item.getAccepted()); field.setStyle(item.getColorStyle()); - field.setOnAction(event -> new CycleDetailsWindow(bsqFormatter, item.getEvaluatedProposal()).show()); + field.setOnAction(event -> new ProposalResultDetailsWindow(bsqFormatter, item.getEvaluatedProposal()).show()); field.setTooltip(new Tooltip(Res.get("tooltip.openPopupForDetails"))); setGraphic(field); } else { @@ -240,28 +240,28 @@ public void updateItem(final CycleListItem item, boolean empty) { }; } }); - acceptedColumn.setComparator(Comparator.comparing(CycleListItem::getAccepted)); + acceptedColumn.setComparator(Comparator.comparing(ProposalResultListItem::getAccepted)); tableView.getColumns().add(acceptedColumn); - TableColumn rejectedColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.result.table.header.rejected")); + TableColumn rejectedColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.result.table.header.rejected")); rejectedColumn.setMinWidth(80); rejectedColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); rejectedColumn.setCellFactory( - new Callback, TableCell>() { + new Callback, TableCell>() { private Hyperlink field; @Override - public TableCell call( - TableColumn column) { - return new TableCell() { + public TableCell call( + TableColumn column) { + return new TableCell() { @Override - public void updateItem(final CycleListItem item, boolean empty) { + public void updateItem(final ProposalResultListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { field = new Hyperlink(item.getRejected()); field.setStyle(item.getColorStyle()); - field.setOnAction(event -> new CycleDetailsWindow(bsqFormatter, item.getEvaluatedProposal()).show()); + field.setOnAction(event -> new ProposalResultDetailsWindow(bsqFormatter, item.getEvaluatedProposal()).show()); field.setTooltip(new Tooltip(Res.get("tooltip.openPopupForDetails"))); setGraphic(field); } else { @@ -274,22 +274,22 @@ public void updateItem(final CycleListItem item, boolean empty) { }; } }); - rejectedColumn.setComparator(Comparator.comparing(CycleListItem::getRejected)); + rejectedColumn.setComparator(Comparator.comparing(ProposalResultListItem::getRejected)); tableView.getColumns().add(rejectedColumn); - TableColumn thresholdColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.result.table.header.threshold")); + TableColumn thresholdColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.result.table.header.threshold")); thresholdColumn.setMinWidth(100); thresholdColumn.setMaxWidth(100); thresholdColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); thresholdColumn.setCellFactory( - new Callback, TableCell>() { + new Callback, TableCell>() { @Override - public TableCell call( - TableColumn column) { - return new TableCell() { + public TableCell call( + TableColumn column) { + return new TableCell() { @Override - public void updateItem(final CycleListItem item, boolean empty) { + public void updateItem(final ProposalResultListItem item, boolean empty) { super.updateItem(item, empty); if (item != null) setText(item.getThreshold()); @@ -299,22 +299,22 @@ public void updateItem(final CycleListItem item, boolean empty) { }; } }); - thresholdColumn.setComparator(Comparator.comparing(CycleListItem::getThreshold)); + thresholdColumn.setComparator(Comparator.comparing(ProposalResultListItem::getThreshold)); tableView.getColumns().add(thresholdColumn); - TableColumn quorumColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.result.table.header.quorum")); + TableColumn quorumColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.result.table.header.quorum")); quorumColumn.setMinWidth(130); quorumColumn.setMaxWidth(130); quorumColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); quorumColumn.setCellFactory( - new Callback, TableCell>() { + new Callback, TableCell>() { @Override - public TableCell call( - TableColumn column) { - return new TableCell() { + public TableCell call( + TableColumn column) { + return new TableCell() { @Override - public void updateItem(final CycleListItem item, boolean empty) { + public void updateItem(final ProposalResultListItem item, boolean empty) { super.updateItem(item, empty); if (item != null) setText(item.getQuorum()); @@ -324,22 +324,22 @@ public void updateItem(final CycleListItem item, boolean empty) { }; } }); - quorumColumn.setComparator(Comparator.comparing(CycleListItem::getThreshold)); + quorumColumn.setComparator(Comparator.comparing(ProposalResultListItem::getThreshold)); tableView.getColumns().add(quorumColumn); - TableColumn issuanceColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.result.table.header.issuance")); + TableColumn issuanceColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.result.table.header.issuance")); issuanceColumn.setMinWidth(130); issuanceColumn.setMaxWidth(130); issuanceColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); issuanceColumn.setCellFactory( - new Callback, TableCell>() { + new Callback, TableCell>() { @Override - public TableCell call( - TableColumn column) { - return new TableCell() { + public TableCell call( + TableColumn column) { + return new TableCell() { @Override - public void updateItem(final CycleListItem item, boolean empty) { + public void updateItem(final ProposalResultListItem item, boolean empty) { super.updateItem(item, empty); if (item != null) setText(item.getIssuance()); @@ -349,25 +349,25 @@ public void updateItem(final CycleListItem item, boolean empty) { }; } }); - issuanceColumn.setComparator(Comparator.comparing(CycleListItem::getThreshold)); + issuanceColumn.setComparator(Comparator.comparing(ProposalResultListItem::getThreshold)); tableView.getColumns().add(issuanceColumn); - TableColumn resultColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.result.table.header.result")); + TableColumn resultColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.result.table.header.result")); resultColumn.setMinWidth(60); resultColumn.setMaxWidth(60); resultColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - resultColumn.setCellFactory(new Callback, - TableCell>() { + resultColumn.setCellFactory(new Callback, + TableCell>() { @Override - public TableCell call(TableColumn column) { - return new TableCell() { + public TableCell call(TableColumn column) { + return new TableCell() { Label icon; @Override - public void updateItem(final CycleListItem item, boolean empty) { + public void updateItem(final ProposalResultListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { @@ -386,7 +386,7 @@ public void updateItem(final CycleListItem item, boolean empty) { }); - resultColumn.setComparator(Comparator.comparing(CycleListItem::getThreshold)); + resultColumn.setComparator(Comparator.comparing(ProposalResultListItem::getThreshold)); tableView.getColumns().add(resultColumn); } diff --git a/src/main/java/bisq/desktop/main/dao/cycles/cycle/CycleListItem.java b/src/main/java/bisq/desktop/main/dao/results/proposal/ProposalResultListItem.java similarity index 94% rename from src/main/java/bisq/desktop/main/dao/cycles/cycle/CycleListItem.java rename to src/main/java/bisq/desktop/main/dao/results/proposal/ProposalResultListItem.java index de87fed8e57..f176f44bdb5 100644 --- a/src/main/java/bisq/desktop/main/dao/cycles/cycle/CycleListItem.java +++ b/src/main/java/bisq/desktop/main/dao/results/proposal/ProposalResultListItem.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.desktop.main.dao.cycles.cycle; +package bisq.desktop.main.dao.results.proposal; import bisq.core.dao.voting.proposal.compensation.CompensationProposal; import bisq.core.dao.voting.voteresult.EvaluatedProposal; @@ -29,13 +29,13 @@ import lombok.Getter; -public class CycleListItem { +public class ProposalResultListItem { private final ProposalVoteResult proposalVoteResult; private final BsqFormatter bsqFormatter; @Getter private EvaluatedProposal evaluatedProposal; - public CycleListItem(EvaluatedProposal evaluatedProposal, BsqFormatter bsqFormatter) { + public ProposalResultListItem(EvaluatedProposal evaluatedProposal, BsqFormatter bsqFormatter) { this.evaluatedProposal = evaluatedProposal; proposalVoteResult = evaluatedProposal.getProposalVoteResult(); this.bsqFormatter = bsqFormatter; From e1f23be46e850198eff8af2276307672d42f0611 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Thu, 19 Jul 2018 16:44:35 +0200 Subject: [PATCH 152/197] Add vote result view --- src/main/java/bisq/desktop/bisq.css | 5 +- .../desktop/components/HyperlinkWithIcon.java | 6 +- .../dao/results/BaseResultsTableView.java | 110 +++++ ...java => ProposalResultsDetailsWindow.java} | 10 +- .../desktop/main/dao/results/ResultsView.fxml | 20 +- .../desktop/main/dao/results/ResultsView.java | 158 ++++--- .../EvaluatedProposalWithDecryptedVote.java | 46 ++ .../combo/VotesPerProposalListItem.java | 84 ++++ .../combo/VotesPerProposalTableView.java | 193 ++++++++ .../dao/results/model/ResultsOfCycle.java | 7 +- .../proposal/ProposalResultDisplay.java | 427 ------------------ .../ProposalResultsListItem.java} | 14 +- .../proposals/ProposalResultsTableView.java | 327 ++++++++++++++ .../main/dao/results/votes/VotesListItem.java | 113 +++++ .../dao/results/votes/VotesTableView.java | 289 ++++++++++++ src/main/java/bisq/desktop/util/GUIUtil.java | 12 + 16 files changed, 1321 insertions(+), 500 deletions(-) create mode 100644 src/main/java/bisq/desktop/main/dao/results/BaseResultsTableView.java rename src/main/java/bisq/desktop/main/dao/results/{proposal/ProposalResultDetailsWindow.java => ProposalResultsDetailsWindow.java} (86%) create mode 100644 src/main/java/bisq/desktop/main/dao/results/combo/EvaluatedProposalWithDecryptedVote.java create mode 100644 src/main/java/bisq/desktop/main/dao/results/combo/VotesPerProposalListItem.java create mode 100644 src/main/java/bisq/desktop/main/dao/results/combo/VotesPerProposalTableView.java delete mode 100644 src/main/java/bisq/desktop/main/dao/results/proposal/ProposalResultDisplay.java rename src/main/java/bisq/desktop/main/dao/results/{proposal/ProposalResultListItem.java => proposals/ProposalResultsListItem.java} (87%) create mode 100644 src/main/java/bisq/desktop/main/dao/results/proposals/ProposalResultsTableView.java create mode 100644 src/main/java/bisq/desktop/main/dao/results/votes/VotesListItem.java create mode 100644 src/main/java/bisq/desktop/main/dao/results/votes/VotesTableView.java diff --git a/src/main/java/bisq/desktop/bisq.css b/src/main/java/bisq/desktop/bisq.css index ab34bbd487d..2d70ef65e45 100644 --- a/src/main/java/bisq/desktop/bisq.css +++ b/src/main/java/bisq/desktop/bisq.css @@ -395,6 +395,10 @@ bg color of non edit textFields: fafafa -fx-text-fill: -bs-error-red; } +.dao-ignored-icon { + -fx-text-fill: -bs-medium-grey; +} + .version { -fx-text-fill: black; -fx-underline: false; @@ -1354,4 +1358,3 @@ textfield */ .compensation-root { -fx-background-insets: 0, 0 0 0 0 } - diff --git a/src/main/java/bisq/desktop/components/HyperlinkWithIcon.java b/src/main/java/bisq/desktop/components/HyperlinkWithIcon.java index 2a6a1963b1b..be5e5004f33 100644 --- a/src/main/java/bisq/desktop/components/HyperlinkWithIcon.java +++ b/src/main/java/bisq/desktop/components/HyperlinkWithIcon.java @@ -26,7 +26,11 @@ import javafx.geometry.Insets; +import lombok.Getter; + public class HyperlinkWithIcon extends Hyperlink { + @Getter + private final Label icon; public HyperlinkWithIcon(String text) { this(text, AwesomeIcon.INFO_SIGN); @@ -36,7 +40,7 @@ public HyperlinkWithIcon(String text, AwesomeIcon awesomeIcon) { super(text); - Label icon = new Label(); + icon = new Label(); AwesomeDude.setIcon(icon, awesomeIcon); icon.setMinWidth(20); icon.setOpacity(0.7); diff --git a/src/main/java/bisq/desktop/main/dao/results/BaseResultsTableView.java b/src/main/java/bisq/desktop/main/dao/results/BaseResultsTableView.java new file mode 100644 index 00000000000..2b862f8f4c0 --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/results/BaseResultsTableView.java @@ -0,0 +1,110 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.desktop.main.dao.results; + +import bisq.desktop.components.AutoTooltipLabel; +import bisq.desktop.components.TableGroupHeadline; +import bisq.desktop.main.dao.results.model.ResultsOfCycle; +import bisq.desktop.util.GUIUtil; + +import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.dao.DaoFacade; +import bisq.core.locale.Res; +import bisq.core.util.BsqFormatter; + +import javafx.scene.control.TableView; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.Priority; + +import javafx.geometry.Insets; + +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.collections.transformation.SortedList; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public abstract class BaseResultsTableView { + protected final GridPane gridPane; + protected final BsqWalletService bsqWalletService; + protected final DaoFacade daoFacade; + protected final BsqFormatter bsqFormatter; + + protected int gridRow; + protected int gridRowStartIndex; + + + protected final ObservableList itemList = FXCollections.observableArrayList(); + private final SortedList sortedList = new SortedList<>(itemList); + protected ResultsOfCycle resultsOfCycle; + protected TableView tableView; + + protected abstract String getTitle(); + + protected abstract void fillList(); + + protected abstract void createColumns(TableView tableView); + + public BaseResultsTableView(GridPane gridPane, BsqWalletService bsqWalletService, DaoFacade daoFacade, BsqFormatter bsqFormatter) { + this.gridPane = gridPane; + this.bsqWalletService = bsqWalletService; + this.daoFacade = daoFacade; + this.bsqFormatter = bsqFormatter; + } + + public int createAllFields(int gridRowStartIndex, ResultsOfCycle resultsOfCycle) { + this.resultsOfCycle = resultsOfCycle; + this.gridRowStartIndex = gridRowStartIndex; + this.gridRow = gridRowStartIndex; + + removeAllFields(); + createTableView(); + fillList(); + GUIUtil.setFitToRowsForTableView(tableView, 33, 28, 80); + + return gridRow; + } + + private void createTableView() { + TableGroupHeadline headline = new TableGroupHeadline(getTitle()); + GridPane.setRowIndex(headline, gridRow); + GridPane.setMargin(headline, new Insets(15, -10, -10, -10)); + GridPane.setColumnSpan(headline, 2); + gridPane.getChildren().add(headline); + + tableView = new TableView<>(); + tableView.setPlaceholder(new AutoTooltipLabel(Res.get("table.placeholder.noData"))); + tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); + + createColumns(tableView); + GridPane.setRowIndex(tableView, gridRow); + GridPane.setMargin(tableView, new Insets(35, -10, 5, -10)); + GridPane.setColumnSpan(tableView, 2); + GridPane.setHgrow(tableView, Priority.SOMETIMES); + gridPane.getChildren().add(tableView); + + tableView.setItems(sortedList); + sortedList.comparatorProperty().bind(tableView.comparatorProperty()); + } + + private void removeAllFields() { + GUIUtil.removeChildrenFromGridPaneRows(gridPane, gridRowStartIndex, gridRow); + gridRow = gridRowStartIndex; + } +} diff --git a/src/main/java/bisq/desktop/main/dao/results/proposal/ProposalResultDetailsWindow.java b/src/main/java/bisq/desktop/main/dao/results/ProposalResultsDetailsWindow.java similarity index 86% rename from src/main/java/bisq/desktop/main/dao/results/proposal/ProposalResultDetailsWindow.java rename to src/main/java/bisq/desktop/main/dao/results/ProposalResultsDetailsWindow.java index f50078b104b..100f9efada5 100644 --- a/src/main/java/bisq/desktop/main/dao/results/proposal/ProposalResultDetailsWindow.java +++ b/src/main/java/bisq/desktop/main/dao/results/ProposalResultsDetailsWindow.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.desktop.main.dao.results.proposal; +package bisq.desktop.main.dao.results; import bisq.desktop.main.overlays.Overlay; import bisq.desktop.util.FormBuilder; @@ -30,7 +30,7 @@ import static bisq.desktop.util.FormBuilder.addTitledGroupBg; -class ProposalResultDetailsWindow extends Overlay { +public class ProposalResultsDetailsWindow extends Overlay { private final BsqFormatter bsqFormatter; private final EvaluatedProposal evaluatedProposal; @@ -40,7 +40,7 @@ class ProposalResultDetailsWindow extends Overlay { // Public API /////////////////////////////////////////////////////////////////////////////////////////// - public ProposalResultDetailsWindow(BsqFormatter bsqFormatter, EvaluatedProposal evaluatedProposal) { + public ProposalResultsDetailsWindow(BsqFormatter bsqFormatter, EvaluatedProposal evaluatedProposal) { this.bsqFormatter = bsqFormatter; this.evaluatedProposal = evaluatedProposal; type = Type.Confirmation; @@ -68,10 +68,10 @@ protected void createGridPane() { } private void addContent() { - addTitledGroupBg(gridPane, ++rowIndex, 5, Res.get("dao.results.result.detail.header")); + addTitledGroupBg(gridPane, ++rowIndex, 5, Res.get("dao.results.proposals.detail.header")); //TODO impl - //addLabelTextField(gridPane, rowIndex, Res.get("dao.results.result.detail.header"), evaluatedProposal.getProposal().getName(), Layout.FIRST_ROW_DISTANCE); + //addLabelTextField(gridPane, rowIndex, Res.get("dao.results.proposals.detail.header"), evaluatedProposal.getProposal().getName(), Layout.FIRST_ROW_DISTANCE); Button closeButton = FormBuilder.addButtonAfterGroup(gridPane, ++rowIndex, Res.get("shared.close")); diff --git a/src/main/java/bisq/desktop/main/dao/results/ResultsView.fxml b/src/main/java/bisq/desktop/main/dao/results/ResultsView.fxml index 4b19a62a649..6960acea524 100644 --- a/src/main/java/bisq/desktop/main/dao/results/ResultsView.fxml +++ b/src/main/java/bisq/desktop/main/dao/results/ResultsView.fxml @@ -17,11 +17,7 @@ ~ along with Bisq. If not, see . --> - - - - - - +--> + + + + + + + + + diff --git a/src/main/java/bisq/desktop/main/dao/results/ResultsView.java b/src/main/java/bisq/desktop/main/dao/results/ResultsView.java index 4c1dab92601..73197e3754c 100644 --- a/src/main/java/bisq/desktop/main/dao/results/ResultsView.java +++ b/src/main/java/bisq/desktop/main/dao/results/ResultsView.java @@ -24,8 +24,12 @@ import bisq.desktop.components.AutoTooltipLabel; import bisq.desktop.components.AutoTooltipTableColumn; import bisq.desktop.components.TableGroupHeadline; +import bisq.desktop.main.dao.results.combo.VotesPerProposalTableView; import bisq.desktop.main.dao.results.model.ResultsOfCycle; -import bisq.desktop.main.dao.results.proposal.ProposalResultDisplay; +import bisq.desktop.main.dao.results.proposals.ProposalResultsTableView; +import bisq.desktop.main.dao.results.votes.VotesTableView; +import bisq.desktop.util.FormBuilder; +import bisq.desktop.util.GUIUtil; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; @@ -36,21 +40,31 @@ import bisq.core.dao.state.period.CycleService; import bisq.core.dao.voting.proposal.Proposal; import bisq.core.dao.voting.proposal.ProposalService; +import bisq.core.dao.voting.proposal.ProposalType; import bisq.core.dao.voting.proposal.storage.appendonly.ProposalPayload; +import bisq.core.dao.voting.voteresult.DecryptedVote; import bisq.core.dao.voting.voteresult.EvaluatedProposal; import bisq.core.dao.voting.voteresult.VoteResultService; import bisq.core.locale.Res; +import bisq.core.user.Preferences; import bisq.core.util.BsqFormatter; +import org.bitcoinj.core.Coin; + import javax.inject.Inject; +import javafx.fxml.FXML; + import javafx.scene.control.ScrollPane; import javafx.scene.control.TableCell; import javafx.scene.control.TableColumn; import javafx.scene.control.TableView; +import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.ColumnConstraints; import javafx.scene.layout.GridPane; import javafx.scene.layout.Priority; +import javafx.geometry.HPos; import javafx.geometry.Insets; import javafx.beans.property.ReadOnlyObjectWrapper; @@ -64,11 +78,16 @@ import java.util.Collections; import java.util.Comparator; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; @FxmlView -public class ResultsView extends ActivatableViewAndModel implements BsqStateListener { +public class ResultsView extends ActivatableViewAndModel implements BsqStateListener { + @FXML + private ScrollPane scrollPane; + private final DaoFacade daoFacade; // TODO use daoFacade once dev work completed private final BsqStateService bsqStateService; @@ -76,8 +95,10 @@ public class ResultsView extends ActivatableViewAndModel private final VoteResultService voteResultService; private final ProposalService proposalService; private final BsqWalletService bsqWalletService; + private final Preferences preferences; private final BsqFormatter bsqFormatter; + private int gridRow = 0; private TableView tableView; @@ -85,10 +106,10 @@ public class ResultsView extends ActivatableViewAndModel private final SortedList sortedList = new SortedList<>(itemList); private ChangeListener selectedItemListener; - private GridPane resultGridPane; - private ProposalResultDisplay proposalsDisplay; - private ScrollPane resultDisplayView; - private boolean resultDisplayInitialized; + private VotesPerProposalTableView votesPerProposalTableView; + private ProposalResultsTableView proposalResultsTableView; + private VotesTableView votesTableView; + private GridPane gridPane; /////////////////////////////////////////////////////////////////////////////////////////// @@ -102,6 +123,7 @@ private ResultsView(DaoFacade daoFacade, VoteResultService voteResultService, ProposalService proposalService, BsqWalletService bsqWalletService, + Preferences preferences, BsqFormatter bsqFormatter) { this.daoFacade = daoFacade; this.bsqStateService = bsqStateService; @@ -109,6 +131,7 @@ private ResultsView(DaoFacade daoFacade, this.voteResultService = voteResultService; this.proposalService = proposalService; this.bsqWalletService = bsqWalletService; + this.preferences = preferences; this.bsqFormatter = bsqFormatter; } @@ -116,11 +139,12 @@ private ResultsView(DaoFacade daoFacade, public void initialize() { daoFacade.addBsqStateListener(this); - resultGridPane = new GridPane(); - createResultsTable(); - createResultDisplay(); + createCyclesTable(); - selectedItemListener = (observable, oldValue, newValue) -> onCycleListItemSelected(newValue); + votesPerProposalTableView = new VotesPerProposalTableView(gridPane, bsqWalletService, daoFacade, bsqStateService, bsqFormatter); + proposalResultsTableView = new ProposalResultsTableView(gridPane, bsqWalletService, daoFacade, bsqFormatter); + votesTableView = new VotesTableView(gridPane, bsqWalletService, daoFacade, bsqStateService, preferences, bsqFormatter); + selectedItemListener = (observable, oldValue, newValue) -> onResultsListItemSelected(newValue); } @Override @@ -161,12 +185,35 @@ public void onParseBlockChainComplete() { // UI handlers /////////////////////////////////////////////////////////////////////////////////////////// - private void onCycleListItemSelected(ResultsListItem item) { - if (item != null) - createAllFieldsOnResultDisplay(item); - else - hideResultDisplay(); - + private void onResultsListItemSelected(ResultsListItem item) { + removeDetailsViews(); + if (item != null) { + ResultsOfCycle resultsOfCycle = item.getResultsOfCycle(); + + gridRow = votesPerProposalTableView.createAllFields(++gridRow, resultsOfCycle); + gridRow = proposalResultsTableView.createAllFields(++gridRow, resultsOfCycle); + gridRow = votesTableView.createAllFields(++gridRow, resultsOfCycle); + + Map requiredThresholdByType = new HashMap<>(); + resultsOfCycle.getEvaluatedProposals().forEach(e -> { + requiredThresholdByType.putIfAbsent(e.getProposal().getType(), e.getRequiredThreshold()); + }); + requiredThresholdByType.forEach((key, value) -> { + String title = Res.get("dao.results.proposals.requiredThreshold." + key.name()); + String requiredThreshold = String.valueOf(value / 100) + "%"; + FormBuilder.addLabelTextField(gridPane, ++gridRow, title, requiredThreshold, 0); + }); + + Map requiredQuorumByType = new HashMap<>(); + resultsOfCycle.getEvaluatedProposals().forEach(e -> { + requiredQuorumByType.putIfAbsent(e.getProposal().getType(), e.getRequiredQuorum()); + }); + requiredQuorumByType.forEach((key, value) -> { + String title = Res.get("dao.results.proposals.requiredQuorum." + key.name()); + String requiredQuorum = bsqFormatter.formatCoinWithCode(Coin.valueOf(value)); + FormBuilder.addLabelTextField(gridPane, ++gridRow, title, requiredQuorum); + }); + } } @@ -174,38 +221,47 @@ private void onCycleListItemSelected(ResultsListItem item) { // Create views /////////////////////////////////////////////////////////////////////////////////////////// - private void createResultsTable() { - TableGroupHeadline headline = new TableGroupHeadline(Res.get("dao.results.results.header")); - GridPane.setRowIndex(headline, ++gridRow); + private void createCyclesTable() { + gridPane = new GridPane(); + + gridPane.setHgap(5); + gridPane.setVgap(5); + + gridPane.setPadding(new Insets(15, 25, 10, 25)); + + ColumnConstraints columnConstraints1 = new ColumnConstraints(); + columnConstraints1.setHalignment(HPos.RIGHT); + columnConstraints1.setHgrow(Priority.SOMETIMES); + + columnConstraints1.setMinWidth(140); + + ColumnConstraints columnConstraints2 = new ColumnConstraints(); + columnConstraints2.setHgrow(Priority.ALWAYS); + columnConstraints1.setMinWidth(300); + + gridPane.getColumnConstraints().addAll(columnConstraints1, columnConstraints2); + scrollPane.setContent(gridPane); + + TableGroupHeadline headline = new TableGroupHeadline(Res.get("dao.results.cycles.header")); + GridPane.setRowIndex(headline, gridRow); GridPane.setMargin(headline, new Insets(0, -10, -10, -10)); GridPane.setColumnSpan(headline, 2); - root.getChildren().add(headline); + gridPane.getChildren().add(headline); tableView = new TableView<>(); tableView.setPlaceholder(new AutoTooltipLabel(Res.get("table.placeholder.noData"))); tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); - tableView.setPrefHeight(200); createColumns(tableView); GridPane.setRowIndex(tableView, gridRow); GridPane.setMargin(tableView, new Insets(20, -10, 5, -10)); GridPane.setColumnSpan(tableView, 2); - GridPane.setHgrow(tableView, Priority.ALWAYS); - root.getChildren().add(tableView); + gridPane.getChildren().add(tableView); tableView.setItems(sortedList); sortedList.comparatorProperty().bind(tableView.comparatorProperty()); } - private void createResultDisplay() { - proposalsDisplay = new ProposalResultDisplay(resultGridPane, bsqWalletService, daoFacade, bsqFormatter); - resultDisplayView = proposalsDisplay.getView(); - GridPane.setMargin(resultDisplayView, new Insets(10, -10, 0, -10)); - GridPane.setRowIndex(resultDisplayView, ++gridRow); - GridPane.setColumnSpan(resultDisplayView, 2); - root.getChildren().add(resultDisplayView); - } - /////////////////////////////////////////////////////////////////////////////////////////// // Private @@ -215,6 +271,7 @@ private void fillCycleList() { itemList.clear(); bsqStateService.getCycles().forEach(this::addCycleListItem); Collections.reverse(itemList); + GUIUtil.setFitToRowsForTableView(tableView, 24, 28, 80); } private void addCycleListItem(Cycle cycle) { @@ -227,6 +284,11 @@ private void addCycleListItem(Cycle cycle) { .filter(evaluatedProposal -> cycleService.isTxInCycle(cycle, evaluatedProposal.getProposal().getTxId())) .collect(Collectors.toList()); + List decryptedVotesForCycle = voteResultService.getAllDecryptedVotes().stream() + .filter(decryptedVote -> cycleService.isTxInCycle(cycle, decryptedVote.getBlindVoteTxId())) + .filter(decryptedVote -> cycleService.isTxInCycle(cycle, decryptedVote.getVoteRevealTxId())) + .collect(Collectors.toList()); + long cycleStartTime = bsqStateService.getBlockAtHeight(cycle.getHeightOfFirstBlock()) .map(e -> e.getTime() * 1000) .orElse(0L); @@ -235,25 +297,15 @@ private void addCycleListItem(Cycle cycle) { cycleIndex, cycleStartTime, proposalsForCycle, - evaluatedProposalsForCycle); + evaluatedProposalsForCycle, + decryptedVotesForCycle); ResultsListItem resultsListItem = new ResultsListItem(resultsOfCycle, bsqFormatter); itemList.add(resultsListItem); } - private void hideResultDisplay() { - if (resultDisplayInitialized) { - proposalsDisplay.removeAllFields(); - resultDisplayView.setVisible(false); - resultDisplayView.setManaged(false); - } - } - - private void createAllFieldsOnResultDisplay(ResultsListItem resultsListItem) { - resultDisplayView.setVisible(true); - resultDisplayView.setManaged(true); - - proposalsDisplay.createAllFields(0, resultsListItem.getResultsOfCycle()); - resultDisplayInitialized = true; + private void removeDetailsViews() { + GUIUtil.removeChildrenFromGridPaneRows(gridPane, 1, gridRow); + gridRow = 0; } @@ -262,7 +314,7 @@ private void createAllFieldsOnResultDisplay(ResultsListItem resultsListItem) { /////////////////////////////////////////////////////////////////////////////////////////// private void createColumns(TableView tableView) { - TableColumn cycleColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.results.table.header.cycle")); + TableColumn cycleColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.cycles.table.header.cycle")); cycleColumn.setMinWidth(160); cycleColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); cycleColumn.setCellFactory( @@ -286,7 +338,7 @@ public void updateItem(final ResultsListItem item, boolean empty) { cycleColumn.setComparator(Comparator.comparing(ResultsListItem::getCycleStartTime)); tableView.getColumns().add(cycleColumn); - TableColumn proposalsColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.results.table.header.numProposals")); + TableColumn proposalsColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.cycles.table.header.numProposals")); proposalsColumn.setMinWidth(90); proposalsColumn.setMaxWidth(90); proposalsColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); @@ -311,7 +363,7 @@ public void updateItem(final ResultsListItem item, boolean empty) { proposalsColumn.setComparator(Comparator.comparing(ResultsListItem::getNumProposals)); tableView.getColumns().add(proposalsColumn); - TableColumn votesColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.results.table.header.numVotes")); + TableColumn votesColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.cycles.table.header.numVotes")); votesColumn.setMinWidth(70); votesColumn.setMaxWidth(70); votesColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); @@ -336,7 +388,8 @@ public void updateItem(final ResultsListItem item, boolean empty) { votesColumn.setComparator(Comparator.comparing(ResultsListItem::getNumProposals)); tableView.getColumns().add(votesColumn); - TableColumn stakeColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.results.table.header.stake")); + TableColumn stakeColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.cycles.table.header.stake")); + stakeColumn.setMinWidth(70); stakeColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); stakeColumn.setCellFactory( new Callback, TableCell issuanceColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.results.table.header.issuance")); + TableColumn issuanceColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.cycles.table.header.issuance")); + issuanceColumn.setMinWidth(70); issuanceColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); issuanceColumn.setCellFactory( new Callback, TableCell. + */ + +package bisq.desktop.main.dao.results.combo; + +import bisq.core.dao.voting.voteresult.DecryptedVote; +import bisq.core.dao.voting.voteresult.EvaluatedProposal; + +import java.util.HashMap; +import java.util.Map; + +import lombok.Data; +import lombok.Setter; + +import javax.annotation.Nullable; + +@Data +public class EvaluatedProposalWithDecryptedVote { + private final EvaluatedProposal evaluatedProposal; + @Setter + @Nullable + private DecryptedVote decryptedVote; + private Map decryptedVotesByBlindVoteTxId = new HashMap<>(); + + public EvaluatedProposalWithDecryptedVote(EvaluatedProposal evaluatedProposal) { + this.evaluatedProposal = evaluatedProposal; + } + + public void addDecryptedVote(DecryptedVote decryptedVote) { + decryptedVotesByBlindVoteTxId.put(decryptedVote.getBlindVoteTxId(), decryptedVote); + } +} diff --git a/src/main/java/bisq/desktop/main/dao/results/combo/VotesPerProposalListItem.java b/src/main/java/bisq/desktop/main/dao/results/combo/VotesPerProposalListItem.java new file mode 100644 index 00000000000..1000023bc78 --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/results/combo/VotesPerProposalListItem.java @@ -0,0 +1,84 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.desktop.main.dao.results.combo; + +import bisq.core.dao.voting.ballot.Ballot; +import bisq.core.dao.voting.ballot.vote.BooleanVote; +import bisq.core.dao.voting.proposal.Proposal; +import bisq.core.dao.voting.voteresult.DecryptedVote; + +import bisq.common.util.Tuple2; + +import de.jensd.fx.fontawesome.AwesomeIcon; + +import java.util.Map; +import java.util.Optional; + +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class VotesPerProposalListItem { + @Getter + private final EvaluatedProposalWithDecryptedVote evaluatedProposalWithDecryptedVote; + @Getter + private final Proposal proposal; + private final String proposalTxId; + + public VotesPerProposalListItem(EvaluatedProposalWithDecryptedVote evaluatedProposalWithDecryptedVote) { + this.evaluatedProposalWithDecryptedVote = evaluatedProposalWithDecryptedVote; + proposal = evaluatedProposalWithDecryptedVote.getEvaluatedProposal().getProposal(); + proposalTxId = proposal.getTxId(); + } + + public String getProposalInfo() { + return proposal.getName(); + } + + public Tuple2 getIconStyleTuple(String blindVoteTxId) { + Optional isAccepted = Optional.empty(); + Map map = evaluatedProposalWithDecryptedVote.getDecryptedVotesByBlindVoteTxId(); + if (map.containsKey(blindVoteTxId)) { + DecryptedVote decryptedVote = map.get(blindVoteTxId); + isAccepted = decryptedVote.getBallotList().stream() + .filter(ballot -> ballot.getProposalTxId().equals(proposalTxId)) + .map(Ballot::getVote) + .filter(vote -> vote instanceof BooleanVote) + .map(vote -> (BooleanVote) vote) + .map(BooleanVote::isAccepted) + .findAny(); + } + if (isAccepted.isPresent()) { + if (isAccepted.get()) + return new Tuple2<>(AwesomeIcon.OK_SIGN, "dao-accepted-icon"); + else + return new Tuple2<>(AwesomeIcon.REMOVE_SIGN, "dao-rejected-icon"); + } else { + return new Tuple2<>(AwesomeIcon.MINUS_SIGN, "dao-ignored-icon"); + } + } + + @Override + public String toString() { + return "VotesPerProposalListItem{" + + "\n evaluatedProposalWithDecryptedVote=" + evaluatedProposalWithDecryptedVote + + "\n}"; + } + + +} diff --git a/src/main/java/bisq/desktop/main/dao/results/combo/VotesPerProposalTableView.java b/src/main/java/bisq/desktop/main/dao/results/combo/VotesPerProposalTableView.java new file mode 100644 index 00000000000..1886b636a93 --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/results/combo/VotesPerProposalTableView.java @@ -0,0 +1,193 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.desktop.main.dao.results.combo; + +import bisq.desktop.components.AutoTooltipTableColumn; +import bisq.desktop.main.dao.results.BaseResultsTableView; +import bisq.desktop.main.dao.results.ProposalResultsDetailsWindow; +import bisq.desktop.main.dao.results.model.ResultsOfCycle; +import bisq.desktop.util.GUIUtil; + +import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.dao.DaoFacade; +import bisq.core.dao.state.BsqStateService; +import bisq.core.dao.voting.voteresult.DecryptedVote; +import bisq.core.dao.voting.voteresult.EvaluatedProposal; +import bisq.core.locale.Res; +import bisq.core.util.BsqFormatter; + +import bisq.common.util.Tuple2; + +import org.bitcoinj.core.Coin; + +import de.jensd.fx.fontawesome.AwesomeDude; +import de.jensd.fx.fontawesome.AwesomeIcon; + +import javafx.scene.control.Hyperlink; +import javafx.scene.control.Label; +import javafx.scene.control.TableCell; +import javafx.scene.control.TableColumn; +import javafx.scene.control.TableView; +import javafx.scene.control.Tooltip; +import javafx.scene.layout.GridPane; + +import javafx.beans.property.ReadOnlyObjectWrapper; + +import javafx.util.Callback; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class VotesPerProposalTableView extends BaseResultsTableView { + + private final BsqStateService bsqStateService; + + public VotesPerProposalTableView(GridPane gridPane, BsqWalletService bsqWalletService, DaoFacade daoFacade, + BsqStateService bsqStateService, BsqFormatter bsqFormatter) { + super(gridPane, bsqWalletService, daoFacade, bsqFormatter); + this.bsqStateService = bsqStateService; + } + + @Override + protected String getTitle() { + return Res.get("dao.results.combo.header"); + } + + @Override + protected void fillList() { + Map map = resultsOfCycle.getEvaluatedProposals().stream() + .collect(Collectors.toMap(EvaluatedProposal::getProposalTxId, + EvaluatedProposalWithDecryptedVote::new)); + + resultsOfCycle.getDecryptedVotesForCycle() + .forEach(decryptedVote -> { + decryptedVote.getBallotList().stream().forEach(ballot -> { + EvaluatedProposalWithDecryptedVote evaluatedProposalWithDecryptedVote = map.get(ballot.getProposalTxId()); + evaluatedProposalWithDecryptedVote.addDecryptedVote(decryptedVote); + }); + }); + + itemList.setAll(map.values().stream() + .map(VotesPerProposalListItem::new) + .collect(Collectors.toList())); + + itemList.sort(Comparator.comparing(votesPerProposalListItem -> votesPerProposalListItem.getProposal().getCreationDate())); + } + + + public int createAllFields(int gridRowStartIndex, ResultsOfCycle resultsOfCycle) { + super.createAllFields(gridRowStartIndex, resultsOfCycle); + + createColumnsFromData(tableView); + + GUIUtil.setFitToRowsForTableView(tableView, 30, 28, 80); + + return gridRow; + } + + private void createColumnsFromData(TableView tableView) { + TableColumn votesColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.combo.table.proposals")); + votesColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + votesColumn.setSortable(false); + votesColumn.setMinWidth(150); + votesColumn.setCellFactory( + new Callback, TableCell>() { + + @Override + public TableCell call( + TableColumn column) { + return new TableCell() { + private Hyperlink hyperlinkWithIcon; + + @Override + public void updateItem(final VotesPerProposalListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null && !empty) { + hyperlinkWithIcon = new Hyperlink(item.getProposalInfo()); + hyperlinkWithIcon.setOnAction(event -> new ProposalResultsDetailsWindow(bsqFormatter, + item.getEvaluatedProposalWithDecryptedVote().getEvaluatedProposal()).show()); + hyperlinkWithIcon.setTooltip(new Tooltip(Res.get("tooltip.openPopupForDetails"))); + + setGraphic(hyperlinkWithIcon); + } else { + setGraphic(null); + if (hyperlinkWithIcon != null) + hyperlinkWithIcon.setOnAction(null); + } + } + }; + } + }); + tableView.getColumns().add(votesColumn); + + List list = new ArrayList<>(resultsOfCycle.getDecryptedVotesForCycle()); + list.sort(Comparator.comparing(DecryptedVote::getBlindVoteTxId)); + AtomicInteger index = new AtomicInteger(); + list.forEach(decryptedVote -> { + index.getAndIncrement(); + String stake = bsqFormatter.formatCoinWithCode(Coin.valueOf(decryptedVote.getStake() + decryptedVote.getMerit(bsqStateService))); + String header = "Vote " + index.get() + " (" + stake + ")"; + TableColumn column = new AutoTooltipTableColumn<>(header); + column.setSortable(false); + column.setMinWidth(150); + column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + column.setCellFactory( + new Callback, TableCell>() { + + @Override + public TableCell call( + TableColumn column) { + return new TableCell() { + private Label icon; + + @Override + public void updateItem(final VotesPerProposalListItem item, boolean empty) { + super.updateItem(item, empty); + + if (item != null && !empty) { + String blindVoteTxId = decryptedVote.getBlindVoteTxId(); + Tuple2 iconStyleTuple = item.getIconStyleTuple(blindVoteTxId); + icon = new Label(); + AwesomeDude.setIcon(icon, iconStyleTuple.first); + icon.getStyleClass().add(iconStyleTuple.second); + setGraphic(icon); + } else { + setGraphic(null); + } + } + }; + } + }); + tableView.getColumns().add(column); + }); + } + + @Override + protected void createColumns(TableView tableView) { + // do nothing as we create the columns dynamically + } +} diff --git a/src/main/java/bisq/desktop/main/dao/results/model/ResultsOfCycle.java b/src/main/java/bisq/desktop/main/dao/results/model/ResultsOfCycle.java index 5c67cdef68d..2530c7af755 100644 --- a/src/main/java/bisq/desktop/main/dao/results/model/ResultsOfCycle.java +++ b/src/main/java/bisq/desktop/main/dao/results/model/ResultsOfCycle.java @@ -19,6 +19,7 @@ import bisq.core.dao.state.period.Cycle; import bisq.core.dao.voting.proposal.Proposal; +import bisq.core.dao.voting.voteresult.DecryptedVote; import bisq.core.dao.voting.voteresult.EvaluatedProposal; import bisq.core.util.BsqFormatter; @@ -42,16 +43,20 @@ public class ResultsOfCycle { // Proposals which ended up in voting private final List evaluatedProposals; + private final List decryptedVotesForCycle; + public ResultsOfCycle(Cycle cycle, int cycleIndex, long cycleStartTime, List proposals, - List evaluatedProposals) { + List evaluatedProposals, + List decryptedVotesForCycle) { this.cycle = cycle; this.cycleIndex = cycleIndex; this.cycleStartTime = cycleStartTime; this.proposals = proposals; this.evaluatedProposals = evaluatedProposals; + this.decryptedVotesForCycle = decryptedVotesForCycle; numVotes = evaluatedProposals.stream() .mapToInt(e -> e.getProposalVoteResult().getNumActiveVotes()) diff --git a/src/main/java/bisq/desktop/main/dao/results/proposal/ProposalResultDisplay.java b/src/main/java/bisq/desktop/main/dao/results/proposal/ProposalResultDisplay.java deleted file mode 100644 index dd8e7b96475..00000000000 --- a/src/main/java/bisq/desktop/main/dao/results/proposal/ProposalResultDisplay.java +++ /dev/null @@ -1,427 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.desktop.main.dao.results.proposal; - -import bisq.desktop.components.AutoTooltipLabel; -import bisq.desktop.components.AutoTooltipTableColumn; -import bisq.desktop.components.TableGroupHeadline; -import bisq.desktop.main.dao.proposal.ProposalDetailsWindow; -import bisq.desktop.main.dao.results.model.ResultsOfCycle; -import bisq.desktop.util.FormBuilder; -import bisq.desktop.util.GUIUtil; - -import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.DaoFacade; -import bisq.core.dao.voting.proposal.ProposalType; -import bisq.core.locale.Res; -import bisq.core.util.BsqFormatter; - -import org.bitcoinj.core.Coin; - -import de.jensd.fx.fontawesome.AwesomeDude; - -import javafx.scene.control.Hyperlink; -import javafx.scene.control.Label; -import javafx.scene.control.ScrollPane; -import javafx.scene.control.TableCell; -import javafx.scene.control.TableColumn; -import javafx.scene.control.TableView; -import javafx.scene.control.Tooltip; -import javafx.scene.layout.AnchorPane; -import javafx.scene.layout.ColumnConstraints; -import javafx.scene.layout.GridPane; -import javafx.scene.layout.Priority; - -import javafx.geometry.HPos; -import javafx.geometry.Insets; - -import javafx.beans.property.ReadOnlyObjectWrapper; - -import javafx.collections.FXCollections; -import javafx.collections.ObservableList; -import javafx.collections.transformation.SortedList; - -import javafx.util.Callback; - -import java.util.Comparator; -import java.util.HashMap; -import java.util.Map; -import java.util.stream.Collectors; - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class ProposalResultDisplay { - private final GridPane gridPane; - private final BsqWalletService bsqWalletService; - private final DaoFacade daoFacade; - private final BsqFormatter bsqFormatter; - - private int gridRow; - private int gridRowStartIndex; - - - private final ObservableList itemList = FXCollections.observableArrayList(); - private final SortedList sortedList = new SortedList<>(itemList); - - - public ProposalResultDisplay(GridPane gridPane, BsqWalletService bsqWalletService, DaoFacade daoFacade, BsqFormatter bsqFormatter) { - this.gridPane = gridPane; - this.bsqWalletService = bsqWalletService; - this.daoFacade = daoFacade; - this.bsqFormatter = bsqFormatter; - } - - public void createAllFields(int gridRowStartIndex, ResultsOfCycle resultsOfCycle) { - removeAllFields(); - - this.gridRowStartIndex = gridRowStartIndex; - this.gridRow = gridRowStartIndex; - - createTableView(); - - itemList.setAll(resultsOfCycle.getEvaluatedProposals().stream().map(e -> new ProposalResultListItem(e, bsqFormatter)).collect(Collectors.toList())); - - Map requiredThresholdByType = new HashMap<>(); - resultsOfCycle.getEvaluatedProposals().forEach(e -> { - requiredThresholdByType.putIfAbsent(e.getProposal().getType(), e.getRequiredThreshold()); - }); - Map requiredQuorumByType = new HashMap<>(); - resultsOfCycle.getEvaluatedProposals().forEach(e -> { - requiredQuorumByType.putIfAbsent(e.getProposal().getType(), e.getRequiredQuorum()); - }); - - requiredThresholdByType.forEach((key, value) -> { - String title = Res.get("dao.results.result.requiredThreshold." + key.name()); - String requiredThreshold = String.valueOf(value / 100) + "%"; - FormBuilder.addLabelTextField(gridPane, ++gridRow, title, requiredThreshold, 0); - }); - requiredQuorumByType.forEach((key, value) -> { - String title = Res.get("dao.results.result.requiredQuorum." + key.name()); - String requiredQuorum = bsqFormatter.formatCoinWithCode(Coin.valueOf(value)); - FormBuilder.addLabelTextField(gridPane, ++gridRow, title, requiredQuorum); - }); - } - - private void createTableView() { - TableGroupHeadline headline = new TableGroupHeadline(Res.get("dao.results.result.header")); - GridPane.setRowIndex(headline, gridRow); - GridPane.setMargin(headline, new Insets(0, -10, -10, -10)); - GridPane.setColumnSpan(headline, 2); - gridPane.getChildren().add(headline); - - TableView tableView = new TableView<>(); - tableView.setPlaceholder(new AutoTooltipLabel(Res.get("table.placeholder.noData"))); - tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); - tableView.setPrefHeight(200); - - createColumns(tableView); - GridPane.setRowIndex(tableView, gridRow); - GridPane.setMargin(tableView, new Insets(20, -10, 5, -10)); - GridPane.setColumnSpan(tableView, 2); - GridPane.setHgrow(tableView, Priority.ALWAYS); - gridPane.getChildren().add(tableView); - - tableView.setItems(sortedList); - sortedList.comparatorProperty().bind(tableView.comparatorProperty()); - } - - private void createColumns(TableView tableView) { - TableColumn proposalColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.result.table.header.proposalOwnerName")); - proposalColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - proposalColumn.setCellFactory( - new Callback, TableCell>() { - @Override - public TableCell call( - TableColumn column) { - return new TableCell() { - @Override - public void updateItem(final ProposalResultListItem item, boolean empty) { - super.updateItem(item, empty); - if (item != null) - setText(item.getProposalOwnerName()); - else - setText(""); - } - }; - } - }); - proposalColumn.setComparator(Comparator.comparing(ProposalResultListItem::getProposalOwnerName)); - tableView.getColumns().add(proposalColumn); - - TableColumn proposalIdColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.result.table.header.proposalId")); - proposalIdColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - - proposalIdColumn.setCellFactory( - new Callback, TableCell>() { - - @Override - public TableCell call(TableColumn column) { - return new TableCell() { - private Hyperlink field; - - @Override - public void updateItem(final ProposalResultListItem item, boolean empty) { - super.updateItem(item, empty); - - // cycleDetailsWindow.show(item.getEvaluatedProposal()) - if (item != null && !empty) { - field = new Hyperlink(item.getProposalId()); - - //TODO setId or getStyleClass.add does not apply color... - //field.getStyleClass().add(item.getColorStyleClass()); - //field.setId(item.getColorStyleClass()); - field.setStyle(item.getColorStyle()); - field.setOnAction(event -> new ProposalDetailsWindow(bsqFormatter, - bsqWalletService, - item.getEvaluatedProposal().getProposal(), - daoFacade) - .show()); - field.setTooltip(new Tooltip(Res.get("tooltip.openPopupForDetails"))); - setGraphic(field); - } else { - setGraphic(null); - if (field != null) - field.setOnAction(null); - } - } - }; - } - }); - proposalIdColumn.setComparator(Comparator.comparing(ProposalResultListItem::getProposalOwnerName)); - tableView.getColumns().add(proposalIdColumn); - - TableColumn acceptedColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.result.table.header.accepted")); - acceptedColumn.setMinWidth(80); - acceptedColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - acceptedColumn.setCellFactory( - new Callback, TableCell>() { - private Hyperlink field; - - @Override - public TableCell call( - TableColumn column) { - return new TableCell() { - @Override - public void updateItem(final ProposalResultListItem item, boolean empty) { - super.updateItem(item, empty); - if (item != null && !empty) { - field = new Hyperlink(item.getAccepted()); - field.setStyle(item.getColorStyle()); - field.setOnAction(event -> new ProposalResultDetailsWindow(bsqFormatter, item.getEvaluatedProposal()).show()); - field.setTooltip(new Tooltip(Res.get("tooltip.openPopupForDetails"))); - setGraphic(field); - } else { - setGraphic(null); - - //TODO does get called on active items somehow... - //if (field != null) - // field.setOnAction(null); - } - } - }; - } - }); - acceptedColumn.setComparator(Comparator.comparing(ProposalResultListItem::getAccepted)); - tableView.getColumns().add(acceptedColumn); - - TableColumn rejectedColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.result.table.header.rejected")); - rejectedColumn.setMinWidth(80); - rejectedColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - rejectedColumn.setCellFactory( - new Callback, TableCell>() { - private Hyperlink field; - - @Override - public TableCell call( - TableColumn column) { - return new TableCell() { - @Override - public void updateItem(final ProposalResultListItem item, boolean empty) { - super.updateItem(item, empty); - if (item != null && !empty) { - field = new Hyperlink(item.getRejected()); - field.setStyle(item.getColorStyle()); - field.setOnAction(event -> new ProposalResultDetailsWindow(bsqFormatter, item.getEvaluatedProposal()).show()); - field.setTooltip(new Tooltip(Res.get("tooltip.openPopupForDetails"))); - setGraphic(field); - } else { - setGraphic(null); - //TODO does get called on active items somehow... - //if (field != null) - // field.setOnAction(null); - } - } - }; - } - }); - rejectedColumn.setComparator(Comparator.comparing(ProposalResultListItem::getRejected)); - tableView.getColumns().add(rejectedColumn); - - TableColumn thresholdColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.result.table.header.threshold")); - thresholdColumn.setMinWidth(100); - thresholdColumn.setMaxWidth(100); - thresholdColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - thresholdColumn.setCellFactory( - new Callback, TableCell>() { - @Override - public TableCell call( - TableColumn column) { - return new TableCell() { - @Override - public void updateItem(final ProposalResultListItem item, boolean empty) { - super.updateItem(item, empty); - if (item != null) - setText(item.getThreshold()); - else - setText(""); - } - }; - } - }); - thresholdColumn.setComparator(Comparator.comparing(ProposalResultListItem::getThreshold)); - tableView.getColumns().add(thresholdColumn); - - TableColumn quorumColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.result.table.header.quorum")); - quorumColumn.setMinWidth(130); - quorumColumn.setMaxWidth(130); - quorumColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - quorumColumn.setCellFactory( - new Callback, TableCell>() { - @Override - public TableCell call( - TableColumn column) { - return new TableCell() { - @Override - public void updateItem(final ProposalResultListItem item, boolean empty) { - super.updateItem(item, empty); - if (item != null) - setText(item.getQuorum()); - else - setText(""); - } - }; - } - }); - quorumColumn.setComparator(Comparator.comparing(ProposalResultListItem::getThreshold)); - tableView.getColumns().add(quorumColumn); - - TableColumn issuanceColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.result.table.header.issuance")); - issuanceColumn.setMinWidth(130); - issuanceColumn.setMaxWidth(130); - issuanceColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - issuanceColumn.setCellFactory( - new Callback, TableCell>() { - @Override - public TableCell call( - TableColumn column) { - return new TableCell() { - @Override - public void updateItem(final ProposalResultListItem item, boolean empty) { - super.updateItem(item, empty); - if (item != null) - setText(item.getIssuance()); - else - setText(""); - } - }; - } - }); - issuanceColumn.setComparator(Comparator.comparing(ProposalResultListItem::getThreshold)); - tableView.getColumns().add(issuanceColumn); - - - TableColumn resultColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.result.table.header.result")); - resultColumn.setMinWidth(60); - resultColumn.setMaxWidth(60); - resultColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - resultColumn.setCellFactory(new Callback, - TableCell>() { - - @Override - public TableCell call(TableColumn column) { - return new TableCell() { - Label icon; - - @Override - public void updateItem(final ProposalResultListItem item, boolean empty) { - super.updateItem(item, empty); - - if (item != null && !empty) { - icon = new Label(); - AwesomeDude.setIcon(icon, item.getIcon()); - icon.getStyleClass().add(item.getColorStyleClass()); - setGraphic(icon); - } else { - setGraphic(null); - if (icon != null) - icon = null; - } - } - }; - } - }); - - - resultColumn.setComparator(Comparator.comparing(ProposalResultListItem::getThreshold)); - tableView.getColumns().add(resultColumn); - } - - public void removeAllFields() { - GUIUtil.removeChildrenFromGridPaneRows(gridPane, gridRowStartIndex, gridRow); - gridRow = gridRowStartIndex; - } - - @SuppressWarnings("Duplicates") - public ScrollPane getView() { - ScrollPane scrollPane = new ScrollPane(); - scrollPane.setFitToWidth(true); - scrollPane.setFitToHeight(true); - scrollPane.setMinHeight(280); // just enough to display overview at voting without scroller - - AnchorPane anchorPane = new AnchorPane(); - scrollPane.setContent(anchorPane); - - gridPane.setHgap(5); - gridPane.setVgap(5); - ColumnConstraints columnConstraints1 = new ColumnConstraints(); - columnConstraints1.setHalignment(HPos.RIGHT); - columnConstraints1.setHgrow(Priority.SOMETIMES); - columnConstraints1.setMinWidth(140); - ColumnConstraints columnConstraints2 = new ColumnConstraints(); - columnConstraints2.setHgrow(Priority.ALWAYS); - columnConstraints2.setMinWidth(300); - - gridPane.getColumnConstraints().addAll(columnConstraints1, columnConstraints2); - AnchorPane.setBottomAnchor(gridPane, 20d); - AnchorPane.setRightAnchor(gridPane, 10d); - AnchorPane.setLeftAnchor(gridPane, 10d); - AnchorPane.setTopAnchor(gridPane, 20d); - anchorPane.getChildren().add(gridPane); - - return scrollPane; - } -} diff --git a/src/main/java/bisq/desktop/main/dao/results/proposal/ProposalResultListItem.java b/src/main/java/bisq/desktop/main/dao/results/proposals/ProposalResultsListItem.java similarity index 87% rename from src/main/java/bisq/desktop/main/dao/results/proposal/ProposalResultListItem.java rename to src/main/java/bisq/desktop/main/dao/results/proposals/ProposalResultsListItem.java index f176f44bdb5..1b5edd8a2f3 100644 --- a/src/main/java/bisq/desktop/main/dao/results/proposal/ProposalResultListItem.java +++ b/src/main/java/bisq/desktop/main/dao/results/proposals/ProposalResultsListItem.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.desktop.main.dao.results.proposal; +package bisq.desktop.main.dao.results.proposals; import bisq.core.dao.voting.proposal.compensation.CompensationProposal; import bisq.core.dao.voting.voteresult.EvaluatedProposal; @@ -29,13 +29,13 @@ import lombok.Getter; -public class ProposalResultListItem { +public class ProposalResultsListItem { private final ProposalVoteResult proposalVoteResult; private final BsqFormatter bsqFormatter; @Getter private EvaluatedProposal evaluatedProposal; - public ProposalResultListItem(EvaluatedProposal evaluatedProposal, BsqFormatter bsqFormatter) { + public ProposalResultsListItem(EvaluatedProposal evaluatedProposal, BsqFormatter bsqFormatter) { this.evaluatedProposal = evaluatedProposal; proposalVoteResult = evaluatedProposal.getProposalVoteResult(); this.bsqFormatter = bsqFormatter; @@ -50,19 +50,19 @@ public String getProposalId() { } public String getAccepted() { - return Res.get("dao.results.result.table.item.votes", + return Res.get("dao.results.proposals.table.item.votes", bsqFormatter.formatCoinWithCode(Coin.valueOf(proposalVoteResult.getStakeOfAcceptedVotes())), String.valueOf(proposalVoteResult.getNumAcceptedVotes())); } public String getRejected() { - return Res.get("dao.results.result.table.item.votes", + return Res.get("dao.results.proposals.table.item.votes", bsqFormatter.formatCoinWithCode(Coin.valueOf(proposalVoteResult.getStakeOfRejectedVotes())), String.valueOf(proposalVoteResult.getNumRejectedVotes())); } public String getThreshold() { - return (proposalVoteResult.getThreshold() / 100D) + "%"; + return proposalVoteResult.getThreshold() > 0 ? (proposalVoteResult.getThreshold() / 100D) + "%" : ""; } public String getQuorum() { @@ -70,7 +70,7 @@ public String getQuorum() { } public AwesomeIcon getIcon() { - return evaluatedProposal.isAccepted() ? AwesomeIcon.OK_SIGN : AwesomeIcon.BAN_CIRCLE; + return evaluatedProposal.isAccepted() ? AwesomeIcon.OK_SIGN : AwesomeIcon.REMOVE_SIGN; } public String getColorStyleClass() { diff --git a/src/main/java/bisq/desktop/main/dao/results/proposals/ProposalResultsTableView.java b/src/main/java/bisq/desktop/main/dao/results/proposals/ProposalResultsTableView.java new file mode 100644 index 00000000000..885389ff5a0 --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/results/proposals/ProposalResultsTableView.java @@ -0,0 +1,327 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.desktop.main.dao.results.proposals; + +import bisq.desktop.components.AutoTooltipTableColumn; +import bisq.desktop.main.dao.proposal.ProposalDetailsWindow; +import bisq.desktop.main.dao.results.BaseResultsTableView; +import bisq.desktop.main.dao.results.ProposalResultsDetailsWindow; +import bisq.desktop.main.dao.results.model.ResultsOfCycle; +import bisq.desktop.util.GUIUtil; + +import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.dao.DaoFacade; +import bisq.core.locale.Res; +import bisq.core.util.BsqFormatter; + +import de.jensd.fx.fontawesome.AwesomeDude; + +import javafx.scene.control.Hyperlink; +import javafx.scene.control.Label; +import javafx.scene.control.TableCell; +import javafx.scene.control.TableColumn; +import javafx.scene.control.TableView; +import javafx.scene.control.Tooltip; +import javafx.scene.layout.GridPane; + +import javafx.beans.property.ReadOnlyObjectWrapper; + +import javafx.util.Callback; + +import java.util.Comparator; +import java.util.stream.Collectors; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class ProposalResultsTableView extends BaseResultsTableView { + + public ProposalResultsTableView(GridPane gridPane, BsqWalletService bsqWalletService, DaoFacade daoFacade, BsqFormatter bsqFormatter) { + super(gridPane, bsqWalletService, daoFacade, bsqFormatter); + } + + @Override + protected String getTitle() { + return Res.get("dao.results.proposals.header"); + } + + @Override + protected void fillList() { + itemList.setAll(resultsOfCycle.getEvaluatedProposals().stream() + .map(e -> new ProposalResultsListItem(e, bsqFormatter)) + .collect(Collectors.toList())); + + itemList.sort(Comparator.comparing(proposalResultsListItem -> proposalResultsListItem.getEvaluatedProposal().getProposal().getCreationDate())); + } + + public int createAllFields(int gridRowStartIndex, ResultsOfCycle resultsOfCycle) { + super.createAllFields(gridRowStartIndex, resultsOfCycle); + + GUIUtil.setFitToRowsForTableView(tableView, 30, 28, 80); + + return gridRow; + } + + @Override + protected void createColumns(TableView tableView) { + TableColumn nameColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.proposals.table.header.proposalOwnerName")); + nameColumn.setMinWidth(100); + nameColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + nameColumn.setCellFactory( + new Callback, TableCell>() { + @Override + public TableCell call( + TableColumn column) { + return new TableCell() { + @Override + public void updateItem(final ProposalResultsListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null) + setText(item.getProposalOwnerName()); + else + setText(""); + } + }; + } + }); + nameColumn.setComparator(Comparator.comparing(ProposalResultsListItem::getProposalOwnerName)); + tableView.getColumns().add(nameColumn); + + TableColumn idColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.proposals.table.header.proposalId")); + idColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + idColumn.setMinWidth(100); + idColumn.setCellFactory( + new Callback, TableCell>() { + + @Override + public TableCell call(TableColumn column) { + return new TableCell() { + private Hyperlink field; + + @Override + public void updateItem(final ProposalResultsListItem item, boolean empty) { + super.updateItem(item, empty); + + // cycleDetailsWindow.show(item.getEvaluatedProposal()) + if (item != null && !empty) { + field = new Hyperlink(item.getProposalId()); + + //TODO setId or getStyleClass.add does not apply color... + //field.getStyleClass().add(item.getColorStyleClass()); + //field.setId(item.getColorStyleClass()); + field.setStyle(item.getColorStyle()); + field.setOnAction(event -> new ProposalDetailsWindow(bsqFormatter, + bsqWalletService, + item.getEvaluatedProposal().getProposal(), + daoFacade) + .show()); + field.setTooltip(new Tooltip(Res.get("tooltip.openPopupForDetails"))); + setGraphic(field); + } else { + setGraphic(null); + if (field != null) + field.setOnAction(null); + } + } + }; + } + }); + idColumn.setComparator(Comparator.comparing(ProposalResultsListItem::getProposalOwnerName)); + tableView.getColumns().add(idColumn); + + TableColumn acceptedColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.proposals.table.header.accepted")); + acceptedColumn.setMinWidth(80); + acceptedColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + acceptedColumn.setCellFactory( + new Callback, TableCell>() { + private Hyperlink field; + + @Override + public TableCell call( + TableColumn column) { + return new TableCell() { + @Override + public void updateItem(final ProposalResultsListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null && !empty) { + field = new Hyperlink(item.getAccepted()); + field.setStyle(item.getColorStyle()); + field.setOnAction(event -> new ProposalResultsDetailsWindow(bsqFormatter, item.getEvaluatedProposal()).show()); + field.setTooltip(new Tooltip(Res.get("tooltip.openPopupForDetails"))); + setGraphic(field); + } else { + setGraphic(null); + + //TODO does get called on active items somehow... + //if (field != null) + // field.setOnAction(null); + } + } + }; + } + }); + acceptedColumn.setComparator(Comparator.comparing(ProposalResultsListItem::getAccepted)); + tableView.getColumns().add(acceptedColumn); + + TableColumn rejectedColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.proposals.table.header.rejected")); + rejectedColumn.setMinWidth(80); + rejectedColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + rejectedColumn.setCellFactory( + new Callback, TableCell>() { + private Hyperlink field; + + @Override + public TableCell call( + TableColumn column) { + return new TableCell() { + @Override + public void updateItem(final ProposalResultsListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null && !empty) { + field = new Hyperlink(item.getRejected()); + field.setStyle(item.getColorStyle()); + field.setOnAction(event -> new ProposalResultsDetailsWindow(bsqFormatter, item.getEvaluatedProposal()).show()); + field.setTooltip(new Tooltip(Res.get("tooltip.openPopupForDetails"))); + setGraphic(field); + } else { + setGraphic(null); + //TODO does get called on active items somehow... + //if (field != null) + // field.setOnAction(null); + } + } + }; + } + }); + rejectedColumn.setComparator(Comparator.comparing(ProposalResultsListItem::getRejected)); + tableView.getColumns().add(rejectedColumn); + + TableColumn thresholdColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.proposals.table.header.threshold")); + thresholdColumn.setMinWidth(100); + thresholdColumn.setMaxWidth(100); + thresholdColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + thresholdColumn.setCellFactory( + new Callback, TableCell>() { + @Override + public TableCell call( + TableColumn column) { + return new TableCell() { + @Override + public void updateItem(final ProposalResultsListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null) + setText(item.getThreshold()); + else + setText(""); + } + }; + } + }); + thresholdColumn.setComparator(Comparator.comparing(ProposalResultsListItem::getThreshold)); + tableView.getColumns().add(thresholdColumn); + + TableColumn quorumColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.proposals.table.header.quorum")); + quorumColumn.setMinWidth(130); + quorumColumn.setMaxWidth(130); + quorumColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + quorumColumn.setCellFactory( + new Callback, TableCell>() { + @Override + public TableCell call( + TableColumn column) { + return new TableCell() { + @Override + public void updateItem(final ProposalResultsListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null) + setText(item.getQuorum()); + else + setText(""); + } + }; + } + }); + quorumColumn.setComparator(Comparator.comparing(ProposalResultsListItem::getThreshold)); + tableView.getColumns().add(quorumColumn); + + TableColumn issuanceColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.proposals.table.header.issuance")); + issuanceColumn.setMinWidth(130); + issuanceColumn.setMaxWidth(130); + issuanceColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + issuanceColumn.setCellFactory( + new Callback, TableCell>() { + @Override + public TableCell call( + TableColumn column) { + return new TableCell() { + @Override + public void updateItem(final ProposalResultsListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null) + setText(item.getIssuance()); + else + setText(""); + } + }; + } + }); + issuanceColumn.setComparator(Comparator.comparing(ProposalResultsListItem::getThreshold)); + tableView.getColumns().add(issuanceColumn); + + TableColumn resultColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.proposals.table.header.result")); + resultColumn.setMinWidth(60); + resultColumn.setMaxWidth(60); + resultColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + resultColumn.setCellFactory(new Callback, + TableCell>() { + @Override + public TableCell call(TableColumn column) { + return new TableCell() { + Label icon; + + @Override + public void updateItem(final ProposalResultsListItem item, boolean empty) { + super.updateItem(item, empty); + + if (item != null && !empty) { + icon = new Label(); + AwesomeDude.setIcon(icon, item.getIcon()); + icon.getStyleClass().add(item.getColorStyleClass()); + setGraphic(icon); + } else { + setGraphic(null); + if (icon != null) + icon = null; + } + } + }; + } + }); + + resultColumn.setComparator(Comparator.comparing(ProposalResultsListItem::getThreshold)); + tableView.getColumns().add(resultColumn); + } +} diff --git a/src/main/java/bisq/desktop/main/dao/results/votes/VotesListItem.java b/src/main/java/bisq/desktop/main/dao/results/votes/VotesListItem.java new file mode 100644 index 00000000000..4733980ce2e --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/results/votes/VotesListItem.java @@ -0,0 +1,113 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.desktop.main.dao.results.votes; + +import bisq.core.dao.state.BsqStateService; +import bisq.core.dao.voting.ballot.vote.BooleanVote; +import bisq.core.dao.voting.ballot.vote.LongVote; +import bisq.core.dao.voting.proposal.Proposal; +import bisq.core.dao.voting.voteresult.DecryptedVote; +import bisq.core.locale.Res; +import bisq.core.util.BsqFormatter; + +import org.bitcoinj.core.Coin; + +import com.google.common.base.Joiner; + +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import lombok.Getter; + +public class VotesListItem { + private final BsqStateService bsqStateService; + private final BsqFormatter bsqFormatter; + private int id; + @Getter + private final DecryptedVote decryptedVote; + + public VotesListItem(int id, DecryptedVote decryptedVote, BsqStateService bsqStateService, BsqFormatter bsqFormatter) { + this.id = id; + this.decryptedVote = decryptedVote; + this.bsqStateService = bsqStateService; + this.bsqFormatter = bsqFormatter; + } + + public String getBlindVoteTxId() { + return decryptedVote.getBlindVoteTxId(); + } + + public String getVoteRevealTxId() { + return decryptedVote.getVoteRevealTxId(); + } + + public String getStake() { + return bsqFormatter.formatCoinWithCode(getStakeAsCoin()); + } + + public Coin getStakeAsCoin() { + return Coin.valueOf(decryptedVote.getStake()); + } + + public String getMerit() { + return bsqFormatter.formatCoinWithCode(getMeritAsCoin()); + } + + public Coin getMeritAsCoin() { + return Coin.valueOf(decryptedVote.getMerit(bsqStateService)); + } + + public String getNumAcceptedVotes() { + return String.valueOf(getBooleanVoteStream() + .filter(BooleanVote::isAccepted) + .collect(Collectors.toList()) + .size()); + } + + public String getNumRejectedVotes() { + return String.valueOf(getBooleanVoteStream() + .filter(booleanVote -> !booleanVote.isAccepted()) + .collect(Collectors.toList()) + .size()); + } + + private Stream getBooleanVoteStream() { + return decryptedVote.getBallotList().getList().stream() + .filter(ballot -> ballot.getVote() instanceof BooleanVote) + .map(ballot -> (BooleanVote) ballot.getVote()); + } + + public String getBallotList() { + return Joiner.on(", ").join(decryptedVote.getBallotList().getList().stream() + .map(ballot -> { + Proposal proposal = ballot.getProposal(); + String proposalUid = proposal.getShortId(); + if (ballot.getVote() instanceof BooleanVote) + return proposalUid + ": " + ((BooleanVote) ballot.getVote()).isAccepted(); + else if (ballot.getVote() instanceof LongVote) + return proposalUid + ": " + ((LongVote) ballot.getVote()).getValue(); + else + return proposalUid; + }) + .collect(Collectors.toList())); + } + + public String getId() { + return Res.get("dao.results.votes.table.cell.id", id); + } +} diff --git a/src/main/java/bisq/desktop/main/dao/results/votes/VotesTableView.java b/src/main/java/bisq/desktop/main/dao/results/votes/VotesTableView.java new file mode 100644 index 00000000000..38726529318 --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/results/votes/VotesTableView.java @@ -0,0 +1,289 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.desktop.main.dao.results.votes; + +import bisq.desktop.components.AutoTooltipTableColumn; +import bisq.desktop.components.HyperlinkWithIcon; +import bisq.desktop.main.dao.results.BaseResultsTableView; +import bisq.desktop.main.dao.results.model.ResultsOfCycle; +import bisq.desktop.util.GUIUtil; + +import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.dao.DaoFacade; +import bisq.core.dao.state.BsqStateService; +import bisq.core.dao.voting.voteresult.DecryptedVote; +import bisq.core.locale.Res; +import bisq.core.user.Preferences; +import bisq.core.util.BsqFormatter; + +import de.jensd.fx.fontawesome.AwesomeIcon; + +import javafx.scene.control.TableCell; +import javafx.scene.control.TableColumn; +import javafx.scene.control.TableView; +import javafx.scene.control.Tooltip; +import javafx.scene.layout.GridPane; + +import javafx.beans.property.ReadOnlyObjectWrapper; + +import javafx.util.Callback; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class VotesTableView extends BaseResultsTableView { + private final BsqStateService bsqStateService; + private final Preferences preferences; + + public VotesTableView(GridPane gridPane, BsqWalletService bsqWalletService, DaoFacade daoFacade, + BsqStateService bsqStateService, Preferences preferences, BsqFormatter bsqFormatter) { + super(gridPane, bsqWalletService, daoFacade, bsqFormatter); + + this.bsqStateService = bsqStateService; + this.preferences = preferences; + } + + @Override + protected String getTitle() { + return Res.get("dao.results.votes.header"); + } + + @Override + protected void fillList() { + List decryptedVotesForCycle = new ArrayList<>(resultsOfCycle.getDecryptedVotesForCycle()); + decryptedVotesForCycle.sort(Comparator.comparing(DecryptedVote::getBlindVoteTxId)); + AtomicInteger index = new AtomicInteger(); + itemList.setAll(decryptedVotesForCycle.stream() + .map(decryptedVote -> { + int id = index.incrementAndGet(); + return new VotesListItem(id, decryptedVote, bsqStateService, bsqFormatter); + }) + .collect(Collectors.toList())); + } + + public int createAllFields(int gridRowStartIndex, ResultsOfCycle resultsOfCycle) { + super.createAllFields(gridRowStartIndex, resultsOfCycle); + + GUIUtil.setFitToRowsForTableView(tableView, 33, 28, 80); + + return gridRow; + } + + @Override + protected void createColumns(TableView tableView) { + TableColumn indexColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.id")); + indexColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + indexColumn.setMinWidth(70); + indexColumn.setCellFactory( + new Callback, TableCell>() { + @Override + public TableCell call( + TableColumn column) { + return new TableCell() { + @Override + public void updateItem(final VotesListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null) + setText(item.getId()); + else + setText(""); + } + }; + } + }); + indexColumn.setComparator(Comparator.comparing(VotesListItem::getStakeAsCoin)); + tableView.getColumns().add(indexColumn); + + TableColumn stakeColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.stake")); + stakeColumn.setMinWidth(70); + stakeColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + stakeColumn.setCellFactory( + new Callback, TableCell>() { + @Override + public TableCell call( + TableColumn column) { + return new TableCell() { + @Override + public void updateItem(final VotesListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null) + setText(item.getStake()); + else + setText(""); + } + }; + } + }); + stakeColumn.setComparator(Comparator.comparing(VotesListItem::getStakeAsCoin)); + tableView.getColumns().add(stakeColumn); + + TableColumn meritColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.merit")); + meritColumn.setMinWidth(70); + meritColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + meritColumn.setCellFactory( + new Callback, TableCell>() { + @Override + public TableCell call( + TableColumn column) { + return new TableCell() { + @Override + public void updateItem(final VotesListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null) + setText(item.getMerit()); + else + setText(""); + } + }; + } + }); + meritColumn.setComparator(Comparator.comparing(VotesListItem::getMeritAsCoin)); + tableView.getColumns().add(meritColumn); + + TableColumn acceptedColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.accepted")); + acceptedColumn.setMinWidth(70); + acceptedColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + acceptedColumn.setCellFactory( + new Callback, TableCell>() { + @Override + public TableCell call( + TableColumn column) { + return new TableCell() { + @Override + public void updateItem(final VotesListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null) + setText(item.getNumAcceptedVotes()); + else + setText(""); + } + }; + } + }); + acceptedColumn.setComparator(Comparator.comparing(VotesListItem::getNumAcceptedVotes)); + tableView.getColumns().add(acceptedColumn); + + TableColumn rejectedColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.rejected")); + rejectedColumn.setMinWidth(70); + rejectedColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + rejectedColumn.setCellFactory( + new Callback, TableCell>() { + @Override + public TableCell call( + TableColumn column) { + return new TableCell() { + @Override + public void updateItem(final VotesListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null) + setText(item.getNumRejectedVotes()); + else + setText(""); + } + }; + } + }); + rejectedColumn.setComparator(Comparator.comparing(VotesListItem::getNumRejectedVotes)); + tableView.getColumns().add(rejectedColumn); + + TableColumn blindVoteTxIdColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.blindVoteTxId")); + blindVoteTxIdColumn.setMinWidth(120); + blindVoteTxIdColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + blindVoteTxIdColumn.setCellFactory( + new Callback, TableCell>() { + + @Override + public TableCell call( + TableColumn column) { + return new TableCell() { + private HyperlinkWithIcon hyperlinkWithIcon; + + @Override + public void updateItem(final VotesListItem item, boolean empty) { + super.updateItem(item, empty); + + if (item != null && !empty) { + String txId = item.getBlindVoteTxId(); + hyperlinkWithIcon = new HyperlinkWithIcon(txId, AwesomeIcon.EXTERNAL_LINK); + hyperlinkWithIcon.setOnAction(event -> openTxInBlockExplorer(txId)); + hyperlinkWithIcon.setTooltip(new Tooltip(Res.get("tooltip.openBlockchainForTx", txId))); + setGraphic(hyperlinkWithIcon); + } else { + setGraphic(null); + if (hyperlinkWithIcon != null) + hyperlinkWithIcon.setOnAction(null); + } + } + }; + } + }); + blindVoteTxIdColumn.setComparator(Comparator.comparing(VotesListItem::getBlindVoteTxId)); + tableView.getColumns().add(blindVoteTxIdColumn); + + TableColumn voteRevealTxIdColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.voteRevealTxId")); + voteRevealTxIdColumn.setMinWidth(420); + voteRevealTxIdColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + voteRevealTxIdColumn.setCellFactory( + new Callback, TableCell>() { + @Override + public TableCell call( + TableColumn column) { + return new TableCell() { + private HyperlinkWithIcon hyperlinkWithIcon; + + @Override + public void updateItem(final VotesListItem item, boolean empty) { + super.updateItem(item, empty); + + if (item != null && !empty) { + String txId = item.getVoteRevealTxId(); + hyperlinkWithIcon = new HyperlinkWithIcon(txId, AwesomeIcon.EXTERNAL_LINK); + hyperlinkWithIcon.setOnAction(event -> openTxInBlockExplorer(txId)); + hyperlinkWithIcon.setTooltip(new Tooltip(Res.get("tooltip.openBlockchainForTx", txId))); + setGraphic(hyperlinkWithIcon); + } else { + setGraphic(null); + if (hyperlinkWithIcon != null) + hyperlinkWithIcon.setOnAction(null); + } + } + }; + } + }); + voteRevealTxIdColumn.setComparator(Comparator.comparing(VotesListItem::getVoteRevealTxId)); + tableView.getColumns().add(voteRevealTxIdColumn); + } + + private void openTxInBlockExplorer(String txId) { + if (txId != null) + GUIUtil.openWebPage(preferences.getBsqBlockChainExplorer().txUrl + txId); + } +} diff --git a/src/main/java/bisq/desktop/util/GUIUtil.java b/src/main/java/bisq/desktop/util/GUIUtil.java index e4fd0bfe09d..9d740c66ab5 100644 --- a/src/main/java/bisq/desktop/util/GUIUtil.java +++ b/src/main/java/bisq/desktop/util/GUIUtil.java @@ -69,6 +69,7 @@ import javafx.scene.Node; import javafx.scene.Scene; import javafx.scene.control.ScrollBar; +import javafx.scene.control.TableView; import javafx.scene.control.TextArea; import javafx.scene.control.Tooltip; import javafx.scene.layout.GridPane; @@ -569,4 +570,15 @@ public static void showBsqFeeInfoPopup(Coin fee, Coin miningFee, int txSize, Bsq .closeButtonText(Res.get("shared.cancel")) .show(); } + + public static void setFitToRowsForTableView(TableView tableView, int rowHeight, int headerHeight, int minHeight) { + int size = tableView.getItems().size(); + if (size > 0) { + int height = Math.max(minHeight, size * rowHeight + headerHeight); + tableView.setMaxHeight(height); + tableView.setMinHeight(height); + } else { + log.warn("setFitToRowsForTableView should be called after the table is filled"); + } + } } From 5e07a94a3c80d81a22232c8328102e94125b00ed Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Thu, 19 Jul 2018 17:17:13 +0200 Subject: [PATCH 153/197] Fix wrong values for vote and issuance --- .../main/dao/results/ResultsListItem.java | 18 +++++++++++++++++- .../desktop/main/dao/results/ResultsView.java | 2 +- .../combo/VotesPerProposalTableView.java | 1 + .../main/dao/results/model/ResultsOfCycle.java | 14 ++------------ 4 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/results/ResultsListItem.java b/src/main/java/bisq/desktop/main/dao/results/ResultsListItem.java index 0d0e3e6220e..c9563698728 100644 --- a/src/main/java/bisq/desktop/main/dao/results/ResultsListItem.java +++ b/src/main/java/bisq/desktop/main/dao/results/ResultsListItem.java @@ -19,24 +19,31 @@ import bisq.desktop.main.dao.results.model.ResultsOfCycle; +import bisq.core.dao.state.BsqStateService; import bisq.core.dao.voting.proposal.compensation.CompensationProposal; +import bisq.core.dao.voting.voteresult.EvaluatedProposal; import bisq.core.locale.Res; import bisq.core.util.BsqFormatter; import org.bitcoinj.core.Coin; import java.util.Date; +import java.util.HashMap; +import java.util.Map; import lombok.Getter; public class ResultsListItem { + private final BsqStateService bsqStateService; private final BsqFormatter bsqFormatter; @Getter private ResultsOfCycle resultsOfCycle; public ResultsListItem(ResultsOfCycle resultsOfCycle, + BsqStateService bsqStateService, BsqFormatter bsqFormatter) { this.resultsOfCycle = resultsOfCycle; + this.bsqStateService = bsqStateService; this.bsqFormatter = bsqFormatter; } @@ -55,11 +62,20 @@ public String getNumVotesAsString() { } public String getStake() { - return bsqFormatter.formatCoinWithCode(Coin.valueOf(resultsOfCycle.getTotalStake())); + //TODO move to domain + Map map = new HashMap<>(); + resultsOfCycle.getDecryptedVotesForCycle() + .forEach(decryptedVote -> { + decryptedVote.getBallotList().stream().forEach(ballot -> { + map.putIfAbsent(decryptedVote.getBlindVoteTxId(), decryptedVote.getStake() + decryptedVote.getMerit(bsqStateService)); + }); + }); + return bsqFormatter.formatCoinWithCode(Coin.valueOf(map.values().stream().mapToLong(e -> e).sum())); } public String getIssuance() { long totalIssuance = resultsOfCycle.getEvaluatedProposals().stream() + .filter(EvaluatedProposal::isAccepted) .filter(e -> e.getProposal() instanceof CompensationProposal) .map(e -> (CompensationProposal) e.getProposal()) .mapToLong(e -> e.getRequestedBsq().value) diff --git a/src/main/java/bisq/desktop/main/dao/results/ResultsView.java b/src/main/java/bisq/desktop/main/dao/results/ResultsView.java index 73197e3754c..eb5ebaa37db 100644 --- a/src/main/java/bisq/desktop/main/dao/results/ResultsView.java +++ b/src/main/java/bisq/desktop/main/dao/results/ResultsView.java @@ -299,7 +299,7 @@ private void addCycleListItem(Cycle cycle) { proposalsForCycle, evaluatedProposalsForCycle, decryptedVotesForCycle); - ResultsListItem resultsListItem = new ResultsListItem(resultsOfCycle, bsqFormatter); + ResultsListItem resultsListItem = new ResultsListItem(resultsOfCycle, bsqStateService, bsqFormatter); itemList.add(resultsListItem); } diff --git a/src/main/java/bisq/desktop/main/dao/results/combo/VotesPerProposalTableView.java b/src/main/java/bisq/desktop/main/dao/results/combo/VotesPerProposalTableView.java index 1886b636a93..be000a6a03f 100644 --- a/src/main/java/bisq/desktop/main/dao/results/combo/VotesPerProposalTableView.java +++ b/src/main/java/bisq/desktop/main/dao/results/combo/VotesPerProposalTableView.java @@ -77,6 +77,7 @@ protected String getTitle() { @Override protected void fillList() { + //TODO move to domain Map map = resultsOfCycle.getEvaluatedProposals().stream() .collect(Collectors.toMap(EvaluatedProposal::getProposalTxId, EvaluatedProposalWithDecryptedVote::new)); diff --git a/src/main/java/bisq/desktop/main/dao/results/model/ResultsOfCycle.java b/src/main/java/bisq/desktop/main/dao/results/model/ResultsOfCycle.java index 2530c7af755..b6d916ba4c6 100644 --- a/src/main/java/bisq/desktop/main/dao/results/model/ResultsOfCycle.java +++ b/src/main/java/bisq/desktop/main/dao/results/model/ResultsOfCycle.java @@ -26,14 +26,14 @@ import java.util.List; import lombok.Data; +import lombok.extern.slf4j.Slf4j; +@Slf4j @Data public class ResultsOfCycle { private final Cycle cycle; private final int cycleIndex; private final int numVotes, numAcceptedVotes, numRejectedVotes; - private final long stakeOfAcceptedVotes; - private final long stakeOfRejectedVotes; private BsqFormatter bsqFormatter; private long cycleStartTime; @@ -67,15 +67,5 @@ public ResultsOfCycle(Cycle cycle, numRejectedVotes = evaluatedProposals.stream() .mapToInt(e -> e.getProposalVoteResult().getNumRejectedVotes()) .sum(); - stakeOfAcceptedVotes = evaluatedProposals.stream() - .mapToLong(e -> e.getProposalVoteResult().getStakeOfAcceptedVotes()) - .sum(); - stakeOfRejectedVotes = evaluatedProposals.stream() - .mapToLong(e -> e.getProposalVoteResult().getStakeOfRejectedVotes()) - .sum(); - } - - public long getTotalStake() { - return stakeOfAcceptedVotes + stakeOfRejectedVotes; } } From c1a1608ae93a7f17725ef51d7fb4e606f9dcccc6 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sat, 21 Jul 2018 12:30:01 +0200 Subject: [PATCH 154/197] Change dummy dev account to AliPayAccount --- .../java/bisq/desktop/main/MainViewModel.java | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/main/java/bisq/desktop/main/MainViewModel.java b/src/main/java/bisq/desktop/main/MainViewModel.java index bb5f03032e4..f54415c432b 100644 --- a/src/main/java/bisq/desktop/main/MainViewModel.java +++ b/src/main/java/bisq/desktop/main/MainViewModel.java @@ -36,11 +36,10 @@ import bisq.core.btc.wallet.BtcWalletService; import bisq.core.btc.wallet.WalletsSetup; import bisq.core.locale.CurrencyUtil; -import bisq.core.locale.FiatCurrency; import bisq.core.locale.Res; import bisq.core.payment.AccountAgeWitnessService; +import bisq.core.payment.AliPayAccount; import bisq.core.payment.CryptoCurrencyAccount; -import bisq.core.payment.PerfectMoneyAccount; import bisq.core.presentation.BalancePresentation; import bisq.core.presentation.DisputePresentation; import bisq.core.presentation.TradePresentation; @@ -425,20 +424,19 @@ private void showSecondPopupIfResyncSPVRequested(Popup firstPopup) { private void setupDevDummyPaymentAccounts() { if (user.getPaymentAccounts() != null && user.getPaymentAccounts().isEmpty()) { - PerfectMoneyAccount perfectMoneyAccount = new PerfectMoneyAccount(); - perfectMoneyAccount.init(); - perfectMoneyAccount.setAccountNr("dummy_" + new Random().nextInt(100)); - perfectMoneyAccount.setAccountName("PerfectMoney dummy");// Don't translate only for dev - perfectMoneyAccount.setSelectedTradeCurrency(new FiatCurrency("USD")); - user.addPaymentAccount(perfectMoneyAccount); + AliPayAccount aliPayAccount = new AliPayAccount(); + aliPayAccount.init(); + aliPayAccount.setAccountNr("dummy_" + new Random().nextInt(100)); + aliPayAccount.setAccountName("AliPayAccount dummy");// Don't translate only for dev + user.addPaymentAccount(aliPayAccount); if (p2PService.isBootstrapped()) { - accountAgeWitnessService.publishMyAccountAgeWitness(perfectMoneyAccount.getPaymentAccountPayload()); + accountAgeWitnessService.publishMyAccountAgeWitness(aliPayAccount.getPaymentAccountPayload()); } else { p2PService.addP2PServiceListener(new BootstrapListener() { @Override public void onUpdatedDataReceived() { - accountAgeWitnessService.publishMyAccountAgeWitness(perfectMoneyAccount.getPaymentAccountPayload()); + accountAgeWitnessService.publishMyAccountAgeWitness(aliPayAccount.getPaymentAccountPayload()); } }); } From caff652487bd6de93db6dde3ea8e97a1bed80ad4 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sat, 21 Jul 2018 16:29:37 +0200 Subject: [PATCH 155/197] Add display of all params --- .../desktop/main/dao/results/ResultsView.java | 115 ++++++++++++++---- .../dao/results/votes/VotesTableView.java | 2 +- src/main/java/bisq/desktop/util/GUIUtil.java | 10 +- 3 files changed, 96 insertions(+), 31 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/results/ResultsView.java b/src/main/java/bisq/desktop/main/dao/results/ResultsView.java index eb5ebaa37db..d57a86fb986 100644 --- a/src/main/java/bisq/desktop/main/dao/results/ResultsView.java +++ b/src/main/java/bisq/desktop/main/dao/results/ResultsView.java @@ -24,6 +24,7 @@ import bisq.desktop.components.AutoTooltipLabel; import bisq.desktop.components.AutoTooltipTableColumn; import bisq.desktop.components.TableGroupHeadline; +import bisq.desktop.components.TitledGroupBg; import bisq.desktop.main.dao.results.combo.VotesPerProposalTableView; import bisq.desktop.main.dao.results.model.ResultsOfCycle; import bisq.desktop.main.dao.results.proposals.ProposalResultsTableView; @@ -36,11 +37,13 @@ import bisq.core.dao.state.BsqStateListener; import bisq.core.dao.state.BsqStateService; import bisq.core.dao.state.blockchain.Block; +import bisq.core.dao.state.ext.Param; import bisq.core.dao.state.period.Cycle; import bisq.core.dao.state.period.CycleService; +import bisq.core.dao.voting.blindvote.BlindVoteConsensus; import bisq.core.dao.voting.proposal.Proposal; +import bisq.core.dao.voting.proposal.ProposalConsensus; import bisq.core.dao.voting.proposal.ProposalService; -import bisq.core.dao.voting.proposal.ProposalType; import bisq.core.dao.voting.proposal.storage.appendonly.ProposalPayload; import bisq.core.dao.voting.voteresult.DecryptedVote; import bisq.core.dao.voting.voteresult.EvaluatedProposal; @@ -76,13 +79,15 @@ import javafx.util.Callback; +import java.util.Arrays; import java.util.Collections; import java.util.Comparator; -import java.util.HashMap; import java.util.List; -import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; +import static bisq.desktop.util.FormBuilder.addLabelTextField; + @FxmlView public class ResultsView extends ActivatableViewAndModel implements BsqStateListener { @FXML @@ -193,26 +198,7 @@ private void onResultsListItemSelected(ResultsListItem item) { gridRow = votesPerProposalTableView.createAllFields(++gridRow, resultsOfCycle); gridRow = proposalResultsTableView.createAllFields(++gridRow, resultsOfCycle); gridRow = votesTableView.createAllFields(++gridRow, resultsOfCycle); - - Map requiredThresholdByType = new HashMap<>(); - resultsOfCycle.getEvaluatedProposals().forEach(e -> { - requiredThresholdByType.putIfAbsent(e.getProposal().getType(), e.getRequiredThreshold()); - }); - requiredThresholdByType.forEach((key, value) -> { - String title = Res.get("dao.results.proposals.requiredThreshold." + key.name()); - String requiredThreshold = String.valueOf(value / 100) + "%"; - FormBuilder.addLabelTextField(gridPane, ++gridRow, title, requiredThreshold, 0); - }); - - Map requiredQuorumByType = new HashMap<>(); - resultsOfCycle.getEvaluatedProposals().forEach(e -> { - requiredQuorumByType.putIfAbsent(e.getProposal().getType(), e.getRequiredQuorum()); - }); - requiredQuorumByType.forEach((key, value) -> { - String title = Res.get("dao.results.proposals.requiredQuorum." + key.name()); - String requiredQuorum = bsqFormatter.formatCoinWithCode(Coin.valueOf(value)); - FormBuilder.addLabelTextField(gridPane, ++gridRow, title, requiredQuorum); - }); + addParams(resultsOfCycle); } } @@ -262,6 +248,89 @@ private void createCyclesTable() { sortedList.comparatorProperty().bind(tableView.comparatorProperty()); } + private void addParams(ResultsOfCycle resultsOfCycle) { + //TODO + AtomicInteger rowSpan = new AtomicInteger(2); + TitledGroupBg header = FormBuilder.addTitledGroupBg(gridPane, ++gridRow, rowSpan.get(), Res.get("dao.results.cycle.header"), 20); + + int height = resultsOfCycle.getCycle().getHeightOfFirstBlock(); + gridRow--; // first item use same gridRow as header. as we use a ++ in the loop adjust by --. + Arrays.stream(Param.values()).forEach(param -> { + String label = null; + long paramValue = bsqStateService.getParamValue(param, height); + boolean isDefaultValue = param.getDefaultValue() == paramValue; + String value = null; + int top = (param == Param.BSQ_MAKER_FEE_IN_PERCENT) ? 40 : 0; + switch (param) { + case UNDEFINED: + // ignore + break; + + case BSQ_MAKER_FEE_IN_PERCENT: + case BSQ_TAKER_FEE_IN_PERCENT: + case BTC_MAKER_FEE_IN_PERCENT: + case BTC_TAKER_FEE_IN_PERCENT: + label = Res.getWithCol("dao.results.cycle.param." + param.name()); + value = bsqFormatter.formatToPercentWithSymbol(paramValue / 10000d); + break; + + case PROPOSAL_FEE: + label = Res.getWithCol("dao.results.cycle.param." + param.name()); + value = bsqFormatter.formatCoinWithCode(ProposalConsensus.getFee(bsqStateService, height)); + break; + case BLIND_VOTE_FEE: + label = Res.getWithCol("dao.results.cycle.param." + param.name()); + value = bsqFormatter.formatCoinWithCode(BlindVoteConsensus.getFee(bsqStateService, height)); + break; + + case QUORUM_PROPOSAL: + case QUORUM_COMP_REQUEST: + case QUORUM_CHANGE_PARAM: + case QUORUM_REMOVE_ASSET: + case QUORUM_CONFISCATION: + label = Res.getWithCol("dao.results.cycle.param." + param.name()); + value = bsqFormatter.formatCoinWithCode(Coin.valueOf(paramValue)); + break; + case THRESHOLD_PROPOSAL: + + case THRESHOLD_COMP_REQUEST: + case THRESHOLD_CHANGE_PARAM: + case THRESHOLD_REMOVE_ASSET: + case THRESHOLD_CONFISCATION: + label = Res.getWithCol("dao.results.cycle.param." + param.name()); + value = bsqFormatter.formatToPercentWithSymbol(paramValue / 10000d); + break; + + case PHASE_UNDEFINED: + // ignore + break; + + case PHASE_PROPOSAL: + case PHASE_BREAK1: + case PHASE_BLIND_VOTE: + case PHASE_BREAK2: + case PHASE_VOTE_REVEAL: + case PHASE_BREAK3: + case PHASE_RESULT: + case PHASE_BREAK4: + String phase = Res.get("dao.phase." + param.name()); + label = Res.getWithCol("dao.results.cycle.duration.label", phase); + value = Res.get("dao.results.cycle.duration.value", paramValue); + break; + } + if (value != null) { + String postFix = isDefaultValue ? + Res.get("dao.results.cycle.value.postFix.isDefaultValue") : + Res.get("dao.results.cycle.value.postFix.hasChanged"); + value += " " + postFix; + addLabelTextField(gridPane, ++gridRow, label, value, top); + rowSpan.getAndIncrement(); + } + }); + + GridPane.setRowSpan(header, rowSpan.get()); + } + /////////////////////////////////////////////////////////////////////////////////////////// // Private diff --git a/src/main/java/bisq/desktop/main/dao/results/votes/VotesTableView.java b/src/main/java/bisq/desktop/main/dao/results/votes/VotesTableView.java index 38726529318..d19b11b62f9 100644 --- a/src/main/java/bisq/desktop/main/dao/results/votes/VotesTableView.java +++ b/src/main/java/bisq/desktop/main/dao/results/votes/VotesTableView.java @@ -248,7 +248,7 @@ public void updateItem(final VotesListItem item, boolean empty) { tableView.getColumns().add(blindVoteTxIdColumn); TableColumn voteRevealTxIdColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.voteRevealTxId")); - voteRevealTxIdColumn.setMinWidth(420); + voteRevealTxIdColumn.setMinWidth(120); voteRevealTxIdColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); voteRevealTxIdColumn.setCellFactory( new Callback, TableCell 0) { - int height = Math.max(minHeight, size * rowHeight + headerHeight); - tableView.setMaxHeight(height); - tableView.setMinHeight(height); - } else { - log.warn("setFitToRowsForTableView should be called after the table is filled"); - } + int height = Math.max(minHeight, size * rowHeight + headerHeight); + tableView.setMaxHeight(height); + tableView.setMinHeight(height); } } From 771a48991ce60a1e9509377a150579168b0eb576 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sat, 21 Jul 2018 18:30:00 +0200 Subject: [PATCH 156/197] Add popup or vote result per proposal --- .../desktop/main/dao/BaseProposalView.java | 4 +- ...DetailsWindow.java => ProposalWindow.java} | 6 +- .../results/ProposalResultsDetailsWindow.java | 83 ------ .../desktop/main/dao/results/ResultsView.java | 6 +- ... EvaluatedProposalWithDecryptedVotes.java} | 10 +- .../combo/VotesPerProposalListItem.java | 19 +- .../combo/VotesPerProposalTableView.java | 17 +- .../proposals/ProposalResultsTableView.java | 36 ++- .../VoteResultsForProposalListItem.java | 95 +++++++ .../VoteResultsForProposalWindow.java | 269 ++++++++++++++++++ 10 files changed, 421 insertions(+), 124 deletions(-) rename src/main/java/bisq/desktop/main/dao/proposal/{ProposalDetailsWindow.java => ProposalWindow.java} (92%) delete mode 100644 src/main/java/bisq/desktop/main/dao/results/ProposalResultsDetailsWindow.java rename src/main/java/bisq/desktop/main/dao/results/combo/{EvaluatedProposalWithDecryptedVote.java => EvaluatedProposalWithDecryptedVotes.java} (83%) create mode 100644 src/main/java/bisq/desktop/main/dao/results/proposals/VoteResultsForProposalListItem.java create mode 100644 src/main/java/bisq/desktop/main/dao/results/proposals/VoteResultsForProposalWindow.java diff --git a/src/main/java/bisq/desktop/main/dao/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/BaseProposalView.java index 17bffb94749..7dc7b0bdf3d 100644 --- a/src/main/java/bisq/desktop/main/dao/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/BaseProposalView.java @@ -23,8 +23,8 @@ import bisq.desktop.components.AutoTooltipTableColumn; import bisq.desktop.components.HyperlinkWithIcon; import bisq.desktop.components.TableGroupHeadline; -import bisq.desktop.main.dao.proposal.ProposalDetailsWindow; import bisq.desktop.main.dao.proposal.ProposalDisplay; +import bisq.desktop.main.dao.proposal.ProposalWindow; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; @@ -328,7 +328,7 @@ public void updateItem(final BaseProposalListItem item, boolean empty) { final Proposal proposal = item.getProposal(); field = new HyperlinkWithIcon(proposal.getShortId()); field.setOnAction(event -> { - new ProposalDetailsWindow(bsqFormatter, bsqWalletService, proposal, daoFacade).show(); + new ProposalWindow(bsqFormatter, bsqWalletService, proposal, daoFacade).show(); }); field.setTooltip(new Tooltip(Res.get("tooltip.openPopupForDetails"))); setGraphic(field); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalWindow.java similarity index 92% rename from src/main/java/bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java rename to src/main/java/bisq/desktop/main/dao/proposal/ProposalWindow.java index f9afafaaa1f..f5f93b6227f 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDetailsWindow.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalWindow.java @@ -30,7 +30,7 @@ import static bisq.desktop.util.FormBuilder.addButtonAfterGroup; -public class ProposalDetailsWindow extends Overlay { +public class ProposalWindow extends Overlay { private final BsqFormatter bsqFormatter; private final BsqWalletService bsqWalletService; private final Proposal proposal; @@ -43,8 +43,8 @@ public class ProposalDetailsWindow extends Overlay { // Public API /////////////////////////////////////////////////////////////////////////////////////////// - public ProposalDetailsWindow(BsqFormatter bsqFormatter, BsqWalletService bsqWalletService, Proposal proposal, - DaoFacade daoFacade) { + public ProposalWindow(BsqFormatter bsqFormatter, BsqWalletService bsqWalletService, Proposal proposal, + DaoFacade daoFacade) { this.bsqFormatter = bsqFormatter; this.bsqWalletService = bsqWalletService; this.proposal = proposal; diff --git a/src/main/java/bisq/desktop/main/dao/results/ProposalResultsDetailsWindow.java b/src/main/java/bisq/desktop/main/dao/results/ProposalResultsDetailsWindow.java deleted file mode 100644 index 100f9efada5..00000000000 --- a/src/main/java/bisq/desktop/main/dao/results/ProposalResultsDetailsWindow.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.desktop.main.dao.results; - -import bisq.desktop.main.overlays.Overlay; -import bisq.desktop.util.FormBuilder; - -import bisq.core.dao.voting.voteresult.EvaluatedProposal; -import bisq.core.locale.Res; -import bisq.core.util.BsqFormatter; - -import javafx.scene.control.Button; - -import javafx.geometry.Insets; - -import static bisq.desktop.util.FormBuilder.addTitledGroupBg; - -public class ProposalResultsDetailsWindow extends Overlay { - - private final BsqFormatter bsqFormatter; - private final EvaluatedProposal evaluatedProposal; - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Public API - /////////////////////////////////////////////////////////////////////////////////////////// - - public ProposalResultsDetailsWindow(BsqFormatter bsqFormatter, EvaluatedProposal evaluatedProposal) { - this.bsqFormatter = bsqFormatter; - this.evaluatedProposal = evaluatedProposal; - type = Type.Confirmation; - } - - @Override - public void show() { - rowIndex = -1; - width = 850; - createGridPane(); - addContent(); - display(); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Protected - /////////////////////////////////////////////////////////////////////////////////////////// - - @Override - protected void createGridPane() { - super.createGridPane(); - gridPane.setPadding(new Insets(35, 40, 30, 40)); - gridPane.getStyleClass().add("grid-pane"); - } - - private void addContent() { - addTitledGroupBg(gridPane, ++rowIndex, 5, Res.get("dao.results.proposals.detail.header")); - - //TODO impl - //addLabelTextField(gridPane, rowIndex, Res.get("dao.results.proposals.detail.header"), evaluatedProposal.getProposal().getName(), Layout.FIRST_ROW_DISTANCE); - - - Button closeButton = FormBuilder.addButtonAfterGroup(gridPane, ++rowIndex, Res.get("shared.close")); - closeButton.setOnAction(e -> { - closeHandlerOptional.ifPresent(Runnable::run); - hide(); - }); - } -} diff --git a/src/main/java/bisq/desktop/main/dao/results/ResultsView.java b/src/main/java/bisq/desktop/main/dao/results/ResultsView.java index d57a86fb986..b7a74bc922b 100644 --- a/src/main/java/bisq/desktop/main/dao/results/ResultsView.java +++ b/src/main/java/bisq/desktop/main/dao/results/ResultsView.java @@ -147,7 +147,11 @@ public void initialize() { createCyclesTable(); votesPerProposalTableView = new VotesPerProposalTableView(gridPane, bsqWalletService, daoFacade, bsqStateService, bsqFormatter); - proposalResultsTableView = new ProposalResultsTableView(gridPane, bsqWalletService, daoFacade, bsqFormatter); + proposalResultsTableView = new ProposalResultsTableView(gridPane, bsqWalletService, daoFacade, bsqFormatter, + bsqStateService, + cycleService, + voteResultService, + proposalService); votesTableView = new VotesTableView(gridPane, bsqWalletService, daoFacade, bsqStateService, preferences, bsqFormatter); selectedItemListener = (observable, oldValue, newValue) -> onResultsListItemSelected(newValue); } diff --git a/src/main/java/bisq/desktop/main/dao/results/combo/EvaluatedProposalWithDecryptedVote.java b/src/main/java/bisq/desktop/main/dao/results/combo/EvaluatedProposalWithDecryptedVotes.java similarity index 83% rename from src/main/java/bisq/desktop/main/dao/results/combo/EvaluatedProposalWithDecryptedVote.java rename to src/main/java/bisq/desktop/main/dao/results/combo/EvaluatedProposalWithDecryptedVotes.java index 8d235b19d52..1adcc630270 100644 --- a/src/main/java/bisq/desktop/main/dao/results/combo/EvaluatedProposalWithDecryptedVote.java +++ b/src/main/java/bisq/desktop/main/dao/results/combo/EvaluatedProposalWithDecryptedVotes.java @@ -24,19 +24,13 @@ import java.util.Map; import lombok.Data; -import lombok.Setter; - -import javax.annotation.Nullable; @Data -public class EvaluatedProposalWithDecryptedVote { +public class EvaluatedProposalWithDecryptedVotes { private final EvaluatedProposal evaluatedProposal; - @Setter - @Nullable - private DecryptedVote decryptedVote; private Map decryptedVotesByBlindVoteTxId = new HashMap<>(); - public EvaluatedProposalWithDecryptedVote(EvaluatedProposal evaluatedProposal) { + public EvaluatedProposalWithDecryptedVotes(EvaluatedProposal evaluatedProposal) { this.evaluatedProposal = evaluatedProposal; } diff --git a/src/main/java/bisq/desktop/main/dao/results/combo/VotesPerProposalListItem.java b/src/main/java/bisq/desktop/main/dao/results/combo/VotesPerProposalListItem.java index 1000023bc78..cd1fad5a003 100644 --- a/src/main/java/bisq/desktop/main/dao/results/combo/VotesPerProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/results/combo/VotesPerProposalListItem.java @@ -35,14 +35,14 @@ @Slf4j public class VotesPerProposalListItem { @Getter - private final EvaluatedProposalWithDecryptedVote evaluatedProposalWithDecryptedVote; + private final EvaluatedProposalWithDecryptedVotes evaluatedProposalWithDecryptedVotes; @Getter private final Proposal proposal; private final String proposalTxId; - public VotesPerProposalListItem(EvaluatedProposalWithDecryptedVote evaluatedProposalWithDecryptedVote) { - this.evaluatedProposalWithDecryptedVote = evaluatedProposalWithDecryptedVote; - proposal = evaluatedProposalWithDecryptedVote.getEvaluatedProposal().getProposal(); + public VotesPerProposalListItem(EvaluatedProposalWithDecryptedVotes evaluatedProposalWithDecryptedVotes) { + this.evaluatedProposalWithDecryptedVotes = evaluatedProposalWithDecryptedVotes; + proposal = evaluatedProposalWithDecryptedVotes.getEvaluatedProposal().getProposal(); proposalTxId = proposal.getTxId(); } @@ -52,7 +52,7 @@ public String getProposalInfo() { public Tuple2 getIconStyleTuple(String blindVoteTxId) { Optional isAccepted = Optional.empty(); - Map map = evaluatedProposalWithDecryptedVote.getDecryptedVotesByBlindVoteTxId(); + Map map = evaluatedProposalWithDecryptedVotes.getDecryptedVotesByBlindVoteTxId(); if (map.containsKey(blindVoteTxId)) { DecryptedVote decryptedVote = map.get(blindVoteTxId); isAccepted = decryptedVote.getBallotList().stream() @@ -72,13 +72,4 @@ public Tuple2 getIconStyleTuple(String blindVoteTxId) { return new Tuple2<>(AwesomeIcon.MINUS_SIGN, "dao-ignored-icon"); } } - - @Override - public String toString() { - return "VotesPerProposalListItem{" + - "\n evaluatedProposalWithDecryptedVote=" + evaluatedProposalWithDecryptedVote + - "\n}"; - } - - } diff --git a/src/main/java/bisq/desktop/main/dao/results/combo/VotesPerProposalTableView.java b/src/main/java/bisq/desktop/main/dao/results/combo/VotesPerProposalTableView.java index be000a6a03f..d53316ea3d3 100644 --- a/src/main/java/bisq/desktop/main/dao/results/combo/VotesPerProposalTableView.java +++ b/src/main/java/bisq/desktop/main/dao/results/combo/VotesPerProposalTableView.java @@ -18,8 +18,8 @@ package bisq.desktop.main.dao.results.combo; import bisq.desktop.components.AutoTooltipTableColumn; +import bisq.desktop.main.dao.proposal.ProposalWindow; import bisq.desktop.main.dao.results.BaseResultsTableView; -import bisq.desktop.main.dao.results.ProposalResultsDetailsWindow; import bisq.desktop.main.dao.results.model.ResultsOfCycle; import bisq.desktop.util.GUIUtil; @@ -78,15 +78,15 @@ protected String getTitle() { @Override protected void fillList() { //TODO move to domain - Map map = resultsOfCycle.getEvaluatedProposals().stream() + Map map = resultsOfCycle.getEvaluatedProposals().stream() .collect(Collectors.toMap(EvaluatedProposal::getProposalTxId, - EvaluatedProposalWithDecryptedVote::new)); + EvaluatedProposalWithDecryptedVotes::new)); resultsOfCycle.getDecryptedVotesForCycle() .forEach(decryptedVote -> { decryptedVote.getBallotList().stream().forEach(ballot -> { - EvaluatedProposalWithDecryptedVote evaluatedProposalWithDecryptedVote = map.get(ballot.getProposalTxId()); - evaluatedProposalWithDecryptedVote.addDecryptedVote(decryptedVote); + EvaluatedProposalWithDecryptedVotes evaluatedProposalWithDecryptedVotes = map.get(ballot.getProposalTxId()); + evaluatedProposalWithDecryptedVotes.addDecryptedVote(decryptedVote); }); }); @@ -128,8 +128,11 @@ public void updateItem(final VotesPerProposalListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { hyperlinkWithIcon = new Hyperlink(item.getProposalInfo()); - hyperlinkWithIcon.setOnAction(event -> new ProposalResultsDetailsWindow(bsqFormatter, - item.getEvaluatedProposalWithDecryptedVote().getEvaluatedProposal()).show()); + hyperlinkWithIcon.setOnAction(event -> new ProposalWindow(bsqFormatter, + bsqWalletService, + item.getEvaluatedProposalWithDecryptedVotes().getEvaluatedProposal().getProposal(), + daoFacade) + .show()); hyperlinkWithIcon.setTooltip(new Tooltip(Res.get("tooltip.openPopupForDetails"))); setGraphic(hyperlinkWithIcon); diff --git a/src/main/java/bisq/desktop/main/dao/results/proposals/ProposalResultsTableView.java b/src/main/java/bisq/desktop/main/dao/results/proposals/ProposalResultsTableView.java index 885389ff5a0..a526615d5f2 100644 --- a/src/main/java/bisq/desktop/main/dao/results/proposals/ProposalResultsTableView.java +++ b/src/main/java/bisq/desktop/main/dao/results/proposals/ProposalResultsTableView.java @@ -18,14 +18,17 @@ package bisq.desktop.main.dao.results.proposals; import bisq.desktop.components.AutoTooltipTableColumn; -import bisq.desktop.main.dao.proposal.ProposalDetailsWindow; +import bisq.desktop.main.dao.proposal.ProposalWindow; import bisq.desktop.main.dao.results.BaseResultsTableView; -import bisq.desktop.main.dao.results.ProposalResultsDetailsWindow; import bisq.desktop.main.dao.results.model.ResultsOfCycle; import bisq.desktop.util.GUIUtil; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; +import bisq.core.dao.state.BsqStateService; +import bisq.core.dao.state.period.CycleService; +import bisq.core.dao.voting.proposal.ProposalService; +import bisq.core.dao.voting.voteresult.VoteResultService; import bisq.core.locale.Res; import bisq.core.util.BsqFormatter; @@ -51,8 +54,21 @@ @Slf4j public class ProposalResultsTableView extends BaseResultsTableView { - public ProposalResultsTableView(GridPane gridPane, BsqWalletService bsqWalletService, DaoFacade daoFacade, BsqFormatter bsqFormatter) { + private final BsqStateService bsqStateService; + private final CycleService cycleService; + private final VoteResultService voteResultService; + private final ProposalService proposalService; + + public ProposalResultsTableView(GridPane gridPane, BsqWalletService bsqWalletService, DaoFacade daoFacade, BsqFormatter bsqFormatter, + BsqStateService bsqStateService, + CycleService cycleService, + VoteResultService voteResultService, + ProposalService proposalService) { super(gridPane, bsqWalletService, daoFacade, bsqFormatter); + this.bsqStateService = bsqStateService; + this.cycleService = cycleService; + this.voteResultService = voteResultService; + this.proposalService = proposalService; } @Override @@ -127,7 +143,7 @@ public void updateItem(final ProposalResultsListItem item, boolean empty) { //field.getStyleClass().add(item.getColorStyleClass()); //field.setId(item.getColorStyleClass()); field.setStyle(item.getColorStyle()); - field.setOnAction(event -> new ProposalDetailsWindow(bsqFormatter, + field.setOnAction(event -> new ProposalWindow(bsqFormatter, bsqWalletService, item.getEvaluatedProposal().getProposal(), daoFacade) @@ -164,7 +180,11 @@ public void updateItem(final ProposalResultsListItem item, boolean empty) { if (item != null && !empty) { field = new Hyperlink(item.getAccepted()); field.setStyle(item.getColorStyle()); - field.setOnAction(event -> new ProposalResultsDetailsWindow(bsqFormatter, item.getEvaluatedProposal()).show()); + field.setOnAction(event -> new VoteResultsForProposalWindow(resultsOfCycle, + item.getEvaluatedProposal().getProposal(), + bsqStateService, + bsqFormatter) + .show()); field.setTooltip(new Tooltip(Res.get("tooltip.openPopupForDetails"))); setGraphic(field); } else { @@ -199,7 +219,11 @@ public void updateItem(final ProposalResultsListItem item, boolean empty) { if (item != null && !empty) { field = new Hyperlink(item.getRejected()); field.setStyle(item.getColorStyle()); - field.setOnAction(event -> new ProposalResultsDetailsWindow(bsqFormatter, item.getEvaluatedProposal()).show()); + field.setOnAction(event -> new VoteResultsForProposalWindow(resultsOfCycle, + item.getEvaluatedProposal().getProposal(), + bsqStateService, + bsqFormatter) + .show()); field.setTooltip(new Tooltip(Res.get("tooltip.openPopupForDetails"))); setGraphic(field); } else { diff --git a/src/main/java/bisq/desktop/main/dao/results/proposals/VoteResultsForProposalListItem.java b/src/main/java/bisq/desktop/main/dao/results/proposals/VoteResultsForProposalListItem.java new file mode 100644 index 00000000000..880d06a014a --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/results/proposals/VoteResultsForProposalListItem.java @@ -0,0 +1,95 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.desktop.main.dao.results.proposals; + +import bisq.core.dao.state.BsqStateService; +import bisq.core.dao.voting.ballot.Ballot; +import bisq.core.dao.voting.ballot.vote.BooleanVote; +import bisq.core.dao.voting.proposal.Proposal; +import bisq.core.dao.voting.voteresult.DecryptedVote; +import bisq.core.util.BsqFormatter; + +import bisq.common.util.Tuple2; + +import org.bitcoinj.core.Coin; + +import de.jensd.fx.fontawesome.AwesomeIcon; + +import java.util.Optional; + +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class VoteResultsForProposalListItem { + @Getter + private final BsqFormatter bsqFormatter; + private final DecryptedVote decryptedVote; + + private long merit; + private long stake; + private String proposalTxId = ""; + private String blindVoteTxId = ""; + + public VoteResultsForProposalListItem(Proposal proposal, + DecryptedVote decryptedVote, + BsqStateService bsqStateService, + BsqFormatter bsqFormatter) { + this.decryptedVote = decryptedVote; + this.bsqFormatter = bsqFormatter; + proposalTxId = proposal.getTxId(); + + if (decryptedVote != null) { + merit = decryptedVote.getMerit(bsqStateService); + stake = decryptedVote.getStake(); + blindVoteTxId = decryptedVote.getBlindVoteTxId(); + } + } + + public Tuple2 getIconStyleTuple() { + Optional isAccepted; + isAccepted = decryptedVote.getBallotList().stream() + .filter(ballot -> ballot.getProposalTxId().equals(proposalTxId)) + .map(Ballot::getVote) + .filter(vote -> vote instanceof BooleanVote) + .map(vote -> (BooleanVote) vote) + .map(BooleanVote::isAccepted) + .findAny(); + if (isAccepted.isPresent()) { + if (isAccepted.get()) + return new Tuple2<>(AwesomeIcon.OK_SIGN, "dao-accepted-icon"); + else + return new Tuple2<>(AwesomeIcon.REMOVE_SIGN, "dao-rejected-icon"); + } else { + return new Tuple2<>(AwesomeIcon.MINUS_SIGN, "dao-ignored-icon"); + } + } + + + public String getMerit() { + return bsqFormatter.formatCoinWithCode(Coin.valueOf(merit)); + } + + public String getStake() { + return bsqFormatter.formatCoinWithCode(Coin.valueOf(stake)); + } + + public String getBlindVoteTxId() { + return blindVoteTxId; + } +} diff --git a/src/main/java/bisq/desktop/main/dao/results/proposals/VoteResultsForProposalWindow.java b/src/main/java/bisq/desktop/main/dao/results/proposals/VoteResultsForProposalWindow.java new file mode 100644 index 00000000000..18b2a678a93 --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/results/proposals/VoteResultsForProposalWindow.java @@ -0,0 +1,269 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.desktop.main.dao.results.proposals; + +import bisq.desktop.components.AutoTooltipLabel; +import bisq.desktop.components.AutoTooltipTableColumn; +import bisq.desktop.components.TableGroupHeadline; +import bisq.desktop.main.MainView; +import bisq.desktop.main.dao.results.model.ResultsOfCycle; +import bisq.desktop.main.overlays.Overlay; +import bisq.desktop.util.FormBuilder; +import bisq.desktop.util.GUIUtil; + +import bisq.core.dao.state.BsqStateService; +import bisq.core.dao.voting.proposal.Proposal; +import bisq.core.locale.Res; +import bisq.core.util.BsqFormatter; + +import bisq.common.util.Tuple2; + +import de.jensd.fx.fontawesome.AwesomeDude; +import de.jensd.fx.fontawesome.AwesomeIcon; + +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.control.TableCell; +import javafx.scene.control.TableColumn; +import javafx.scene.control.TableView; +import javafx.scene.layout.GridPane; + +import javafx.geometry.HPos; +import javafx.geometry.Insets; + +import javafx.beans.property.ReadOnlyObjectWrapper; + +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.collections.transformation.SortedList; + +import javafx.util.Callback; + +import java.util.Comparator; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class VoteResultsForProposalWindow extends Overlay { + private Proposal proposal; + private BsqStateService bsqStateService; + private final BsqFormatter bsqFormatter; + + private TableView tableView; + private int gridRow = 0; + private final ObservableList itemList = FXCollections.observableArrayList(); + private final SortedList sortedList = new SortedList<>(itemList); + protected ResultsOfCycle resultsOfCycle; + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Public API + /////////////////////////////////////////////////////////////////////////////////////////// + + public VoteResultsForProposalWindow(ResultsOfCycle resultsOfCycle, + Proposal proposal, + BsqStateService bsqStateService, + BsqFormatter bsqFormatter) { + this.resultsOfCycle = resultsOfCycle; + this.proposal = proposal; + this.bsqStateService = bsqStateService; + this.bsqFormatter = bsqFormatter; + type = Type.Confirmation; + } + + @Override + public void show() { + rowIndex = -1; + width = MainView.getRootContainer().getWidth() - 20; + createGridPane(); + addContent(); + display(); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Protected + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + protected void createGridPane() { + super.createGridPane(); + gridPane.setPadding(new Insets(35, 40, 30, 40)); + gridPane.getStyleClass().add("grid-pane"); + } + + private void addContent() { + TableGroupHeadline headline = new TableGroupHeadline(Res.get("dao.results.proposals.voting.detail.header")); + GridPane.setRowIndex(headline, gridRow); + GridPane.setMargin(headline, new Insets(0, -10, -10, -10)); + GridPane.setColumnSpan(headline, 2); + gridPane.getChildren().add(headline); + + tableView = new TableView<>(); + tableView.setPlaceholder(new AutoTooltipLabel(Res.get("table.placeholder.noData"))); + tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); + + createColumns(tableView); + GridPane.setRowIndex(tableView, gridRow); + GridPane.setMargin(tableView, new Insets(20, -10, 5, -10)); + GridPane.setColumnSpan(tableView, 2); + gridPane.getChildren().add(tableView); + + tableView.setItems(sortedList); + sortedList.comparatorProperty().bind(tableView.comparatorProperty()); + + fillList(); + + GUIUtil.setFitToRowsForTableView(tableView, 24, 28, 150); + + // Somehow setting the margin for closeButton does not work here as expected. adding a row does give us the desired layout... + ++rowIndex; + Button closeButton = FormBuilder.addButton(gridPane, ++rowIndex, Res.get("shared.close")); + GridPane.setHalignment(closeButton, HPos.RIGHT); + closeButton.setOnAction(e -> { + closeHandlerOptional.ifPresent(Runnable::run); + hide(); + }); + } + + private void fillList() { + itemList.clear(); + + resultsOfCycle.getEvaluatedProposals().stream() + .filter(evaluatedProposal -> evaluatedProposal.getProposal().equals(proposal)) + .forEach(evaluatedProposal -> { + resultsOfCycle.getDecryptedVotesForCycle().forEach(decryptedVote -> { + itemList.add(new VoteResultsForProposalListItem(evaluatedProposal.getProposal(), decryptedVote, + bsqStateService, bsqFormatter)); + }); + }); + + itemList.sort(Comparator.comparing(item -> item.getBlindVoteTxId())); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // TableColumns + /////////////////////////////////////////////////////////////////////////////////////////// + + private void createColumns(TableView tableView) { + TableColumn blindVoteTxIdColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.blindVoteTxId")); + blindVoteTxIdColumn.setSortable(false); + blindVoteTxIdColumn.setMinWidth(150); + blindVoteTxIdColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + blindVoteTxIdColumn.setCellFactory( + new Callback, TableCell>() { + @Override + public TableCell call( + TableColumn column) { + return new TableCell() { + @Override + public void updateItem(final VoteResultsForProposalListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null) + setText(item.getBlindVoteTxId()); + else + setText(""); + } + }; + } + }); + tableView.getColumns().add(blindVoteTxIdColumn); + + TableColumn voteColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.vote")); + voteColumn.setSortable(false); + voteColumn.setMinWidth(150); + voteColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + voteColumn.setCellFactory( + new Callback, TableCell>() { + @Override + public TableCell call( + TableColumn column) { + return new TableCell() { + private Label icon; + + @Override + public void updateItem(final VoteResultsForProposalListItem item, boolean empty) { + super.updateItem(item, empty); + + if (item != null && !empty) { + Tuple2 iconStyleTuple = item.getIconStyleTuple(); + icon = new Label(); + AwesomeDude.setIcon(icon, iconStyleTuple.first); + icon.getStyleClass().add(iconStyleTuple.second); + setGraphic(icon); + } else { + setGraphic(null); + } + } + }; + } + }); + tableView.getColumns().add(voteColumn); + + TableColumn meritColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.merit")); + meritColumn.setSortable(false); + meritColumn.setMinWidth(150); + meritColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + meritColumn.setCellFactory( + new Callback, TableCell>() { + @Override + public TableCell call( + TableColumn column) { + return new TableCell() { + @Override + public void updateItem(final VoteResultsForProposalListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null) + setText(item.getMerit()); + else + setText(""); + } + }; + } + }); + tableView.getColumns().add(meritColumn); + + TableColumn stakeColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.stake")); + stakeColumn.setSortable(false); + stakeColumn.setMinWidth(150); + stakeColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + stakeColumn.setCellFactory( + new Callback, TableCell>() { + @Override + public TableCell call( + TableColumn column) { + return new TableCell() { + @Override + public void updateItem(final VoteResultsForProposalListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null) + setText(item.getStake()); + else + setText(""); + } + }; + } + }); + tableView.getColumns().add(stakeColumn); + } +} From c40072e74d8a607e0ec09295510717cd6152b36b Mon Sep 17 00:00:00 2001 From: sqrrm Date: Wed, 18 Jul 2018 23:11:02 +0200 Subject: [PATCH 157/197] Add burn bond proposal --- .../main/dao/proposal/ProposalDisplay.java | 24 +++++++++++++++++-- .../dao/proposal/make/MakeProposalView.java | 10 ++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java index fbd909d4a98..d48a52f4672 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java @@ -33,6 +33,7 @@ import bisq.core.dao.voting.proposal.Proposal; import bisq.core.dao.voting.proposal.ProposalConsensus; import bisq.core.dao.voting.proposal.ProposalType; +import bisq.core.dao.voting.proposal.burnbond.BurnBondProposal; import bisq.core.dao.voting.proposal.compensation.CompensationConsensus; import bisq.core.dao.voting.proposal.compensation.CompensationProposal; import bisq.core.dao.voting.proposal.param.ChangeParamProposal; @@ -53,6 +54,7 @@ import javafx.beans.value.ChangeListener; import javafx.collections.FXCollections; +import javafx.collections.ObservableList; import javafx.util.StringConverter; @@ -82,6 +84,7 @@ public class ProposalDisplay { public InputTextField requestedBsqTextField, bsqAddressTextField, paramValueTextField; @Nullable public ComboBox paramComboBox; + public ComboBox burnBondComboBox; @Getter private int gridRow; public TextArea descriptionTextArea; @@ -121,7 +124,7 @@ public void createAllFields(String title, int gridRowStartIndex, double top, Pro int rowSpan; boolean hasAddedFields = proposalType == ProposalType.COMPENSATION_REQUEST || - proposalType == ProposalType.CHANGE_PARAM; + proposalType == ProposalType.CHANGE_PARAM || proposalType == ProposalType.BURN_BOND; if (isMakeProposalScreen) { rowSpan = hasAddedFields ? 8 : 6; } else if (showDetails) { @@ -132,6 +135,8 @@ public void createAllFields(String title, int gridRowStartIndex, double top, Pro rowSpan = 6; else if (proposalType == ProposalType.CHANGE_PARAM) rowSpan = 7; + else if (proposalType == ProposalType.BURN_BOND) + rowSpan = 6; else rowSpan = 5; } @@ -201,6 +206,13 @@ public Param fromString(String string) { break; case REMOVE_ALTCOIN: break; + case BURN_BOND: + burnBondComboBox = addLabelComboBox(gridPane, ++gridRow, + Res.get("dao.proposal.display.burnBondComboBox.label")).second; + ObservableList burnableBonds = FXCollections.observableArrayList(); + burnableBonds.addAll("bond1", "bond2", "bond3"); + burnBondComboBox.setItems(burnableBonds); + break; } if (!isMakeProposalScreen && showDetails) @@ -232,10 +244,14 @@ public void applyProposalPayload(Proposal proposal) { bsqAddressTextField.setText(compensationProposal.getBsqAddress()); } else if (proposal instanceof ChangeParamProposal) { ChangeParamProposal changeParamProposal = (ChangeParamProposal) proposal; - checkNotNull(paramComboBox, "paramComboBox must no tbe null"); + checkNotNull(paramComboBox, "paramComboBox must not be null"); paramComboBox.getSelectionModel().select(changeParamProposal.getParam()); checkNotNull(paramValueTextField, "paramValueTextField must no tbe null"); paramValueTextField.setText(String.valueOf(changeParamProposal.getParamValue())); + } else if (proposal instanceof BurnBondProposal) { + BurnBondProposal burnBondProposal = (BurnBondProposal) proposal; + checkNotNull(burnBondComboBox, "burnBondComboBox must not be null"); + burnBondComboBox.getSelectionModel().select(burnBondProposal.getBondId()); } int chainHeight; if (txIdTextField != null) { @@ -258,6 +274,7 @@ public void clearForm() { if (bsqAddressTextField != null) bsqAddressTextField.clear(); if (paramComboBox != null) paramComboBox.getSelectionModel().clearSelection(); if (paramValueTextField != null) paramValueTextField.clear(); + if (burnBondComboBox != null) burnBondComboBox.getSelectionModel().clearSelection(); if (txIdTextField != null) txIdTextField.cleanup(); if (descriptionTextArea != null) descriptionTextArea.textProperty().removeListener(descriptionTextAreaListener); } @@ -294,6 +311,9 @@ public void setEditable(boolean isEditable) { if (paramValueTextField != null) paramValueTextField.setEditable(isEditable); + if (burnBondComboBox != null) + burnBondComboBox.setDisable(!isEditable); + linkInputTextField.setVisible(true); linkInputTextField.setManaged(true); linkHyperlinkWithIcon.setVisible(false); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index 68009e61692..8ee00c73483 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -282,6 +282,16 @@ private ProposalWithTransaction getProposalWithTransaction(ProposalType type) case REMOVE_ALTCOIN: //TODO throw new RuntimeException("Not implemented yet"); + case BURN_BOND: + String bondId = proposalDisplay.burnBondComboBox.getSelectionModel().getSelectedItem(); + if (bondId == null || bondId.isEmpty()) + throw new ValidationException("Invalid bond id, null or empty"); + + return daoFacade.getBurnBondProposalWithTransaction(proposalDisplay.nameTextField.getText(), + proposalDisplay.titleTextField.getText(), + proposalDisplay.descriptionTextArea.getText(), + proposalDisplay.linkInputTextField.getText(), + bondId); default: final String msg = "Undefined ProposalType " + selectedProposalType; log.error(msg); From 71e3aed7b1254e5bd3e7d276cc02d6e3180b3ece Mon Sep 17 00:00:00 2001 From: sqrrm Date: Sat, 21 Jul 2018 19:49:03 +0200 Subject: [PATCH 158/197] Burn bonds when proposal is accepted Add bond id for bonds tied to role. Currently as a manual field to test things out. Should be some kind of automatically generated hash eventually. --- .../main/dao/bonding/lockup/LockupView.java | 46 +++++++++++++++++++ .../main/dao/proposal/ProposalDisplay.java | 21 +++++++-- .../dao/proposal/make/MakeProposalView.java | 6 +-- 3 files changed, 67 insertions(+), 6 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java b/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java index 007c59e8a1f..789cbc33c83 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java @@ -36,9 +36,11 @@ import bisq.core.btc.wallet.WalletsSetup; import bisq.core.dao.DaoFacade; import bisq.core.dao.bonding.BondingConsensus; +import bisq.core.dao.bonding.lockup.LockupType; import bisq.core.locale.Res; import bisq.core.util.BsqFormatter; import bisq.core.util.validation.IntegerValidator; +import bisq.core.util.validation.StringValidator; import bisq.network.p2p.P2PService; @@ -48,11 +50,19 @@ import javax.inject.Inject; import javafx.scene.control.Button; +import javafx.scene.control.ComboBox; import javafx.scene.layout.GridPane; import javafx.beans.value.ChangeListener; +import javafx.collections.FXCollections; + +import javafx.util.StringConverter; + +import java.util.Arrays; + import static bisq.desktop.util.FormBuilder.addButtonAfterGroup; +import static bisq.desktop.util.FormBuilder.addLabelComboBox; import static bisq.desktop.util.FormBuilder.addLabelInputTextField; import static bisq.desktop.util.FormBuilder.addTitledGroupBg; @@ -67,10 +77,13 @@ public class LockupView extends ActivatableView implements BsqBa private final BsqValidator bsqValidator; private final DaoFacade daoFacade; private final IntegerValidator timeInputTextFieldValidator; + private final StringValidator bondIdValidator; private int gridRow = 0; private InputTextField amountInputTextField; private InputTextField timeInputTextField; + private ComboBox lockupTypeComboBox; + private InputTextField bondIdInputTextField; private Button lockupButton; private ChangeListener focusOutListener; private ChangeListener inputTextFieldListener; @@ -101,6 +114,9 @@ private LockupView(BsqWalletService bsqWalletService, timeInputTextFieldValidator = new IntegerValidator(); timeInputTextFieldValidator.setMinValue(BondingConsensus.getMinLockTime()); timeInputTextFieldValidator.setMaxValue(BondingConsensus.getMaxLockTime()); + + bondIdValidator = new StringValidator(); + bondIdValidator.setLength(20); } @Override @@ -119,11 +135,39 @@ public void initialize() { String.valueOf(BondingConsensus.getMinLockTime()), String.valueOf(BondingConsensus.getMaxLockTime()))); timeInputTextField.setValidator(timeInputTextFieldValidator); + lockupTypeComboBox = addLabelComboBox(root, ++gridRow, + Res.getWithCol("dao.bonding.lock.type"), Layout.GRID_GAP).second; + lockupTypeComboBox.setConverter(new StringConverter() { + @Override + public String toString(LockupType lockupType) { + return lockupType.toString(); + } + + @Override + public LockupType fromString(String string) { + return null; + } + }); + lockupTypeComboBox.setItems(FXCollections.observableArrayList(Arrays.asList(LockupType.values()))); + lockupTypeComboBox.getSelectionModel().selectFirst(); + + bondIdInputTextField = addLabelInputTextField(root, ++gridRow, Res.get("dao.bonding.lock.bondId"), Layout.GRID_GAP).second; + bondIdInputTextField.setPromptText(Res.get("dao.bonding.lock.setBondId")); + bondIdInputTextField.setValidator(bondIdValidator); + lockupButton = addButtonAfterGroup(root, ++gridRow, Res.get("dao.bonding.lock.lockupButton")); lockupButton.setOnAction((event) -> { if (GUIUtil.isReadyForTxBroadcast(p2PService, walletsSetup)) { Coin lockupAmount = bsqFormatter.parseToCoin(amountInputTextField.getText()); int lockupTime = Integer.parseInt(timeInputTextField.getText()); + LockupType type = lockupTypeComboBox.getValue(); + // TODO get hash of something +// byte[] bytes = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; + byte[] bytes = bondIdInputTextField.getText().getBytes(); + if (type != LockupType.BONDED_ROLE) + bytes = null; + final byte[] hash = bytes; + new Popup<>().headLine(Res.get("dao.bonding.lock.sendFunds.headline")) .confirmation(Res.get("dao.bonding.lock.sendFunds.details", bsqFormatter.formatCoinWithCode(lockupAmount), @@ -133,6 +177,8 @@ public void initialize() { .onAction(() -> { daoFacade.publishLockupTx(lockupAmount, lockupTime, + type, + hash, () -> { new Popup<>().feedback(Res.get("dao.tx.published.success")).show(); }, diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java index d48a52f4672..09e3367d8a7 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java @@ -40,6 +40,8 @@ import bisq.core.locale.Res; import bisq.core.util.BsqFormatter; +import bisq.common.util.Utilities; + import javafx.scene.control.ComboBox; import javafx.scene.control.ScrollPane; import javafx.scene.control.TextArea; @@ -84,7 +86,7 @@ public class ProposalDisplay { public InputTextField requestedBsqTextField, bsqAddressTextField, paramValueTextField; @Nullable public ComboBox paramComboBox; - public ComboBox burnBondComboBox; + public ComboBox burnBondComboBox; @Getter private int gridRow; public TextArea descriptionTextArea; @@ -209,9 +211,22 @@ public Param fromString(String string) { case BURN_BOND: burnBondComboBox = addLabelComboBox(gridPane, ++gridRow, Res.get("dao.proposal.display.burnBondComboBox.label")).second; - ObservableList burnableBonds = FXCollections.observableArrayList(); - burnableBonds.addAll("bond1", "bond2", "bond3"); + ObservableList burnableBonds = + FXCollections.observableArrayList(daoFacade.getLockupAndUnlockingBondIds()); +// burnableBonds.addAll("bond1", "bond2", "bond3"); burnBondComboBox.setItems(burnableBonds); + burnBondComboBox.setConverter(new StringConverter() { + @Override + public String toString(byte[] id) { + return Utilities.bytesAsHexString(id); + } + + @Override + public byte[] fromString(String string) { + return null; + } + }); + break; } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index 8ee00c73483..431252d5478 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -283,9 +283,9 @@ private ProposalWithTransaction getProposalWithTransaction(ProposalType type) //TODO throw new RuntimeException("Not implemented yet"); case BURN_BOND: - String bondId = proposalDisplay.burnBondComboBox.getSelectionModel().getSelectedItem(); - if (bondId == null || bondId.isEmpty()) - throw new ValidationException("Invalid bond id, null or empty"); + byte[] bondId = proposalDisplay.burnBondComboBox.getSelectionModel().getSelectedItem(); + if (bondId == null || bondId.length == 0) + throw new ValidationException("Invalid bond id, null or zero length"); return daoFacade.getBurnBondProposalWithTransaction(proposalDisplay.nameTextField.getText(), proposalDisplay.titleTextField.getText(), From 369ed5bff9ff7e20e96f1a0640d7410c7b5b8f59 Mon Sep 17 00:00:00 2001 From: sqrrm Date: Sat, 21 Jul 2018 20:29:27 +0200 Subject: [PATCH 159/197] Rename burn bond to confiscate bond --- .../main/dao/proposal/ProposalDisplay.java | 36 +++++++++---------- .../dao/proposal/make/MakeProposalView.java | 6 ++-- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java index 09e3367d8a7..e322ac3a545 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java @@ -33,9 +33,9 @@ import bisq.core.dao.voting.proposal.Proposal; import bisq.core.dao.voting.proposal.ProposalConsensus; import bisq.core.dao.voting.proposal.ProposalType; -import bisq.core.dao.voting.proposal.burnbond.BurnBondProposal; import bisq.core.dao.voting.proposal.compensation.CompensationConsensus; import bisq.core.dao.voting.proposal.compensation.CompensationProposal; +import bisq.core.dao.voting.proposal.confiscatebond.ConfiscateBondProposal; import bisq.core.dao.voting.proposal.param.ChangeParamProposal; import bisq.core.locale.Res; import bisq.core.util.BsqFormatter; @@ -86,7 +86,7 @@ public class ProposalDisplay { public InputTextField requestedBsqTextField, bsqAddressTextField, paramValueTextField; @Nullable public ComboBox paramComboBox; - public ComboBox burnBondComboBox; + public ComboBox confiscateBondComboBox; @Getter private int gridRow; public TextArea descriptionTextArea; @@ -126,7 +126,7 @@ public void createAllFields(String title, int gridRowStartIndex, double top, Pro int rowSpan; boolean hasAddedFields = proposalType == ProposalType.COMPENSATION_REQUEST || - proposalType == ProposalType.CHANGE_PARAM || proposalType == ProposalType.BURN_BOND; + proposalType == ProposalType.CHANGE_PARAM || proposalType == ProposalType.CONFISCATE_BOND; if (isMakeProposalScreen) { rowSpan = hasAddedFields ? 8 : 6; } else if (showDetails) { @@ -137,7 +137,7 @@ public void createAllFields(String title, int gridRowStartIndex, double top, Pro rowSpan = 6; else if (proposalType == ProposalType.CHANGE_PARAM) rowSpan = 7; - else if (proposalType == ProposalType.BURN_BOND) + else if (proposalType == ProposalType.CONFISCATE_BOND) rowSpan = 6; else rowSpan = 5; @@ -208,14 +208,14 @@ public Param fromString(String string) { break; case REMOVE_ALTCOIN: break; - case BURN_BOND: - burnBondComboBox = addLabelComboBox(gridPane, ++gridRow, - Res.get("dao.proposal.display.burnBondComboBox.label")).second; - ObservableList burnableBonds = + case CONFISCATE_BOND: + confiscateBondComboBox = addLabelComboBox(gridPane, ++gridRow, + Res.get("dao.proposal.display.confiscateBondComboBox.label")).second; + ObservableList confiscatableBonds = FXCollections.observableArrayList(daoFacade.getLockupAndUnlockingBondIds()); -// burnableBonds.addAll("bond1", "bond2", "bond3"); - burnBondComboBox.setItems(burnableBonds); - burnBondComboBox.setConverter(new StringConverter() { +// confiscatableBonds.addAll("bond1", "bond2", "bond3"); + confiscateBondComboBox.setItems(confiscatableBonds); + confiscateBondComboBox.setConverter(new StringConverter() { @Override public String toString(byte[] id) { return Utilities.bytesAsHexString(id); @@ -263,10 +263,10 @@ public void applyProposalPayload(Proposal proposal) { paramComboBox.getSelectionModel().select(changeParamProposal.getParam()); checkNotNull(paramValueTextField, "paramValueTextField must no tbe null"); paramValueTextField.setText(String.valueOf(changeParamProposal.getParamValue())); - } else if (proposal instanceof BurnBondProposal) { - BurnBondProposal burnBondProposal = (BurnBondProposal) proposal; - checkNotNull(burnBondComboBox, "burnBondComboBox must not be null"); - burnBondComboBox.getSelectionModel().select(burnBondProposal.getBondId()); + } else if (proposal instanceof ConfiscateBondProposal) { + ConfiscateBondProposal confiscateBondProposal = (ConfiscateBondProposal) proposal; + checkNotNull(confiscateBondComboBox, "confiscateBondComboBox must not be null"); + confiscateBondComboBox.getSelectionModel().select(confiscateBondProposal.getBondId()); } int chainHeight; if (txIdTextField != null) { @@ -289,7 +289,7 @@ public void clearForm() { if (bsqAddressTextField != null) bsqAddressTextField.clear(); if (paramComboBox != null) paramComboBox.getSelectionModel().clearSelection(); if (paramValueTextField != null) paramValueTextField.clear(); - if (burnBondComboBox != null) burnBondComboBox.getSelectionModel().clearSelection(); + if (confiscateBondComboBox != null) confiscateBondComboBox.getSelectionModel().clearSelection(); if (txIdTextField != null) txIdTextField.cleanup(); if (descriptionTextArea != null) descriptionTextArea.textProperty().removeListener(descriptionTextAreaListener); } @@ -326,8 +326,8 @@ public void setEditable(boolean isEditable) { if (paramValueTextField != null) paramValueTextField.setEditable(isEditable); - if (burnBondComboBox != null) - burnBondComboBox.setDisable(!isEditable); + if (confiscateBondComboBox != null) + confiscateBondComboBox.setDisable(!isEditable); linkInputTextField.setVisible(true); linkInputTextField.setManaged(true); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index 431252d5478..7a19c6c6c28 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -282,12 +282,12 @@ private ProposalWithTransaction getProposalWithTransaction(ProposalType type) case REMOVE_ALTCOIN: //TODO throw new RuntimeException("Not implemented yet"); - case BURN_BOND: - byte[] bondId = proposalDisplay.burnBondComboBox.getSelectionModel().getSelectedItem(); + case CONFISCATE_BOND: + byte[] bondId = proposalDisplay.confiscateBondComboBox.getSelectionModel().getSelectedItem(); if (bondId == null || bondId.length == 0) throw new ValidationException("Invalid bond id, null or zero length"); - return daoFacade.getBurnBondProposalWithTransaction(proposalDisplay.nameTextField.getText(), + return daoFacade.getConfiscateBondProposalWithTransaction(proposalDisplay.nameTextField.getText(), proposalDisplay.titleTextField.getText(), proposalDisplay.descriptionTextArea.getText(), proposalDisplay.linkInputTextField.getText(), From 68e2389c301ac7845ac3b4b79c0bb9bdefd1800a Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sun, 22 Jul 2018 00:12:20 +0200 Subject: [PATCH 160/197] Changes from review of bond confiscation PR --- .../main/dao/bonding/lockup/LockupView.java | 22 ++++++++++++------- .../main/dao/proposal/ProposalDisplay.java | 21 +++++++++--------- .../dao/proposal/make/MakeProposalView.java | 6 ++--- 3 files changed, 28 insertions(+), 21 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java b/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java index 789cbc33c83..19d0931b21b 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java @@ -44,6 +44,8 @@ import bisq.network.p2p.P2PService; +import bisq.common.util.Utilities; + import org.bitcoinj.core.Coin; import org.bitcoinj.core.InsufficientMoneyException; @@ -60,6 +62,7 @@ import javafx.util.StringConverter; import java.util.Arrays; +import java.util.Optional; import static bisq.desktop.util.FormBuilder.addButtonAfterGroup; import static bisq.desktop.util.FormBuilder.addLabelComboBox; @@ -153,7 +156,10 @@ public LockupType fromString(String string) { bondIdInputTextField = addLabelInputTextField(root, ++gridRow, Res.get("dao.bonding.lock.bondId"), Layout.GRID_GAP).second; bondIdInputTextField.setPromptText(Res.get("dao.bonding.lock.setBondId")); - bondIdInputTextField.setValidator(bondIdValidator); + + // TODO atm it does not make sense to validate as we dont use real data + // data should get derived anyway sfrom human readable sources + //bondIdInputTextField.setValidator(bondIdValidator); lockupButton = addButtonAfterGroup(root, ++gridRow, Res.get("dao.bonding.lock.lockupButton")); lockupButton.setOnAction((event) -> { @@ -161,12 +167,12 @@ public LockupType fromString(String string) { Coin lockupAmount = bsqFormatter.parseToCoin(amountInputTextField.getText()); int lockupTime = Integer.parseInt(timeInputTextField.getText()); LockupType type = lockupTypeComboBox.getValue(); - // TODO get hash of something -// byte[] bytes = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; - byte[] bytes = bondIdInputTextField.getText().getBytes(); - if (type != LockupType.BONDED_ROLE) - bytes = null; - final byte[] hash = bytes; + //TODO use mapping to human readable input + Optional hashOfBondId; + if (type == LockupType.BONDED_ROLE) + hashOfBondId = Optional.of(Utilities.decodeFromHex(bondIdInputTextField.getText())); + else + hashOfBondId = Optional.empty(); new Popup<>().headLine(Res.get("dao.bonding.lock.sendFunds.headline")) .confirmation(Res.get("dao.bonding.lock.sendFunds.details", @@ -178,7 +184,7 @@ public LockupType fromString(String string) { daoFacade.publishLockupTx(lockupAmount, lockupTime, type, - hash, + hashOfBondId, () -> { new Popup<>().feedback(Res.get("dao.tx.published.success")).show(); }, diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java index e322ac3a545..a557983503b 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java @@ -86,6 +86,7 @@ public class ProposalDisplay { public InputTextField requestedBsqTextField, bsqAddressTextField, paramValueTextField; @Nullable public ComboBox paramComboBox; + @Nullable public ComboBox confiscateBondComboBox; @Getter private int gridRow; @@ -175,13 +176,13 @@ else if (proposalType == ProposalType.CONFISCATE_BOND) requestedBsqTextField = addLabelInputTextField(gridPane, ++gridRow, Res.get("dao.proposal.display.requestedBsq")).second; BsqValidator bsqValidator = new BsqValidator(bsqFormatter); bsqValidator.setMinValue(CompensationConsensus.getMinCompensationRequestAmount()); - checkNotNull(requestedBsqTextField, "requestedBsqTextField must no tbe null"); + checkNotNull(requestedBsqTextField, "requestedBsqTextField must not be null"); requestedBsqTextField.setValidator(bsqValidator); // TODO validator, addressTF if (showDetails) { bsqAddressTextField = addLabelInputTextField(gridPane, ++gridRow, Res.get("dao.proposal.display.bsqAddress")).second; - checkNotNull(bsqAddressTextField, "bsqAddressTextField must no tbe null"); + checkNotNull(bsqAddressTextField, "bsqAddressTextField must not be null"); bsqAddressTextField.setText("B" + bsqWalletService.getUnusedAddress().toBase58()); bsqAddressTextField.setValidator(new BsqAddressValidator(bsqFormatter)); } @@ -189,9 +190,9 @@ else if (proposalType == ProposalType.CONFISCATE_BOND) case GENERIC: break; case CHANGE_PARAM: - checkNotNull(gridPane, "gridPane must no tbe null"); + checkNotNull(gridPane, "gridPane must not be null"); paramComboBox = addLabelComboBox(gridPane, ++gridRow, Res.get("dao.proposal.display.paramComboBox.label")).second; - checkNotNull(paramComboBox, "paramComboBox must no tbe null"); + checkNotNull(paramComboBox, "paramComboBox must not be null"); paramComboBox.setItems(FXCollections.observableArrayList(Param.values())); paramComboBox.setConverter(new StringConverter() { @Override @@ -211,13 +212,13 @@ public Param fromString(String string) { case CONFISCATE_BOND: confiscateBondComboBox = addLabelComboBox(gridPane, ++gridRow, Res.get("dao.proposal.display.confiscateBondComboBox.label")).second; - ObservableList confiscatableBonds = + ObservableList lockupAndUnlockingBondIds = FXCollections.observableArrayList(daoFacade.getLockupAndUnlockingBondIds()); -// confiscatableBonds.addAll("bond1", "bond2", "bond3"); - confiscateBondComboBox.setItems(confiscatableBonds); + confiscateBondComboBox.setItems(lockupAndUnlockingBondIds); confiscateBondComboBox.setConverter(new StringConverter() { @Override public String toString(byte[] id) { + //TODO map to some human readable data source return Utilities.bytesAsHexString(id); } @@ -253,7 +254,7 @@ public void applyProposalPayload(Proposal proposal) { linkHyperlinkWithIcon.setOnAction(e -> GUIUtil.openWebPage(proposal.getLink())); if (proposal instanceof CompensationProposal) { CompensationProposal compensationProposal = (CompensationProposal) proposal; - checkNotNull(requestedBsqTextField, "requestedBsqTextField must no tbe null"); + checkNotNull(requestedBsqTextField, "requestedBsqTextField must not be null"); requestedBsqTextField.setText(bsqFormatter.formatCoinWithCode(compensationProposal.getRequestedBsq())); if (bsqAddressTextField != null) bsqAddressTextField.setText(compensationProposal.getBsqAddress()); @@ -261,12 +262,12 @@ public void applyProposalPayload(Proposal proposal) { ChangeParamProposal changeParamProposal = (ChangeParamProposal) proposal; checkNotNull(paramComboBox, "paramComboBox must not be null"); paramComboBox.getSelectionModel().select(changeParamProposal.getParam()); - checkNotNull(paramValueTextField, "paramValueTextField must no tbe null"); + checkNotNull(paramValueTextField, "paramValueTextField must not be null"); paramValueTextField.setText(String.valueOf(changeParamProposal.getParamValue())); } else if (proposal instanceof ConfiscateBondProposal) { ConfiscateBondProposal confiscateBondProposal = (ConfiscateBondProposal) proposal; checkNotNull(confiscateBondComboBox, "confiscateBondComboBox must not be null"); - confiscateBondComboBox.getSelectionModel().select(confiscateBondProposal.getBondId()); + confiscateBondComboBox.getSelectionModel().select(confiscateBondProposal.getHashOfBondId()); } int chainHeight; if (txIdTextField != null) { diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index 7a19c6c6c28..313403f6162 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -283,15 +283,15 @@ private ProposalWithTransaction getProposalWithTransaction(ProposalType type) //TODO throw new RuntimeException("Not implemented yet"); case CONFISCATE_BOND: - byte[] bondId = proposalDisplay.confiscateBondComboBox.getSelectionModel().getSelectedItem(); - if (bondId == null || bondId.length == 0) + byte[] hashOfBondId = proposalDisplay.confiscateBondComboBox.getSelectionModel().getSelectedItem(); + if (hashOfBondId == null || hashOfBondId.length == 0) throw new ValidationException("Invalid bond id, null or zero length"); return daoFacade.getConfiscateBondProposalWithTransaction(proposalDisplay.nameTextField.getText(), proposalDisplay.titleTextField.getText(), proposalDisplay.descriptionTextArea.getText(), proposalDisplay.linkInputTextField.getText(), - bondId); + hashOfBondId); default: final String msg = "Undefined ProposalType " + selectedProposalType; log.error(msg); From 6077cca35f700daee79b2ade4a47eecd03e556ca Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sun, 22 Jul 2018 02:16:27 +0200 Subject: [PATCH 161/197] Add bonds for selecting bond id --- .../main/dao/bonding/lockup/LockupView.java | 48 ++++++++++--------- .../main/dao/proposal/ProposalDisplay.java | 11 +++-- 2 files changed, 32 insertions(+), 27 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java b/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java index 19d0931b21b..b6b9fcdff4c 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java @@ -35,17 +35,16 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.WalletsSetup; import bisq.core.dao.DaoFacade; +import bisq.core.dao.bonding.Bond; import bisq.core.dao.bonding.BondingConsensus; +import bisq.core.dao.bonding.Bonds; import bisq.core.dao.bonding.lockup.LockupType; import bisq.core.locale.Res; import bisq.core.util.BsqFormatter; import bisq.core.util.validation.IntegerValidator; -import bisq.core.util.validation.StringValidator; import bisq.network.p2p.P2PService; -import bisq.common.util.Utilities; - import org.bitcoinj.core.Coin; import org.bitcoinj.core.InsufficientMoneyException; @@ -80,13 +79,12 @@ public class LockupView extends ActivatableView implements BsqBa private final BsqValidator bsqValidator; private final DaoFacade daoFacade; private final IntegerValidator timeInputTextFieldValidator; - private final StringValidator bondIdValidator; private int gridRow = 0; private InputTextField amountInputTextField; private InputTextField timeInputTextField; private ComboBox lockupTypeComboBox; - private InputTextField bondIdInputTextField; + private ComboBox bondsComboBox; private Button lockupButton; private ChangeListener focusOutListener; private ChangeListener inputTextFieldListener; @@ -117,9 +115,6 @@ private LockupView(BsqWalletService bsqWalletService, timeInputTextFieldValidator = new IntegerValidator(); timeInputTextFieldValidator.setMinValue(BondingConsensus.getMinLockTime()); timeInputTextFieldValidator.setMaxValue(BondingConsensus.getMaxLockTime()); - - bondIdValidator = new StringValidator(); - bondIdValidator.setLength(20); } @Override @@ -133,13 +128,13 @@ public void initialize() { amountInputTextField.setPromptText(Res.get("dao.bonding.lock.setAmount", bsqFormatter.formatCoinWithCode(Restrictions.getMinNonDustOutput()))); amountInputTextField.setValidator(bsqValidator); - timeInputTextField = addLabelInputTextField(root, ++gridRow, Res.get("dao.bonding.lock.time"), Layout.GRID_GAP).second; + timeInputTextField = addLabelInputTextField(root, ++gridRow, Res.get("dao.bonding.lock.time")).second; timeInputTextField.setPromptText(Res.get("dao.bonding.lock.setTime", String.valueOf(BondingConsensus.getMinLockTime()), String.valueOf(BondingConsensus.getMaxLockTime()))); timeInputTextField.setValidator(timeInputTextFieldValidator); - lockupTypeComboBox = addLabelComboBox(root, ++gridRow, - Res.getWithCol("dao.bonding.lock.type"), Layout.GRID_GAP).second; + lockupTypeComboBox = addLabelComboBox(root, ++gridRow, Res.get("dao.bonding.lock.type")).second; + lockupTypeComboBox.setPromptText(Res.get("list.currency.select")); lockupTypeComboBox.setConverter(new StringConverter() { @Override public String toString(LockupType lockupType) { @@ -152,14 +147,21 @@ public LockupType fromString(String string) { } }); lockupTypeComboBox.setItems(FXCollections.observableArrayList(Arrays.asList(LockupType.values()))); - lockupTypeComboBox.getSelectionModel().selectFirst(); - bondIdInputTextField = addLabelInputTextField(root, ++gridRow, Res.get("dao.bonding.lock.bondId"), Layout.GRID_GAP).second; - bondIdInputTextField.setPromptText(Res.get("dao.bonding.lock.setBondId")); + bondsComboBox = addLabelComboBox(root, ++gridRow, Res.get("dao.bonding.lock.bonds")).second; + bondsComboBox.setPromptText(Res.get("list.currency.select")); + bondsComboBox.setConverter(new StringConverter() { + @Override + public String toString(Bond bond) { + return bond.toDisplayString(); + } - // TODO atm it does not make sense to validate as we dont use real data - // data should get derived anyway sfrom human readable sources - //bondIdInputTextField.setValidator(bondIdValidator); + @Override + public Bond fromString(String string) { + return null; + } + }); + bondsComboBox.setItems(FXCollections.observableArrayList(Bonds.getBonds())); lockupButton = addButtonAfterGroup(root, ++gridRow, Res.get("dao.bonding.lock.lockupButton")); lockupButton.setOnAction((event) -> { @@ -169,11 +171,11 @@ public LockupType fromString(String string) { LockupType type = lockupTypeComboBox.getValue(); //TODO use mapping to human readable input Optional hashOfBondId; - if (type == LockupType.BONDED_ROLE) - hashOfBondId = Optional.of(Utilities.decodeFromHex(bondIdInputTextField.getText())); - else + if (type == LockupType.BONDED_ROLE) { + hashOfBondId = Optional.of(bondsComboBox.getSelectionModel().getSelectedItem().getHash()); + } else { hashOfBondId = Optional.empty(); - + } new Popup<>().headLine(Res.get("dao.bonding.lock.sendFunds.headline")) .confirmation(Res.get("dao.bonding.lock.sendFunds.details", bsqFormatter.formatCoinWithCode(lockupAmount), @@ -256,7 +258,9 @@ private void onUpdateBalances() { private void updateButtonState() { lockupButton.setDisable(!bsqValidator.validate(amountInputTextField.getText()).isValid || - !timeInputTextFieldValidator.validate(timeInputTextField.getText()).isValid); + !timeInputTextFieldValidator.validate(timeInputTextField.getText()).isValid || + bondsComboBox.getSelectionModel().getSelectedItem() == null || + lockupTypeComboBox.getSelectionModel().getSelectedItem() == null); } private void handleError(Throwable throwable) { diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java index a557983503b..e44438eec06 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java @@ -28,6 +28,8 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; +import bisq.core.dao.bonding.Bond; +import bisq.core.dao.bonding.Bonds; import bisq.core.dao.state.blockchain.Tx; import bisq.core.dao.state.ext.Param; import bisq.core.dao.voting.proposal.Proposal; @@ -40,8 +42,6 @@ import bisq.core.locale.Res; import bisq.core.util.BsqFormatter; -import bisq.common.util.Utilities; - import javafx.scene.control.ComboBox; import javafx.scene.control.ScrollPane; import javafx.scene.control.TextArea; @@ -60,6 +60,7 @@ import javafx.util.StringConverter; +import java.util.Optional; import java.util.UUID; import lombok.Getter; @@ -217,9 +218,9 @@ public Param fromString(String string) { confiscateBondComboBox.setItems(lockupAndUnlockingBondIds); confiscateBondComboBox.setConverter(new StringConverter() { @Override - public String toString(byte[] id) { - //TODO map to some human readable data source - return Utilities.bytesAsHexString(id); + public String toString(byte[] hashOfBondId) { + Optional bond = Bonds.getBond(hashOfBondId); + return bond.isPresent() ? bond.get().toDisplayString() : "-"; } @Override From ccd3e9c5bafbc34916eafe3c8fab40b61601db64 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Mon, 23 Jul 2018 02:22:18 +0200 Subject: [PATCH 162/197] Add BondedRoles proposal and views --- .../ArbitratorRegistrationViewModel.java | 8 +- .../desktop/main/dao/BaseProposalView.java | 2 +- .../desktop/main/dao/bonding/BondingView.java | 13 +- .../main/dao/bonding/lockup/LockupView.java | 70 ++- .../bonding/roles/BondedRoleTypeWindow.java | 93 ++++ .../bonding/roles/BondedRolesListItem.java | 72 +++ .../dao/bonding/roles/BondedRolesView.fxml | 34 ++ .../dao/bonding/roles/BondedRolesView.java | 490 ++++++++++++++++++ .../main/dao/bonding/unlock/UnlockView.java | 4 +- .../main/dao/proposal/ProposalDisplay.java | 210 +++++--- .../main/dao/proposal/ProposalWindow.java | 2 +- .../proposal/active/ActiveProposalsView.java | 2 +- .../dao/proposal/make/MakeProposalView.java | 73 ++- .../desktop/main/dao/results/ResultsView.java | 11 +- .../proposals/ProposalResultsListItem.java | 20 +- .../VoteResultsForProposalWindow.java | 4 +- 16 files changed, 959 insertions(+), 149 deletions(-) create mode 100644 src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRoleTypeWindow.java create mode 100644 src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesListItem.java create mode 100644 src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesView.fxml create mode 100644 src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesView.java diff --git a/src/main/java/bisq/desktop/main/account/arbitratorregistration/ArbitratorRegistrationViewModel.java b/src/main/java/bisq/desktop/main/account/arbitratorregistration/ArbitratorRegistrationViewModel.java index 1ffa41fddf0..035cfde20e6 100644 --- a/src/main/java/bisq/desktop/main/account/arbitratorregistration/ArbitratorRegistrationViewModel.java +++ b/src/main/java/bisq/desktop/main/account/arbitratorregistration/ArbitratorRegistrationViewModel.java @@ -136,12 +136,12 @@ void onRemoveLanguage(String code) { } boolean setPrivKeyAndCheckPubKey(String privKeyString) { - ECKey _registrationKey = arbitratorManager.getRegistrationKey(privKeyString); - if (_registrationKey != null) { - String _registrationPubKeyAsHex = Utils.HEX.encode(_registrationKey.getPubKey()); + ECKey registrationKey = arbitratorManager.getRegistrationKey(privKeyString); + if (registrationKey != null) { + String _registrationPubKeyAsHex = Utils.HEX.encode(registrationKey.getPubKey()); boolean isKeyValid = arbitratorManager.isPublicKeyInList(_registrationPubKeyAsHex); if (isKeyValid) { - registrationKey = _registrationKey; + this.registrationKey = registrationKey; registrationPubKeyAsHex.set(_registrationPubKeyAsHex); } updateDisableStates(); diff --git a/src/main/java/bisq/desktop/main/dao/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/BaseProposalView.java index 7dc7b0bdf3d..ec228a74acf 100644 --- a/src/main/java/bisq/desktop/main/dao/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/BaseProposalView.java @@ -181,7 +181,7 @@ protected void createAllFieldsOnProposalDisplay(Proposal proposal) { proposalDisplayView.setManaged(true); proposalDisplay.createAllFields(Res.get("dao.proposal.selectedProposal"), 0, 0, proposal.getType(), - false, false); + false); proposalDisplay.setEditable(false); proposalDisplay.applyProposalPayload(proposal); proposalDisplayInitialized = true; diff --git a/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java b/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java index 0e4670a91de..973464a6920 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java @@ -29,6 +29,7 @@ import bisq.desktop.main.dao.DaoView; import bisq.desktop.main.dao.bonding.dashboard.BondingDashboardView; import bisq.desktop.main.dao.bonding.lockup.LockupView; +import bisq.desktop.main.dao.bonding.roles.BondedRolesView; import bisq.desktop.main.dao.bonding.unlock.UnlockView; import bisq.core.locale.Res; @@ -52,7 +53,7 @@ public class BondingView extends ActivatableViewAndModel { private final ViewLoader viewLoader; private final Navigation navigation; - private MenuItem dashboard, lockupBSQ, unlockBSQ; + private MenuItem dashboard, bondedRoles, lockupBSQ, unlockBSQ; private Navigation.Listener listener; @FXML @@ -82,16 +83,20 @@ public void initialize() { final List> baseNavPath = Arrays.asList(MainView.class, DaoView.class, bisq.desktop.main.dao.bonding.BondingView.class); dashboard = new MenuItem(navigation, toggleGroup, Res.get("shared.dashboard"), BondingDashboardView.class, AwesomeIcon.DASHBOARD, baseNavPath); + bondedRoles = new MenuItem(navigation, toggleGroup, Res.get("dao.bonding.menuItem.bondedRoles"), + BondedRolesView.class, AwesomeIcon.SHIELD, baseNavPath); lockupBSQ = new MenuItem(navigation, toggleGroup, Res.get("dao.bonding.menuItem.lockupBSQ"), LockupView.class, AwesomeIcon.LOCK, baseNavPath); unlockBSQ = new MenuItem(navigation, toggleGroup, Res.get("dao.bonding.menuItem.unlockBSQ"), UnlockView.class, AwesomeIcon.UNLOCK, baseNavPath); - leftVBox.getChildren().addAll(dashboard, lockupBSQ, unlockBSQ); + + leftVBox.getChildren().addAll(dashboard, bondedRoles, lockupBSQ, unlockBSQ); } @Override protected void activate() { dashboard.activate(); + bondedRoles.activate(); lockupBSQ.activate(); unlockBSQ.activate(); @@ -100,7 +105,7 @@ protected void activate() { if (viewPath.size() == 3 && viewPath.indexOf(BondingView.class) == 2 || viewPath.size() == 2 && viewPath.indexOf(DaoView.class) == 1) { if (selectedViewClass == null) - selectedViewClass = LockupView.class; + selectedViewClass = BondedRolesView.class; loadView(selectedViewClass); @@ -115,6 +120,7 @@ protected void deactivate() { navigation.removeListener(listener); dashboard.deactivate(); + bondedRoles.deactivate(); lockupBSQ.deactivate(); unlockBSQ.deactivate(); } @@ -124,6 +130,7 @@ private void loadView(Class viewClass) { content.getChildren().setAll(view.getRoot()); if (view instanceof BondingDashboardView) dashboard.setSelected(true); + else if (view instanceof BondedRolesView) bondedRoles.setSelected(true); else if (view instanceof LockupView) lockupBSQ.setSelected(true); else if (view instanceof UnlockView) unlockBSQ.setSelected(true); } diff --git a/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java b/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java index b6b9fcdff4c..36aeb8d427b 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java @@ -35,10 +35,9 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.WalletsSetup; import bisq.core.dao.DaoFacade; -import bisq.core.dao.bonding.Bond; import bisq.core.dao.bonding.BondingConsensus; -import bisq.core.dao.bonding.Bonds; import bisq.core.dao.bonding.lockup.LockupType; +import bisq.core.dao.role.BondedRole; import bisq.core.locale.Res; import bisq.core.util.BsqFormatter; import bisq.core.util.validation.IntegerValidator; @@ -61,7 +60,6 @@ import javafx.util.StringConverter; import java.util.Arrays; -import java.util.Optional; import static bisq.desktop.util.FormBuilder.addButtonAfterGroup; import static bisq.desktop.util.FormBuilder.addLabelComboBox; @@ -84,10 +82,12 @@ public class LockupView extends ActivatableView implements BsqBa private InputTextField amountInputTextField; private InputTextField timeInputTextField; private ComboBox lockupTypeComboBox; - private ComboBox bondsComboBox; + private ComboBox bondedRolesComboBox; private Button lockupButton; private ChangeListener focusOutListener; private ChangeListener inputTextFieldListener; + private ChangeListener bondedRolesListener; + private ChangeListener lockupTypeListener; /////////////////////////////////////////////////////////////////////////////////////////// @@ -134,11 +134,11 @@ public void initialize() { timeInputTextField.setValidator(timeInputTextFieldValidator); lockupTypeComboBox = addLabelComboBox(root, ++gridRow, Res.get("dao.bonding.lock.type")).second; - lockupTypeComboBox.setPromptText(Res.get("list.currency.select")); + lockupTypeComboBox.setPromptText(Res.get("shared.select")); lockupTypeComboBox.setConverter(new StringConverter() { @Override public String toString(LockupType lockupType) { - return lockupType.toString(); + return lockupType.getDisplayString(); } @Override @@ -147,35 +147,52 @@ public LockupType fromString(String string) { } }); lockupTypeComboBox.setItems(FXCollections.observableArrayList(Arrays.asList(LockupType.values()))); + lockupTypeListener = (observable, oldValue, newValue) -> { + if (newValue != null) { + bondedRolesComboBox.getSelectionModel().clearSelection(); + } + }; + //TODO handle trade type + lockupTypeComboBox.getSelectionModel().select(0); - bondsComboBox = addLabelComboBox(root, ++gridRow, Res.get("dao.bonding.lock.bonds")).second; - bondsComboBox.setPromptText(Res.get("list.currency.select")); - bondsComboBox.setConverter(new StringConverter() { + bondedRolesComboBox = addLabelComboBox(root, ++gridRow, Res.get("dao.bonding.lock.bondedRoles")).second; + bondedRolesComboBox.setPromptText(Res.get("shared.select")); + bondedRolesComboBox.setConverter(new StringConverter() { @Override - public String toString(Bond bond) { - return bond.toDisplayString(); + public String toString(BondedRole bondedRole) { + return bondedRole.getDisplayString(); } @Override - public Bond fromString(String string) { + public BondedRole fromString(String string) { return null; } }); - bondsComboBox.setItems(FXCollections.observableArrayList(Bonds.getBonds())); + bondedRolesListener = (observable, oldValue, newValue) -> { + if (newValue != null) { + amountInputTextField.setText(bsqFormatter.formatCoin(Coin.valueOf(newValue.getBondedRoleType().getRequiredBond()))); + timeInputTextField.setText(String.valueOf(newValue.getBondedRoleType().getUnlockTime())); + amountInputTextField.resetValidation(); + timeInputTextField.resetValidation(); + amountInputTextField.setEditable(false); + timeInputTextField.setEditable(false); + } else { + amountInputTextField.clear(); + timeInputTextField.clear(); + amountInputTextField.resetValidation(); + timeInputTextField.resetValidation(); + amountInputTextField.setEditable(true); + timeInputTextField.setEditable(true); + } + }; lockupButton = addButtonAfterGroup(root, ++gridRow, Res.get("dao.bonding.lock.lockupButton")); lockupButton.setOnAction((event) -> { if (GUIUtil.isReadyForTxBroadcast(p2PService, walletsSetup)) { Coin lockupAmount = bsqFormatter.parseToCoin(amountInputTextField.getText()); int lockupTime = Integer.parseInt(timeInputTextField.getText()); - LockupType type = lockupTypeComboBox.getValue(); - //TODO use mapping to human readable input - Optional hashOfBondId; - if (type == LockupType.BONDED_ROLE) { - hashOfBondId = Optional.of(bondsComboBox.getSelectionModel().getSelectedItem().getHash()); - } else { - hashOfBondId = Optional.empty(); - } + LockupType lockupType = lockupTypeComboBox.getValue(); + BondedRole bondedRole = bondedRolesComboBox.getValue(); new Popup<>().headLine(Res.get("dao.bonding.lock.sendFunds.headline")) .confirmation(Res.get("dao.bonding.lock.sendFunds.details", bsqFormatter.formatCoinWithCode(lockupAmount), @@ -185,8 +202,8 @@ public Bond fromString(String string) { .onAction(() -> { daoFacade.publishLockupTx(lockupAmount, lockupTime, - type, - hashOfBondId, + lockupType, + bondedRole, () -> { new Popup<>().feedback(Res.get("dao.tx.published.success")).show(); }, @@ -218,9 +235,12 @@ protected void activate() { amountInputTextField.textProperty().addListener(inputTextFieldListener); timeInputTextField.textProperty().addListener(inputTextFieldListener); amountInputTextField.focusedProperty().addListener(focusOutListener); + lockupTypeComboBox.getSelectionModel().selectedItemProperty().addListener(lockupTypeListener); + bondedRolesComboBox.getSelectionModel().selectedItemProperty().addListener(bondedRolesListener); bsqWalletService.addBsqBalanceListener(this); + bondedRolesComboBox.setItems(FXCollections.observableArrayList(daoFacade.getBondedRoleList())); onUpdateBalances(); } @@ -231,6 +251,8 @@ protected void deactivate() { amountInputTextField.textProperty().removeListener(inputTextFieldListener); timeInputTextField.textProperty().removeListener(inputTextFieldListener); amountInputTextField.focusedProperty().removeListener(focusOutListener); + lockupTypeComboBox.getSelectionModel().selectedItemProperty().removeListener(lockupTypeListener); + bondedRolesComboBox.getSelectionModel().selectedItemProperty().removeListener(bondedRolesListener); bsqWalletService.removeBsqBalanceListener(this); } @@ -259,7 +281,7 @@ private void onUpdateBalances() { private void updateButtonState() { lockupButton.setDisable(!bsqValidator.validate(amountInputTextField.getText()).isValid || !timeInputTextFieldValidator.validate(timeInputTextField.getText()).isValid || - bondsComboBox.getSelectionModel().getSelectedItem() == null || + bondedRolesComboBox.getSelectionModel().getSelectedItem() == null || lockupTypeComboBox.getSelectionModel().getSelectedItem() == null); } diff --git a/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRoleTypeWindow.java b/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRoleTypeWindow.java new file mode 100644 index 00000000000..760f9b29c73 --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRoleTypeWindow.java @@ -0,0 +1,93 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.desktop.main.dao.bonding.roles; + +import bisq.desktop.main.overlays.Overlay; +import bisq.desktop.util.FormBuilder; + +import bisq.core.dao.role.BondedRoleType; +import bisq.core.locale.Res; +import bisq.core.util.BsqFormatter; + +import org.bitcoinj.core.Coin; + +import javafx.geometry.Insets; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class BondedRoleTypeWindow extends Overlay { + private final BondedRoleType bondedRoleType; + private final BsqFormatter bsqFormatter; + + + public BondedRoleTypeWindow(BondedRoleType bondedRoleType, BsqFormatter bsqFormatter) { + this.bondedRoleType = bondedRoleType; + this.bsqFormatter = bsqFormatter; + + width = 900; + type = Type.Confirmation; + + } + + /////////////////////////////////////////////////////////////////////////////////////////// + // Public API + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public void show() { + headLine = Res.get("dao.bond.bondedRoleType.details.header"); + + createGridPane(); + addHeadLine(); + addSeparator(); + addContent(); + addCloseButton(); + applyStyles(); + display(); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Protected + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + protected void createGridPane() { + super.createGridPane(); + gridPane.setPadding(new Insets(35, 40, 30, 40)); + gridPane.getStyleClass().add("grid-pane"); + } + + private void addContent() { + FormBuilder.addLabelTextField(gridPane, ++rowIndex, Res.getWithCol("dao.bond.bondedRoleType.details.role"), + bondedRoleType.getDisplayString()); + + FormBuilder.addLabelTextField(gridPane, ++rowIndex, Res.getWithCol("dao.bond.bondedRoleType.details.requiredBond"), + bsqFormatter.formatCoinWithCode(Coin.valueOf(bondedRoleType.getRequiredBond()))); + + FormBuilder.addLabelTextField(gridPane, ++rowIndex, Res.getWithCol("dao.bond.bondedRoleType.details.unlockTime"), + Res.get("dao.bond.bondedRoleType.details.blocks", bondedRoleType.getUnlockTime())); + + FormBuilder.addLabelHyperlinkWithIcon(gridPane, ++rowIndex, Res.getWithCol("dao.bond.bondedRoleType.details.link"), + bondedRoleType.getLink(), bondedRoleType.getLink()); + + FormBuilder.addLabelTextField(gridPane, ++rowIndex, Res.getWithCol("dao.bond.bondedRoleType.details.isSingleton"), + bsqFormatter.booleanToYesNo(bondedRoleType.isAllowMultipleHolders())); + } +} diff --git a/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesListItem.java b/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesListItem.java new file mode 100644 index 00000000000..5ef042d82f0 --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesListItem.java @@ -0,0 +1,72 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.desktop.main.dao.bonding.roles; + +import bisq.desktop.components.AutoTooltipButton; + +import bisq.core.dao.DaoFacade; +import bisq.core.dao.role.BondedRole; +import bisq.core.locale.Res; +import bisq.core.util.BsqFormatter; + +import java.util.Date; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.Getter; + +@EqualsAndHashCode +@Data +class BondedRolesListItem { + @Getter + private final BondedRole bondedRole; + private final DaoFacade daoFacade; + private final BsqFormatter bsqFormatter; + private final AutoTooltipButton button; + + BondedRolesListItem(BondedRole bondedRole, + DaoFacade daoFacade, + BsqFormatter bsqFormatter) { + this.bondedRole = bondedRole; + this.daoFacade = daoFacade; + this.bsqFormatter = bsqFormatter; + + + button = new AutoTooltipButton(); + button.setMinWidth(70); + button.setText(Res.get("dao.bond.table.revoke")); + button.setVisible(true); + button.setManaged(true); + } + + public String getStartDate() { + return bondedRole.getStartDate() > 0 ? + bsqFormatter.formatDateTime(new Date(bondedRole.getStartDate())) : + "-"; + } + + public String getRevokeDate() { + return bondedRole.getRevokeDate() > 0 ? + bsqFormatter.formatDateTime(new Date(bondedRole.getRevokeDate())) : + "-"; + } + + public static void cleanup() { + + } +} diff --git a/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesView.fxml b/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesView.fxml new file mode 100644 index 00000000000..987214b4904 --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesView.fxml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + diff --git a/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesView.java b/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesView.java new file mode 100644 index 00000000000..f970711a91b --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesView.java @@ -0,0 +1,490 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.desktop.main.dao.bonding.roles; + +import bisq.desktop.common.view.ActivatableView; +import bisq.desktop.common.view.FxmlView; +import bisq.desktop.components.AutoTooltipLabel; +import bisq.desktop.components.AutoTooltipTableColumn; +import bisq.desktop.components.HyperlinkWithIcon; +import bisq.desktop.components.TableGroupHeadline; +import bisq.desktop.main.dao.wallet.BsqBalanceUtil; +import bisq.desktop.util.GUIUtil; + +import bisq.core.btc.wallet.WalletsSetup; +import bisq.core.dao.DaoFacade; +import bisq.core.dao.role.BondedRoleType; +import bisq.core.dao.state.BsqStateListener; +import bisq.core.dao.state.blockchain.Block; +import bisq.core.locale.Res; +import bisq.core.user.Preferences; +import bisq.core.util.BsqFormatter; + +import bisq.network.p2p.P2PService; + +import javax.inject.Inject; + +import de.jensd.fx.fontawesome.AwesomeIcon; + +import javafx.scene.control.Button; +import javafx.scene.control.Hyperlink; +import javafx.scene.control.Label; +import javafx.scene.control.TableCell; +import javafx.scene.control.TableColumn; +import javafx.scene.control.TableView; +import javafx.scene.control.Tooltip; +import javafx.scene.layout.GridPane; + +import javafx.geometry.Insets; + +import javafx.beans.property.ReadOnlyObjectWrapper; + +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.collections.transformation.SortedList; + +import javafx.util.Callback; + +import java.util.stream.Collectors; + +@FxmlView +public class BondedRolesView extends ActivatableView implements BsqStateListener { + private TableView tableView; + + private final BsqFormatter bsqFormatter; + private final DaoFacade daoFacade; + private final Preferences preferences; + + private final WalletsSetup walletsSetup; + private final P2PService p2PService; + + private int gridRow = 0; + + private final ObservableList observableList = FXCollections.observableArrayList(); + private final SortedList sortedList = new SortedList<>(observableList); + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Constructor, lifecycle + /////////////////////////////////////////////////////////////////////////////////////////// + + @Inject + private BondedRolesView(BsqFormatter bsqFormatter, + BsqBalanceUtil bsqBalanceUtil, + DaoFacade daoFacade, + Preferences preferences, + WalletsSetup walletsSetup, + P2PService p2PService) { + this.bsqFormatter = bsqFormatter; + this.daoFacade = daoFacade; + this.preferences = preferences; + this.walletsSetup = walletsSetup; + this.p2PService = p2PService; + } + + @Override + public void initialize() { + TableGroupHeadline headline = new TableGroupHeadline(Res.get("dao.bond.table.header")); + GridPane.setRowIndex(headline, gridRow); + GridPane.setMargin(headline, new Insets(0, -10, -10, -10)); + GridPane.setColumnSpan(headline, 2); + root.getChildren().add(headline); + + tableView = new TableView<>(); + tableView.setPlaceholder(new AutoTooltipLabel(Res.get("table.placeholder.noData"))); + tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); + + createColumns(); + + GridPane.setRowIndex(tableView, gridRow); + GridPane.setMargin(tableView, new Insets(20, -10, 5, -10)); + GridPane.setColumnSpan(tableView, 2); + root.getChildren().add(tableView); + + sortedList.comparatorProperty().bind(tableView.comparatorProperty()); + tableView.setItems(sortedList); + } + + @Override + protected void activate() { + daoFacade.addBsqStateListener(this); + + updateList(); + } + + @Override + protected void deactivate() { + daoFacade.removeBsqStateListener(this); + + observableList.forEach(e -> BondedRolesListItem.cleanup()); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // BsqStateListener + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public void onNewBlockHeight(int blockHeight) { + } + + @Override + public void onEmptyBlockAdded(Block block) { + } + + @Override + public void onParseTxsComplete(Block block) { + updateList(); + } + + @Override + public void onParseBlockChainComplete() { + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Private + /////////////////////////////////////////////////////////////////////////////////////////// + + + private void updateList() { + observableList.forEach(e -> BondedRolesListItem.cleanup()); + observableList.setAll(daoFacade.getBondedRoleList().stream() + .map(bondedRole -> new BondedRolesListItem(bondedRole, daoFacade, bsqFormatter)) + .collect(Collectors.toList())); + } + + private void onButtonClick() { + if (GUIUtil.isReadyForTxBroadcast(p2PService, walletsSetup)) { + // revoke TODO + /* Optional lockupTxOutput = daoFacade.getBondedRolesOutput(selectedItem.getTxId()); + if (!lockupTxOutput.isPresent()) { + log.warn("Lockup output not found, txId = ", selectedItem.getTxId()); + return; + } + + Coin unlockAmount = Coin.valueOf(lockupTxOutput.get().getValue()); + Optional opLockTime = daoFacade.getLockTime(selectedItem.getTxId()); + int lockTime = opLockTime.orElse(-1); + + try { + new Popup<>().headLine(Res.get("dao.bonding.unlock.sendTx.headline")) + .confirmation(Res.get("dao.bonding.unlock.sendTx.details", + bsqFormatter.formatCoinWithCode(unlockAmount), + lockTime + )) + .actionButtonText(Res.get("shared.yes")) + .onAction(() -> { + daoFacade.publishUnlockTx(selectedItem.getTxId(), + () -> { + new Popup<>().confirmation(Res.get("dao.tx.published.success")).show(); + }, + errorMessage -> new Popup<>().warning(errorMessage.toString()).show() + ); + }) + .closeButtonText(Res.get("shared.cancel")) + .show(); + } catch (Throwable t) { + log.error(t.toString()); + t.printStackTrace(); + new Popup<>().warning(t.getMessage()).show(); + }*/ + } else { + GUIUtil.showNotReadyForTxBroadcastPopups(p2PService, walletsSetup); + } + // log.info("unlock tx: {}", selectedItem.getTxId()); + } + + + private void openTxInBlockExplorer(String transactionId) { + if (transactionId != null) + GUIUtil.openWebPage(preferences.getBsqBlockChainExplorer().txUrl + transactionId); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Table columns + /////////////////////////////////////////////////////////////////////////////////////////// + + private void createColumns() { + TableColumn column; + + column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.name")); + column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); + column.setMinWidth(120); + column.setCellFactory( + new Callback, TableCell>() { + + @Override + public TableCell call(TableColumn column) { + return new TableCell() { + @Override + public void updateItem(final BondedRolesListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null && !empty) { + setText(item.getBondedRole().getName()); + } else + setText(""); + } + }; + } + }); + tableView.getColumns().add(column); + + column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.linkToAccount")); + column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); + column.setMinWidth(60); + column.setCellFactory( + new Callback, TableCell>() { + + @Override + public TableCell call(TableColumn column) { + return new TableCell() { + private HyperlinkWithIcon hyperlinkWithIcon; + + @Override + public void updateItem(final BondedRolesListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null && !empty) { + String link = item.getBondedRole().getLinkToAccount(); + hyperlinkWithIcon = new HyperlinkWithIcon(link, AwesomeIcon.EXTERNAL_LINK); + hyperlinkWithIcon.setOnAction(event -> GUIUtil.openWebPage(link)); + hyperlinkWithIcon.setTooltip(new Tooltip(Res.get("shared.openURL", link))); + setGraphic(hyperlinkWithIcon); + } else { + setGraphic(null); + if (hyperlinkWithIcon != null) + hyperlinkWithIcon.setOnAction(null); + } + } + }; + } + }); + tableView.getColumns().add(column); + + column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.bondedRoleType")); + column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); + column.setMinWidth(120); + column.setCellFactory( + new Callback, TableCell>() { + + @Override + public TableCell call(TableColumn column) { + return new TableCell() { + private Hyperlink hyperlink; + + @Override + public void updateItem(final BondedRolesListItem item, boolean empty) { + super.updateItem(item, empty); + + if (item != null && !empty) { + BondedRoleType bondedRoleType = item.getBondedRole().getBondedRoleType(); + String type = bondedRoleType.getDisplayString(); + hyperlink = new Hyperlink(type); + hyperlink.setOnAction(event -> { + new BondedRoleTypeWindow(bondedRoleType, bsqFormatter).show(); + }); + hyperlink.setTooltip(new Tooltip(Res.get("tooltip.openPopupForDetails", type))); + setGraphic(hyperlink); + } else { + setGraphic(null); + if (hyperlink != null) + hyperlink.setOnAction(null); + } + } + }; + } + }); + tableView.getColumns().add(column); + + column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.startDate")); + column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); + column.setMinWidth(60); + column.setCellFactory( + new Callback, TableCell>() { + + @Override + public TableCell call(TableColumn column) { + return new TableCell() { + @Override + public void updateItem(final BondedRolesListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null && !empty) { + setText(item.getStartDate()); + } else + setText(""); + } + }; + } + }); + tableView.getColumns().add(column); + + column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.revokeDate")); + column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); + column.setMinWidth(60); + column.setCellFactory( + new Callback, TableCell>() { + + @Override + public TableCell call(TableColumn column) { + return new TableCell() { + @Override + public void updateItem(final BondedRolesListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null && !empty) { + setText(item.getRevokeDate()); + } else + setText(""); + } + }; + } + }); + tableView.getColumns().add(column); + + column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.lockupTxId")); + column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); + column.setMinWidth(60); + column.setCellFactory( + new Callback, TableCell>() { + + @Override + public TableCell call(TableColumn column) { + return new TableCell() { + private HyperlinkWithIcon hyperlinkWithIcon; + private Label label; + + @Override + public void updateItem(final BondedRolesListItem item, boolean empty) { + super.updateItem(item, empty); + + if (item != null && !empty) { + String transactionId = item.getBondedRole().getLockupTxId(); + if (transactionId != null) { + hyperlinkWithIcon = new HyperlinkWithIcon(transactionId, AwesomeIcon.EXTERNAL_LINK); + hyperlinkWithIcon.setOnAction(event -> openTxInBlockExplorer(transactionId)); + hyperlinkWithIcon.setTooltip(new Tooltip(Res.get("tooltip.openBlockchainForTx", transactionId))); + setGraphic(hyperlinkWithIcon); + } else { + label = new Label("-"); + setGraphic(label); + } + } else { + setGraphic(null); + if (hyperlinkWithIcon != null) + hyperlinkWithIcon.setOnAction(null); + if (label != null) + label = null; + } + } + }; + } + }); + tableView.getColumns().add(column); + + column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.unlockTxId")); + column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); + column.setMinWidth(60); + column.setCellFactory( + new Callback, TableCell>() { + + @Override + public TableCell call(TableColumn column) { + return new TableCell() { + private HyperlinkWithIcon hyperlinkWithIcon; + private Label label; + + @Override + public void updateItem(final BondedRolesListItem item, boolean empty) { + super.updateItem(item, empty); + + if (item != null && !empty) { + String transactionId = item.getBondedRole().getUnlockTxId(); + if (transactionId != null) { + hyperlinkWithIcon = new HyperlinkWithIcon(transactionId, AwesomeIcon.EXTERNAL_LINK); + hyperlinkWithIcon.setOnAction(event -> openTxInBlockExplorer(transactionId)); + hyperlinkWithIcon.setTooltip(new Tooltip(Res.get("tooltip.openBlockchainForTx", transactionId))); + setGraphic(hyperlinkWithIcon); + } else { + label = new Label("-"); + setGraphic(label); + } + } else { + setGraphic(null); + if (hyperlinkWithIcon != null) + hyperlinkWithIcon.setOnAction(null); + if (label != null) + label = null; + } + } + }; + } + }); + tableView.getColumns().add(column); + + column = new TableColumn<>(); + column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); + column.setMinWidth(60); + column.setCellFactory( + new Callback, TableCell>() { + @Override + public TableCell call(TableColumn column) { + return new TableCell() { + Button button; + + @Override + public void updateItem(final BondedRolesListItem item, boolean empty) { + super.updateItem(item, empty); + + if (item != null && !empty) { + if (button == null) { + button = item.getButton(); + button.setOnAction(e -> { + onButtonClick(); + }); + setGraphic(button); + } + } else { + setGraphic(null); + if (button != null) { + button.setOnAction(null); + button = null; + } + } + } + }; + } + }); + tableView.getColumns().add(column); + } +} diff --git a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java index 1d0d01587fe..80ac11c52f1 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java @@ -422,8 +422,8 @@ public void updateItem(final LockupTxListItem item, boolean empty) { if (button == null) { button = item.getButton(); button.setOnAction(e -> { - UnlockView.this.selectedItem = item; - UnlockView.this.onButtonClick(); + selectedItem = item; + onButtonClick(); }); setGraphic(button); } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java index e44438eec06..4ee1c19c5aa 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java @@ -28,8 +28,8 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; -import bisq.core.dao.bonding.Bond; -import bisq.core.dao.bonding.Bonds; +import bisq.core.dao.role.BondedRole; +import bisq.core.dao.role.BondedRoleType; import bisq.core.dao.state.blockchain.Tx; import bisq.core.dao.state.ext.Param; import bisq.core.dao.voting.proposal.Proposal; @@ -39,10 +39,14 @@ import bisq.core.dao.voting.proposal.compensation.CompensationProposal; import bisq.core.dao.voting.proposal.confiscatebond.ConfiscateBondProposal; import bisq.core.dao.voting.proposal.param.ChangeParamProposal; +import bisq.core.dao.voting.proposal.role.BondedRoleProposal; import bisq.core.locale.Res; import bisq.core.util.BsqFormatter; +import bisq.common.util.Tuple2; + import javafx.scene.control.ComboBox; +import javafx.scene.control.Label; import javafx.scene.control.ScrollPane; import javafx.scene.control.TextArea; import javafx.scene.control.TextField; @@ -56,12 +60,13 @@ import javafx.beans.value.ChangeListener; import javafx.collections.FXCollections; -import javafx.collections.ObservableList; import javafx.util.StringConverter; -import java.util.Optional; +import java.util.Arrays; +import java.util.List; import java.util.UUID; +import java.util.stream.Collectors; import lombok.Getter; import lombok.extern.slf4j.Slf4j; @@ -80,7 +85,9 @@ public class ProposalDisplay { private DaoFacade daoFacade; private InputTextField uidTextField; private TextField proposalFeeTextField; + private TextField proposalTypeTextField; public InputTextField nameTextField; + @Nullable public InputTextField titleTextField; public InputTextField linkInputTextField; @Nullable @@ -88,15 +95,20 @@ public class ProposalDisplay { @Nullable public ComboBox paramComboBox; @Nullable - public ComboBox confiscateBondComboBox; + public ComboBox confiscateBondComboBox; + @Nullable + public ComboBox bondedRoleTypeComboBox; + @Getter private int gridRow; + @Nullable public TextArea descriptionTextArea; private HyperlinkWithIcon linkHyperlinkWithIcon; @Nullable private TxIdTextField txIdTextField; private final ChangeListener descriptionTextAreaListener; private int gridRowStartIndex; + private Label linkLabel; // TODO get that warning at closing the window... @@ -115,90 +127,131 @@ public ProposalDisplay(GridPane gridPane, BsqFormatter bsqFormatter, BsqWalletSe descriptionTextAreaListener = (observable, oldValue, newValue) -> { if (!ProposalConsensus.isDescriptionSizeValid(newValue)) { new Popup<>().warning(Res.get("dao.proposal.display.description.tooLong", maxLengthDescriptionText)).show(); - descriptionTextArea.setText(newValue.substring(0, maxLengthDescriptionText)); + if (descriptionTextArea != null) + descriptionTextArea.setText(newValue.substring(0, maxLengthDescriptionText)); } }; } public void createAllFields(String title, int gridRowStartIndex, double top, ProposalType proposalType, - boolean isMakeProposalScreen, boolean showDetails) { + boolean isMakeProposalScreen) { removeAllFields(); this.gridRowStartIndex = gridRowStartIndex; this.gridRow = gridRowStartIndex; - int rowSpan; - - boolean hasAddedFields = proposalType == ProposalType.COMPENSATION_REQUEST || - proposalType == ProposalType.CHANGE_PARAM || proposalType == ProposalType.CONFISCATE_BOND; - if (isMakeProposalScreen) { - rowSpan = hasAddedFields ? 8 : 6; - } else if (showDetails) { - rowSpan = hasAddedFields ? 9 : 7; - } else { - //noinspection IfCanBeSwitch - if (proposalType == ProposalType.COMPENSATION_REQUEST) + int rowSpan = 5; + boolean showTitle = true; + boolean showDescription = true; + + switch (proposalType) { + case COMPENSATION_REQUEST: rowSpan = 6; - else if (proposalType == ProposalType.CHANGE_PARAM) - rowSpan = 7; - else if (proposalType == ProposalType.CONFISCATE_BOND) + break; + case BONDED_ROLE: + rowSpan = 3; + showTitle = false; + showDescription = false; + break; + case REMOVE_ALTCOIN: + break; + case CHANGE_PARAM: rowSpan = 6; - else + break; + case GENERIC: + break; + case CONFISCATE_BOND: rowSpan = 5; + break; } + if (isMakeProposalScreen) + rowSpan += 2; addTitledGroupBg(gridPane, gridRow, rowSpan, title, top); - if (showDetails) { - uidTextField = addLabelInputTextField(gridPane, gridRow, - Res.getWithCol("shared.id"), top == Layout.GROUP_DISTANCE ? Layout.FIRST_ROW_AND_GROUP_DISTANCE : Layout.FIRST_ROW_DISTANCE).second; + double proposalTypeTop = top == Layout.GROUP_DISTANCE ? Layout.FIRST_ROW_AND_GROUP_DISTANCE : Layout.FIRST_ROW_DISTANCE; + proposalTypeTextField = addLabelTextField(gridPane, gridRow, + Res.getWithCol("dao.proposal.display.type"), proposalType.getDisplayName(), proposalTypeTop).second; + + if (!isMakeProposalScreen) { + uidTextField = addLabelInputTextField(gridPane, ++gridRow, Res.getWithCol("shared.id")).second; uidTextField.setEditable(false); nameTextField = addLabelInputTextField(gridPane, ++gridRow, Res.get("dao.proposal.display.name")).second; } else { - nameTextField = addLabelInputTextField(gridPane, gridRow, Res.get("dao.proposal.display.name"), - top == Layout.GROUP_DISTANCE ? Layout.FIRST_ROW_AND_GROUP_DISTANCE : Layout.FIRST_ROW_DISTANCE).second; + nameTextField = addLabelInputTextField(gridPane, ++gridRow, Res.get("dao.proposal.display.name")).second; } - titleTextField = addLabelInputTextField(gridPane, ++gridRow, Res.getWithCol("dao.proposal.title")).second; + if (showTitle) + titleTextField = addLabelInputTextField(gridPane, ++gridRow, Res.getWithCol("dao.proposal.title")).second; - descriptionTextArea = addLabelTextArea(gridPane, ++gridRow, Res.get("dao.proposal.display.description"), - Res.get("dao.proposal.display.description.prompt", maxLengthDescriptionText)).second; - descriptionTextArea.setMaxHeight(42); // for 2 lines - descriptionTextArea.setMinHeight(descriptionTextArea.getMaxHeight()); - if (isMakeProposalScreen) - descriptionTextArea.textProperty().addListener(descriptionTextAreaListener); + if (showDescription) { + descriptionTextArea = addLabelTextArea(gridPane, ++gridRow, Res.get("dao.proposal.display.description"), + Res.get("dao.proposal.display.description.prompt", maxLengthDescriptionText)).second; + descriptionTextArea.setMaxHeight(42); // for 2 lines + descriptionTextArea.setMinHeight(descriptionTextArea.getMaxHeight()); + if (isMakeProposalScreen) + descriptionTextArea.textProperty().addListener(descriptionTextAreaListener); + } + + Tuple2 tuple = addLabelInputTextField(gridPane, ++gridRow, + Res.get("dao.proposal.display.link")); + linkLabel = tuple.first; + linkInputTextField = tuple.second; + linkInputTextField.setPromptText(Res.get("dao.proposal.display.link.prompt")); - linkInputTextField = addLabelInputTextField(gridPane, ++gridRow, Res.get("dao.proposal.display.link")).second; - linkHyperlinkWithIcon = addLabelHyperlinkWithIcon(gridPane, gridRow, Res.get("dao.proposal.display.link"), "", "").second; + linkHyperlinkWithIcon = addLabelHyperlinkWithIcon(gridPane, gridRow, + "", "", "").second; linkHyperlinkWithIcon.setVisible(false); linkHyperlinkWithIcon.setManaged(false); - linkInputTextField.setPromptText(Res.get("dao.proposal.display.link.prompt")); switch (proposalType) { case COMPENSATION_REQUEST: - - requestedBsqTextField = addLabelInputTextField(gridPane, ++gridRow, Res.get("dao.proposal.display.requestedBsq")).second; + requestedBsqTextField = addLabelInputTextField(gridPane, ++gridRow, + Res.get("dao.proposal.display.requestedBsq")).second; BsqValidator bsqValidator = new BsqValidator(bsqFormatter); bsqValidator.setMinValue(CompensationConsensus.getMinCompensationRequestAmount()); checkNotNull(requestedBsqTextField, "requestedBsqTextField must not be null"); requestedBsqTextField.setValidator(bsqValidator); // TODO validator, addressTF - if (showDetails) { - bsqAddressTextField = addLabelInputTextField(gridPane, ++gridRow, - Res.get("dao.proposal.display.bsqAddress")).second; - checkNotNull(bsqAddressTextField, "bsqAddressTextField must not be null"); - bsqAddressTextField.setText("B" + bsqWalletService.getUnusedAddress().toBase58()); - bsqAddressTextField.setValidator(new BsqAddressValidator(bsqFormatter)); - } + bsqAddressTextField = addLabelInputTextField(gridPane, ++gridRow, + Res.get("dao.proposal.display.bsqAddress")).second; + checkNotNull(bsqAddressTextField, "bsqAddressTextField must not be null"); + bsqAddressTextField.setText("B" + bsqWalletService.getUnusedAddress().toBase58()); + bsqAddressTextField.setValidator(new BsqAddressValidator(bsqFormatter)); break; - case GENERIC: + case BONDED_ROLE: + linkLabel.setText(Res.get("dao.proposal.display.link.bondRole")); + linkInputTextField.setPromptText(Res.get("dao.proposal.display.link.bondRole.prompt")); + bondedRoleTypeComboBox = addLabelComboBox(gridPane, ++gridRow, + Res.getWithCol("dao.proposal.display.bondedRoleComboBox.label")).second; + checkNotNull(bondedRoleTypeComboBox, "bondedRoleTypeComboBox must not be null"); + bondedRoleTypeComboBox.setPromptText(Res.get("shared.select")); + bondedRoleTypeComboBox.setItems(FXCollections.observableArrayList(BondedRoleType.values())); + bondedRoleTypeComboBox.setConverter(new StringConverter() { + @Override + public String toString(BondedRoleType bondedRoleType) { + return bondedRoleType.getDisplayString(); + } + + @Override + public BondedRoleType fromString(String string) { + return null; + } + }); + break; + case REMOVE_ALTCOIN: break; case CHANGE_PARAM: checkNotNull(gridPane, "gridPane must not be null"); - paramComboBox = addLabelComboBox(gridPane, ++gridRow, Res.get("dao.proposal.display.paramComboBox.label")).second; + paramComboBox = addLabelComboBox(gridPane, ++gridRow, + Res.getWithCol("dao.proposal.display.paramComboBox.label")).second; checkNotNull(paramComboBox, "paramComboBox must not be null"); - paramComboBox.setItems(FXCollections.observableArrayList(Param.values())); + paramComboBox.setPromptText(Res.get("shared.select")); + List list = Arrays.stream(Param.values()) + .filter(e -> e != Param.UNDEFINED && e != Param.PHASE_UNDEFINED) + .collect(Collectors.toList()); + paramComboBox.setItems(FXCollections.observableArrayList(list)); paramComboBox.setConverter(new StringConverter() { @Override public String toString(Param param) { - return param.name(); + return param.toDisplayString(); } @Override @@ -206,33 +259,32 @@ public Param fromString(String string) { return null; } }); - paramValueTextField = addLabelInputTextField(gridPane, ++gridRow, Res.get("dao.proposal.display.paramValue")).second; + paramValueTextField = addLabelInputTextField(gridPane, ++gridRow, + Res.get("dao.proposal.display.paramValue")).second; break; - case REMOVE_ALTCOIN: + case GENERIC: break; case CONFISCATE_BOND: confiscateBondComboBox = addLabelComboBox(gridPane, ++gridRow, - Res.get("dao.proposal.display.confiscateBondComboBox.label")).second; - ObservableList lockupAndUnlockingBondIds = - FXCollections.observableArrayList(daoFacade.getLockupAndUnlockingBondIds()); - confiscateBondComboBox.setItems(lockupAndUnlockingBondIds); - confiscateBondComboBox.setConverter(new StringConverter() { + Res.getWithCol("dao.proposal.display.confiscateBondComboBox.label")).second; + checkNotNull(confiscateBondComboBox, "confiscateBondComboBox must not be null"); + confiscateBondComboBox.setPromptText(Res.get("shared.select")); + confiscateBondComboBox.setItems(FXCollections.observableArrayList(daoFacade.getValidBondedRoleList())); + confiscateBondComboBox.setConverter(new StringConverter() { @Override - public String toString(byte[] hashOfBondId) { - Optional bond = Bonds.getBond(hashOfBondId); - return bond.isPresent() ? bond.get().toDisplayString() : "-"; + public String toString(BondedRole bondedRole) { + return bondedRole.getDisplayString(); } @Override - public byte[] fromString(String string) { + public BondedRole fromString(String string) { return null; } }); - break; } - if (!isMakeProposalScreen && showDetails) + if (!isMakeProposalScreen) txIdTextField = addLabelTxIdTextField(gridPane, ++gridRow, Res.get("dao.proposal.display.txId"), "").second; @@ -242,11 +294,14 @@ public byte[] fromString(String string) { } public void applyProposalPayload(Proposal proposal) { + proposalTypeTextField.setText(proposal.getType().getDisplayName()); if (uidTextField != null) uidTextField.setText(proposal.getUid()); nameTextField.setText(proposal.getName()); - titleTextField.setText(proposal.getTitle()); - descriptionTextArea.setText(proposal.getDescription()); + if (titleTextField != null) + titleTextField.setText(proposal.getTitle()); + if (descriptionTextArea != null) + descriptionTextArea.setText(proposal.getDescription()); linkInputTextField.setVisible(false); linkInputTextField.setManaged(false); linkHyperlinkWithIcon.setVisible(true); @@ -265,10 +320,17 @@ public void applyProposalPayload(Proposal proposal) { paramComboBox.getSelectionModel().select(changeParamProposal.getParam()); checkNotNull(paramValueTextField, "paramValueTextField must not be null"); paramValueTextField.setText(String.valueOf(changeParamProposal.getParamValue())); + } else if (proposal instanceof BondedRoleProposal) { + BondedRoleProposal bondedRoleProposal = (BondedRoleProposal) proposal; + checkNotNull(bondedRoleTypeComboBox, "bondedRoleComboBox must not be null"); + BondedRole bondedRole = bondedRoleProposal.getBondedRole(); + bondedRoleTypeComboBox.getSelectionModel().select(bondedRole.getBondedRoleType()); + } else if (proposal instanceof ConfiscateBondProposal) { ConfiscateBondProposal confiscateBondProposal = (ConfiscateBondProposal) proposal; checkNotNull(confiscateBondComboBox, "confiscateBondComboBox must not be null"); - confiscateBondComboBox.getSelectionModel().select(confiscateBondProposal.getHashOfBondId()); + daoFacade.getBondedRoleFromHash(confiscateBondProposal.getHash()) + .ifPresent(bondedRole -> confiscateBondComboBox.getSelectionModel().select(bondedRole)); } int chainHeight; if (txIdTextField != null) { @@ -291,6 +353,7 @@ public void clearForm() { if (bsqAddressTextField != null) bsqAddressTextField.clear(); if (paramComboBox != null) paramComboBox.getSelectionModel().clearSelection(); if (paramValueTextField != null) paramValueTextField.clear(); + if (bondedRoleTypeComboBox != null) bondedRoleTypeComboBox.getSelectionModel().clearSelection(); if (confiscateBondComboBox != null) confiscateBondComboBox.getSelectionModel().clearSelection(); if (txIdTextField != null) txIdTextField.cleanup(); if (descriptionTextArea != null) descriptionTextArea.textProperty().removeListener(descriptionTextAreaListener); @@ -299,8 +362,10 @@ public void clearForm() { public void fillWithMock() { uidTextField.setText(UUID.randomUUID().toString()); nameTextField.setText("Manfred Karrer"); - titleTextField.setText("Development work November 2017"); - descriptionTextArea.setText("Development work"); + if (titleTextField != null) + titleTextField.setText("Development work November 2017"); + if (descriptionTextArea != null) + descriptionTextArea.setText("Development work"); linkInputTextField.setText("https://github.com/bisq-network/compensation/issues/12"); if (requestedBsqTextField != null) requestedBsqTextField.setText("14000"); @@ -315,8 +380,10 @@ public void fillWithMock() { public void setEditable(boolean isEditable) { nameTextField.setEditable(isEditable); - titleTextField.setEditable(isEditable); - descriptionTextArea.setEditable(isEditable); + if (titleTextField != null) + titleTextField.setEditable(isEditable); + if (descriptionTextArea != null) + descriptionTextArea.setEditable(isEditable); linkInputTextField.setEditable(isEditable); if (requestedBsqTextField != null) requestedBsqTextField.setEditable(isEditable); @@ -331,6 +398,9 @@ public void setEditable(boolean isEditable) { if (confiscateBondComboBox != null) confiscateBondComboBox.setDisable(!isEditable); + if (bondedRoleTypeComboBox != null) + bondedRoleTypeComboBox.setDisable(!isEditable); + linkInputTextField.setVisible(true); linkInputTextField.setManaged(true); linkHyperlinkWithIcon.setVisible(false); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalWindow.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalWindow.java index f5f93b6227f..04dda005e75 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalWindow.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalWindow.java @@ -59,7 +59,7 @@ public void show() { proposalDisplay = new ProposalDisplay(gridPane, bsqFormatter, bsqWalletService, daoFacade); proposalDisplay.createAllFields(Res.get("dao.proposal.details"), 1, Layout.GROUP_DISTANCE, - proposal.getType(), false, true); + proposal.getType(), false); proposalDisplay.setEditable(false); proposalDisplay.applyProposalPayload(proposal); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index 5734eb4af2c..c5b95a0087a 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -123,7 +123,7 @@ protected void onPhaseChanged(DaoPhase.Phase phase) { //noinspection IfCanBeSwitch,IfCanBeSwitch,IfCanBeSwitch if (phase == DaoPhase.Phase.PROPOSAL) { if (selectedBaseProposalListItem != null && selectedBaseProposalListItem.getProposal() != null) { - button.setText(Res.get("dao.proposal.active.remove")); + button.setText(Res.get("shared.remove")); final boolean isMyProposal = daoFacade.isMyProposal(selectedBaseProposalListItem.getProposal()); button.setVisible(isMyProposal); button.setManaged(isMyProposal); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index 313403f6162..ed626a24a5b 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -30,6 +30,7 @@ import bisq.core.btc.wallet.InsufficientBsqException; import bisq.core.btc.wallet.WalletsSetup; import bisq.core.dao.DaoFacade; +import bisq.core.dao.role.BondedRole; import bisq.core.dao.state.BsqStateListener; import bisq.core.dao.state.blockchain.Block; import bisq.core.dao.state.ext.Param; @@ -65,6 +66,8 @@ import java.io.IOException; import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; import javax.annotation.Nullable; @@ -120,7 +123,7 @@ public void initialize() { proposalTypeComboBox.setConverter(new StringConverter() { @Override public String toString(ProposalType proposalType) { - return Res.get("dao.proposal.type." + proposalType.name()); + return proposalType.getDisplayName(); } @Override @@ -135,7 +138,12 @@ public ProposalType fromString(String string) { addProposalDisplay(); }; - proposalTypeComboBox.setItems(FXCollections.observableArrayList(Arrays.asList(ProposalType.values()))); + //TODO remove filter once all are implemented + List proposalTypes = Arrays.stream(ProposalType.values()) + .filter(proposalType -> proposalType != ProposalType.GENERIC && + proposalType != ProposalType.REMOVE_ALTCOIN) + .collect(Collectors.toList()); + proposalTypeComboBox.setItems(FXCollections.observableArrayList(proposalTypes)); } @Override @@ -234,31 +242,42 @@ private ProposalWithTransaction getProposalWithTransaction(ProposalType type) WalletException, IOException { validateInputs(); - + BondedRole bondedRole; switch (type) { case COMPENSATION_REQUEST: checkNotNull(proposalDisplay.requestedBsqTextField, "proposalDisplay.requestedBsqTextField must not be null"); checkNotNull(proposalDisplay.bsqAddressTextField, "proposalDisplay.bsqAddressTextField must not be null"); + checkNotNull(proposalDisplay.titleTextField, + "proposalDisplay.titleTextField must not be null"); + checkNotNull(proposalDisplay.descriptionTextArea, + "proposalDisplay.descriptionTextArea must not be null"); return daoFacade.getCompensationProposalWithTransaction(proposalDisplay.nameTextField.getText(), proposalDisplay.titleTextField.getText(), proposalDisplay.descriptionTextArea.getText(), proposalDisplay.linkInputTextField.getText(), bsqFormatter.parseToCoin(proposalDisplay.requestedBsqTextField.getText()), proposalDisplay.bsqAddressTextField.getText()); - case GENERIC: + case BONDED_ROLE: + checkNotNull(proposalDisplay.bondedRoleTypeComboBox, + "proposalDisplay.bondedRoleTypeComboBox must not be null"); + bondedRole = new BondedRole(proposalDisplay.nameTextField.getText(), + proposalDisplay.linkInputTextField.getText(), + proposalDisplay.bondedRoleTypeComboBox.getSelectionModel().getSelectedItem()); + return daoFacade.getBondedRoleProposalWithTransaction(bondedRole); + case REMOVE_ALTCOIN: //TODO throw new RuntimeException("Not implemented yet"); - /* - return genericBallotFactory.makeTxAndGetGenericProposal( - proposalDisplay.nameTextField.getText(), - proposalDisplay.titleTextField.getText(), - proposalDisplay.descriptionTextArea.getText(), - proposalDisplay.linkInputTextField.getText());*/ case CHANGE_PARAM: - checkNotNull(proposalDisplay.paramComboBox, "proposalDisplay.paramComboBox must no tbe null"); - checkNotNull(proposalDisplay.paramValueTextField, "proposalDisplay.paramValueTextField must no tbe null"); + checkNotNull(proposalDisplay.paramComboBox, + "proposalDisplay.paramComboBox must no tbe null"); + checkNotNull(proposalDisplay.paramValueTextField, + "proposalDisplay.paramValueTextField must no tbe null"); + checkNotNull(proposalDisplay.titleTextField, + "proposalDisplay.titleTextField must not be null"); + checkNotNull(proposalDisplay.descriptionTextArea, + "proposalDisplay.descriptionTextArea must not be null"); Param selectedParam = proposalDisplay.paramComboBox.getSelectionModel().getSelectedItem(); if (selectedParam == null) throw new ValidationException("selectedParam is null"); @@ -272,26 +291,28 @@ private ProposalWithTransaction getProposalWithTransaction(ProposalType type) throw new ValidationException("paramValue is not a long value", t); } //TODO add more custom param validation - return daoFacade.getParamProposalWithTransaction(proposalDisplay.nameTextField.getText(), proposalDisplay.titleTextField.getText(), proposalDisplay.descriptionTextArea.getText(), proposalDisplay.linkInputTextField.getText(), selectedParam, paramValue); - case REMOVE_ALTCOIN: + case GENERIC: //TODO throw new RuntimeException("Not implemented yet"); case CONFISCATE_BOND: - byte[] hashOfBondId = proposalDisplay.confiscateBondComboBox.getSelectionModel().getSelectedItem(); - if (hashOfBondId == null || hashOfBondId.length == 0) - throw new ValidationException("Invalid bond id, null or zero length"); - + checkNotNull(proposalDisplay.confiscateBondComboBox, + "proposalDisplay.confiscateBondComboBox must not be null"); + checkNotNull(proposalDisplay.titleTextField, + "proposalDisplay.titleTextField must not be null"); + checkNotNull(proposalDisplay.descriptionTextArea, + "proposalDisplay.descriptionTextArea must not be null"); + bondedRole = proposalDisplay.confiscateBondComboBox.getSelectionModel().getSelectedItem(); return daoFacade.getConfiscateBondProposalWithTransaction(proposalDisplay.nameTextField.getText(), proposalDisplay.titleTextField.getText(), proposalDisplay.descriptionTextArea.getText(), proposalDisplay.linkInputTextField.getText(), - hashOfBondId); + bondedRole.getHash()); default: final String msg = "Undefined ProposalType " + selectedProposalType; log.error(msg); @@ -303,8 +324,9 @@ private void addProposalDisplay() { if (selectedProposalType != null) { proposalDisplay = new ProposalDisplay(root, bsqFormatter, bsqWalletService, daoFacade); proposalDisplay.createAllFields(Res.get("dao.proposal.create.createNew"), 1, Layout.GROUP_DISTANCE, - selectedProposalType, true, true); - proposalDisplay.fillWithMock(); + selectedProposalType, true); + + // proposalDisplay.fillWithMock(); createButton = addButtonAfterGroup(root, proposalDisplay.incrementAndGetGridRow(), Res.get("dao.proposal.create.create.button")); setCreateButtonHandler(); @@ -332,10 +354,11 @@ private void setCreateButtonHandler() { private void validateInputs() { // We check in proposalDisplay that no invalid input as allowed - checkArgument(ProposalConsensus.isDescriptionSizeValid(proposalDisplay.descriptionTextArea.getText()), - "descriptionText must not be longer than " + - ProposalConsensus.getMaxLengthDescriptionText() + " chars"); - + if (proposalDisplay.descriptionTextArea != null) { + checkArgument(ProposalConsensus.isDescriptionSizeValid(proposalDisplay.descriptionTextArea.getText()), + "descriptionText must not be longer than " + + ProposalConsensus.getMaxLengthDescriptionText() + " chars"); + } // TODO add more checks for all input fields } } diff --git a/src/main/java/bisq/desktop/main/dao/results/ResultsView.java b/src/main/java/bisq/desktop/main/dao/results/ResultsView.java index b7a74bc922b..1c815e871ba 100644 --- a/src/main/java/bisq/desktop/main/dao/results/ResultsView.java +++ b/src/main/java/bisq/desktop/main/dao/results/ResultsView.java @@ -243,6 +243,7 @@ private void createCyclesTable() { tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); createColumns(tableView); + GridPane.setRowIndex(tableView, gridRow); GridPane.setMargin(tableView, new Insets(20, -10, 5, -10)); GridPane.setColumnSpan(tableView, 2); @@ -274,16 +275,16 @@ private void addParams(ResultsOfCycle resultsOfCycle) { case BSQ_TAKER_FEE_IN_PERCENT: case BTC_MAKER_FEE_IN_PERCENT: case BTC_TAKER_FEE_IN_PERCENT: - label = Res.getWithCol("dao.results.cycle.param." + param.name()); + label = Res.getWithCol("dao.param." + param.name()); value = bsqFormatter.formatToPercentWithSymbol(paramValue / 10000d); break; case PROPOSAL_FEE: - label = Res.getWithCol("dao.results.cycle.param." + param.name()); + label = Res.getWithCol("dao.param." + param.name()); value = bsqFormatter.formatCoinWithCode(ProposalConsensus.getFee(bsqStateService, height)); break; case BLIND_VOTE_FEE: - label = Res.getWithCol("dao.results.cycle.param." + param.name()); + label = Res.getWithCol("dao.param." + param.name()); value = bsqFormatter.formatCoinWithCode(BlindVoteConsensus.getFee(bsqStateService, height)); break; @@ -292,7 +293,7 @@ private void addParams(ResultsOfCycle resultsOfCycle) { case QUORUM_CHANGE_PARAM: case QUORUM_REMOVE_ASSET: case QUORUM_CONFISCATION: - label = Res.getWithCol("dao.results.cycle.param." + param.name()); + label = Res.getWithCol("dao.param." + param.name()); value = bsqFormatter.formatCoinWithCode(Coin.valueOf(paramValue)); break; case THRESHOLD_PROPOSAL: @@ -301,7 +302,7 @@ private void addParams(ResultsOfCycle resultsOfCycle) { case THRESHOLD_CHANGE_PARAM: case THRESHOLD_REMOVE_ASSET: case THRESHOLD_CONFISCATION: - label = Res.getWithCol("dao.results.cycle.param." + param.name()); + label = Res.getWithCol("dao.param." + param.name()); value = bsqFormatter.formatToPercentWithSymbol(paramValue / 10000d); break; diff --git a/src/main/java/bisq/desktop/main/dao/results/proposals/ProposalResultsListItem.java b/src/main/java/bisq/desktop/main/dao/results/proposals/ProposalResultsListItem.java index 1b5edd8a2f3..db85bcf0208 100644 --- a/src/main/java/bisq/desktop/main/dao/results/proposals/ProposalResultsListItem.java +++ b/src/main/java/bisq/desktop/main/dao/results/proposals/ProposalResultsListItem.java @@ -17,6 +17,7 @@ package bisq.desktop.main.dao.results.proposals; +import bisq.core.dao.voting.proposal.ProposalType; import bisq.core.dao.voting.proposal.compensation.CompensationProposal; import bisq.core.dao.voting.voteresult.EvaluatedProposal; import bisq.core.dao.voting.voteresult.ProposalVoteResult; @@ -82,18 +83,13 @@ public String getColorStyle() { } public String getIssuance() { - switch (evaluatedProposal.getProposal().getType()) { - case COMPENSATION_REQUEST: - Coin requestedBsq = evaluatedProposal.isAccepted() ? - ((CompensationProposal) evaluatedProposal.getProposal()).getRequestedBsq() : - Coin.ZERO; - return bsqFormatter.formatCoinWithCode(requestedBsq); - case GENERIC: - case CHANGE_PARAM: - case REMOVE_ALTCOIN: - default: - return ""; + if (evaluatedProposal.getProposal().getType() == ProposalType.COMPENSATION_REQUEST) { + Coin requestedBsq = evaluatedProposal.isAccepted() ? + ((CompensationProposal) evaluatedProposal.getProposal()).getRequestedBsq() : + Coin.ZERO; + return bsqFormatter.formatCoinWithCode(requestedBsq); + } else { + return ""; } - } } diff --git a/src/main/java/bisq/desktop/main/dao/results/proposals/VoteResultsForProposalWindow.java b/src/main/java/bisq/desktop/main/dao/results/proposals/VoteResultsForProposalWindow.java index 18b2a678a93..041c7cab4fc 100644 --- a/src/main/java/bisq/desktop/main/dao/results/proposals/VoteResultsForProposalWindow.java +++ b/src/main/java/bisq/desktop/main/dao/results/proposals/VoteResultsForProposalWindow.java @@ -88,8 +88,8 @@ public VoteResultsForProposalWindow(ResultsOfCycle resultsOfCycle, @Override public void show() { - rowIndex = -1; width = MainView.getRootContainer().getWidth() - 20; + createGridPane(); addContent(); display(); @@ -103,6 +103,7 @@ public void show() { @Override protected void createGridPane() { super.createGridPane(); + gridPane.setPadding(new Insets(35, 40, 30, 40)); gridPane.getStyleClass().add("grid-pane"); } @@ -114,6 +115,7 @@ private void addContent() { GridPane.setColumnSpan(headline, 2); gridPane.getChildren().add(headline); + // For some weird reason the stage key handler (ESC, ENTER) does not work as soon a tableView gets added... tableView = new TableView<>(); tableView.setPlaceholder(new AutoTooltipLabel(Res.get("table.placeholder.noData"))); tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); From 39a685956fc2df0c5162ecc3db391c76899784ec Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Mon, 23 Jul 2018 13:36:50 +0200 Subject: [PATCH 163/197] Improve bonded roles table --- src/main/java/bisq/desktop/DesktopModule.java | 3 + .../main/dao/bonding/BondingViewUtils.java | 155 ++++++++++++++++++ .../main/dao/bonding/lockup/LockupView.java | 72 +------- .../bonding/roles/BondedRolesListItem.java | 80 ++++++++- .../dao/bonding/roles/BondedRolesView.java | 115 ++++++------- .../main/dao/bonding/unlock/UnlockView.java | 65 +------- 6 files changed, 295 insertions(+), 195 deletions(-) create mode 100644 src/main/java/bisq/desktop/main/dao/bonding/BondingViewUtils.java diff --git a/src/main/java/bisq/desktop/DesktopModule.java b/src/main/java/bisq/desktop/DesktopModule.java index a59cedc4b3d..aeef737f3b5 100644 --- a/src/main/java/bisq/desktop/DesktopModule.java +++ b/src/main/java/bisq/desktop/DesktopModule.java @@ -23,6 +23,7 @@ import bisq.desktop.common.view.ViewLoader; import bisq.desktop.common.view.guice.InjectorViewFactory; import bisq.desktop.main.MarketPricePresentation; +import bisq.desktop.main.dao.bonding.BondingViewUtils; import bisq.desktop.main.funds.transactions.DisplayedTransactionsFactory; import bisq.desktop.main.funds.transactions.TradableRepository; import bisq.desktop.main.funds.transactions.TransactionAwareTradableFactory; @@ -79,6 +80,8 @@ protected void configure() { bind(TransactionAwareTradableFactory.class).in(Singleton.class); bind(DisplayedTransactionsFactory.class).in(Singleton.class); + bind(BondingViewUtils.class).in(Singleton.class); + bindConstant().annotatedWith(Names.named(AppOptionKeys.APP_NAME_KEY)).to(environment.getRequiredProperty(AppOptionKeys.APP_NAME_KEY)); } } diff --git a/src/main/java/bisq/desktop/main/dao/bonding/BondingViewUtils.java b/src/main/java/bisq/desktop/main/dao/bonding/BondingViewUtils.java new file mode 100644 index 00000000000..d0f23c543f3 --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/bonding/BondingViewUtils.java @@ -0,0 +1,155 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.desktop.main.dao.bonding; + +import bisq.desktop.Navigation; +import bisq.desktop.main.MainView; +import bisq.desktop.main.funds.FundsView; +import bisq.desktop.main.funds.deposit.DepositView; +import bisq.desktop.main.overlays.popups.Popup; +import bisq.desktop.util.GUIUtil; + +import bisq.core.btc.wallet.WalletsSetup; +import bisq.core.dao.DaoFacade; +import bisq.core.dao.bonding.lockup.LockupType; +import bisq.core.dao.role.BondedRole; +import bisq.core.dao.role.BondedRoleType; +import bisq.core.dao.state.blockchain.TxOutput; +import bisq.core.locale.Res; +import bisq.core.util.BsqFormatter; + +import bisq.network.p2p.P2PService; + +import bisq.common.handlers.ResultHandler; + +import org.bitcoinj.core.Coin; +import org.bitcoinj.core.InsufficientMoneyException; + +import javax.inject.Inject; + +import java.util.Optional; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class BondingViewUtils { + + private final P2PService p2PService; + private final WalletsSetup walletsSetup; + private final DaoFacade daoFacade; + private final Navigation navigation; + private final BsqFormatter bsqFormatter; + + @Inject + public BondingViewUtils(P2PService p2PService, WalletsSetup walletsSetup, DaoFacade daoFacade, + Navigation navigation, BsqFormatter bsqFormatter) { + this.p2PService = p2PService; + this.walletsSetup = walletsSetup; + this.daoFacade = daoFacade; + this.navigation = navigation; + this.bsqFormatter = bsqFormatter; + } + + public void lockupBondForBondedRole(BondedRole bondedRole, ResultHandler resultHandler) { + if (GUIUtil.isReadyForTxBroadcast(p2PService, walletsSetup)) { + BondedRoleType bondedRoleType = bondedRole.getBondedRoleType(); + Coin lockupAmount = Coin.valueOf(bondedRoleType.getRequiredBond()); + int lockupTime = bondedRoleType.getUnlockTime(); + LockupType lockupType = LockupType.BONDED_ROLE; + new Popup<>().headLine(Res.get("dao.bonding.lock.sendFunds.headline")) + .confirmation(Res.get("dao.bonding.lock.sendFunds.details", + bsqFormatter.formatCoinWithCode(lockupAmount), + lockupTime + )) + .actionButtonText(Res.get("shared.yes")) + .onAction(() -> { + daoFacade.publishLockupTx(lockupAmount, + lockupTime, + lockupType, + bondedRole, + () -> { + new Popup<>().feedback(Res.get("dao.tx.published.success")).show(); + }, + this::handleError + ); + if (resultHandler != null) + resultHandler.handleResult(); + }) + .closeButtonText(Res.get("shared.cancel")) + .show(); + } else { + GUIUtil.showNotReadyForTxBroadcastPopups(p2PService, walletsSetup); + } + } + + public void unLock(String lockupTxId) { + if (GUIUtil.isReadyForTxBroadcast(p2PService, walletsSetup)) { + Optional lockupTxOutput = daoFacade.getLockupTxOutput(lockupTxId); + if (!lockupTxOutput.isPresent()) { + log.warn("Lockup output not found, txId = ", lockupTxId); + return; + } + + Coin unlockAmount = Coin.valueOf(lockupTxOutput.get().getValue()); + Optional opLockTime = daoFacade.getLockTime(lockupTxId); + int lockTime = opLockTime.orElse(-1); + + try { + new Popup<>().headLine(Res.get("dao.bonding.unlock.sendTx.headline")) + .confirmation(Res.get("dao.bonding.unlock.sendTx.details", + bsqFormatter.formatCoinWithCode(unlockAmount), + lockTime + )) + .actionButtonText(Res.get("shared.yes")) + .onAction(() -> { + daoFacade.publishUnlockTx(lockupTxId, + () -> { + new Popup<>().confirmation(Res.get("dao.tx.published.success")).show(); + }, + errorMessage -> new Popup<>().warning(errorMessage.toString()).show() + ); + }) + .closeButtonText(Res.get("shared.cancel")) + .show(); + } catch (Throwable t) { + log.error(t.toString()); + t.printStackTrace(); + new Popup<>().warning(t.getMessage()).show(); + } + } else { + GUIUtil.showNotReadyForTxBroadcastPopups(p2PService, walletsSetup); + } + log.info("unlock tx: {}", lockupTxId); + } + + public void handleError(Throwable throwable) { + if (throwable instanceof InsufficientMoneyException) { + final Coin missingCoin = ((InsufficientMoneyException) throwable).missing; + final String missing = missingCoin != null ? missingCoin.toFriendlyString() : "null"; + //noinspection unchecked + new Popup<>().warning(Res.get("popup.warning.insufficientBtcFundsForBsqTx", missing)) + .actionButtonTextWithGoTo("navigation.funds.depositFunds") + .onAction(() -> navigation.navigateTo(MainView.class, FundsView.class, DepositView.class)) + .show(); + } else { + log.error(throwable.toString()); + throwable.printStackTrace(); + new Popup<>().warning(throwable.toString()).show(); + } + } +} diff --git a/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java b/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java index 36aeb8d427b..0f654db3cab 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java @@ -17,23 +17,17 @@ package bisq.desktop.main.dao.bonding.lockup; -import bisq.desktop.Navigation; import bisq.desktop.common.view.ActivatableView; import bisq.desktop.common.view.FxmlView; import bisq.desktop.components.InputTextField; -import bisq.desktop.main.MainView; +import bisq.desktop.main.dao.bonding.BondingViewUtils; import bisq.desktop.main.dao.wallet.BsqBalanceUtil; -import bisq.desktop.main.funds.FundsView; -import bisq.desktop.main.funds.deposit.DepositView; -import bisq.desktop.main.overlays.popups.Popup; -import bisq.desktop.util.GUIUtil; import bisq.desktop.util.Layout; import bisq.desktop.util.validation.BsqValidator; import bisq.core.btc.Restrictions; import bisq.core.btc.wallet.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.btc.wallet.WalletsSetup; import bisq.core.dao.DaoFacade; import bisq.core.dao.bonding.BondingConsensus; import bisq.core.dao.bonding.lockup.LockupType; @@ -42,10 +36,7 @@ import bisq.core.util.BsqFormatter; import bisq.core.util.validation.IntegerValidator; -import bisq.network.p2p.P2PService; - import org.bitcoinj.core.Coin; -import org.bitcoinj.core.InsufficientMoneyException; import javax.inject.Inject; @@ -69,11 +60,9 @@ @FxmlView public class LockupView extends ActivatableView implements BsqBalanceListener { private final BsqWalletService bsqWalletService; - private final WalletsSetup walletsSetup; - private final P2PService p2PService; private final BsqFormatter bsqFormatter; - private final Navigation navigation; private final BsqBalanceUtil bsqBalanceUtil; + private final BondingViewUtils bondingViewUtils; private final BsqValidator bsqValidator; private final DaoFacade daoFacade; private final IntegerValidator timeInputTextFieldValidator; @@ -96,19 +85,15 @@ public class LockupView extends ActivatableView implements BsqBa @Inject private LockupView(BsqWalletService bsqWalletService, - WalletsSetup walletsSetup, - P2PService p2PService, BsqFormatter bsqFormatter, - Navigation navigation, BsqBalanceUtil bsqBalanceUtil, + BondingViewUtils bondingViewUtils, BsqValidator bsqValidator, DaoFacade daoFacade) { this.bsqWalletService = bsqWalletService; - this.walletsSetup = walletsSetup; - this.p2PService = p2PService; this.bsqFormatter = bsqFormatter; - this.navigation = navigation; this.bsqBalanceUtil = bsqBalanceUtil; + this.bondingViewUtils = bondingViewUtils; this.bsqValidator = bsqValidator; this.daoFacade = daoFacade; @@ -188,35 +173,10 @@ public BondedRole fromString(String string) { lockupButton = addButtonAfterGroup(root, ++gridRow, Res.get("dao.bonding.lock.lockupButton")); lockupButton.setOnAction((event) -> { - if (GUIUtil.isReadyForTxBroadcast(p2PService, walletsSetup)) { - Coin lockupAmount = bsqFormatter.parseToCoin(amountInputTextField.getText()); - int lockupTime = Integer.parseInt(timeInputTextField.getText()); - LockupType lockupType = lockupTypeComboBox.getValue(); - BondedRole bondedRole = bondedRolesComboBox.getValue(); - new Popup<>().headLine(Res.get("dao.bonding.lock.sendFunds.headline")) - .confirmation(Res.get("dao.bonding.lock.sendFunds.details", - bsqFormatter.formatCoinWithCode(lockupAmount), - lockupTime - )) - .actionButtonText(Res.get("shared.yes")) - .onAction(() -> { - daoFacade.publishLockupTx(lockupAmount, - lockupTime, - lockupType, - bondedRole, - () -> { - new Popup<>().feedback(Res.get("dao.tx.published.success")).show(); - }, - this::handleError - ); - amountInputTextField.setText(""); - timeInputTextField.setText(""); - }) - .closeButtonText(Res.get("shared.cancel")) - .show(); - } else { - GUIUtil.showNotReadyForTxBroadcastPopups(p2PService, walletsSetup); - } + bondingViewUtils.lockupBondForBondedRole(bondedRolesComboBox.getValue(), + () -> { + bondedRolesComboBox.getSelectionModel().clearSelection(); + }); }); focusOutListener = (observable, oldValue, newValue) -> { @@ -284,20 +244,4 @@ private void updateButtonState() { bondedRolesComboBox.getSelectionModel().getSelectedItem() == null || lockupTypeComboBox.getSelectionModel().getSelectedItem() == null); } - - private void handleError(Throwable throwable) { - if (throwable instanceof InsufficientMoneyException) { - final Coin missingCoin = ((InsufficientMoneyException) throwable).missing; - final String missing = missingCoin != null ? missingCoin.toFriendlyString() : "null"; - //noinspection unchecked - new Popup<>().warning(Res.get("popup.warning.insufficientBtcFundsForBsqTx", missing)) - .actionButtonTextWithGoTo("navigation.funds.depositFunds") - .onAction(() -> navigation.navigateTo(MainView.class, FundsView.class, DepositView.class)) - .show(); - } else { - log.error(throwable.toString()); - throwable.printStackTrace(); - new Popup<>().warning(throwable.toString()).show(); - } - } } diff --git a/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesListItem.java b/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesListItem.java index 5ef042d82f0..7fcf180edc8 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesListItem.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesListItem.java @@ -21,23 +21,28 @@ import bisq.core.dao.DaoFacade; import bisq.core.dao.role.BondedRole; +import bisq.core.dao.state.BsqStateListener; +import bisq.core.dao.state.blockchain.Block; import bisq.core.locale.Res; import bisq.core.util.BsqFormatter; +import javafx.scene.control.Label; + import java.util.Date; import lombok.Data; import lombok.EqualsAndHashCode; -import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +@Slf4j @EqualsAndHashCode @Data -class BondedRolesListItem { - @Getter +class BondedRolesListItem implements BsqStateListener { private final BondedRole bondedRole; private final DaoFacade daoFacade; private final BsqFormatter bsqFormatter; private final AutoTooltipButton button; + private final Label label; BondedRolesListItem(BondedRole bondedRole, DaoFacade daoFacade, @@ -46,12 +51,14 @@ class BondedRolesListItem { this.daoFacade = daoFacade; this.bsqFormatter = bsqFormatter; + daoFacade.addBsqStateListener(this); button = new AutoTooltipButton(); button.setMinWidth(70); - button.setText(Res.get("dao.bond.table.revoke")); - button.setVisible(true); - button.setManaged(true); + + label = new Label(); + + update(); } public String getStartDate() { @@ -66,7 +73,66 @@ public String getRevokeDate() { "-"; } - public static void cleanup() { + public void cleanup() { + daoFacade.removeBsqStateListener(this); + setOnAction(null); + } + + public void setOnAction(Runnable handler) { + button.setOnAction(e -> handler.run()); + } + + public boolean isBonded() { + return bondedRole.isLockedUp(); + } + + private void update() { + // We have following state: + // 1. Not bonded: !isLockedUp, !isUnlocked, !isUnlocking: notBonded + // 2. Locked up: isLockedUp, !isUnlocked, !isUnlocking: lockedUp + // 3. Unlocking: isLockedUp, isUnlocked, isUnlocking: unlocking + // 4. Unlocked: isLockedUp, isUnlocked, !isUnlocking: unlocked + + boolean isLockedUp = bondedRole.isLockedUp(); + boolean isUnlocked = bondedRole.isUnlocked(); + boolean isUnlocking = bondedRole.isUnlocking(daoFacade); + log.error("name={}, isLockedUp={}, isUnlocked={}, isUnlocking={}", bondedRole.getName(), isLockedUp, isUnlocked, isUnlocking); + + String text; + if (!isLockedUp) + text = Res.get("dao.bond.table.notBonded"); + else if (!isUnlocked) + text = Res.get("dao.bond.table.lockedUp"); + else if (isUnlocking) + text = Res.get("dao.bond.table.unlocking"); + else + text = Res.get("dao.bond.table.unlocked"); + + label.setText(text); + + button.setText(isLockedUp ? Res.get("dao.bond.table.button.revoke") : Res.get("dao.bond.table.button.lockup")); + button.setVisible(!isLockedUp || !isUnlocked); + button.setManaged(button.isVisible()); + + //TODO listen to unconfirmed txs and update button and label state + } + + + // BsqStateListener + @Override + public void onNewBlockHeight(int blockHeight) { + } + + @Override + public void onEmptyBlockAdded(Block block) { + } + + @Override + public void onParseTxsComplete(Block block) { + update(); + } + @Override + public void onParseBlockChainComplete() { } } diff --git a/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesView.java b/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesView.java index f970711a91b..88213225fa6 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesView.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesView.java @@ -23,10 +23,10 @@ import bisq.desktop.components.AutoTooltipTableColumn; import bisq.desktop.components.HyperlinkWithIcon; import bisq.desktop.components.TableGroupHeadline; +import bisq.desktop.main.dao.bonding.BondingViewUtils; import bisq.desktop.main.dao.wallet.BsqBalanceUtil; import bisq.desktop.util.GUIUtil; -import bisq.core.btc.wallet.WalletsSetup; import bisq.core.dao.DaoFacade; import bisq.core.dao.role.BondedRoleType; import bisq.core.dao.state.BsqStateListener; @@ -35,8 +35,6 @@ import bisq.core.user.Preferences; import bisq.core.util.BsqFormatter; -import bisq.network.p2p.P2PService; - import javax.inject.Inject; import de.jensd.fx.fontawesome.AwesomeIcon; @@ -67,12 +65,10 @@ public class BondedRolesView extends ActivatableView implements private TableView tableView; private final BsqFormatter bsqFormatter; + private final BondingViewUtils bondingViewUtils; private final DaoFacade daoFacade; private final Preferences preferences; - private final WalletsSetup walletsSetup; - private final P2PService p2PService; - private int gridRow = 0; private final ObservableList observableList = FXCollections.observableArrayList(); @@ -86,15 +82,13 @@ public class BondedRolesView extends ActivatableView implements @Inject private BondedRolesView(BsqFormatter bsqFormatter, BsqBalanceUtil bsqBalanceUtil, + BondingViewUtils bondingViewUtils, DaoFacade daoFacade, - Preferences preferences, - WalletsSetup walletsSetup, - P2PService p2PService) { + Preferences preferences) { this.bsqFormatter = bsqFormatter; + this.bondingViewUtils = bondingViewUtils; this.daoFacade = daoFacade; this.preferences = preferences; - this.walletsSetup = walletsSetup; - this.p2PService = p2PService; } @Override @@ -131,7 +125,7 @@ protected void activate() { protected void deactivate() { daoFacade.removeBsqStateListener(this); - observableList.forEach(e -> BondedRolesListItem.cleanup()); + observableList.forEach(BondedRolesListItem::cleanup); } @@ -163,54 +157,12 @@ public void onParseBlockChainComplete() { private void updateList() { - observableList.forEach(e -> BondedRolesListItem.cleanup()); + observableList.forEach(BondedRolesListItem::cleanup); observableList.setAll(daoFacade.getBondedRoleList().stream() .map(bondedRole -> new BondedRolesListItem(bondedRole, daoFacade, bsqFormatter)) .collect(Collectors.toList())); } - private void onButtonClick() { - if (GUIUtil.isReadyForTxBroadcast(p2PService, walletsSetup)) { - // revoke TODO - /* Optional lockupTxOutput = daoFacade.getBondedRolesOutput(selectedItem.getTxId()); - if (!lockupTxOutput.isPresent()) { - log.warn("Lockup output not found, txId = ", selectedItem.getTxId()); - return; - } - - Coin unlockAmount = Coin.valueOf(lockupTxOutput.get().getValue()); - Optional opLockTime = daoFacade.getLockTime(selectedItem.getTxId()); - int lockTime = opLockTime.orElse(-1); - - try { - new Popup<>().headLine(Res.get("dao.bonding.unlock.sendTx.headline")) - .confirmation(Res.get("dao.bonding.unlock.sendTx.details", - bsqFormatter.formatCoinWithCode(unlockAmount), - lockTime - )) - .actionButtonText(Res.get("shared.yes")) - .onAction(() -> { - daoFacade.publishUnlockTx(selectedItem.getTxId(), - () -> { - new Popup<>().confirmation(Res.get("dao.tx.published.success")).show(); - }, - errorMessage -> new Popup<>().warning(errorMessage.toString()).show() - ); - }) - .closeButtonText(Res.get("shared.cancel")) - .show(); - } catch (Throwable t) { - log.error(t.toString()); - t.printStackTrace(); - new Popup<>().warning(t.getMessage()).show(); - }*/ - } else { - GUIUtil.showNotReadyForTxBroadcastPopups(p2PService, walletsSetup); - } - // log.info("unlock tx: {}", selectedItem.getTxId()); - } - - private void openTxInBlockExplorer(String transactionId) { if (transactionId != null) GUIUtil.openWebPage(preferences.getBsqBlockChainExplorer().txUrl + transactionId); @@ -226,7 +178,7 @@ private void createColumns() { column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.name")); column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); - column.setMinWidth(120); + column.setMinWidth(80); column.setCellFactory( new Callback, TableCell>() { @@ -283,7 +235,7 @@ public void updateItem(final BondedRolesListItem item, boolean empty) { column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.bondedRoleType")); column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); - column.setMinWidth(120); + column.setMinWidth(80); column.setCellFactory( new Callback, TableCell>() { @@ -320,7 +272,7 @@ public void updateItem(final BondedRolesListItem item, boolean empty) { column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.startDate")); column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); - column.setMinWidth(60); + column.setMinWidth(120); column.setCellFactory( new Callback, TableCell>() { @@ -344,7 +296,7 @@ public void updateItem(final BondedRolesListItem item, boolean empty) { column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.revokeDate")); column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); - column.setMinWidth(60); + column.setMinWidth(120); column.setCellFactory( new Callback, TableCell>() { @@ -450,9 +402,41 @@ public void updateItem(final BondedRolesListItem item, boolean empty) { }); tableView.getColumns().add(column); + column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.bondState")); + column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); + column.setMinWidth(120); + column.setCellFactory( + new Callback, TableCell>() { + @Override + public TableCell call(TableColumn column) { + return new TableCell() { + Label label; + + @Override + public void updateItem(final BondedRolesListItem item, boolean empty) { + super.updateItem(item, empty); + + if (item != null && !empty) { + if (label == null) { + label = item.getLabel(); + setGraphic(label); + } + } else { + setGraphic(null); + if (label != null) + label = null; + } + } + }; + } + }); + tableView.getColumns().add(column); + column = new TableColumn<>(); column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); - column.setMinWidth(60); + column.setMinWidth(80); column.setCellFactory( new Callback, TableCell>() { @@ -469,17 +453,18 @@ public void updateItem(final BondedRolesListItem item, boolean empty) { if (item != null && !empty) { if (button == null) { button = item.getButton(); - button.setOnAction(e -> { - onButtonClick(); + item.setOnAction(() -> { + if (item.isBonded()) + bondingViewUtils.unLock(item.getBondedRole().getLockupTxId()); + else + bondingViewUtils.lockupBondForBondedRole(item.getBondedRole(), null); }); setGraphic(button); } } else { setGraphic(null); - if (button != null) { - button.setOnAction(null); + if (button != null) button = null; - } } } }; diff --git a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java index 80ac11c52f1..e419bbe1869 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java @@ -21,26 +21,22 @@ import bisq.desktop.common.view.FxmlView; import bisq.desktop.components.AutoTooltipTableColumn; import bisq.desktop.components.HyperlinkWithIcon; +import bisq.desktop.main.dao.bonding.BondingViewUtils; import bisq.desktop.main.dao.wallet.BsqBalanceUtil; -import bisq.desktop.main.overlays.popups.Popup; import bisq.desktop.util.GUIUtil; import bisq.desktop.util.validation.BsqValidator; import bisq.core.btc.wallet.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; -import bisq.core.btc.wallet.WalletsSetup; import bisq.core.dao.DaoFacade; import bisq.core.dao.state.BsqStateListener; import bisq.core.dao.state.blockchain.Block; -import bisq.core.dao.state.blockchain.TxOutput; import bisq.core.dao.state.blockchain.TxType; import bisq.core.locale.Res; import bisq.core.user.Preferences; import bisq.core.util.BsqFormatter; -import bisq.network.p2p.P2PService; - import org.bitcoinj.core.Coin; import org.bitcoinj.core.Transaction; @@ -71,7 +67,6 @@ import java.util.ArrayList; import java.util.Comparator; import java.util.List; -import java.util.Optional; import java.util.stream.Collectors; @FxmlView @@ -83,14 +78,12 @@ public class UnlockView extends ActivatableView implements BsqBa private final BsqFormatter bsqFormatter; private final BsqBalanceUtil bsqBalanceUtil; private final BsqValidator bsqValidator; + private final BondingViewUtils bondingViewUtils; private final DaoFacade daoFacade; private final Preferences preferences; - private final WalletsSetup walletsSetup; - private final P2PService p2PService; private int gridRow = 0; - private LockupTxListItem selectedItem; private final ObservableList observableList = FXCollections.observableArrayList(); private final FilteredList lockupTxs = new FilteredList<>(observableList); @@ -109,22 +102,19 @@ private UnlockView(BsqWalletService bsqWalletService, BsqFormatter bsqFormatter, BsqBalanceUtil bsqBalanceUtil, BsqValidator bsqValidator, + BondingViewUtils bondingViewUtils, DaoFacade daoFacade, - Preferences preferences, - WalletsSetup walletsSetup, - P2PService p2PService) { + Preferences preferences) { this.bsqWalletService = bsqWalletService; this.btcWalletService = btcWalletService; this.bsqFormatter = bsqFormatter; this.bsqBalanceUtil = bsqBalanceUtil; this.bsqValidator = bsqValidator; + this.bondingViewUtils = bondingViewUtils; this.daoFacade = daoFacade; this.preferences = preferences; - this.walletsSetup = walletsSetup; - this.p2PService = p2PService; } - @Override public void initialize() { gridRow = bsqBalanceUtil.addGroup(root, gridRow); @@ -228,46 +218,6 @@ public void onParseBlockChainComplete() { // Private /////////////////////////////////////////////////////////////////////////////////////////// - private void onButtonClick() { - if (GUIUtil.isReadyForTxBroadcast(p2PService, walletsSetup)) { - Optional lockupTxOutput = daoFacade.getLockupTxOutput(selectedItem.getTxId()); - if (!lockupTxOutput.isPresent()) { - log.warn("Lockup output not found, txId = ", selectedItem.getTxId()); - return; - } - - Coin unlockAmount = Coin.valueOf(lockupTxOutput.get().getValue()); - Optional opLockTime = daoFacade.getLockTime(selectedItem.getTxId()); - int lockTime = opLockTime.orElse(-1); - - try { - new Popup<>().headLine(Res.get("dao.bonding.unlock.sendTx.headline")) - .confirmation(Res.get("dao.bonding.unlock.sendTx.details", - bsqFormatter.formatCoinWithCode(unlockAmount), - lockTime - )) - .actionButtonText(Res.get("shared.yes")) - .onAction(() -> { - daoFacade.publishUnlockTx(selectedItem.getTxId(), - () -> { - new Popup<>().confirmation(Res.get("dao.tx.published.success")).show(); - }, - errorMessage -> new Popup<>().warning(errorMessage.toString()).show() - ); - }) - .closeButtonText(Res.get("shared.cancel")) - .show(); - } catch (Throwable t) { - log.error(t.toString()); - t.printStackTrace(); - new Popup<>().warning(t.getMessage()).show(); - } - } else { - GUIUtil.showNotReadyForTxBroadcastPopups(p2PService, walletsSetup); - } - log.info("unlock tx: {}", selectedItem.getTxId()); - } - private void openTxInBlockExplorer(LockupTxListItem item) { if (item.getTxId() != null) GUIUtil.openWebPage(preferences.getBsqBlockChainExplorer().txUrl + item.getTxId()); @@ -421,10 +371,7 @@ public void updateItem(final LockupTxListItem item, boolean empty) { if (item != null && !empty) { if (button == null) { button = item.getButton(); - button.setOnAction(e -> { - selectedItem = item; - onButtonClick(); - }); + button.setOnAction(e -> bondingViewUtils.unLock(item.getTxId())); setGraphic(button); } } else { From 4ad66b6f6bae2ddc475cb58a91b7e60a48a8b248 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Mon, 23 Jul 2018 13:56:20 +0200 Subject: [PATCH 164/197] Add EqualsAndHashCode to PersistableLists - fix row display in proposal display --- .../desktop/main/dao/proposal/ProposalDisplay.java | 11 ++++++----- src/main/java/bisq/desktop/util/GUIUtil.java | 4 +++- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java index 4ee1c19c5aa..172eb9d0673 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java @@ -144,25 +144,26 @@ public void createAllFields(String title, int gridRowStartIndex, double top, Pro switch (proposalType) { case COMPENSATION_REQUEST: - rowSpan = 6; + rowSpan = 8; break; case BONDED_ROLE: - rowSpan = 3; + rowSpan = 5; showTitle = false; showDescription = false; break; case REMOVE_ALTCOIN: break; case CHANGE_PARAM: - rowSpan = 6; + rowSpan = 8; break; case GENERIC: break; case CONFISCATE_BOND: - rowSpan = 5; + rowSpan = 7; break; } - if (isMakeProposalScreen) + // for already created proposals we show the uid and tx id so we add 2 rows + if (!isMakeProposalScreen) rowSpan += 2; addTitledGroupBg(gridPane, gridRow, rowSpan, title, top); diff --git a/src/main/java/bisq/desktop/util/GUIUtil.java b/src/main/java/bisq/desktop/util/GUIUtil.java index 075bcd7ed26..c7b8476ac92 100644 --- a/src/main/java/bisq/desktop/util/GUIUtil.java +++ b/src/main/java/bisq/desktop/util/GUIUtil.java @@ -60,6 +60,8 @@ import com.google.common.base.Charsets; +import org.apache.commons.lang3.StringUtils; + import javafx.stage.DirectoryChooser; import javafx.stage.FileChooser; import javafx.stage.Modality; @@ -559,7 +561,7 @@ public static void showBsqFeeInfoPopup(Coin fee, Coin miningFee, int txSize, Bsq Runnable actionHandler) { new Popup<>().headLine(Res.get("dao.feeTx.confirm", type)) .confirmation(Res.get("dao.feeTx.confirm.details", - type, + StringUtils.capitalize(type), bsqFormatter.formatCoinWithCode(fee), btcFormatter.formatCoinWithCode(miningFee), CoinUtil.getFeePerByte(miningFee, txSize), From 577633f5bbc005e23c4c2e09059c61bf25b31595 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Mon, 23 Jul 2018 21:53:36 +0200 Subject: [PATCH 165/197] Add nullable, cleanup --- .../main/dao/proposal/ProposalDisplay.java | 16 +-- .../dao/results/BaseResultsTableView1.java | 110 ++++++++++++++++++ 2 files changed, 119 insertions(+), 7 deletions(-) create mode 100644 src/main/java/bisq/desktop/main/dao/results/BaseResultsTableView1.java diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java index 172eb9d0673..82275f9ee4a 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java @@ -82,10 +82,11 @@ public class ProposalDisplay { private final int maxLengthDescriptionText; private final BsqFormatter bsqFormatter; private final BsqWalletService bsqWalletService; - private DaoFacade daoFacade; - private InputTextField uidTextField; - private TextField proposalFeeTextField; - private TextField proposalTypeTextField; + private final DaoFacade daoFacade; + + @Nullable + private TextField uidTextField; + private TextField proposalFeeTextField, proposalTypeTextField; public InputTextField nameTextField; @Nullable public InputTextField titleTextField; @@ -172,8 +173,7 @@ public void createAllFields(String title, int gridRowStartIndex, double top, Pro Res.getWithCol("dao.proposal.display.type"), proposalType.getDisplayName(), proposalTypeTop).second; if (!isMakeProposalScreen) { - uidTextField = addLabelInputTextField(gridPane, ++gridRow, Res.getWithCol("shared.id")).second; - uidTextField.setEditable(false); + uidTextField = addLabelTextField(gridPane, ++gridRow, Res.getWithCol("shared.id")).second; nameTextField = addLabelInputTextField(gridPane, ++gridRow, Res.get("dao.proposal.display.name")).second; } else { nameTextField = addLabelInputTextField(gridPane, ++gridRow, Res.get("dao.proposal.display.name")).second; @@ -298,6 +298,7 @@ public void applyProposalPayload(Proposal proposal) { proposalTypeTextField.setText(proposal.getType().getDisplayName()); if (uidTextField != null) uidTextField.setText(proposal.getUid()); + nameTextField.setText(proposal.getName()); if (titleTextField != null) titleTextField.setText(proposal.getTitle()); @@ -361,7 +362,8 @@ public void clearForm() { } public void fillWithMock() { - uidTextField.setText(UUID.randomUUID().toString()); + if (uidTextField != null) + uidTextField.setText(UUID.randomUUID().toString()); nameTextField.setText("Manfred Karrer"); if (titleTextField != null) titleTextField.setText("Development work November 2017"); diff --git a/src/main/java/bisq/desktop/main/dao/results/BaseResultsTableView1.java b/src/main/java/bisq/desktop/main/dao/results/BaseResultsTableView1.java new file mode 100644 index 00000000000..27ff8d7145b --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/results/BaseResultsTableView1.java @@ -0,0 +1,110 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.desktop.main.dao.results; + +import bisq.desktop.components.AutoTooltipLabel; +import bisq.desktop.components.TableGroupHeadline; +import bisq.desktop.main.dao.results.model.ResultsOfCycle; +import bisq.desktop.util.GUIUtil; + +import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.dao.DaoFacade; +import bisq.core.locale.Res; +import bisq.core.util.BsqFormatter; + +import javafx.scene.control.TableView; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.Priority; + +import javafx.geometry.Insets; + +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.collections.transformation.SortedList; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public abstract class BaseResultsTableView1 { + protected final GridPane gridPane; + protected final BsqWalletService bsqWalletService; + protected final DaoFacade daoFacade; + protected final BsqFormatter bsqFormatter; + + protected int gridRow; + protected int gridRowStartIndex; + + + protected final ObservableList itemList = FXCollections.observableArrayList(); + private final SortedList sortedList = new SortedList<>(itemList); + protected ResultsOfCycle resultsOfCycle; + protected TableView tableView; + + protected abstract String getTitle(); + + protected abstract void fillList(); + + protected abstract void createColumns(TableView tableView); + + public BaseResultsTableView1(GridPane gridPane, BsqWalletService bsqWalletService, DaoFacade daoFacade, BsqFormatter bsqFormatter) { + this.gridPane = gridPane; + this.bsqWalletService = bsqWalletService; + this.daoFacade = daoFacade; + this.bsqFormatter = bsqFormatter; + } + + public int createAllFields(int gridRowStartIndex, ResultsOfCycle resultsOfCycle) { + this.resultsOfCycle = resultsOfCycle; + this.gridRowStartIndex = gridRowStartIndex; + this.gridRow = gridRowStartIndex; + + removeAllFields(); + createTableView(); + fillList(); + GUIUtil.setFitToRowsForTableView(tableView, 33, 28, 80); + + return gridRow; + } + + private void createTableView() { + TableGroupHeadline headline = new TableGroupHeadline(getTitle()); + GridPane.setRowIndex(headline, gridRow); + GridPane.setMargin(headline, new Insets(15, -10, -10, -10)); + GridPane.setColumnSpan(headline, 2); + gridPane.getChildren().add(headline); + + tableView = new TableView<>(); + tableView.setPlaceholder(new AutoTooltipLabel(Res.get("table.placeholder.noData"))); + tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); + + createColumns(tableView); + GridPane.setRowIndex(tableView, gridRow); + GridPane.setMargin(tableView, new Insets(35, -10, 5, -10)); + GridPane.setColumnSpan(tableView, 2); + GridPane.setHgrow(tableView, Priority.SOMETIMES); + gridPane.getChildren().add(tableView); + + tableView.setItems(sortedList); + sortedList.comparatorProperty().bind(tableView.comparatorProperty()); + } + + private void removeAllFields() { + GUIUtil.removeChildrenFromGridPaneRows(gridPane, gridRowStartIndex, gridRow); + gridRow = gridRowStartIndex; + } +} From 1ab786828776edd60991883fea18c10247dd7f6a Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Tue, 24 Jul 2018 18:21:05 +0200 Subject: [PATCH 166/197] Improve UI for results --- src/main/java/bisq/desktop/bisq.css | 23 +- .../main/dao/results/BaseResultsListItem.java | 48 ++++ .../dao/results/BaseResultsTableView1.java | 63 ++--- .../desktop/main/dao/results/ResultsView.java | 65 ++++- .../main/dao/results/SelectionListener.java | 28 ++ .../proposals/ProposalResultsListItem.java | 4 +- .../proposals/ProposalResultsTableView.java | 249 +++++++++++------- .../main/dao/results/votes/VotesListItem.java | 13 +- .../dao/results/votes/VotesTableView.java | 168 ++++++++++-- 9 files changed, 494 insertions(+), 167 deletions(-) create mode 100644 src/main/java/bisq/desktop/main/dao/results/BaseResultsListItem.java create mode 100644 src/main/java/bisq/desktop/main/dao/results/SelectionListener.java diff --git a/src/main/java/bisq/desktop/bisq.css b/src/main/java/bisq/desktop/bisq.css index 2b9ef1bb534..7582f5b45c6 100644 --- a/src/main/java/bisq/desktop/bisq.css +++ b/src/main/java/bisq/desktop/bisq.css @@ -1352,7 +1352,6 @@ textfield */ -fx-font-size: 0.846em; } - /******************************************************************************************************************** * * * DAO * @@ -1362,3 +1361,25 @@ textfield */ .compensation-root { -fx-background-insets: 0, 0 0 0 0 } + +.info-icon { + -fx-text-fill: -fx-accent; +} + +.info-icon-button { + -fx-cursor: hand; + -fx-background-color: transparent; +} + +/* +.vote-result-table-row-accepted { + -fx-background-color: rgba(0, 255, 0, 0.4); +} + +.vote-result-table-row-rejected { + -fx-background-color: rgba(255, 0, 68, 0.23); +} + +.vote-result-table-row-ignored { + -fx-background-color: rgba(182, 182, 182, 0.4); +}*/ diff --git a/src/main/java/bisq/desktop/main/dao/results/BaseResultsListItem.java b/src/main/java/bisq/desktop/main/dao/results/BaseResultsListItem.java new file mode 100644 index 00000000000..6506dcb5960 --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/results/BaseResultsListItem.java @@ -0,0 +1,48 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.desktop.main.dao.results; + +import bisq.core.dao.voting.voteresult.DecryptedVote; +import bisq.core.dao.voting.voteresult.EvaluatedProposal; + +import javafx.scene.control.TableRow; + +public class BaseResultsListItem { + private TableRow tableRow; + + public void setTableRow(TableRow tableRow) { + this.tableRow = tableRow; + } + + public void resetTableRow() { + if (tableRow != null) { + tableRow.setStyle(null); + tableRow.requestLayout(); + + } + } + + public void applyVoteAndProposal(DecryptedVote decryptedVote, EvaluatedProposal evaluatedProposal) { + String rowBgColor = decryptedVote.getVote(evaluatedProposal.getProposalTxId()) + .map(booleanVote -> booleanVote.isAccepted() ? + "-fx-background-color: rgba(0, 255, 0, 0.4)" : + "-fx-background-color: rgba(255, 0, 0, 0.23)") + .orElse("-fx-background-color: rgba(182, 182, 182, 0.4)"); + tableRow.setStyle(rowBgColor); + } +} diff --git a/src/main/java/bisq/desktop/main/dao/results/BaseResultsTableView1.java b/src/main/java/bisq/desktop/main/dao/results/BaseResultsTableView1.java index 27ff8d7145b..1e8789865b8 100644 --- a/src/main/java/bisq/desktop/main/dao/results/BaseResultsTableView1.java +++ b/src/main/java/bisq/desktop/main/dao/results/BaseResultsTableView1.java @@ -20,7 +20,6 @@ import bisq.desktop.components.AutoTooltipLabel; import bisq.desktop.components.TableGroupHeadline; import bisq.desktop.main.dao.results.model.ResultsOfCycle; -import bisq.desktop.util.GUIUtil; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; @@ -33,27 +32,29 @@ import javafx.geometry.Insets; +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; + import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.collections.transformation.SortedList; +import lombok.Getter; import lombok.extern.slf4j.Slf4j; @Slf4j public abstract class BaseResultsTableView1 { - protected final GridPane gridPane; + @Getter + protected GridPane gridPane = new GridPane(); protected final BsqWalletService bsqWalletService; protected final DaoFacade daoFacade; protected final BsqFormatter bsqFormatter; - protected int gridRow; - protected int gridRowStartIndex; - - protected final ObservableList itemList = FXCollections.observableArrayList(); private final SortedList sortedList = new SortedList<>(itemList); protected ResultsOfCycle resultsOfCycle; protected TableView tableView; + private TableGroupHeadline headline; protected abstract String getTitle(); @@ -61,31 +62,15 @@ public abstract class BaseResultsTableView1 { protected abstract void createColumns(TableView tableView); - public BaseResultsTableView1(GridPane gridPane, BsqWalletService bsqWalletService, DaoFacade daoFacade, BsqFormatter bsqFormatter) { - this.gridPane = gridPane; + public BaseResultsTableView1(BsqWalletService bsqWalletService, DaoFacade daoFacade, + BsqFormatter bsqFormatter, int columnIndex) { this.bsqWalletService = bsqWalletService; this.daoFacade = daoFacade; this.bsqFormatter = bsqFormatter; - } - - public int createAllFields(int gridRowStartIndex, ResultsOfCycle resultsOfCycle) { - this.resultsOfCycle = resultsOfCycle; - this.gridRowStartIndex = gridRowStartIndex; - this.gridRow = gridRowStartIndex; - - removeAllFields(); - createTableView(); - fillList(); - GUIUtil.setFitToRowsForTableView(tableView, 33, 28, 80); - - return gridRow; - } - private void createTableView() { - TableGroupHeadline headline = new TableGroupHeadline(getTitle()); - GridPane.setRowIndex(headline, gridRow); + headline = new TableGroupHeadline(getTitle()); GridPane.setMargin(headline, new Insets(15, -10, -10, -10)); - GridPane.setColumnSpan(headline, 2); + GridPane.setColumnIndex(headline, columnIndex); gridPane.getChildren().add(headline); tableView = new TableView<>(); @@ -93,18 +78,28 @@ private void createTableView() { tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); createColumns(tableView); - GridPane.setRowIndex(tableView, gridRow); GridPane.setMargin(tableView, new Insets(35, -10, 5, -10)); - GridPane.setColumnSpan(tableView, 2); - GridPane.setHgrow(tableView, Priority.SOMETIMES); + GridPane.setColumnIndex(tableView, columnIndex); gridPane.getChildren().add(tableView); - tableView.setItems(sortedList); - sortedList.comparatorProperty().bind(tableView.comparatorProperty()); + GridPane.setHgrow(headline, Priority.ALWAYS); + GridPane.setHgrow(tableView, Priority.ALWAYS); + + tableView.getSelectionModel().selectedItemProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue observable, R oldValue, R newValue) { + onSelected(newValue); + } + }); } - private void removeAllFields() { - GUIUtil.removeChildrenFromGridPaneRows(gridPane, gridRowStartIndex, gridRow); - gridRow = gridRowStartIndex; + protected abstract void onSelected(R item); + + public void createAllFields(ResultsOfCycle resultsOfCycle) { + this.resultsOfCycle = resultsOfCycle; + + tableView.setItems(sortedList); + sortedList.comparatorProperty().bind(tableView.comparatorProperty()); + fillList(); } } diff --git a/src/main/java/bisq/desktop/main/dao/results/ResultsView.java b/src/main/java/bisq/desktop/main/dao/results/ResultsView.java index 1c815e871ba..78982fa0c74 100644 --- a/src/main/java/bisq/desktop/main/dao/results/ResultsView.java +++ b/src/main/java/bisq/desktop/main/dao/results/ResultsView.java @@ -58,6 +58,7 @@ import javafx.fxml.FXML; +import javafx.scene.control.Label; import javafx.scene.control.ScrollPane; import javafx.scene.control.TableCell; import javafx.scene.control.TableColumn; @@ -65,7 +66,9 @@ import javafx.scene.layout.AnchorPane; import javafx.scene.layout.ColumnConstraints; import javafx.scene.layout.GridPane; +import javafx.scene.layout.HBox; import javafx.scene.layout.Priority; +import javafx.scene.layout.StackPane; import javafx.geometry.HPos; import javafx.geometry.Insets; @@ -89,7 +92,7 @@ import static bisq.desktop.util.FormBuilder.addLabelTextField; @FxmlView -public class ResultsView extends ActivatableViewAndModel implements BsqStateListener { +public class ResultsView extends ActivatableViewAndModel implements BsqStateListener, SelectionListener { @FXML private ScrollPane scrollPane; @@ -115,6 +118,8 @@ public class ResultsView extends ActivatableViewAndModel onResultsListItemSelected(newValue); } + @Override + public void onSelectedEvaluatedProposal(EvaluatedProposal evaluatedProposal) { + votesTableView.onSelectedEvaluatedProposal(evaluatedProposal); + } + + @Override + public void onSelectedDecryptedVote(DecryptedVote decryptedVote) { + proposalResultsTableView.onSelectedDecryptedVote(decryptedVote); + } + @Override protected void activate() { tableView.getSelectionModel().selectedItemProperty().addListener(selectedItemListener); @@ -195,14 +224,24 @@ public void onParseBlockChainComplete() { /////////////////////////////////////////////////////////////////////////////////////////// private void onResultsListItemSelected(ResultsListItem item) { - removeDetailsViews(); + //removeDetailsViews(); if (item != null) { ResultsOfCycle resultsOfCycle = item.getResultsOfCycle(); - gridRow = votesPerProposalTableView.createAllFields(++gridRow, resultsOfCycle); - gridRow = proposalResultsTableView.createAllFields(++gridRow, resultsOfCycle); - gridRow = votesTableView.createAllFields(++gridRow, resultsOfCycle); - addParams(resultsOfCycle); + GUIUtil.removeChildrenFromGridPaneRows(gridPane, 1, gridRow); + gridRow = 1; + + // gridRow = votesPerProposalTableView.createAllFields(++gridRow, resultsOfCycle); + proposalResultsTableView.createAllFields(resultsOfCycle); + votesTableView.createAllFields(resultsOfCycle); + + gridPane.getChildren().add(hBox); + + GridPane.setRowIndex(hBox, gridRow); + GridPane.setMargin(hBox, new Insets(0, 0, 0, 0)); + GridPane.setColumnSpan(hBox, 2); + + // addParams(resultsOfCycle); } } diff --git a/src/main/java/bisq/desktop/main/dao/results/SelectionListener.java b/src/main/java/bisq/desktop/main/dao/results/SelectionListener.java new file mode 100644 index 00000000000..7a57dc21e8f --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/results/SelectionListener.java @@ -0,0 +1,28 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.desktop.main.dao.results; + +import bisq.core.dao.voting.voteresult.DecryptedVote; +import bisq.core.dao.voting.voteresult.EvaluatedProposal; + +public interface SelectionListener { + + void onSelectedEvaluatedProposal(EvaluatedProposal evaluatedProposal); + + void onSelectedDecryptedVote(DecryptedVote decryptedVote); +} diff --git a/src/main/java/bisq/desktop/main/dao/results/proposals/ProposalResultsListItem.java b/src/main/java/bisq/desktop/main/dao/results/proposals/ProposalResultsListItem.java index db85bcf0208..bcc4a9ee7c3 100644 --- a/src/main/java/bisq/desktop/main/dao/results/proposals/ProposalResultsListItem.java +++ b/src/main/java/bisq/desktop/main/dao/results/proposals/ProposalResultsListItem.java @@ -17,6 +17,8 @@ package bisq.desktop.main.dao.results.proposals; +import bisq.desktop.main.dao.results.BaseResultsListItem; + import bisq.core.dao.voting.proposal.ProposalType; import bisq.core.dao.voting.proposal.compensation.CompensationProposal; import bisq.core.dao.voting.voteresult.EvaluatedProposal; @@ -30,7 +32,7 @@ import lombok.Getter; -public class ProposalResultsListItem { +public class ProposalResultsListItem extends BaseResultsListItem { private final ProposalVoteResult proposalVoteResult; private final BsqFormatter bsqFormatter; @Getter diff --git a/src/main/java/bisq/desktop/main/dao/results/proposals/ProposalResultsTableView.java b/src/main/java/bisq/desktop/main/dao/results/proposals/ProposalResultsTableView.java index a526615d5f2..0d0f03455bf 100644 --- a/src/main/java/bisq/desktop/main/dao/results/proposals/ProposalResultsTableView.java +++ b/src/main/java/bisq/desktop/main/dao/results/proposals/ProposalResultsTableView.java @@ -18,29 +18,25 @@ package bisq.desktop.main.dao.results.proposals; import bisq.desktop.components.AutoTooltipTableColumn; -import bisq.desktop.main.dao.proposal.ProposalWindow; -import bisq.desktop.main.dao.results.BaseResultsTableView; -import bisq.desktop.main.dao.results.model.ResultsOfCycle; -import bisq.desktop.util.GUIUtil; +import bisq.desktop.main.dao.results.BaseResultsTableView1; +import bisq.desktop.main.dao.results.SelectionListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; import bisq.core.dao.state.BsqStateService; -import bisq.core.dao.state.period.CycleService; -import bisq.core.dao.voting.proposal.ProposalService; -import bisq.core.dao.voting.voteresult.VoteResultService; +import bisq.core.dao.voting.voteresult.DecryptedVote; import bisq.core.locale.Res; import bisq.core.util.BsqFormatter; import de.jensd.fx.fontawesome.AwesomeDude; +import de.jensd.fx.fontawesome.AwesomeIcon; -import javafx.scene.control.Hyperlink; +import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.control.TableCell; import javafx.scene.control.TableColumn; import javafx.scene.control.TableView; import javafx.scene.control.Tooltip; -import javafx.scene.layout.GridPane; import javafx.beans.property.ReadOnlyObjectWrapper; @@ -52,32 +48,35 @@ import lombok.extern.slf4j.Slf4j; @Slf4j -public class ProposalResultsTableView extends BaseResultsTableView { +public class ProposalResultsTableView extends BaseResultsTableView1 { + private SelectionListener selectionListener; private final BsqStateService bsqStateService; - private final CycleService cycleService; - private final VoteResultService voteResultService; - private final ProposalService proposalService; - - public ProposalResultsTableView(GridPane gridPane, BsqWalletService bsqWalletService, DaoFacade daoFacade, BsqFormatter bsqFormatter, - BsqStateService bsqStateService, - CycleService cycleService, - VoteResultService voteResultService, - ProposalService proposalService) { - super(gridPane, bsqWalletService, daoFacade, bsqFormatter); + + public ProposalResultsTableView(SelectionListener selectionListener, + BsqWalletService bsqWalletService, DaoFacade daoFacade, BsqFormatter bsqFormatter, + BsqStateService bsqStateService) { + super(bsqWalletService, daoFacade, bsqFormatter, 0); + this.selectionListener = selectionListener; this.bsqStateService = bsqStateService; - this.cycleService = cycleService; - this.voteResultService = voteResultService; - this.proposalService = proposalService; } @Override - protected String getTitle() { - return Res.get("dao.results.proposals.header"); + protected void onSelected(ProposalResultsListItem item) { + itemList.forEach(ProposalResultsListItem::resetTableRow); + + if (item != null) + selectionListener.onSelectedEvaluatedProposal(item.getEvaluatedProposal()); + } + + public void onSelectedDecryptedVote(DecryptedVote decryptedVote) { + itemList.forEach(item -> item.applyVoteAndProposal(decryptedVote, item.getEvaluatedProposal())); } @Override protected void fillList() { + itemList.forEach(ProposalResultsListItem::resetTableRow); + itemList.setAll(resultsOfCycle.getEvaluatedProposals().stream() .map(e -> new ProposalResultsListItem(e, bsqFormatter)) .collect(Collectors.toList())); @@ -85,18 +84,15 @@ protected void fillList() { itemList.sort(Comparator.comparing(proposalResultsListItem -> proposalResultsListItem.getEvaluatedProposal().getProposal().getCreationDate())); } - public int createAllFields(int gridRowStartIndex, ResultsOfCycle resultsOfCycle) { - super.createAllFields(gridRowStartIndex, resultsOfCycle); - - GUIUtil.setFitToRowsForTableView(tableView, 30, 28, 80); - - return gridRow; + @Override + protected String getTitle() { + return Res.get("dao.results.proposals.header"); } @Override protected void createColumns(TableView tableView) { TableColumn nameColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.proposals.table.header.proposalOwnerName")); - nameColumn.setMinWidth(100); + nameColumn.setMinWidth(110); nameColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); nameColumn.setCellFactory( new Callback, TableCell tableView) { public TableCell call( TableColumn column) { return new TableCell() { + @Override public void updateItem(final ProposalResultsListItem item, boolean empty) { super.updateItem(item, empty); - if (item != null) + if (item != null) { + item.setTableRow(getTableRow()); setText(item.getProposalOwnerName()); - else + } else { setText(""); + } } }; } @@ -119,7 +118,114 @@ public void updateItem(final ProposalResultsListItem item, boolean empty) { nameColumn.setComparator(Comparator.comparing(ProposalResultsListItem::getProposalOwnerName)); tableView.getColumns().add(nameColumn); - TableColumn idColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.proposals.table.header.proposalId")); + + TableColumn issuanceColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.proposals.table.header.issuance")); + issuanceColumn.setMinWidth(100); + issuanceColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + issuanceColumn.setCellFactory( + new Callback, TableCell>() { + @Override + public TableCell call( + TableColumn column) { + return new TableCell() { + @Override + public void updateItem(final ProposalResultsListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null) + setText(item.getIssuance()); + else + setText(""); + } + }; + } + }); + issuanceColumn.setComparator(Comparator.comparing(ProposalResultsListItem::getThreshold)); + tableView.getColumns().add(issuanceColumn); + + TableColumn resultColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.proposals.table.header.result")); + resultColumn.setMinWidth(60); + resultColumn.setMaxWidth(60); + resultColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + resultColumn.setCellFactory(new Callback, + TableCell>() { + @Override + public TableCell call(TableColumn column) { + return new TableCell() { + Label icon; + + @Override + public void updateItem(final ProposalResultsListItem item, boolean empty) { + super.updateItem(item, empty); + + if (item != null && !empty) { + icon = new Label(); + AwesomeDude.setIcon(icon, item.getIcon()); + icon.getStyleClass().add(item.getColorStyleClass()); + setGraphic(icon); + } else { + setGraphic(null); + if (icon != null) + icon = null; + } + } + }; + } + }); + tableView.getColumns().add(resultColumn); + + + TableColumn detailsColumn = new TableColumn<>(); + detailsColumn.setMinWidth(60); + detailsColumn.setMaxWidth(60); + detailsColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + detailsColumn.setCellFactory(new Callback, + TableCell>() { + @Override + public TableCell call(TableColumn column) { + return new TableCell() { + Label icon; + Button button; + + @Override + public void updateItem(final ProposalResultsListItem item, boolean empty) { + super.updateItem(item, empty); + + if (item != null && !empty) { + icon = new Label(); + AwesomeDude.setIcon(icon, AwesomeIcon.INFO_SIGN); + icon.setTooltip(new Tooltip(Res.get("tooltip.openPopupForDetails"))); + icon.getStyleClass().add("info-icon"); + + button = new Button("", icon); + button.getStyleClass().add("info-icon-button"); + button.setOnAction(e -> { + new VoteResultsForProposalWindow(resultsOfCycle, + item.getEvaluatedProposal().getProposal(), + bsqStateService, + bsqFormatter) + .show(); + }); + setGraphic(button); + } else { + setGraphic(null); + if (icon != null) + icon = null; + if (button != null) + button = null; + } + } + }; + } + }); + tableView.getColumns().add(detailsColumn); + + + + + /* TableColumn idColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.proposals.table.header.proposalId")); idColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); idColumn.setMinWidth(100); idColumn.setCellFactory( @@ -160,9 +266,9 @@ public void updateItem(final ProposalResultsListItem item, boolean empty) { } }); idColumn.setComparator(Comparator.comparing(ProposalResultsListItem::getProposalOwnerName)); - tableView.getColumns().add(idColumn); + tableView.getColumns().add(idColumn);*/ - TableColumn acceptedColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.proposals.table.header.accepted")); + /* TableColumn acceptedColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.proposals.table.header.accepted")); acceptedColumn.setMinWidth(80); acceptedColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); acceptedColumn.setCellFactory( @@ -237,9 +343,9 @@ public void updateItem(final ProposalResultsListItem item, boolean empty) { } }); rejectedColumn.setComparator(Comparator.comparing(ProposalResultsListItem::getRejected)); - tableView.getColumns().add(rejectedColumn); + tableView.getColumns().add(rejectedColumn);*/ - TableColumn thresholdColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.proposals.table.header.threshold")); + /* TableColumn thresholdColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.proposals.table.header.threshold")); thresholdColumn.setMinWidth(100); thresholdColumn.setMaxWidth(100); thresholdColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); @@ -262,9 +368,9 @@ public void updateItem(final ProposalResultsListItem item, boolean empty) { } }); thresholdColumn.setComparator(Comparator.comparing(ProposalResultsListItem::getThreshold)); - tableView.getColumns().add(thresholdColumn); + tableView.getColumns().add(thresholdColumn);*/ - TableColumn quorumColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.proposals.table.header.quorum")); + /* TableColumn quorumColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.proposals.table.header.quorum")); quorumColumn.setMinWidth(130); quorumColumn.setMaxWidth(130); quorumColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); @@ -287,65 +393,6 @@ public void updateItem(final ProposalResultsListItem item, boolean empty) { } }); quorumColumn.setComparator(Comparator.comparing(ProposalResultsListItem::getThreshold)); - tableView.getColumns().add(quorumColumn); - - TableColumn issuanceColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.proposals.table.header.issuance")); - issuanceColumn.setMinWidth(130); - issuanceColumn.setMaxWidth(130); - issuanceColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - issuanceColumn.setCellFactory( - new Callback, TableCell>() { - @Override - public TableCell call( - TableColumn column) { - return new TableCell() { - @Override - public void updateItem(final ProposalResultsListItem item, boolean empty) { - super.updateItem(item, empty); - if (item != null) - setText(item.getIssuance()); - else - setText(""); - } - }; - } - }); - issuanceColumn.setComparator(Comparator.comparing(ProposalResultsListItem::getThreshold)); - tableView.getColumns().add(issuanceColumn); - - TableColumn resultColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.proposals.table.header.result")); - resultColumn.setMinWidth(60); - resultColumn.setMaxWidth(60); - resultColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - resultColumn.setCellFactory(new Callback, - TableCell>() { - @Override - public TableCell call(TableColumn column) { - return new TableCell() { - Label icon; - - @Override - public void updateItem(final ProposalResultsListItem item, boolean empty) { - super.updateItem(item, empty); - - if (item != null && !empty) { - icon = new Label(); - AwesomeDude.setIcon(icon, item.getIcon()); - icon.getStyleClass().add(item.getColorStyleClass()); - setGraphic(icon); - } else { - setGraphic(null); - if (icon != null) - icon = null; - } - } - }; - } - }); - - resultColumn.setComparator(Comparator.comparing(ProposalResultsListItem::getThreshold)); - tableView.getColumns().add(resultColumn); + tableView.getColumns().add(quorumColumn);*/ } } diff --git a/src/main/java/bisq/desktop/main/dao/results/votes/VotesListItem.java b/src/main/java/bisq/desktop/main/dao/results/votes/VotesListItem.java index 4733980ce2e..2883017841e 100644 --- a/src/main/java/bisq/desktop/main/dao/results/votes/VotesListItem.java +++ b/src/main/java/bisq/desktop/main/dao/results/votes/VotesListItem.java @@ -17,6 +17,8 @@ package bisq.desktop.main.dao.results.votes; +import bisq.desktop.main.dao.results.BaseResultsListItem; + import bisq.core.dao.state.BsqStateService; import bisq.core.dao.voting.ballot.vote.BooleanVote; import bisq.core.dao.voting.ballot.vote.LongVote; @@ -34,7 +36,7 @@ import lombok.Getter; -public class VotesListItem { +public class VotesListItem extends BaseResultsListItem { private final BsqStateService bsqStateService; private final BsqFormatter bsqFormatter; private int id; @@ -60,6 +62,15 @@ public String getStake() { return bsqFormatter.formatCoinWithCode(getStakeAsCoin()); } + public String getStakeAndMerit() { + return bsqFormatter.formatCoinWithCode(getStakeAndMeritAsCoin()); + } + + public Coin getStakeAndMeritAsCoin() { + return getMeritAsCoin().add(getStakeAsCoin()); + } + + public Coin getStakeAsCoin() { return Coin.valueOf(decryptedVote.getStake()); } diff --git a/src/main/java/bisq/desktop/main/dao/results/votes/VotesTableView.java b/src/main/java/bisq/desktop/main/dao/results/votes/VotesTableView.java index d19b11b62f9..5443600dea0 100644 --- a/src/main/java/bisq/desktop/main/dao/results/votes/VotesTableView.java +++ b/src/main/java/bisq/desktop/main/dao/results/votes/VotesTableView.java @@ -18,26 +18,28 @@ package bisq.desktop.main.dao.results.votes; import bisq.desktop.components.AutoTooltipTableColumn; -import bisq.desktop.components.HyperlinkWithIcon; -import bisq.desktop.main.dao.results.BaseResultsTableView; -import bisq.desktop.main.dao.results.model.ResultsOfCycle; +import bisq.desktop.main.dao.results.BaseResultsTableView1; +import bisq.desktop.main.dao.results.SelectionListener; import bisq.desktop.util.GUIUtil; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; import bisq.core.dao.state.BsqStateService; import bisq.core.dao.voting.voteresult.DecryptedVote; +import bisq.core.dao.voting.voteresult.EvaluatedProposal; import bisq.core.locale.Res; import bisq.core.user.Preferences; import bisq.core.util.BsqFormatter; +import de.jensd.fx.fontawesome.AwesomeDude; import de.jensd.fx.fontawesome.AwesomeIcon; +import javafx.scene.control.Button; +import javafx.scene.control.Label; import javafx.scene.control.TableCell; import javafx.scene.control.TableColumn; import javafx.scene.control.TableView; import javafx.scene.control.Tooltip; -import javafx.scene.layout.GridPane; import javafx.beans.property.ReadOnlyObjectWrapper; @@ -52,25 +54,37 @@ import lombok.extern.slf4j.Slf4j; @Slf4j -public class VotesTableView extends BaseResultsTableView { +public class VotesTableView extends BaseResultsTableView1 { + private SelectionListener selectionListener; private final BsqStateService bsqStateService; private final Preferences preferences; - public VotesTableView(GridPane gridPane, BsqWalletService bsqWalletService, DaoFacade daoFacade, + public VotesTableView(SelectionListener selectionListener, + BsqWalletService bsqWalletService, DaoFacade daoFacade, BsqStateService bsqStateService, Preferences preferences, BsqFormatter bsqFormatter) { - super(gridPane, bsqWalletService, daoFacade, bsqFormatter); + super(bsqWalletService, daoFacade, bsqFormatter, 1); + this.selectionListener = selectionListener; this.bsqStateService = bsqStateService; this.preferences = preferences; } @Override - protected String getTitle() { - return Res.get("dao.results.votes.header"); + protected void onSelected(VotesListItem item) { + itemList.forEach(VotesListItem::resetTableRow); + + if (item != null) + selectionListener.onSelectedDecryptedVote(item.getDecryptedVote()); + } + + public void onSelectedEvaluatedProposal(EvaluatedProposal evaluatedProposal) { + itemList.forEach(item -> item.applyVoteAndProposal(item.getDecryptedVote(), evaluatedProposal)); } @Override protected void fillList() { + itemList.forEach(VotesListItem::resetTableRow); + List decryptedVotesForCycle = new ArrayList<>(resultsOfCycle.getDecryptedVotesForCycle()); decryptedVotesForCycle.sort(Comparator.comparing(DecryptedVote::getBlindVoteTxId)); AtomicInteger index = new AtomicInteger(); @@ -82,16 +96,138 @@ protected void fillList() { .collect(Collectors.toList())); } - public int createAllFields(int gridRowStartIndex, ResultsOfCycle resultsOfCycle) { - super.createAllFields(gridRowStartIndex, resultsOfCycle); - - GUIUtil.setFitToRowsForTableView(tableView, 33, 28, 80); - - return gridRow; + @Override + protected String getTitle() { + return Res.get("dao.results.votes.header"); } @Override protected void createColumns(TableView tableView) { + TableColumn stakeAndMeritColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.stakeAndMerit")); + stakeAndMeritColumn.setMinWidth(90); + stakeAndMeritColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + stakeAndMeritColumn.setCellFactory( + new Callback, TableCell>() { + + + @Override + public TableCell call( + TableColumn column) { + return new TableCell() { + @Override + public void updateItem(final VotesListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null) { + item.setTableRow(getTableRow()); + setText(item.getStakeAndMerit()); + } else { + setText(""); + } + } + }; + } + }); + stakeAndMeritColumn.setComparator(Comparator.comparing(VotesListItem::getStakeAsCoin)); + tableView.getColumns().add(stakeAndMeritColumn); + + TableColumn stakeColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.stake")); + stakeColumn.setMinWidth(90); + stakeColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + stakeColumn.setCellFactory( + new Callback, TableCell>() { + @Override + public TableCell call( + TableColumn column) { + return new TableCell() { + @Override + public void updateItem(final VotesListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null) + setText(item.getStake()); + else + setText(""); + } + }; + } + }); + stakeColumn.setComparator(Comparator.comparing(VotesListItem::getStakeAsCoin)); + tableView.getColumns().add(stakeColumn); + + TableColumn meritColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.merit")); + meritColumn.setMinWidth(90); + meritColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + meritColumn.setCellFactory( + new Callback, TableCell>() { + @Override + public TableCell call( + TableColumn column) { + return new TableCell() { + @Override + public void updateItem(final VotesListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null) + setText(item.getMerit()); + else + setText(""); + } + }; + } + }); + meritColumn.setComparator(Comparator.comparing(VotesListItem::getMeritAsCoin)); + tableView.getColumns().add(meritColumn); + + + TableColumn detailsColumn = new TableColumn<>(); + detailsColumn.setMinWidth(60); + detailsColumn.setMaxWidth(60); + detailsColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + detailsColumn.setCellFactory(new Callback, + TableCell>() { + @Override + public TableCell call(TableColumn column) { + return new TableCell() { + Label icon; + Button button; + + @Override + public void updateItem(final VotesListItem item, boolean empty) { + super.updateItem(item, empty); + + if (item != null && !empty) { + icon = new Label(); + AwesomeDude.setIcon(icon, AwesomeIcon.INFO_SIGN); + icon.setTooltip(new Tooltip(Res.get("tooltip.openPopupForDetails"))); + icon.getStyleClass().add("info-icon"); + + button = new Button("", icon); + button.getStyleClass().add("info-icon-button"); + button.setOnAction(e -> { + /* new VoteResultsForProposalWindow(resultsOfCycle, + item.getEvaluatedProposal().getProposal(), + bsqStateService, + bsqFormatter) + .show();*/ + }); + setGraphic(button); + } else { + setGraphic(null); + if (icon != null) + icon = null; + if (button != null) + button = null; + } + } + }; + } + }); + tableView.getColumns().add(detailsColumn); + + /* + TableColumn indexColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.id")); indexColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); indexColumn.setMinWidth(70); @@ -279,7 +415,7 @@ public void updateItem(final VotesListItem item, boolean empty) { } }); voteRevealTxIdColumn.setComparator(Comparator.comparing(VotesListItem::getVoteRevealTxId)); - tableView.getColumns().add(voteRevealTxIdColumn); + tableView.getColumns().add(voteRevealTxIdColumn);*/ } private void openTxInBlockExplorer(String txId) { From 1c71b7ca73e2f61a572cc04ac7d0790e5ff28c2b Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Wed, 25 Jul 2018 00:09:04 +0200 Subject: [PATCH 167/197] Fix missing confidence icon, show genesis tx in tx view --- .../bisq/desktop/main/dao/TxConfidenceListItem.java | 4 ---- .../bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java | 10 +++++----- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/TxConfidenceListItem.java b/src/main/java/bisq/desktop/main/dao/TxConfidenceListItem.java index ab635d2b281..1b79103b14d 100644 --- a/src/main/java/bisq/desktop/main/dao/TxConfidenceListItem.java +++ b/src/main/java/bisq/desktop/main/dao/TxConfidenceListItem.java @@ -44,10 +44,6 @@ protected TxConfidenceListItem(Transaction transaction, this.bsqWalletService = bsqWalletService; txId = transaction.getHashAsString(); - setupConfidence(bsqWalletService); - } - - private void setupConfidence(BsqWalletService bsqWalletService) { txConfidenceIndicator = new TxConfidenceIndicator(); txConfidenceIndicator.setId("funds-confidence"); Tooltip tooltip = new Tooltip(); diff --git a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java index 7eba0c478e1..265b414da15 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java @@ -17,10 +17,8 @@ package bisq.desktop.main.dao.wallet.tx; -import bisq.desktop.components.indicator.TxConfidenceIndicator; import bisq.desktop.main.dao.TxConfidenceListItem; -import bisq.core.btc.listeners.TxConfidenceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; import bisq.core.btc.wallet.WalletService; @@ -56,8 +54,6 @@ class BsqTxListItem extends TxConfidenceListItem { private Coin amount; private boolean received; - private TxConfidenceIndicator txConfidenceIndicator; - private TxConfidenceListener txConfidenceListener; private boolean issuanceTx; BsqTxListItem(Transaction transaction, @@ -81,7 +77,11 @@ class BsqTxListItem extends TxConfidenceListItem { Coin valueSentFromMe = bsqWalletService.getValueSentFromMeForTransaction(transaction); amount = valueSentToMe.subtract(valueSentFromMe); if (amount.isPositive()) { - direction = Res.get("funds.tx.direction.receivedWith"); + if (txId.equals(daoFacade.getGenesisTxId())) + direction = Res.get("funds.tx.direction.genesisTx"); + else + direction = Res.get("funds.tx.direction.receivedWith"); + received = true; } else if (amount.isNegative()) { direction = Res.get("funds.tx.direction.sentTo"); From 058617442a7719d1424549c618bb54ec7bea55da Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Wed, 25 Jul 2018 00:14:46 +0200 Subject: [PATCH 168/197] Rename result views --- ...bleView1.java => BaseResultsGridPane.java} | 11 +- .../desktop/main/dao/results/ResultsView.java | 32 ++- ...View.java => ProposalResultsGridPane.java} | 10 +- ...ableView.java => VoteResultsGridPane.java} | 194 +++++++++--------- ...ListItem.java => VoteResultsListItem.java} | 4 +- 5 files changed, 123 insertions(+), 128 deletions(-) rename src/main/java/bisq/desktop/main/dao/results/{BaseResultsTableView1.java => BaseResultsGridPane.java} (90%) rename src/main/java/bisq/desktop/main/dao/results/proposals/{ProposalResultsTableView.java => ProposalResultsGridPane.java} (98%) rename src/main/java/bisq/desktop/main/dao/results/votes/{VotesTableView.java => VoteResultsGridPane.java} (59%) rename src/main/java/bisq/desktop/main/dao/results/votes/{VotesListItem.java => VoteResultsListItem.java} (95%) diff --git a/src/main/java/bisq/desktop/main/dao/results/BaseResultsTableView1.java b/src/main/java/bisq/desktop/main/dao/results/BaseResultsGridPane.java similarity index 90% rename from src/main/java/bisq/desktop/main/dao/results/BaseResultsTableView1.java rename to src/main/java/bisq/desktop/main/dao/results/BaseResultsGridPane.java index 1e8789865b8..aaea38ed17f 100644 --- a/src/main/java/bisq/desktop/main/dao/results/BaseResultsTableView1.java +++ b/src/main/java/bisq/desktop/main/dao/results/BaseResultsGridPane.java @@ -43,9 +43,8 @@ import lombok.extern.slf4j.Slf4j; @Slf4j -public abstract class BaseResultsTableView1 { +public abstract class BaseResultsGridPane extends GridPane { @Getter - protected GridPane gridPane = new GridPane(); protected final BsqWalletService bsqWalletService; protected final DaoFacade daoFacade; protected final BsqFormatter bsqFormatter; @@ -62,8 +61,8 @@ public abstract class BaseResultsTableView1 { protected abstract void createColumns(TableView tableView); - public BaseResultsTableView1(BsqWalletService bsqWalletService, DaoFacade daoFacade, - BsqFormatter bsqFormatter, int columnIndex) { + public BaseResultsGridPane(BsqWalletService bsqWalletService, DaoFacade daoFacade, + BsqFormatter bsqFormatter, int columnIndex) { this.bsqWalletService = bsqWalletService; this.daoFacade = daoFacade; this.bsqFormatter = bsqFormatter; @@ -71,7 +70,7 @@ public BaseResultsTableView1(BsqWalletService bsqWalletService, DaoFacade daoFac headline = new TableGroupHeadline(getTitle()); GridPane.setMargin(headline, new Insets(15, -10, -10, -10)); GridPane.setColumnIndex(headline, columnIndex); - gridPane.getChildren().add(headline); + getChildren().add(headline); tableView = new TableView<>(); tableView.setPlaceholder(new AutoTooltipLabel(Res.get("table.placeholder.noData"))); @@ -80,7 +79,7 @@ public BaseResultsTableView1(BsqWalletService bsqWalletService, DaoFacade daoFac createColumns(tableView); GridPane.setMargin(tableView, new Insets(35, -10, 5, -10)); GridPane.setColumnIndex(tableView, columnIndex); - gridPane.getChildren().add(tableView); + getChildren().add(tableView); GridPane.setHgrow(headline, Priority.ALWAYS); GridPane.setHgrow(tableView, Priority.ALWAYS); diff --git a/src/main/java/bisq/desktop/main/dao/results/ResultsView.java b/src/main/java/bisq/desktop/main/dao/results/ResultsView.java index 78982fa0c74..64d140ea413 100644 --- a/src/main/java/bisq/desktop/main/dao/results/ResultsView.java +++ b/src/main/java/bisq/desktop/main/dao/results/ResultsView.java @@ -27,8 +27,8 @@ import bisq.desktop.components.TitledGroupBg; import bisq.desktop.main.dao.results.combo.VotesPerProposalTableView; import bisq.desktop.main.dao.results.model.ResultsOfCycle; -import bisq.desktop.main.dao.results.proposals.ProposalResultsTableView; -import bisq.desktop.main.dao.results.votes.VotesTableView; +import bisq.desktop.main.dao.results.proposals.ProposalResultsGridPane; +import bisq.desktop.main.dao.results.votes.VoteResultsGridPane; import bisq.desktop.util.FormBuilder; import bisq.desktop.util.GUIUtil; @@ -68,7 +68,6 @@ import javafx.scene.layout.GridPane; import javafx.scene.layout.HBox; import javafx.scene.layout.Priority; -import javafx.scene.layout.StackPane; import javafx.geometry.HPos; import javafx.geometry.Insets; @@ -115,8 +114,8 @@ public class ResultsView extends ActivatableViewAndModel selectedItemListener; private VotesPerProposalTableView votesPerProposalTableView; - private ProposalResultsTableView proposalResultsTableView; - private VotesTableView votesTableView; + private ProposalResultsGridPane proposalResultsGridPane; + private VoteResultsGridPane voteResultsGridPane; private GridPane gridPane; private HBox hBox; private Label directionLabel; @@ -156,33 +155,30 @@ public void initialize() { hBox.setFillHeight(true); //votesPerProposalTableView = new VotesPerProposalTableView(gridPane, bsqWalletService, daoFacade, bsqStateService, bsqFormatter); - proposalResultsTableView = new ProposalResultsTableView(this, bsqWalletService, daoFacade, bsqFormatter, + proposalResultsGridPane = new ProposalResultsGridPane(this, bsqWalletService, daoFacade, bsqFormatter, bsqStateService); - hBox.getChildren().add(proposalResultsTableView.getGridPane()); + hBox.getChildren().add(proposalResultsGridPane); directionLabel = new Label("<< voted on"); HBox.setMargin(directionLabel, new Insets(0, -10, 0, -10)); - StackPane stackPane = new StackPane(); - stackPane.getChildren().add(directionLabel); - hBox.getChildren().add(stackPane); - votesTableView = new VotesTableView(this, bsqWalletService, daoFacade, bsqStateService, preferences, bsqFormatter); - hBox.getChildren().add(votesTableView.getGridPane()); + voteResultsGridPane = new VoteResultsGridPane(this, bsqWalletService, daoFacade, bsqStateService, preferences, bsqFormatter); + hBox.getChildren().add(voteResultsGridPane); - HBox.setHgrow(proposalResultsTableView.getGridPane(), Priority.ALWAYS); - HBox.setHgrow(votesTableView.getGridPane(), Priority.ALWAYS); + HBox.setHgrow(proposalResultsGridPane, Priority.ALWAYS); + HBox.setHgrow(voteResultsGridPane, Priority.ALWAYS); selectedItemListener = (observable, oldValue, newValue) -> onResultsListItemSelected(newValue); } @Override public void onSelectedEvaluatedProposal(EvaluatedProposal evaluatedProposal) { - votesTableView.onSelectedEvaluatedProposal(evaluatedProposal); + voteResultsGridPane.onSelectedEvaluatedProposal(evaluatedProposal); } @Override public void onSelectedDecryptedVote(DecryptedVote decryptedVote) { - proposalResultsTableView.onSelectedDecryptedVote(decryptedVote); + proposalResultsGridPane.onSelectedDecryptedVote(decryptedVote); } @Override @@ -232,8 +228,8 @@ private void onResultsListItemSelected(ResultsListItem item) { gridRow = 1; // gridRow = votesPerProposalTableView.createAllFields(++gridRow, resultsOfCycle); - proposalResultsTableView.createAllFields(resultsOfCycle); - votesTableView.createAllFields(resultsOfCycle); + proposalResultsGridPane.createAllFields(resultsOfCycle); + voteResultsGridPane.createAllFields(resultsOfCycle); gridPane.getChildren().add(hBox); diff --git a/src/main/java/bisq/desktop/main/dao/results/proposals/ProposalResultsTableView.java b/src/main/java/bisq/desktop/main/dao/results/proposals/ProposalResultsGridPane.java similarity index 98% rename from src/main/java/bisq/desktop/main/dao/results/proposals/ProposalResultsTableView.java rename to src/main/java/bisq/desktop/main/dao/results/proposals/ProposalResultsGridPane.java index 0d0f03455bf..58f4dcfdd70 100644 --- a/src/main/java/bisq/desktop/main/dao/results/proposals/ProposalResultsTableView.java +++ b/src/main/java/bisq/desktop/main/dao/results/proposals/ProposalResultsGridPane.java @@ -18,7 +18,7 @@ package bisq.desktop.main.dao.results.proposals; import bisq.desktop.components.AutoTooltipTableColumn; -import bisq.desktop.main.dao.results.BaseResultsTableView1; +import bisq.desktop.main.dao.results.BaseResultsGridPane; import bisq.desktop.main.dao.results.SelectionListener; import bisq.core.btc.wallet.BsqWalletService; @@ -48,14 +48,14 @@ import lombok.extern.slf4j.Slf4j; @Slf4j -public class ProposalResultsTableView extends BaseResultsTableView1 { +public class ProposalResultsGridPane extends BaseResultsGridPane { private SelectionListener selectionListener; private final BsqStateService bsqStateService; - public ProposalResultsTableView(SelectionListener selectionListener, - BsqWalletService bsqWalletService, DaoFacade daoFacade, BsqFormatter bsqFormatter, - BsqStateService bsqStateService) { + public ProposalResultsGridPane(SelectionListener selectionListener, + BsqWalletService bsqWalletService, DaoFacade daoFacade, BsqFormatter bsqFormatter, + BsqStateService bsqStateService) { super(bsqWalletService, daoFacade, bsqFormatter, 0); this.selectionListener = selectionListener; this.bsqStateService = bsqStateService; diff --git a/src/main/java/bisq/desktop/main/dao/results/votes/VotesTableView.java b/src/main/java/bisq/desktop/main/dao/results/votes/VoteResultsGridPane.java similarity index 59% rename from src/main/java/bisq/desktop/main/dao/results/votes/VotesTableView.java rename to src/main/java/bisq/desktop/main/dao/results/votes/VoteResultsGridPane.java index 5443600dea0..a2564fac77d 100644 --- a/src/main/java/bisq/desktop/main/dao/results/votes/VotesTableView.java +++ b/src/main/java/bisq/desktop/main/dao/results/votes/VoteResultsGridPane.java @@ -18,7 +18,7 @@ package bisq.desktop.main.dao.results.votes; import bisq.desktop.components.AutoTooltipTableColumn; -import bisq.desktop.main.dao.results.BaseResultsTableView1; +import bisq.desktop.main.dao.results.BaseResultsGridPane; import bisq.desktop.main.dao.results.SelectionListener; import bisq.desktop.util.GUIUtil; @@ -54,14 +54,14 @@ import lombok.extern.slf4j.Slf4j; @Slf4j -public class VotesTableView extends BaseResultsTableView1 { +public class VoteResultsGridPane extends BaseResultsGridPane { private SelectionListener selectionListener; private final BsqStateService bsqStateService; private final Preferences preferences; - public VotesTableView(SelectionListener selectionListener, - BsqWalletService bsqWalletService, DaoFacade daoFacade, - BsqStateService bsqStateService, Preferences preferences, BsqFormatter bsqFormatter) { + public VoteResultsGridPane(SelectionListener selectionListener, + BsqWalletService bsqWalletService, DaoFacade daoFacade, + BsqStateService bsqStateService, Preferences preferences, BsqFormatter bsqFormatter) { super(bsqWalletService, daoFacade, bsqFormatter, 1); this.selectionListener = selectionListener; @@ -70,8 +70,8 @@ public VotesTableView(SelectionListener selectionListener, } @Override - protected void onSelected(VotesListItem item) { - itemList.forEach(VotesListItem::resetTableRow); + protected void onSelected(VoteResultsListItem item) { + itemList.forEach(VoteResultsListItem::resetTableRow); if (item != null) selectionListener.onSelectedDecryptedVote(item.getDecryptedVote()); @@ -83,7 +83,7 @@ public void onSelectedEvaluatedProposal(EvaluatedProposal evaluatedProposal) { @Override protected void fillList() { - itemList.forEach(VotesListItem::resetTableRow); + itemList.forEach(VoteResultsListItem::resetTableRow); List decryptedVotesForCycle = new ArrayList<>(resultsOfCycle.getDecryptedVotesForCycle()); decryptedVotesForCycle.sort(Comparator.comparing(DecryptedVote::getBlindVoteTxId)); @@ -91,7 +91,7 @@ protected void fillList() { itemList.setAll(decryptedVotesForCycle.stream() .map(decryptedVote -> { int id = index.incrementAndGet(); - return new VotesListItem(id, decryptedVote, bsqStateService, bsqFormatter); + return new VoteResultsListItem(id, decryptedVote, bsqStateService, bsqFormatter); }) .collect(Collectors.toList())); } @@ -102,21 +102,21 @@ protected String getTitle() { } @Override - protected void createColumns(TableView tableView) { - TableColumn stakeAndMeritColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.stakeAndMerit")); + protected void createColumns(TableView tableView) { + TableColumn stakeAndMeritColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.stakeAndMerit")); stakeAndMeritColumn.setMinWidth(90); stakeAndMeritColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); stakeAndMeritColumn.setCellFactory( - new Callback, TableCell>() { + new Callback, TableCell>() { @Override - public TableCell call( - TableColumn column) { - return new TableCell() { + public TableCell call( + TableColumn column) { + return new TableCell() { @Override - public void updateItem(final VotesListItem item, boolean empty) { + public void updateItem(final VoteResultsListItem item, boolean empty) { super.updateItem(item, empty); if (item != null) { item.setTableRow(getTableRow()); @@ -128,21 +128,21 @@ public void updateItem(final VotesListItem item, boolean empty) { }; } }); - stakeAndMeritColumn.setComparator(Comparator.comparing(VotesListItem::getStakeAsCoin)); + stakeAndMeritColumn.setComparator(Comparator.comparing(VoteResultsListItem::getStakeAsCoin)); tableView.getColumns().add(stakeAndMeritColumn); - TableColumn stakeColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.stake")); + TableColumn stakeColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.stake")); stakeColumn.setMinWidth(90); stakeColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); stakeColumn.setCellFactory( - new Callback, TableCell>() { + new Callback, TableCell>() { @Override - public TableCell call( - TableColumn column) { - return new TableCell() { + public TableCell call( + TableColumn column) { + return new TableCell() { @Override - public void updateItem(final VotesListItem item, boolean empty) { + public void updateItem(final VoteResultsListItem item, boolean empty) { super.updateItem(item, empty); if (item != null) setText(item.getStake()); @@ -152,21 +152,21 @@ public void updateItem(final VotesListItem item, boolean empty) { }; } }); - stakeColumn.setComparator(Comparator.comparing(VotesListItem::getStakeAsCoin)); + stakeColumn.setComparator(Comparator.comparing(VoteResultsListItem::getStakeAsCoin)); tableView.getColumns().add(stakeColumn); - TableColumn meritColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.merit")); + TableColumn meritColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.merit")); meritColumn.setMinWidth(90); meritColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); meritColumn.setCellFactory( - new Callback, TableCell>() { + new Callback, TableCell>() { @Override - public TableCell call( - TableColumn column) { - return new TableCell() { + public TableCell call( + TableColumn column) { + return new TableCell() { @Override - public void updateItem(final VotesListItem item, boolean empty) { + public void updateItem(final VoteResultsListItem item, boolean empty) { super.updateItem(item, empty); if (item != null) setText(item.getMerit()); @@ -176,25 +176,25 @@ public void updateItem(final VotesListItem item, boolean empty) { }; } }); - meritColumn.setComparator(Comparator.comparing(VotesListItem::getMeritAsCoin)); + meritColumn.setComparator(Comparator.comparing(VoteResultsListItem::getMeritAsCoin)); tableView.getColumns().add(meritColumn); - TableColumn detailsColumn = new TableColumn<>(); + TableColumn detailsColumn = new TableColumn<>(); detailsColumn.setMinWidth(60); detailsColumn.setMaxWidth(60); detailsColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - detailsColumn.setCellFactory(new Callback, - TableCell>() { + detailsColumn.setCellFactory(new Callback, + TableCell>() { @Override - public TableCell call(TableColumn column) { - return new TableCell() { + public TableCell call(TableColumn column) { + return new TableCell() { Label icon; Button button; @Override - public void updateItem(final VotesListItem item, boolean empty) { + public void updateItem(final VoteResultsListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { @@ -228,18 +228,18 @@ public void updateItem(final VotesListItem item, boolean empty) { /* - TableColumn indexColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.id")); + TableColumn indexColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.id")); indexColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); indexColumn.setMinWidth(70); indexColumn.setCellFactory( - new Callback, TableCell>() { + new Callback, TableCell>() { @Override - public TableCell call( - TableColumn column) { - return new TableCell() { + public TableCell call( + TableColumn column) { + return new TableCell() { @Override - public void updateItem(final VotesListItem item, boolean empty) { + public void updateItem(final VoteResultsListItem item, boolean empty) { super.updateItem(item, empty); if (item != null) setText(item.getId()); @@ -249,21 +249,21 @@ public void updateItem(final VotesListItem item, boolean empty) { }; } }); - indexColumn.setComparator(Comparator.comparing(VotesListItem::getStakeAsCoin)); + indexColumn.setComparator(Comparator.comparing(VoteResultsListItem::getStakeAsCoin)); tableView.getColumns().add(indexColumn); - TableColumn stakeColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.stake")); + TableColumn stakeColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.stake")); stakeColumn.setMinWidth(70); stakeColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); stakeColumn.setCellFactory( - new Callback, TableCell>() { + new Callback, TableCell>() { @Override - public TableCell call( - TableColumn column) { - return new TableCell() { + public TableCell call( + TableColumn column) { + return new TableCell() { @Override - public void updateItem(final VotesListItem item, boolean empty) { + public void updateItem(final VoteResultsListItem item, boolean empty) { super.updateItem(item, empty); if (item != null) setText(item.getStake()); @@ -273,21 +273,21 @@ public void updateItem(final VotesListItem item, boolean empty) { }; } }); - stakeColumn.setComparator(Comparator.comparing(VotesListItem::getStakeAsCoin)); + stakeColumn.setComparator(Comparator.comparing(VoteResultsListItem::getStakeAsCoin)); tableView.getColumns().add(stakeColumn); - TableColumn meritColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.merit")); + TableColumn meritColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.merit")); meritColumn.setMinWidth(70); meritColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); meritColumn.setCellFactory( - new Callback, TableCell>() { + new Callback, TableCell>() { @Override - public TableCell call( - TableColumn column) { - return new TableCell() { + public TableCell call( + TableColumn column) { + return new TableCell() { @Override - public void updateItem(final VotesListItem item, boolean empty) { + public void updateItem(final VoteResultsListItem item, boolean empty) { super.updateItem(item, empty); if (item != null) setText(item.getMerit()); @@ -297,21 +297,21 @@ public void updateItem(final VotesListItem item, boolean empty) { }; } }); - meritColumn.setComparator(Comparator.comparing(VotesListItem::getMeritAsCoin)); + meritColumn.setComparator(Comparator.comparing(VoteResultsListItem::getMeritAsCoin)); tableView.getColumns().add(meritColumn); - TableColumn acceptedColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.accepted")); + TableColumn acceptedColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.accepted")); acceptedColumn.setMinWidth(70); acceptedColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); acceptedColumn.setCellFactory( - new Callback, TableCell>() { + new Callback, TableCell>() { @Override - public TableCell call( - TableColumn column) { - return new TableCell() { + public TableCell call( + TableColumn column) { + return new TableCell() { @Override - public void updateItem(final VotesListItem item, boolean empty) { + public void updateItem(final VoteResultsListItem item, boolean empty) { super.updateItem(item, empty); if (item != null) setText(item.getNumAcceptedVotes()); @@ -321,21 +321,21 @@ public void updateItem(final VotesListItem item, boolean empty) { }; } }); - acceptedColumn.setComparator(Comparator.comparing(VotesListItem::getNumAcceptedVotes)); + acceptedColumn.setComparator(Comparator.comparing(VoteResultsListItem::getNumAcceptedVotes)); tableView.getColumns().add(acceptedColumn); - TableColumn rejectedColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.rejected")); + TableColumn rejectedColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.rejected")); rejectedColumn.setMinWidth(70); rejectedColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); rejectedColumn.setCellFactory( - new Callback, TableCell>() { + new Callback, TableCell>() { @Override - public TableCell call( - TableColumn column) { - return new TableCell() { + public TableCell call( + TableColumn column) { + return new TableCell() { @Override - public void updateItem(final VotesListItem item, boolean empty) { + public void updateItem(final VoteResultsListItem item, boolean empty) { super.updateItem(item, empty); if (item != null) setText(item.getNumRejectedVotes()); @@ -345,24 +345,24 @@ public void updateItem(final VotesListItem item, boolean empty) { }; } }); - rejectedColumn.setComparator(Comparator.comparing(VotesListItem::getNumRejectedVotes)); + rejectedColumn.setComparator(Comparator.comparing(VoteResultsListItem::getNumRejectedVotes)); tableView.getColumns().add(rejectedColumn); - TableColumn blindVoteTxIdColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.blindVoteTxId")); + TableColumn blindVoteTxIdColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.blindVoteTxId")); blindVoteTxIdColumn.setMinWidth(120); blindVoteTxIdColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); blindVoteTxIdColumn.setCellFactory( - new Callback, TableCell>() { + new Callback, TableCell>() { @Override - public TableCell call( - TableColumn column) { - return new TableCell() { + public TableCell call( + TableColumn column) { + return new TableCell() { private HyperlinkWithIcon hyperlinkWithIcon; @Override - public void updateItem(final VotesListItem item, boolean empty) { + public void updateItem(final VoteResultsListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { @@ -380,23 +380,23 @@ public void updateItem(final VotesListItem item, boolean empty) { }; } }); - blindVoteTxIdColumn.setComparator(Comparator.comparing(VotesListItem::getBlindVoteTxId)); + blindVoteTxIdColumn.setComparator(Comparator.comparing(VoteResultsListItem::getBlindVoteTxId)); tableView.getColumns().add(blindVoteTxIdColumn); - TableColumn voteRevealTxIdColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.voteRevealTxId")); + TableColumn voteRevealTxIdColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.voteRevealTxId")); voteRevealTxIdColumn.setMinWidth(120); voteRevealTxIdColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); voteRevealTxIdColumn.setCellFactory( - new Callback, TableCell>() { + new Callback, TableCell>() { @Override - public TableCell call( - TableColumn column) { - return new TableCell() { + public TableCell call( + TableColumn column) { + return new TableCell() { private HyperlinkWithIcon hyperlinkWithIcon; @Override - public void updateItem(final VotesListItem item, boolean empty) { + public void updateItem(final VoteResultsListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { @@ -414,7 +414,7 @@ public void updateItem(final VotesListItem item, boolean empty) { }; } }); - voteRevealTxIdColumn.setComparator(Comparator.comparing(VotesListItem::getVoteRevealTxId)); + voteRevealTxIdColumn.setComparator(Comparator.comparing(VoteResultsListItem::getVoteRevealTxId)); tableView.getColumns().add(voteRevealTxIdColumn);*/ } diff --git a/src/main/java/bisq/desktop/main/dao/results/votes/VotesListItem.java b/src/main/java/bisq/desktop/main/dao/results/votes/VoteResultsListItem.java similarity index 95% rename from src/main/java/bisq/desktop/main/dao/results/votes/VotesListItem.java rename to src/main/java/bisq/desktop/main/dao/results/votes/VoteResultsListItem.java index 2883017841e..d8b1b589116 100644 --- a/src/main/java/bisq/desktop/main/dao/results/votes/VotesListItem.java +++ b/src/main/java/bisq/desktop/main/dao/results/votes/VoteResultsListItem.java @@ -36,14 +36,14 @@ import lombok.Getter; -public class VotesListItem extends BaseResultsListItem { +public class VoteResultsListItem extends BaseResultsListItem { private final BsqStateService bsqStateService; private final BsqFormatter bsqFormatter; private int id; @Getter private final DecryptedVote decryptedVote; - public VotesListItem(int id, DecryptedVote decryptedVote, BsqStateService bsqStateService, BsqFormatter bsqFormatter) { + public VoteResultsListItem(int id, DecryptedVote decryptedVote, BsqStateService bsqStateService, BsqFormatter bsqFormatter) { this.id = id; this.decryptedVote = decryptedVote; this.bsqStateService = bsqStateService; From 4dad49399ffd87b6130ee6476702b2c847cc361c Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Wed, 25 Jul 2018 13:10:12 +0200 Subject: [PATCH 169/197] Remvoe title and description from Proposal --- .../desktop/main/dao/BaseProposalView.java | 24 --- .../dao/bonding/roles/BondedRolesView.java | 2 +- .../main/dao/proposal/ProposalDisplay.java | 197 +++++++++--------- .../dao/proposal/make/MakeProposalView.java | 57 +++-- .../desktop/main/dao/results/ResultsView.java | 34 ++- .../dao/voting/active/ActiveBallotsView.java | 2 - 6 files changed, 137 insertions(+), 179 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/BaseProposalView.java index ec228a74acf..f5ec48252b9 100644 --- a/src/main/java/bisq/desktop/main/dao/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/BaseProposalView.java @@ -285,30 +285,6 @@ public void updateItem(final BaseProposalListItem item, boolean empty) { nameColumn.setComparator(Comparator.comparing(o2 -> o2.getProposal().getName())); tableView.getColumns().add(nameColumn); - TableColumn titleColumn = new AutoTooltipTableColumn<>(Res.get("dao.proposal.title")); - titleColumn.setPrefWidth(100); - titleColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - titleColumn.setCellFactory( - new Callback, TableCell>() { - @Override - public TableCell call( - TableColumn column) { - return new TableCell() { - @Override - public void updateItem(final BaseProposalListItem item, boolean empty) { - super.updateItem(item, empty); - if (item != null) - setText(item.getProposal().getTitle()); - else - setText(""); - } - }; - } - }); - titleColumn.setComparator(Comparator.comparing(o2 -> o2.getProposal().getTitle())); - tableView.getColumns().add(titleColumn); - TableColumn uidColumn = new AutoTooltipTableColumn<>(Res.get("shared.id")); uidColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); uidColumn.setCellFactory( diff --git a/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesView.java b/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesView.java index 88213225fa6..e4d54c2bf28 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesView.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesView.java @@ -217,7 +217,7 @@ public TableCell call(TableColumn GUIUtil.openWebPage(link)); hyperlinkWithIcon.setTooltip(new Tooltip(Res.get("shared.openURL", link))); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java index 82275f9ee4a..8a5e2187073 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java @@ -20,7 +20,6 @@ import bisq.desktop.components.HyperlinkWithIcon; import bisq.desktop.components.InputTextField; import bisq.desktop.components.TxIdTextField; -import bisq.desktop.main.overlays.popups.Popup; import bisq.desktop.util.GUIUtil; import bisq.desktop.util.Layout; import bisq.desktop.util.validation.BsqAddressValidator; @@ -33,7 +32,6 @@ import bisq.core.dao.state.blockchain.Tx; import bisq.core.dao.state.ext.Param; import bisq.core.dao.voting.proposal.Proposal; -import bisq.core.dao.voting.proposal.ProposalConsensus; import bisq.core.dao.voting.proposal.ProposalType; import bisq.core.dao.voting.proposal.compensation.CompensationConsensus; import bisq.core.dao.voting.proposal.compensation.CompensationProposal; @@ -42,14 +40,16 @@ import bisq.core.dao.voting.proposal.role.BondedRoleProposal; import bisq.core.locale.Res; import bisq.core.util.BsqFormatter; +import bisq.core.util.validation.InputValidator; +import bisq.core.util.validation.IntegerValidator; import bisq.common.util.Tuple2; import javafx.scene.control.ComboBox; import javafx.scene.control.Label; import javafx.scene.control.ScrollPane; -import javafx.scene.control.TextArea; import javafx.scene.control.TextField; +import javafx.scene.control.TextInputControl; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.ColumnConstraints; import javafx.scene.layout.GridPane; @@ -63,8 +63,10 @@ import javafx.util.StringConverter; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Objects; import java.util.UUID; import java.util.stream.Collectors; @@ -79,7 +81,6 @@ @Slf4j public class ProposalDisplay { private final GridPane gridPane; - private final int maxLengthDescriptionText; private final BsqFormatter bsqFormatter; private final BsqWalletService bsqWalletService; private final DaoFacade daoFacade; @@ -88,8 +89,6 @@ public class ProposalDisplay { private TextField uidTextField; private TextField proposalFeeTextField, proposalTypeTextField; public InputTextField nameTextField; - @Nullable - public InputTextField titleTextField; public InputTextField linkInputTextField; @Nullable public InputTextField requestedBsqTextField, bsqAddressTextField, paramValueTextField; @@ -102,14 +101,17 @@ public class ProposalDisplay { @Getter private int gridRow; - @Nullable - public TextArea descriptionTextArea; private HyperlinkWithIcon linkHyperlinkWithIcon; @Nullable private TxIdTextField txIdTextField; - private final ChangeListener descriptionTextAreaListener; private int gridRowStartIndex; - private Label linkLabel; + private List inputChangedListeners = new ArrayList<>(); + @Getter + private List inputControls = new ArrayList<>(); + @Getter + private List comboBoxes = new ArrayList<>(); + private final ChangeListener focusOutListener; + private final ChangeListener inputListener; // TODO get that warning at closing the window... @@ -123,15 +125,21 @@ public ProposalDisplay(GridPane gridPane, BsqFormatter bsqFormatter, BsqWalletSe this.bsqWalletService = bsqWalletService; this.daoFacade = daoFacade; - maxLengthDescriptionText = ProposalConsensus.getMaxLengthDescriptionText(); + // focusOutListener = observable -> inputChangedListeners.forEach(Runnable::run); - descriptionTextAreaListener = (observable, oldValue, newValue) -> { - if (!ProposalConsensus.isDescriptionSizeValid(newValue)) { - new Popup<>().warning(Res.get("dao.proposal.display.description.tooLong", maxLengthDescriptionText)).show(); - if (descriptionTextArea != null) - descriptionTextArea.setText(newValue.substring(0, maxLengthDescriptionText)); - } + focusOutListener = (observable, oldValue, newValue) -> { + if (oldValue && !newValue) + inputChangedListeners.forEach(Runnable::run); }; + inputListener = (observable, oldValue, newValue) -> inputChangedListeners.forEach(Runnable::run); + } + + public void addInputChangedListener(Runnable listener) { + inputChangedListeners.add(listener); + } + + public void removeInputChangedListener(Runnable listener) { + inputChangedListeners.remove(listener); } public void createAllFields(String title, int gridRowStartIndex, double top, ProposalType proposalType, @@ -140,27 +148,23 @@ public void createAllFields(String title, int gridRowStartIndex, double top, Pro this.gridRowStartIndex = gridRowStartIndex; this.gridRow = gridRowStartIndex; int rowSpan = 5; - boolean showTitle = true; - boolean showDescription = true; switch (proposalType) { case COMPENSATION_REQUEST: - rowSpan = 8; + rowSpan = 6; break; case BONDED_ROLE: rowSpan = 5; - showTitle = false; - showDescription = false; break; case REMOVE_ALTCOIN: break; case CHANGE_PARAM: - rowSpan = 8; + rowSpan = 6; break; case GENERIC: break; case CONFISCATE_BOND: - rowSpan = 7; + rowSpan = 5; break; } // for already created proposals we show the uid and tx id so we add 2 rows @@ -172,30 +176,19 @@ public void createAllFields(String title, int gridRowStartIndex, double top, Pro proposalTypeTextField = addLabelTextField(gridPane, gridRow, Res.getWithCol("dao.proposal.display.type"), proposalType.getDisplayName(), proposalTypeTop).second; - if (!isMakeProposalScreen) { + if (!isMakeProposalScreen) uidTextField = addLabelTextField(gridPane, ++gridRow, Res.getWithCol("shared.id")).second; - nameTextField = addLabelInputTextField(gridPane, ++gridRow, Res.get("dao.proposal.display.name")).second; - } else { - nameTextField = addLabelInputTextField(gridPane, ++gridRow, Res.get("dao.proposal.display.name")).second; - } - if (showTitle) - titleTextField = addLabelInputTextField(gridPane, ++gridRow, Res.getWithCol("dao.proposal.title")).second; - - if (showDescription) { - descriptionTextArea = addLabelTextArea(gridPane, ++gridRow, Res.get("dao.proposal.display.description"), - Res.get("dao.proposal.display.description.prompt", maxLengthDescriptionText)).second; - descriptionTextArea.setMaxHeight(42); // for 2 lines - descriptionTextArea.setMinHeight(descriptionTextArea.getMaxHeight()); - if (isMakeProposalScreen) - descriptionTextArea.textProperty().addListener(descriptionTextAreaListener); - } + nameTextField = addLabelInputTextField(gridPane, ++gridRow, Res.get("dao.proposal.display.name")).second; + nameTextField.setValidator(new InputValidator()); + inputControls.add(nameTextField); Tuple2 tuple = addLabelInputTextField(gridPane, ++gridRow, Res.get("dao.proposal.display.link")); - linkLabel = tuple.first; linkInputTextField = tuple.second; linkInputTextField.setPromptText(Res.get("dao.proposal.display.link.prompt")); + linkInputTextField.setValidator(new InputValidator()); + inputControls.add(linkInputTextField); linkHyperlinkWithIcon = addLabelHyperlinkWithIcon(gridPane, gridRow, "", "", "").second; @@ -210,16 +203,17 @@ public void createAllFields(String title, int gridRowStartIndex, double top, Pro bsqValidator.setMinValue(CompensationConsensus.getMinCompensationRequestAmount()); checkNotNull(requestedBsqTextField, "requestedBsqTextField must not be null"); requestedBsqTextField.setValidator(bsqValidator); + inputControls.add(requestedBsqTextField); + // TODO validator, addressTF bsqAddressTextField = addLabelInputTextField(gridPane, ++gridRow, Res.get("dao.proposal.display.bsqAddress")).second; checkNotNull(bsqAddressTextField, "bsqAddressTextField must not be null"); bsqAddressTextField.setText("B" + bsqWalletService.getUnusedAddress().toBase58()); bsqAddressTextField.setValidator(new BsqAddressValidator(bsqFormatter)); + inputControls.add(bsqAddressTextField); break; case BONDED_ROLE: - linkLabel.setText(Res.get("dao.proposal.display.link.bondRole")); - linkInputTextField.setPromptText(Res.get("dao.proposal.display.link.bondRole.prompt")); bondedRoleTypeComboBox = addLabelComboBox(gridPane, ++gridRow, Res.getWithCol("dao.proposal.display.bondedRoleComboBox.label")).second; checkNotNull(bondedRoleTypeComboBox, "bondedRoleTypeComboBox must not be null"); @@ -228,7 +222,7 @@ public void createAllFields(String title, int gridRowStartIndex, double top, Pro bondedRoleTypeComboBox.setConverter(new StringConverter() { @Override public String toString(BondedRoleType bondedRoleType) { - return bondedRoleType.getDisplayString(); + return bondedRoleType != null ? bondedRoleType.getDisplayString() : ""; } @Override @@ -236,6 +230,7 @@ public BondedRoleType fromString(String string) { return null; } }); + comboBoxes.add(bondedRoleTypeComboBox); break; case REMOVE_ALTCOIN: break; @@ -252,7 +247,7 @@ public BondedRoleType fromString(String string) { paramComboBox.setConverter(new StringConverter() { @Override public String toString(Param param) { - return param.toDisplayString(); + return param != null ? param.getDisplayString() : ""; } @Override @@ -260,8 +255,11 @@ public Param fromString(String string) { return null; } }); + comboBoxes.add(paramComboBox); paramValueTextField = addLabelInputTextField(gridPane, ++gridRow, Res.get("dao.proposal.display.paramValue")).second; + paramValueTextField.setValidator(new IntegerValidator()); + inputControls.add(paramValueTextField); break; case GENERIC: break; @@ -274,7 +272,7 @@ public Param fromString(String string) { confiscateBondComboBox.setConverter(new StringConverter() { @Override public String toString(BondedRole bondedRole) { - return bondedRole.getDisplayString(); + return bondedRole != null ? bondedRole.getDisplayString() : ""; } @Override @@ -282,6 +280,7 @@ public BondedRole fromString(String string) { return null; } }); + comboBoxes.add(confiscateBondComboBox); break; } @@ -292,6 +291,8 @@ public BondedRole fromString(String string) { proposalFeeTextField = addLabelTextField(gridPane, ++gridRow, Res.get("dao.proposal.display.proposalFee")).second; if (isMakeProposalScreen) proposalFeeTextField.setText(bsqFormatter.formatCoinWithCode(daoFacade.getProposalFee(daoFacade.getChainHeight()))); + + addListeners(); } public void applyProposalPayload(Proposal proposal) { @@ -300,10 +301,6 @@ public void applyProposalPayload(Proposal proposal) { uidTextField.setText(proposal.getUid()); nameTextField.setText(proposal.getName()); - if (titleTextField != null) - titleTextField.setText(proposal.getTitle()); - if (descriptionTextArea != null) - descriptionTextArea.setText(proposal.getDescription()); linkInputTextField.setVisible(false); linkInputTextField.setManaged(false); linkHyperlinkWithIcon.setVisible(true); @@ -344,65 +341,47 @@ public void applyProposalPayload(Proposal proposal) { proposalFeeTextField.setText(bsqFormatter.formatCoinWithCode(daoFacade.getProposalFee(chainHeight))); } + private void addListeners() { + inputControls.stream() + .filter(Objects::nonNull).forEach(inputControl -> { + inputControl.textProperty().addListener(inputListener); + inputControl.focusedProperty().addListener(focusOutListener); + }); + comboBoxes.stream() + .filter(Objects::nonNull).forEach(comboBox -> { + comboBox.getSelectionModel().selectedItemProperty().addListener(inputListener); + }); + } + + public void removeListeners() { + inputControls.stream() + .filter(Objects::nonNull).forEach(inputControl -> { + inputControl.textProperty().removeListener(inputListener); + inputControl.focusedProperty().removeListener(focusOutListener); + }); + comboBoxes.stream() + .filter(Objects::nonNull).forEach(comboBox -> { + comboBox.getSelectionModel().selectedItemProperty().removeListener(inputListener); + }); + } + public void clearForm() { + inputControls.stream().filter(Objects::nonNull).forEach(TextInputControl::clear); + if (uidTextField != null) uidTextField.clear(); - if (nameTextField != null) nameTextField.clear(); - if (titleTextField != null) titleTextField.clear(); - if (descriptionTextArea != null) descriptionTextArea.clear(); - if (linkInputTextField != null) linkInputTextField.clear(); if (linkHyperlinkWithIcon != null) linkHyperlinkWithIcon.clear(); - if (requestedBsqTextField != null) requestedBsqTextField.clear(); - if (bsqAddressTextField != null) bsqAddressTextField.clear(); - if (paramComboBox != null) paramComboBox.getSelectionModel().clearSelection(); - if (paramValueTextField != null) paramValueTextField.clear(); - if (bondedRoleTypeComboBox != null) bondedRoleTypeComboBox.getSelectionModel().clearSelection(); - if (confiscateBondComboBox != null) confiscateBondComboBox.getSelectionModel().clearSelection(); if (txIdTextField != null) txIdTextField.cleanup(); - if (descriptionTextArea != null) descriptionTextArea.textProperty().removeListener(descriptionTextAreaListener); - } - public void fillWithMock() { - if (uidTextField != null) - uidTextField.setText(UUID.randomUUID().toString()); - nameTextField.setText("Manfred Karrer"); - if (titleTextField != null) - titleTextField.setText("Development work November 2017"); - if (descriptionTextArea != null) - descriptionTextArea.setText("Development work"); - linkInputTextField.setText("https://github.com/bisq-network/compensation/issues/12"); - if (requestedBsqTextField != null) - requestedBsqTextField.setText("14000"); - if (bsqAddressTextField != null) - bsqAddressTextField.setText("B" + bsqWalletService.getUnusedAddress().toBase58()); - - if (paramComboBox != null) - paramComboBox.getSelectionModel().select(8); // PROPOSAL_FEE - if (paramValueTextField != null) - paramValueTextField.setText("333"); + comboBoxes.stream() + .filter(Objects::nonNull).forEach(comboBox -> { + comboBox.getSelectionModel().clearSelection(); + }); } public void setEditable(boolean isEditable) { - nameTextField.setEditable(isEditable); - if (titleTextField != null) - titleTextField.setEditable(isEditable); - if (descriptionTextArea != null) - descriptionTextArea.setEditable(isEditable); - linkInputTextField.setEditable(isEditable); - if (requestedBsqTextField != null) - requestedBsqTextField.setEditable(isEditable); - if (bsqAddressTextField != null) - bsqAddressTextField.setEditable(isEditable); - - if (paramComboBox != null) - paramComboBox.setDisable(!isEditable); - if (paramValueTextField != null) - paramValueTextField.setEditable(isEditable); - - if (confiscateBondComboBox != null) - confiscateBondComboBox.setDisable(!isEditable); - - if (bondedRoleTypeComboBox != null) - bondedRoleTypeComboBox.setDisable(!isEditable); + inputControls.stream().filter(Objects::nonNull).forEach(e -> e.setEditable(!isEditable)); + comboBoxes.stream() + .filter(Objects::nonNull).forEach(comboBox -> comboBox.setEditable(!isEditable)); linkInputTextField.setVisible(true); linkInputTextField.setManaged(true); @@ -452,4 +431,20 @@ public ScrollPane getView() { return scrollPane; } + + public void fillWithMock() { + if (uidTextField != null) + uidTextField.setText(UUID.randomUUID().toString()); + nameTextField.setText("Manfred Karrer"); + linkInputTextField.setText("https://github.com/bisq-network/compensation/issues/12"); + if (requestedBsqTextField != null) + requestedBsqTextField.setText("14000"); + if (bsqAddressTextField != null) + bsqAddressTextField.setText("B" + bsqWalletService.getUnusedAddress().toBase58()); + + if (paramComboBox != null) + paramComboBox.getSelectionModel().select(8); // PROPOSAL_FEE + if (paramValueTextField != null) + paramValueTextField.setText("333"); + } } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index ed626a24a5b..887d62c1a99 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -19,6 +19,7 @@ import bisq.desktop.common.view.ActivatableView; import bisq.desktop.common.view.FxmlView; +import bisq.desktop.components.InputTextField; import bisq.desktop.main.dao.proposal.ProposalDisplay; import bisq.desktop.main.overlays.popups.Popup; import bisq.desktop.util.GUIUtil; @@ -37,7 +38,6 @@ import bisq.core.dao.state.period.DaoPhase; import bisq.core.dao.voting.ValidationException; import bisq.core.dao.voting.proposal.Proposal; -import bisq.core.dao.voting.proposal.ProposalConsensus; import bisq.core.dao.voting.proposal.ProposalType; import bisq.core.dao.voting.proposal.ProposalWithTransaction; import bisq.core.locale.Res; @@ -47,6 +47,8 @@ import bisq.network.p2p.P2PService; +import bisq.common.app.DevEnv; + import org.bitcoinj.core.Coin; import org.bitcoinj.core.InsufficientMoneyException; import org.bitcoinj.core.Transaction; @@ -67,6 +69,8 @@ import java.util.Arrays; import java.util.List; +import java.util.Objects; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Collectors; import javax.annotation.Nullable; @@ -74,7 +78,6 @@ import static bisq.desktop.util.FormBuilder.addButtonAfterGroup; import static bisq.desktop.util.FormBuilder.addLabelComboBox; import static bisq.desktop.util.FormBuilder.addTitledGroupBg; -import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; @FxmlView @@ -232,7 +235,8 @@ private void doPublishMyProposal(Proposal proposal, Transaction transaction) { () -> { proposalDisplay.clearForm(); proposalTypeComboBox.getSelectionModel().clearSelection(); - new Popup<>().confirmation(Res.get("dao.tx.published.success")).show(); + if (!DevEnv.isDevMode()) + new Popup<>().confirmation(Res.get("dao.tx.published.success")).show(); }, errorMessage -> new Popup<>().warning(errorMessage).show()); } @@ -241,7 +245,6 @@ private ProposalWithTransaction getProposalWithTransaction(ProposalType type) throws InsufficientMoneyException, TransactionVerificationException, ValidationException, WalletException, IOException { - validateInputs(); BondedRole bondedRole; switch (type) { case COMPENSATION_REQUEST: @@ -249,13 +252,7 @@ private ProposalWithTransaction getProposalWithTransaction(ProposalType type) "proposalDisplay.requestedBsqTextField must not be null"); checkNotNull(proposalDisplay.bsqAddressTextField, "proposalDisplay.bsqAddressTextField must not be null"); - checkNotNull(proposalDisplay.titleTextField, - "proposalDisplay.titleTextField must not be null"); - checkNotNull(proposalDisplay.descriptionTextArea, - "proposalDisplay.descriptionTextArea must not be null"); return daoFacade.getCompensationProposalWithTransaction(proposalDisplay.nameTextField.getText(), - proposalDisplay.titleTextField.getText(), - proposalDisplay.descriptionTextArea.getText(), proposalDisplay.linkInputTextField.getText(), bsqFormatter.parseToCoin(proposalDisplay.requestedBsqTextField.getText()), proposalDisplay.bsqAddressTextField.getText()); @@ -274,10 +271,6 @@ private ProposalWithTransaction getProposalWithTransaction(ProposalType type) "proposalDisplay.paramComboBox must no tbe null"); checkNotNull(proposalDisplay.paramValueTextField, "proposalDisplay.paramValueTextField must no tbe null"); - checkNotNull(proposalDisplay.titleTextField, - "proposalDisplay.titleTextField must not be null"); - checkNotNull(proposalDisplay.descriptionTextArea, - "proposalDisplay.descriptionTextArea must not be null"); Param selectedParam = proposalDisplay.paramComboBox.getSelectionModel().getSelectedItem(); if (selectedParam == null) throw new ValidationException("selectedParam is null"); @@ -292,8 +285,6 @@ private ProposalWithTransaction getProposalWithTransaction(ProposalType type) } //TODO add more custom param validation return daoFacade.getParamProposalWithTransaction(proposalDisplay.nameTextField.getText(), - proposalDisplay.titleTextField.getText(), - proposalDisplay.descriptionTextArea.getText(), proposalDisplay.linkInputTextField.getText(), selectedParam, paramValue); @@ -303,14 +294,8 @@ private ProposalWithTransaction getProposalWithTransaction(ProposalType type) case CONFISCATE_BOND: checkNotNull(proposalDisplay.confiscateBondComboBox, "proposalDisplay.confiscateBondComboBox must not be null"); - checkNotNull(proposalDisplay.titleTextField, - "proposalDisplay.titleTextField must not be null"); - checkNotNull(proposalDisplay.descriptionTextArea, - "proposalDisplay.descriptionTextArea must not be null"); bondedRole = proposalDisplay.confiscateBondComboBox.getSelectionModel().getSelectedItem(); return daoFacade.getConfiscateBondProposalWithTransaction(proposalDisplay.nameTextField.getText(), - proposalDisplay.titleTextField.getText(), - proposalDisplay.descriptionTextArea.getText(), proposalDisplay.linkInputTextField.getText(), bondedRole.getHash()); default: @@ -330,6 +315,8 @@ private void addProposalDisplay() { createButton = addButtonAfterGroup(root, proposalDisplay.incrementAndGetGridRow(), Res.get("dao.proposal.create.create.button")); setCreateButtonHandler(); + proposalDisplay.addInputChangedListener(this::updateButtonState); + updateButtonState(); } } @@ -337,13 +324,14 @@ private void removeProposalDisplay() { if (proposalDisplay != null) { proposalDisplay.removeAllFields(); GUIUtil.removeChildrenFromGridPaneRows(root, 1, proposalDisplay.getGridRow()); + proposalDisplay.removeInputChangedListener(this::updateButtonState); + proposalDisplay.removeListeners(); proposalDisplay = null; } } private void setCreateButtonHandler() { createButton.setOnAction(event -> { - // TODO break up in methods if (GUIUtil.isReadyForTxBroadcast(p2PService, walletsSetup)) { publishMyProposal(selectedProposalType); } else { @@ -352,14 +340,21 @@ private void setCreateButtonHandler() { }); } - private void validateInputs() { - // We check in proposalDisplay that no invalid input as allowed - if (proposalDisplay.descriptionTextArea != null) { - checkArgument(ProposalConsensus.isDescriptionSizeValid(proposalDisplay.descriptionTextArea.getText()), - "descriptionText must not be longer than " + - ProposalConsensus.getMaxLengthDescriptionText() + " chars"); - } - // TODO add more checks for all input fields + private void updateButtonState() { + AtomicBoolean inputsValid = new AtomicBoolean(true); + proposalDisplay.getInputControls().stream() + .filter(Objects::nonNull).forEach(e -> { + if (e instanceof InputTextField) { + InputTextField inputTextField = (InputTextField) e; + inputsValid.set(inputsValid.get() && inputTextField.getValidator().validate(e.getText()).isValid); + } + }); + proposalDisplay.getComboBoxes().stream() + .filter(Objects::nonNull).forEach(comboBox -> { + inputsValid.set(inputsValid.get() && comboBox.getSelectionModel().getSelectedItem() != null); + }); + + createButton.setDisable(!inputsValid.get()); } } diff --git a/src/main/java/bisq/desktop/main/dao/results/ResultsView.java b/src/main/java/bisq/desktop/main/dao/results/ResultsView.java index 64d140ea413..4e0ac0170e8 100644 --- a/src/main/java/bisq/desktop/main/dao/results/ResultsView.java +++ b/src/main/java/bisq/desktop/main/dao/results/ResultsView.java @@ -25,7 +25,6 @@ import bisq.desktop.components.AutoTooltipTableColumn; import bisq.desktop.components.TableGroupHeadline; import bisq.desktop.components.TitledGroupBg; -import bisq.desktop.main.dao.results.combo.VotesPerProposalTableView; import bisq.desktop.main.dao.results.model.ResultsOfCycle; import bisq.desktop.main.dao.results.proposals.ProposalResultsGridPane; import bisq.desktop.main.dao.results.votes.VoteResultsGridPane; @@ -58,7 +57,6 @@ import javafx.fxml.FXML; -import javafx.scene.control.Label; import javafx.scene.control.ScrollPane; import javafx.scene.control.TableCell; import javafx.scene.control.TableColumn; @@ -105,20 +103,15 @@ public class ResultsView extends ActivatableViewAndModel tableView; - private final ObservableList itemList = FXCollections.observableArrayList(); private final SortedList sortedList = new SortedList<>(itemList); private ChangeListener selectedItemListener; - - private VotesPerProposalTableView votesPerProposalTableView; private ProposalResultsGridPane proposalResultsGridPane; private VoteResultsGridPane voteResultsGridPane; private GridPane gridPane; private HBox hBox; - private Label directionLabel; /////////////////////////////////////////////////////////////////////////////////////////// @@ -154,14 +147,10 @@ public void initialize() { hBox.setSpacing(30); hBox.setFillHeight(true); - //votesPerProposalTableView = new VotesPerProposalTableView(gridPane, bsqWalletService, daoFacade, bsqStateService, bsqFormatter); proposalResultsGridPane = new ProposalResultsGridPane(this, bsqWalletService, daoFacade, bsqFormatter, bsqStateService); hBox.getChildren().add(proposalResultsGridPane); - directionLabel = new Label("<< voted on"); - HBox.setMargin(directionLabel, new Insets(0, -10, 0, -10)); - voteResultsGridPane = new VoteResultsGridPane(this, bsqWalletService, daoFacade, bsqStateService, preferences, bsqFormatter); hBox.getChildren().add(voteResultsGridPane); @@ -172,24 +161,29 @@ public void initialize() { } @Override - public void onSelectedEvaluatedProposal(EvaluatedProposal evaluatedProposal) { - voteResultsGridPane.onSelectedEvaluatedProposal(evaluatedProposal); + protected void activate() { + tableView.getSelectionModel().selectedItemProperty().addListener(selectedItemListener); + fillCycleList(); } @Override - public void onSelectedDecryptedVote(DecryptedVote decryptedVote) { - proposalResultsGridPane.onSelectedDecryptedVote(decryptedVote); + protected void deactivate() { + tableView.getSelectionModel().selectedItemProperty().removeListener(selectedItemListener); } + + /////////////////////////////////////////////////////////////////////////////////////////// + // SelectionListener + /////////////////////////////////////////////////////////////////////////////////////////// + @Override - protected void activate() { - tableView.getSelectionModel().selectedItemProperty().addListener(selectedItemListener); - fillCycleList(); + public void onSelectedEvaluatedProposal(EvaluatedProposal evaluatedProposal) { + voteResultsGridPane.onSelectedEvaluatedProposal(evaluatedProposal); } @Override - protected void deactivate() { - tableView.getSelectionModel().selectedItemProperty().removeListener(selectedItemListener); + public void onSelectedDecryptedVote(DecryptedVote decryptedVote) { + proposalResultsGridPane.onSelectedDecryptedVote(decryptedVote); } diff --git a/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.java b/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.java index 1ed1913cf9a..8377983eda5 100644 --- a/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.java +++ b/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.java @@ -65,7 +65,6 @@ import javafx.util.Callback; -import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; @@ -391,7 +390,6 @@ public void updateItem(final BaseProposalListItem item, boolean empty) { }; } }); - actionColumn.setComparator(Comparator.comparing(BaseProposalListItem::getConfirmations)); tableView.getColumns().add(actionColumn); } } From 149c5a2fc0dbdbc6d9099d67ea1e52607e8f52ce Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Wed, 25 Jul 2018 15:27:21 +0200 Subject: [PATCH 170/197] Add types for addLabelComboBox --- .../bisq/desktop/main/dao/bonding/lockup/LockupView.java | 6 +++--- .../bisq/desktop/main/dao/proposal/ProposalDisplay.java | 7 ++++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java b/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java index 0f654db3cab..63f43403219 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java @@ -22,6 +22,7 @@ import bisq.desktop.components.InputTextField; import bisq.desktop.main.dao.bonding.BondingViewUtils; import bisq.desktop.main.dao.wallet.BsqBalanceUtil; +import bisq.desktop.util.FormBuilder; import bisq.desktop.util.Layout; import bisq.desktop.util.validation.BsqValidator; @@ -53,7 +54,6 @@ import java.util.Arrays; import static bisq.desktop.util.FormBuilder.addButtonAfterGroup; -import static bisq.desktop.util.FormBuilder.addLabelComboBox; import static bisq.desktop.util.FormBuilder.addLabelInputTextField; import static bisq.desktop.util.FormBuilder.addTitledGroupBg; @@ -118,7 +118,7 @@ public void initialize() { String.valueOf(BondingConsensus.getMinLockTime()), String.valueOf(BondingConsensus.getMaxLockTime()))); timeInputTextField.setValidator(timeInputTextFieldValidator); - lockupTypeComboBox = addLabelComboBox(root, ++gridRow, Res.get("dao.bonding.lock.type")).second; + lockupTypeComboBox = FormBuilder.addLabelComboBox(root, ++gridRow, Res.get("dao.bonding.lock.type")).second; lockupTypeComboBox.setPromptText(Res.get("shared.select")); lockupTypeComboBox.setConverter(new StringConverter() { @Override @@ -140,7 +140,7 @@ public LockupType fromString(String string) { //TODO handle trade type lockupTypeComboBox.getSelectionModel().select(0); - bondedRolesComboBox = addLabelComboBox(root, ++gridRow, Res.get("dao.bonding.lock.bondedRoles")).second; + bondedRolesComboBox = FormBuilder.addLabelComboBox(root, ++gridRow, Res.get("dao.bonding.lock.bondedRoles")).second; bondedRolesComboBox.setPromptText(Res.get("shared.select")); bondedRolesComboBox.setConverter(new StringConverter() { @Override diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java index 8a5e2187073..51ccc8c8904 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java @@ -20,6 +20,7 @@ import bisq.desktop.components.HyperlinkWithIcon; import bisq.desktop.components.InputTextField; import bisq.desktop.components.TxIdTextField; +import bisq.desktop.util.FormBuilder; import bisq.desktop.util.GUIUtil; import bisq.desktop.util.Layout; import bisq.desktop.util.validation.BsqAddressValidator; @@ -214,7 +215,7 @@ public void createAllFields(String title, int gridRowStartIndex, double top, Pro inputControls.add(bsqAddressTextField); break; case BONDED_ROLE: - bondedRoleTypeComboBox = addLabelComboBox(gridPane, ++gridRow, + bondedRoleTypeComboBox = FormBuilder.addLabelComboBox(gridPane, ++gridRow, Res.getWithCol("dao.proposal.display.bondedRoleComboBox.label")).second; checkNotNull(bondedRoleTypeComboBox, "bondedRoleTypeComboBox must not be null"); bondedRoleTypeComboBox.setPromptText(Res.get("shared.select")); @@ -236,7 +237,7 @@ public BondedRoleType fromString(String string) { break; case CHANGE_PARAM: checkNotNull(gridPane, "gridPane must not be null"); - paramComboBox = addLabelComboBox(gridPane, ++gridRow, + paramComboBox = FormBuilder.addLabelComboBox(gridPane, ++gridRow, Res.getWithCol("dao.proposal.display.paramComboBox.label")).second; checkNotNull(paramComboBox, "paramComboBox must not be null"); paramComboBox.setPromptText(Res.get("shared.select")); @@ -264,7 +265,7 @@ public Param fromString(String string) { case GENERIC: break; case CONFISCATE_BOND: - confiscateBondComboBox = addLabelComboBox(gridPane, ++gridRow, + confiscateBondComboBox = FormBuilder.addLabelComboBox(gridPane, ++gridRow, Res.getWithCol("dao.proposal.display.confiscateBondComboBox.label")).second; checkNotNull(confiscateBondComboBox, "confiscateBondComboBox must not be null"); confiscateBondComboBox.setPromptText(Res.get("shared.select")); From af614dfeff20021c7906c5617459254b9d6966bd Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Wed, 25 Jul 2018 16:16:59 +0200 Subject: [PATCH 171/197] Add combined proposal vote view (WIP) --- .../main/dao/proposal/ProposalView.java | 10 +- .../proposal/open/OpenProposalListItem.java | 244 +++++++++ .../dao/proposal/open/OpenProposalsView.fxml | 33 ++ .../dao/proposal/open/OpenProposalsView.java | 478 ++++++++++++++++++ 4 files changed, 763 insertions(+), 2 deletions(-) create mode 100644 src/main/java/bisq/desktop/main/dao/proposal/open/OpenProposalListItem.java create mode 100644 src/main/java/bisq/desktop/main/dao/proposal/open/OpenProposalsView.fxml create mode 100644 src/main/java/bisq/desktop/main/dao/proposal/open/OpenProposalsView.java diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalView.java index 0e5ae573a71..93b4ea4a522 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalView.java @@ -31,6 +31,7 @@ import bisq.desktop.main.dao.proposal.closed.ClosedProposalsView; import bisq.desktop.main.dao.proposal.dashboard.ProposalDashboardView; import bisq.desktop.main.dao.proposal.make.MakeProposalView; +import bisq.desktop.main.dao.proposal.open.OpenProposalsView; import bisq.core.locale.Res; @@ -53,7 +54,7 @@ public class ProposalView extends ActivatableViewAndModel { private final ViewLoader viewLoader; private final Navigation navigation; - private MenuItem dashboard, make, active, closed; + private MenuItem dashboard, make, open, active, closed; private Navigation.Listener listener; @FXML @@ -85,17 +86,20 @@ public void initialize() { ProposalDashboardView.class, AwesomeIcon.DASHBOARD, baseNavPath); make = new MenuItem(navigation, toggleGroup, Res.get("dao.proposal.menuItem.make"), MakeProposalView.class, AwesomeIcon.EDIT, baseNavPath); + open = new MenuItem(navigation, toggleGroup, Res.get("dao.proposal.menuItem.open"), + OpenProposalsView.class, AwesomeIcon.LIST_UL, baseNavPath); active = new MenuItem(navigation, toggleGroup, Res.get("dao.proposal.menuItem.active"), ActiveProposalsView.class, AwesomeIcon.LIST_UL, baseNavPath); closed = new MenuItem(navigation, toggleGroup, Res.get("dao.proposal.menuItem.closed"), ClosedProposalsView.class, AwesomeIcon.LIST_ALT, baseNavPath); - leftVBox.getChildren().addAll(dashboard, make, active, closed); + leftVBox.getChildren().addAll(dashboard, make, open, active, closed); } @Override protected void activate() { dashboard.activate(); make.activate(); + open.activate(); active.activate(); closed.activate(); @@ -121,6 +125,7 @@ protected void deactivate() { dashboard.deactivate(); make.deactivate(); + open.deactivate(); active.deactivate(); closed.deactivate(); } @@ -131,6 +136,7 @@ private void loadView(Class viewClass) { if (view instanceof ProposalDashboardView) dashboard.setSelected(true); else if (view instanceof MakeProposalView) make.setSelected(true); + else if (view instanceof OpenProposalsView) open.setSelected(true); else if (view instanceof ActiveProposalsView) active.setSelected(true); else if (view instanceof ClosedProposalsView) closed.setSelected(true); } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/open/OpenProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/open/OpenProposalListItem.java new file mode 100644 index 00000000000..838512d41ec --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/proposal/open/OpenProposalListItem.java @@ -0,0 +1,244 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.desktop.main.dao.proposal.open; + +import bisq.desktop.components.AutoTooltipButton; +import bisq.desktop.components.indicator.TxConfidenceIndicator; + +import bisq.core.btc.listeners.TxConfidenceListener; +import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.dao.DaoFacade; +import bisq.core.dao.state.BsqStateListener; +import bisq.core.dao.state.blockchain.Block; +import bisq.core.dao.state.blockchain.Tx; +import bisq.core.dao.state.period.DaoPhase; +import bisq.core.dao.voting.proposal.Proposal; +import bisq.core.locale.Res; +import bisq.core.util.BsqFormatter; + +import org.bitcoinj.core.Transaction; +import org.bitcoinj.core.TransactionConfidence; + +import javafx.scene.control.Tooltip; +import javafx.scene.image.ImageView; + +import javafx.beans.value.ChangeListener; + +import java.util.Optional; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.ToString; +import lombok.extern.slf4j.Slf4j; + +@ToString +@Slf4j +@EqualsAndHashCode +public class OpenProposalListItem implements BsqStateListener { + @Getter + private final DaoFacade daoFacade; + private final BsqWalletService bsqWalletService; + private final BsqFormatter bsqFormatter; + @Getter + private final Proposal proposal; + + @Getter + private ImageView imageView; + @Getter + private AutoTooltipButton button; + + @Getter + private TxConfidenceIndicator txConfidenceIndicator; + @Getter + private Integer confirmations = 0; + private TxConfidenceListener txConfidenceListener; + private Tooltip tooltip = new Tooltip(Res.get("confidence.unknown")); + private Transaction walletTransaction; + private ChangeListener phaseChangeListener; + private ChangeListener chainHeightListener; + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Constructor, lifecycle + /////////////////////////////////////////////////////////////////////////////////////////// + + OpenProposalListItem(Proposal proposal, + DaoFacade daoFacade, + BsqWalletService bsqWalletService, + BsqFormatter bsqFormatter) { + this.daoFacade = daoFacade; + this.bsqWalletService = bsqWalletService; + this.bsqFormatter = bsqFormatter; + + this.proposal = proposal; + + init(); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // BsqStateListener + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public void onNewBlockHeight(int blockHeight) { + } + + @Override + public void onEmptyBlockAdded(Block block) { + } + + @Override + public void onParseTxsComplete(Block block) { + setupConfidence(); + } + + @Override + public void onParseBlockChainComplete() { + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // API + /////////////////////////////////////////////////////////////////////////////////////////// + + public void cleanup() { + daoFacade.removeBsqStateListener(this); + bsqWalletService.getChainHeightProperty().removeListener(chainHeightListener); + if (txConfidenceListener != null) + bsqWalletService.removeTxConfidenceListener(txConfidenceListener); + + daoFacade.phaseProperty().removeListener(phaseChangeListener); + } + + public void onPhaseChanged(DaoPhase.Phase phase) { + //noinspection IfCanBeSwitch + if (phase == DaoPhase.Phase.PROPOSAL) { + imageView.setId("image-remove"); + button.setGraphic(imageView); + button.setText(Res.get("shared.remove")); + final boolean isMyProposal = daoFacade.isMyProposal(proposal); + button.setVisible(isMyProposal); + button.setManaged(isMyProposal); + } else if (phase == DaoPhase.Phase.BLIND_VOTE) { + button.setGraphic(null); + button.setText(Res.get("dao.proposal.active.vote")); + button.setVisible(true); + button.setManaged(true); + } else { + button.setVisible(false); + button.setManaged(false); + } + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Protected + /////////////////////////////////////////////////////////////////////////////////////////// + + private void init() { + txConfidenceIndicator = new TxConfidenceIndicator(); + txConfidenceIndicator.setId("funds-confidence"); + + txConfidenceIndicator.setProgress(-1); + txConfidenceIndicator.setPrefSize(24, 24); + txConfidenceIndicator.setTooltip(tooltip); + + + imageView = new ImageView(); + + chainHeightListener = (observable, oldValue, newValue) -> setupConfidence(); + bsqWalletService.getChainHeightProperty().addListener(chainHeightListener); + setupConfidence(); + + daoFacade.addBsqStateListener(this); + + phaseChangeListener = (observable, oldValue, newValue) -> onPhaseChanged(newValue); + + daoFacade.phaseProperty().addListener(phaseChangeListener); + + button = new AutoTooltipButton(); + button.setMinWidth(70); + onPhaseChanged(daoFacade.phaseProperty().get()); + } + + private void setupConfidence() { + final String txId = proposal.getTxId(); + Optional optionalTx = daoFacade.getTx(txId); + optionalTx.ifPresent(tx -> { + // We cache the walletTransaction once found + if (walletTransaction == null) { + final Optional transactionOptional = bsqWalletService.isWalletTransaction(txId); + transactionOptional.ifPresent(transaction -> walletTransaction = transaction); + } + + if (walletTransaction != null) { + // It is our tx so we get confidence updates + if (txConfidenceListener == null) { + txConfidenceListener = new TxConfidenceListener(txId) { + @Override + public void onTransactionConfidenceChanged(TransactionConfidence confidence) { + updateConfidence(confidence.getConfidenceType(), confidence.getDepthInBlocks(), confidence.numBroadcastPeers()); + } + }; + bsqWalletService.addTxConfidenceListener(txConfidenceListener); + } + } else { + // tx from other users, we don't get confidence updates but as we have the bsq tx we can calculate it + // we get setupConfidence called at each new block from above listener so no need to register a new listener + int depth = bsqWalletService.getChainHeightProperty().get() - tx.getBlockHeight() + 1; + if (depth > 0) + updateConfidence(TransactionConfidence.ConfidenceType.BUILDING, depth, -1); + } + + final TransactionConfidence confidence = bsqWalletService.getConfidenceForTxId(txId); + if (confidence != null) + updateConfidence(confidence, confidence.getDepthInBlocks()); + }); + } + + private void updateConfidence(TransactionConfidence confidence, int depthInBlocks) { + if (confidence != null) { + updateConfidence(confidence.getConfidenceType(), confidence.getDepthInBlocks(), confidence.numBroadcastPeers()); + confirmations = depthInBlocks; + } + } + + private void updateConfidence(TransactionConfidence.ConfidenceType confidenceType, int depthInBlocks, int numBroadcastPeers) { + switch (confidenceType) { + case UNKNOWN: + tooltip.setText(Res.get("confidence.unknown")); + txConfidenceIndicator.setProgress(0); + break; + case PENDING: + tooltip.setText(Res.get("confidence.seen", numBroadcastPeers > -1 ? numBroadcastPeers : Res.get("shared.na"))); + txConfidenceIndicator.setProgress(-1.0); + break; + case BUILDING: + tooltip.setText(Res.get("confidence.confirmed", depthInBlocks)); + txConfidenceIndicator.setProgress(Math.min(1, (double) depthInBlocks / 6.0)); + break; + case DEAD: + tooltip.setText(Res.get("confidence.invalid")); + txConfidenceIndicator.setProgress(0); + break; + } + + txConfidenceIndicator.setPrefSize(24, 24); + } +} diff --git a/src/main/java/bisq/desktop/main/dao/proposal/open/OpenProposalsView.fxml b/src/main/java/bisq/desktop/main/dao/proposal/open/OpenProposalsView.fxml new file mode 100644 index 00000000000..c09bc2e6a61 --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/proposal/open/OpenProposalsView.fxml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + diff --git a/src/main/java/bisq/desktop/main/dao/proposal/open/OpenProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/open/OpenProposalsView.java new file mode 100644 index 00000000000..1374f622f7f --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/proposal/open/OpenProposalsView.java @@ -0,0 +1,478 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.desktop.main.dao.proposal.open; + +import bisq.desktop.Navigation; +import bisq.desktop.common.view.ActivatableView; +import bisq.desktop.common.view.FxmlView; +import bisq.desktop.components.AutoTooltipLabel; +import bisq.desktop.components.AutoTooltipTableColumn; +import bisq.desktop.components.HyperlinkWithIcon; +import bisq.desktop.components.TableGroupHeadline; +import bisq.desktop.main.MainView; +import bisq.desktop.main.dao.DaoView; +import bisq.desktop.main.dao.proposal.ProposalDisplay; +import bisq.desktop.main.dao.proposal.ProposalWindow; +import bisq.desktop.main.dao.voting.VotingView; +import bisq.desktop.main.dao.voting.active.ActiveBallotsView; +import bisq.desktop.main.overlays.popups.Popup; + +import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.dao.DaoFacade; +import bisq.core.dao.state.period.DaoPhase; +import bisq.core.dao.voting.proposal.Proposal; +import bisq.core.locale.Res; +import bisq.core.util.BSFormatter; +import bisq.core.util.BsqFormatter; + +import javax.inject.Inject; + +import javafx.scene.control.Button; +import javafx.scene.control.ScrollPane; +import javafx.scene.control.TableCell; +import javafx.scene.control.TableColumn; +import javafx.scene.control.TableView; +import javafx.scene.control.Tooltip; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.Priority; + +import javafx.geometry.Insets; + +import org.fxmisc.easybind.EasyBind; +import org.fxmisc.easybind.Subscription; + +import javafx.beans.property.ReadOnlyObjectWrapper; + +import javafx.collections.FXCollections; +import javafx.collections.ListChangeListener; +import javafx.collections.ObservableList; +import javafx.collections.transformation.SortedList; + +import javafx.util.Callback; + +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; + +import static bisq.desktop.util.FormBuilder.addButtonAfterGroup; + +@FxmlView +public class OpenProposalsView extends ActivatableView { + + private final DaoFacade daoFacade; + private final BsqWalletService bsqWalletService; + private final BsqFormatter bsqFormatter; + private final BSFormatter btcFormatter; + + private final ObservableList proposalBaseProposalListItems = FXCollections.observableArrayList(); + private final SortedList sortedList = new SortedList<>(proposalBaseProposalListItems); + private TableView proposalTableView; + private Subscription selectedProposalSubscription; + private ProposalDisplay proposalDisplay; + private int gridRow = 0; + private GridPane detailsGridPane, gridPane; + private OpenProposalListItem selectedBaseProposalListItem; + + private DaoPhase.Phase currentPhase; + private Subscription phaseSubscription; + private ScrollPane proposalDisplayView; + private boolean proposalDisplayInitialized; + + + private ListChangeListener listChangeListener; + private final Navigation navigation; + + private Button button; + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Constructor, lifecycle + /////////////////////////////////////////////////////////////////////////////////////////// + + @Inject + private OpenProposalsView(DaoFacade daoFacade, + BsqWalletService bsqWalletService, + BsqFormatter bsqFormatter, + BSFormatter btcFormatter, + Navigation navigation) { + + this.daoFacade = daoFacade; + this.bsqWalletService = bsqWalletService; + this.bsqFormatter = bsqFormatter; + this.btcFormatter = btcFormatter; + this.navigation = navigation; + } + + @Override + public void initialize() { + super.initialize(); + root.getStyleClass().add("vote-root"); + + detailsGridPane = new GridPane(); + createProposalsTableView(); + createEmptyProposalDisplay(); + + listChangeListener = c -> updateListItems(); + } + + @Override + protected void activate() { + phaseSubscription = EasyBind.subscribe(daoFacade.phaseProperty(), this::onPhaseChanged); + selectedProposalSubscription = EasyBind.subscribe(proposalTableView.getSelectionModel().selectedItemProperty(), this::onSelectProposal); + + sortedList.comparatorProperty().bind(proposalTableView.comparatorProperty()); + + updateListItems(); + + getProposals().addListener(listChangeListener); + } + + @Override + protected void deactivate() { + phaseSubscription.unsubscribe(); + selectedProposalSubscription.unsubscribe(); + + sortedList.comparatorProperty().unbind(); + + proposalBaseProposalListItems.forEach(OpenProposalListItem::cleanup); + proposalTableView.getSelectionModel().clearSelection(); + selectedBaseProposalListItem = null; + + getProposals().removeListener(listChangeListener); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Protected + /////////////////////////////////////////////////////////////////////////////////////////// + + private ObservableList getProposals() { + return daoFacade.getActiveOrMyUnconfirmedProposals(); + } + + private void updateListItems() { + proposalBaseProposalListItems.forEach(OpenProposalListItem::cleanup); + proposalBaseProposalListItems.clear(); + + fillListItems(); + + if (proposalBaseProposalListItems.isEmpty()) + hideProposalDisplay(); + } + + private void createAllFieldsOnProposalDisplay(Proposal proposal) { + proposalDisplayView.setVisible(true); + proposalDisplayView.setManaged(true); + + proposalDisplay.createAllFields(Res.get("dao.proposal.selectedProposal"), 0, 0, proposal.getType(), + false); + proposalDisplay.setEditable(false); + proposalDisplay.applyProposalPayload(proposal); + proposalDisplayInitialized = true; + + button = addButtonAfterGroup(detailsGridPane, proposalDisplay.incrementAndGetGridRow(), ""); + button.setOnAction(event -> onButtonClick()); + onPhaseChanged(daoFacade.phaseProperty().get()); + } + + private void hideProposalDisplay() { + if (proposalDisplayInitialized) { + proposalDisplay.removeAllFields(); + proposalDisplayView.setVisible(false); + proposalDisplayView.setManaged(false); + } + if (button != null) { + button.setManaged(false); + button.setVisible(false); + } + } + + private void fillListItems() { + List list = getProposals(); + proposalBaseProposalListItems.setAll(list.stream() + .map(proposal -> new OpenProposalListItem(proposal, daoFacade, bsqWalletService, bsqFormatter)) + .collect(Collectors.toSet())); + } + + + private void onPhaseChanged(DaoPhase.Phase phase) { + if (phase != null && !phase.equals(currentPhase)) { + currentPhase = phase; + onSelectProposal(selectedBaseProposalListItem); + } + + if (button != null) { + //noinspection IfCanBeSwitch,IfCanBeSwitch,IfCanBeSwitch + if (phase == DaoPhase.Phase.PROPOSAL) { + if (selectedBaseProposalListItem != null && selectedBaseProposalListItem.getProposal() != null) { + button.setText(Res.get("shared.remove")); + final boolean isMyProposal = daoFacade.isMyProposal(selectedBaseProposalListItem.getProposal()); + button.setVisible(isMyProposal); + button.setManaged(isMyProposal); + } + } else if (phase == DaoPhase.Phase.BLIND_VOTE) { + button.setText(Res.get("dao.proposal.active.vote")); + button.setVisible(true); + button.setManaged(true); + } else { + button.setVisible(false); + button.setManaged(false); + } + } + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Handlers + /////////////////////////////////////////////////////////////////////////////////////////// + + private void onButtonClick() { + if (daoFacade.phaseProperty().get() == DaoPhase.Phase.PROPOSAL) { + final Proposal proposal = selectedBaseProposalListItem.getProposal(); + if (daoFacade.removeMyProposal(proposal)) { + hideProposalDisplay(); + } else { + new Popup<>().warning(Res.get("dao.proposal.active.remove.failed")).show(); + } + proposalTableView.getSelectionModel().clearSelection(); + } else if (daoFacade.phaseProperty().get() == DaoPhase.Phase.BLIND_VOTE) { + navigation.navigateTo(MainView.class, DaoView.class, VotingView.class, ActiveBallotsView.class); + } + } + + private void onSelectProposal(OpenProposalListItem item) { + selectedBaseProposalListItem = item; + if (selectedBaseProposalListItem != null) + createAllFieldsOnProposalDisplay(selectedBaseProposalListItem.getProposal()); + else + hideProposalDisplay(); + + onPhaseChanged(daoFacade.phaseProperty().get()); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Create views + /////////////////////////////////////////////////////////////////////////////////////////// + + private void createProposalsTableView() { + createProposalsTableView(Res.get("dao.proposal.active.header"), -10); + } + + private void createProposalsTableView(String header, double top) { + TableGroupHeadline proposalsHeadline = new TableGroupHeadline(header); + GridPane.setRowIndex(proposalsHeadline, ++gridRow); + GridPane.setMargin(proposalsHeadline, new Insets(top, -10, -10, -10)); + GridPane.setColumnSpan(proposalsHeadline, 2); + root.getChildren().add(proposalsHeadline); + + proposalTableView = new TableView<>(); + proposalTableView.setPlaceholder(new AutoTooltipLabel(Res.get("table.placeholder.noData"))); + proposalTableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); + proposalTableView.setPrefHeight(200); + + createProposalColumns(proposalTableView); + GridPane.setRowIndex(proposalTableView, gridRow); + GridPane.setMargin(proposalTableView, new Insets(top + 20, -10, 5, -10)); + GridPane.setColumnSpan(proposalTableView, 2); + GridPane.setHgrow(proposalTableView, Priority.ALWAYS); + root.getChildren().add(proposalTableView); + + proposalTableView.setItems(sortedList); + } + + private void createEmptyProposalDisplay() { + proposalDisplay = new ProposalDisplay(detailsGridPane, bsqFormatter, bsqWalletService, daoFacade); + proposalDisplayView = proposalDisplay.getView(); + GridPane.setMargin(proposalDisplayView, new Insets(10, -10, 0, -10)); + GridPane.setRowIndex(proposalDisplayView, ++gridRow); + GridPane.setColumnSpan(proposalDisplayView, 2); + root.getChildren().add(proposalDisplayView); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // TableColumns + /////////////////////////////////////////////////////////////////////////////////////////// + + private void createProposalColumns(TableView tableView) { + TableColumn dateColumn = new AutoTooltipTableColumn(Res.get("shared.dateTime")) { + { + setMinWidth(190); + setMaxWidth(190); + } + }; + dateColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + dateColumn.setCellFactory( + new Callback, TableCell>() { + @Override + public TableCell call( + TableColumn column) { + return new TableCell() { + @Override + public void updateItem(final OpenProposalListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null) + setText(bsqFormatter.formatDateTime(item.getProposal().getCreationDate())); + else + setText(""); + } + }; + } + }); + dateColumn.setComparator(Comparator.comparing(o3 -> o3.getProposal().getCreationDate())); + dateColumn.setSortType(TableColumn.SortType.DESCENDING); + tableView.getColumns().add(dateColumn); + tableView.getSortOrder().add(dateColumn); + + TableColumn nameColumn = new AutoTooltipTableColumn<>(Res.get("shared.name")); + nameColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + nameColumn.setCellFactory( + new Callback, TableCell>() { + @Override + public TableCell call( + TableColumn column) { + return new TableCell() { + @Override + public void updateItem(final OpenProposalListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null) + setText(item.getProposal().getName()); + else + setText(""); + } + }; + } + }); + nameColumn.setComparator(Comparator.comparing(o2 -> o2.getProposal().getName())); + tableView.getColumns().add(nameColumn); + + TableColumn uidColumn = new AutoTooltipTableColumn<>(Res.get("shared.id")); + uidColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + uidColumn.setCellFactory( + new Callback, TableCell>() { + + @Override + public TableCell call(TableColumn column) { + return new TableCell() { + private HyperlinkWithIcon field; + + @Override + public void updateItem(final OpenProposalListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null && !empty) { + final Proposal proposal = item.getProposal(); + field = new HyperlinkWithIcon(proposal.getShortId()); + field.setOnAction(event -> { + new ProposalWindow(bsqFormatter, bsqWalletService, proposal, daoFacade).show(); + }); + field.setTooltip(new Tooltip(Res.get("tooltip.openPopupForDetails"))); + setGraphic(field); + } else { + setGraphic(null); + if (field != null) + field.setOnAction(null); + } + } + }; + } + }); + uidColumn.setComparator(Comparator.comparing(o -> o.getProposal().getUid())); + tableView.getColumns().add(uidColumn); + + + TableColumn confidenceColumn = new TableColumn<>(Res.get("shared.confirmations")); + confidenceColumn.setMinWidth(130); + confidenceColumn.setMaxWidth(confidenceColumn.getMinWidth()); + + confidenceColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + + confidenceColumn.setCellFactory(new Callback, + TableCell>() { + + @Override + public TableCell call(TableColumn column) { + return new TableCell() { + + @Override + public void updateItem(final OpenProposalListItem item, boolean empty) { + super.updateItem(item, empty); + + if (item != null && !empty) { + setGraphic(item.getTxConfidenceIndicator()); + } else { + setGraphic(null); + } + } + }; + } + }); + confidenceColumn.setComparator(Comparator.comparing(OpenProposalListItem::getConfirmations)); + tableView.getColumns().add(confidenceColumn); + + TableColumn actionColumn = new TableColumn<>(); + actionColumn.setMinWidth(130); + actionColumn.setMaxWidth(actionColumn.getMinWidth()); + + actionColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + + actionColumn.setCellFactory(new Callback, + TableCell>() { + + @Override + public TableCell call(TableColumn column) { + return new TableCell() { + Button button; + + @Override + public void updateItem(final OpenProposalListItem item, boolean empty) { + super.updateItem(item, empty); + + if (item != null && !empty) { + OpenProposalListItem openProposalListItem = item; + if (button == null) { + button = openProposalListItem.getButton(); + button.setOnAction(e -> { + OpenProposalsView.this.selectedBaseProposalListItem = item; + OpenProposalsView.this.onButtonClick(); + }); + setGraphic(button); + } + openProposalListItem.onPhaseChanged(currentPhase); + } else { + setGraphic(null); + if (button != null) { + button.setOnAction(null); + button = null; + } + } + } + }; + } + }); + actionColumn.setComparator(Comparator.comparing(OpenProposalListItem::getConfirmations)); + tableView.getColumns().add(actionColumn); + } +} + From 5f8185a838c85dfe411be051b3d3868d163c6677 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Fri, 27 Jul 2018 00:50:19 +0200 Subject: [PATCH 172/197] Add combined proposal vote view --- .../java/bisq/desktop/main/dao/DaoView.java | 26 +- .../main/dao/bonding/BondingViewUtils.java | 1 - .../main/dao/proposal/ProposalDisplay.java | 38 +- .../main/dao/proposal/ProposalView.java | 10 +- .../active/ActiveProposalListItem.java | 93 ---- .../proposal/active/ActiveProposalsView.fxml | 33 -- .../proposal/active/ActiveProposalsView.java | 216 -------- .../proposal/open/OpenProposalListItem.java | 53 +- .../dao/proposal/open/OpenProposalsView.java | 505 ++++++++++++++---- .../main/dao/wallet/send/BsqSendView.java | 1 - src/main/java/bisq/desktop/util/GUIUtil.java | 2 + 11 files changed, 465 insertions(+), 513 deletions(-) delete mode 100644 src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalListItem.java delete mode 100644 src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.fxml delete mode 100644 src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java diff --git a/src/main/java/bisq/desktop/main/dao/DaoView.java b/src/main/java/bisq/desktop/main/dao/DaoView.java index be9261217b5..ed99ba512bd 100644 --- a/src/main/java/bisq/desktop/main/dao/DaoView.java +++ b/src/main/java/bisq/desktop/main/dao/DaoView.java @@ -28,7 +28,6 @@ import bisq.desktop.main.dao.bonding.BondingView; import bisq.desktop.main.dao.proposal.ProposalView; import bisq.desktop.main.dao.results.ResultsView; -import bisq.desktop.main.dao.voting.VotingView; import bisq.desktop.main.dao.wallet.BsqWalletView; import bisq.desktop.main.dao.wallet.dashboard.BsqDashboardView; @@ -55,8 +54,6 @@ public class DaoView extends ActivatableViewAndModel { @FXML private Tab proposalsTab; @FXML - private Tab votingTab; - @FXML private Tab resultsTab; @FXML private Tab bondingTab; @@ -80,20 +77,17 @@ private DaoView(CachingViewLoader viewLoader, Navigation navigation) { public void initialize() { bsqWalletTab = new Tab(Res.get("dao.tab.bsqWallet")); proposalsTab = new Tab(Res.get("dao.tab.proposals")); - votingTab = new Tab(Res.get("dao.tab.voting")); resultsTab = new Tab(Res.get("dao.tab.results")); bondingTab = new Tab(Res.get("dao.tab.bonding")); bsqWalletTab.setClosable(false); proposalsTab.setClosable(false); - votingTab.setClosable(false); resultsTab.setClosable(false); bondingTab.setClosable(false); - root.getTabs().addAll(bsqWalletTab, proposalsTab, votingTab, resultsTab, bondingTab); + root.getTabs().addAll(bsqWalletTab, proposalsTab, resultsTab, bondingTab); if (!BisqEnvironment.isDAOActivatedAndBaseCurrencySupportingBsq() || !DevEnv.isDaoPhase2Activated()) { - votingTab.setDisable(true); bondingTab.setDisable(true); resultsTab.setDisable(true); proposalsTab.setDisable(true); @@ -102,7 +96,6 @@ public void initialize() { navigationListener = viewPath -> { if (viewPath.size() == 3 && viewPath.indexOf(DaoView.class) == 1) { if (proposalsTab == null && viewPath.get(2).equals(BsqWalletView.class)) - //noinspection unchecked navigation.navigateTo(MainView.class, DaoView.class, BsqWalletView.class); else loadView(viewPath.tip()); @@ -113,22 +106,14 @@ public void initialize() { if (newValue == bsqWalletTab) { Class selectedViewClass = bsqWalletView.getSelectedViewClass(); if (selectedViewClass == null) - //noinspection unchecked navigation.navigateTo(MainView.class, DaoView.class, BsqWalletView.class, BsqDashboardView.class); else - //noinspection unchecked navigation.navigateTo(MainView.class, DaoView.class, BsqWalletView.class, selectedViewClass); } else if (newValue == proposalsTab) { - //noinspection unchecked navigation.navigateTo(MainView.class, DaoView.class, ProposalView.class); - } else if (newValue == votingTab) { - //noinspection unchecked - navigation.navigateTo(MainView.class, DaoView.class, VotingView.class); } else if (newValue == resultsTab) { - //noinspection unchecked navigation.navigateTo(MainView.class, DaoView.class, ResultsView.class); } else if (newValue == bondingTab) { - //noinspection unchecked navigation.navigateTo(MainView.class, DaoView.class, BondingView.class); } }; @@ -142,19 +127,12 @@ protected void activate() { if (navigation.getCurrentPath().size() == 2 && navigation.getCurrentPath().get(1) == DaoView.class) { Tab selectedItem = root.getSelectionModel().getSelectedItem(); if (selectedItem == bsqWalletTab) - //noinspection unchecked navigation.navigateTo(MainView.class, DaoView.class, BsqWalletView.class); else if (selectedItem == proposalsTab) - //noinspection unchecked navigation.navigateTo(MainView.class, DaoView.class, ProposalView.class); - else if (selectedItem == votingTab) - //noinspection unchecked - navigation.navigateTo(MainView.class, DaoView.class, VotingView.class); else if (selectedItem == resultsTab) - //noinspection unchecked navigation.navigateTo(MainView.class, DaoView.class, ResultsView.class); else if (selectedItem == bondingTab) - //noinspection unchecked navigation.navigateTo(MainView.class, DaoView.class, BondingView.class); } } @@ -172,8 +150,6 @@ private void loadView(Class viewClass) { bsqWalletView = (BsqWalletView) view; } else if (view instanceof ProposalView) { selectedTab = proposalsTab; - } else if (view instanceof VotingView) { - selectedTab = votingTab; } else if (view instanceof ResultsView) { selectedTab = resultsTab; } else if (view instanceof BondingView) { diff --git a/src/main/java/bisq/desktop/main/dao/bonding/BondingViewUtils.java b/src/main/java/bisq/desktop/main/dao/bonding/BondingViewUtils.java index d0f23c543f3..59fe692dc1a 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/BondingViewUtils.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/BondingViewUtils.java @@ -141,7 +141,6 @@ public void handleError(Throwable throwable) { if (throwable instanceof InsufficientMoneyException) { final Coin missingCoin = ((InsufficientMoneyException) throwable).missing; final String missing = missingCoin != null ? missingCoin.toFriendlyString() : "null"; - //noinspection unchecked new Popup<>().warning(Res.get("popup.warning.insufficientBtcFundsForBsqTx", missing)) .actionButtonTextWithGoTo("navigation.funds.depositFunds") .onAction(() -> navigation.navigateTo(MainView.class, FundsView.class, DepositView.class)) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java index 51ccc8c8904..224b1f23e80 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java @@ -87,8 +87,8 @@ public class ProposalDisplay { private final DaoFacade daoFacade; @Nullable - private TextField uidTextField; - private TextField proposalFeeTextField, proposalTypeTextField; + private TextField uidTextField, proposalFeeTextField; + private TextField proposalTypeTextField; public InputTextField nameTextField; public InputTextField linkInputTextField; @Nullable @@ -148,28 +148,31 @@ public void createAllFields(String title, int gridRowStartIndex, double top, Pro removeAllFields(); this.gridRowStartIndex = gridRowStartIndex; this.gridRow = gridRowStartIndex; - int rowSpan = 5; + int rowSpan = 4; switch (proposalType) { case COMPENSATION_REQUEST: - rowSpan = 6; + rowSpan = 5; break; case BONDED_ROLE: - rowSpan = 5; + rowSpan = 4; break; case REMOVE_ALTCOIN: break; case CHANGE_PARAM: - rowSpan = 6; + rowSpan = 5; break; case GENERIC: break; case CONFISCATE_BOND: - rowSpan = 5; + rowSpan = 4; break; } - // for already created proposals we show the uid and tx id so we add 2 rows - if (!isMakeProposalScreen) + // at isMakeProposalScreen we show fee but no uid and txID (+1) + // otherwise we don't show fee but show uid and txID (+2) + if (isMakeProposalScreen) + rowSpan += 1; + else rowSpan += 2; addTitledGroupBg(gridPane, gridRow, rowSpan, title, top); @@ -289,9 +292,10 @@ public BondedRole fromString(String string) { txIdTextField = addLabelTxIdTextField(gridPane, ++gridRow, Res.get("dao.proposal.display.txId"), "").second; - proposalFeeTextField = addLabelTextField(gridPane, ++gridRow, Res.get("dao.proposal.display.proposalFee")).second; - if (isMakeProposalScreen) + if (isMakeProposalScreen) { + proposalFeeTextField = addLabelTextField(gridPane, ++gridRow, Res.get("dao.proposal.display.proposalFee")).second; proposalFeeTextField.setText(bsqFormatter.formatCoinWithCode(daoFacade.getProposalFee(daoFacade.getChainHeight()))); + } addListeners(); } @@ -339,7 +343,8 @@ public void applyProposalPayload(Proposal proposal) { } else { chainHeight = daoFacade.getTx(proposal.getTxId()).map(Tx::getBlockHeight).orElse(0); } - proposalFeeTextField.setText(bsqFormatter.formatCoinWithCode(daoFacade.getProposalFee(chainHeight))); + if (proposalFeeTextField != null) + proposalFeeTextField.setText(bsqFormatter.formatCoinWithCode(daoFacade.getProposalFee(chainHeight))); } private void addListeners() { @@ -380,9 +385,8 @@ public void clearForm() { } public void setEditable(boolean isEditable) { - inputControls.stream().filter(Objects::nonNull).forEach(e -> e.setEditable(!isEditable)); - comboBoxes.stream() - .filter(Objects::nonNull).forEach(comboBox -> comboBox.setEditable(!isEditable)); + inputControls.stream().filter(Objects::nonNull).forEach(e -> e.setEditable(isEditable)); + comboBoxes.stream().filter(Objects::nonNull).forEach(comboBox -> comboBox.setDisable(!isEditable)); linkInputTextField.setVisible(true); linkInputTextField.setManaged(true); @@ -397,6 +401,8 @@ public void removeAllFields() { GUIUtil.removeChildrenFromGridPaneRows(gridPane, gridRowStartIndex, gridRow); gridRow = gridRowStartIndex; } + inputControls.clear(); + comboBoxes.clear(); } public int incrementAndGetGridRow() { @@ -408,7 +414,7 @@ public ScrollPane getView() { ScrollPane scrollPane = new ScrollPane(); scrollPane.setFitToWidth(true); scrollPane.setFitToHeight(true); - scrollPane.setMinHeight(280); // just enough to display overview at voting without scroller + //scrollPane.setMinHeight(280); // just enough to display overview at voting without scroller AnchorPane anchorPane = new AnchorPane(); scrollPane.setContent(anchorPane); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalView.java index 93b4ea4a522..73bb249310c 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalView.java @@ -27,7 +27,6 @@ import bisq.desktop.components.MenuItem; import bisq.desktop.main.MainView; import bisq.desktop.main.dao.DaoView; -import bisq.desktop.main.dao.proposal.active.ActiveProposalsView; import bisq.desktop.main.dao.proposal.closed.ClosedProposalsView; import bisq.desktop.main.dao.proposal.dashboard.ProposalDashboardView; import bisq.desktop.main.dao.proposal.make.MakeProposalView; @@ -54,7 +53,7 @@ public class ProposalView extends ActivatableViewAndModel { private final ViewLoader viewLoader; private final Navigation navigation; - private MenuItem dashboard, make, open, active, closed; + private MenuItem dashboard, make, open, closed; private Navigation.Listener listener; @FXML @@ -88,11 +87,9 @@ public void initialize() { MakeProposalView.class, AwesomeIcon.EDIT, baseNavPath); open = new MenuItem(navigation, toggleGroup, Res.get("dao.proposal.menuItem.open"), OpenProposalsView.class, AwesomeIcon.LIST_UL, baseNavPath); - active = new MenuItem(navigation, toggleGroup, Res.get("dao.proposal.menuItem.active"), - ActiveProposalsView.class, AwesomeIcon.LIST_UL, baseNavPath); closed = new MenuItem(navigation, toggleGroup, Res.get("dao.proposal.menuItem.closed"), ClosedProposalsView.class, AwesomeIcon.LIST_ALT, baseNavPath); - leftVBox.getChildren().addAll(dashboard, make, open, active, closed); + leftVBox.getChildren().addAll(dashboard, make, open, closed); } @Override @@ -100,7 +97,6 @@ protected void activate() { dashboard.activate(); make.activate(); open.activate(); - active.activate(); closed.activate(); navigation.addListener(listener); @@ -126,7 +122,6 @@ protected void deactivate() { dashboard.deactivate(); make.deactivate(); open.deactivate(); - active.deactivate(); closed.deactivate(); } @@ -137,7 +132,6 @@ private void loadView(Class viewClass) { if (view instanceof ProposalDashboardView) dashboard.setSelected(true); else if (view instanceof MakeProposalView) make.setSelected(true); else if (view instanceof OpenProposalsView) open.setSelected(true); - else if (view instanceof ActiveProposalsView) active.setSelected(true); else if (view instanceof ClosedProposalsView) closed.setSelected(true); } } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalListItem.java deleted file mode 100644 index 887436fe3e0..00000000000 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalListItem.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.desktop.main.dao.proposal.active; - -import bisq.desktop.components.AutoTooltipButton; -import bisq.desktop.main.dao.proposal.ProposalListItem; - -import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.DaoFacade; -import bisq.core.dao.state.period.DaoPhase; -import bisq.core.dao.voting.proposal.Proposal; -import bisq.core.locale.Res; -import bisq.core.util.BsqFormatter; - -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.ToString; -import lombok.extern.slf4j.Slf4j; - -@ToString -@Slf4j -@EqualsAndHashCode(callSuper = true) -public class ActiveProposalListItem extends ProposalListItem { - @Getter - private AutoTooltipButton button; - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Constructor, lifecycle - /////////////////////////////////////////////////////////////////////////////////////////// - - ActiveProposalListItem(Proposal proposal, - DaoFacade daoFacade, - BsqWalletService bsqWalletService, - BsqFormatter bsqFormatter) { - super(proposal, - daoFacade, - bsqWalletService, - bsqFormatter); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Protected - /////////////////////////////////////////////////////////////////////////////////////////// - - @Override - protected void init() { - super.init(); - - button = new AutoTooltipButton(); - button.setMinWidth(70); - onPhaseChanged(daoFacade.phaseProperty().get()); - } - - @Override - public void onPhaseChanged(DaoPhase.Phase phase) { - super.onPhaseChanged(phase); - - //noinspection IfCanBeSwitch - if (phase == DaoPhase.Phase.PROPOSAL) { - imageView.setId("image-remove"); - button.setGraphic(imageView); - button.setText(Res.get("shared.remove")); - final boolean isMyProposal = daoFacade.isMyProposal(proposal); - button.setVisible(isMyProposal); - button.setManaged(isMyProposal); - } else if (phase == DaoPhase.Phase.BLIND_VOTE) { - button.setGraphic(null); - button.setText(Res.get("dao.proposal.active.vote")); - button.setVisible(true); - button.setManaged(true); - } else { - button.setVisible(false); - button.setManaged(false); - } - } -} diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.fxml b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.fxml deleted file mode 100644 index 97c66cdc0bd..00000000000 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.fxml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java deleted file mode 100644 index c5b95a0087a..00000000000 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ /dev/null @@ -1,216 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.desktop.main.dao.proposal.active; - -import bisq.desktop.Navigation; -import bisq.desktop.common.view.FxmlView; -import bisq.desktop.main.MainView; -import bisq.desktop.main.dao.BaseProposalListItem; -import bisq.desktop.main.dao.DaoView; -import bisq.desktop.main.dao.proposal.ProposalItemsView; -import bisq.desktop.main.dao.voting.VotingView; -import bisq.desktop.main.dao.voting.active.ActiveBallotsView; -import bisq.desktop.main.overlays.popups.Popup; - -import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.DaoFacade; -import bisq.core.dao.state.period.DaoPhase; -import bisq.core.dao.voting.proposal.Proposal; -import bisq.core.locale.Res; -import bisq.core.util.BSFormatter; -import bisq.core.util.BsqFormatter; - -import javax.inject.Inject; - -import javafx.scene.control.Button; -import javafx.scene.control.TableCell; -import javafx.scene.control.TableColumn; -import javafx.scene.control.TableView; - -import javafx.beans.property.ReadOnlyObjectWrapper; - -import javafx.collections.ObservableList; - -import javafx.util.Callback; - -import java.util.Comparator; -import java.util.List; -import java.util.stream.Collectors; - -import static bisq.desktop.util.FormBuilder.addButtonAfterGroup; - -@FxmlView -public class ActiveProposalsView extends ProposalItemsView { - private final Navigation navigation; - - private Button button; - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Constructor, lifecycle - /////////////////////////////////////////////////////////////////////////////////////////// - - @Inject - private ActiveProposalsView(DaoFacade daoFacade, - BsqWalletService bsqWalletService, - BsqFormatter bsqFormatter, - BSFormatter btcFormatter, - Navigation navigation) { - - super(daoFacade, bsqWalletService, bsqFormatter, btcFormatter); - this.navigation = navigation; - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Protected - /////////////////////////////////////////////////////////////////////////////////////////// - - @Override - protected ObservableList getProposals() { - return daoFacade.getActiveOrMyUnconfirmedProposals(); - } - - - @Override - protected void createAllFieldsOnProposalDisplay(Proposal proposal) { - super.createAllFieldsOnProposalDisplay(proposal); - - button = addButtonAfterGroup(detailsGridPane, proposalDisplay.incrementAndGetGridRow(), ""); - button.setOnAction(event -> onButtonClick()); - onPhaseChanged(daoFacade.phaseProperty().get()); - } - - @Override - protected void hideProposalDisplay() { - super.hideProposalDisplay(); - - if (button != null) { - button.setManaged(false); - button.setVisible(false); - } - } - - @Override - protected void fillListItems() { - List list = getProposals(); - proposalBaseProposalListItems.setAll(list.stream() - .map(proposal -> new ActiveProposalListItem(proposal, daoFacade, bsqWalletService, bsqFormatter)) - .collect(Collectors.toSet())); - } - - - @Override - protected void onPhaseChanged(DaoPhase.Phase phase) { - super.onPhaseChanged(phase); - - if (button != null) { - //noinspection IfCanBeSwitch,IfCanBeSwitch,IfCanBeSwitch - if (phase == DaoPhase.Phase.PROPOSAL) { - if (selectedBaseProposalListItem != null && selectedBaseProposalListItem.getProposal() != null) { - button.setText(Res.get("shared.remove")); - final boolean isMyProposal = daoFacade.isMyProposal(selectedBaseProposalListItem.getProposal()); - button.setVisible(isMyProposal); - button.setManaged(isMyProposal); - } - } else if (phase == DaoPhase.Phase.BLIND_VOTE) { - button.setText(Res.get("dao.proposal.active.vote")); - button.setVisible(true); - button.setManaged(true); - } else { - button.setVisible(false); - button.setManaged(false); - } - } - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Handlers - /////////////////////////////////////////////////////////////////////////////////////////// - - private void onButtonClick() { - if (daoFacade.phaseProperty().get() == DaoPhase.Phase.PROPOSAL) { - final Proposal proposal = selectedBaseProposalListItem.getProposal(); - if (daoFacade.removeMyProposal(proposal)) { - hideProposalDisplay(); - } else { - new Popup<>().warning(Res.get("dao.proposal.active.remove.failed")).show(); - } - proposalTableView.getSelectionModel().clearSelection(); - } else if (daoFacade.phaseProperty().get() == DaoPhase.Phase.BLIND_VOTE) { - navigation.navigateTo(MainView.class, DaoView.class, VotingView.class, ActiveBallotsView.class); - } - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // TableColumns - /////////////////////////////////////////////////////////////////////////////////////////// - - @Override - protected void createProposalColumns(TableView tableView) { - super.createProposalColumns(tableView); - createConfidenceColumn(tableView); - - TableColumn actionColumn = new TableColumn<>(); - actionColumn.setMinWidth(130); - actionColumn.setMaxWidth(actionColumn.getMinWidth()); - - actionColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - - actionColumn.setCellFactory(new Callback, - TableCell>() { - - @Override - public TableCell call(TableColumn column) { - return new TableCell() { - Button button; - - @Override - public void updateItem(final BaseProposalListItem item, boolean empty) { - super.updateItem(item, empty); - - if (item != null && !empty) { - ActiveProposalListItem activeProposalListItem = (ActiveProposalListItem) item; - if (button == null) { - button = activeProposalListItem.getButton(); - button.setOnAction(e -> { - ActiveProposalsView.this.selectedBaseProposalListItem = item; - ActiveProposalsView.this.onButtonClick(); - }); - setGraphic(button); - } - activeProposalListItem.onPhaseChanged(currentPhase); - } else { - setGraphic(null); - if (button != null) { - button.setOnAction(null); - button = null; - } - } - } - }; - } - }); - actionColumn.setComparator(Comparator.comparing(BaseProposalListItem::getConfirmations)); - tableView.getColumns().add(actionColumn); - } -} - diff --git a/src/main/java/bisq/desktop/main/dao/proposal/open/OpenProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/open/OpenProposalListItem.java index 838512d41ec..5f51ee6ed7e 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/open/OpenProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/open/OpenProposalListItem.java @@ -27,6 +27,9 @@ import bisq.core.dao.state.blockchain.Block; import bisq.core.dao.state.blockchain.Tx; import bisq.core.dao.state.period.DaoPhase; +import bisq.core.dao.voting.ballot.Ballot; +import bisq.core.dao.voting.ballot.vote.BooleanVote; +import bisq.core.dao.voting.ballot.vote.Vote; import bisq.core.dao.voting.proposal.Proposal; import bisq.core.locale.Res; import bisq.core.util.BsqFormatter; @@ -39,6 +42,7 @@ import javafx.beans.value.ChangeListener; +import java.util.Objects; import java.util.Optional; import lombok.EqualsAndHashCode; @@ -46,16 +50,21 @@ import lombok.ToString; import lombok.extern.slf4j.Slf4j; +import javax.annotation.Nullable; + @ToString @Slf4j @EqualsAndHashCode public class OpenProposalListItem implements BsqStateListener { @Getter + private final Proposal proposal; private final DaoFacade daoFacade; private final BsqWalletService bsqWalletService; private final BsqFormatter bsqFormatter; + @Getter - private final Proposal proposal; + @Nullable + private Ballot ballot; @Getter private ImageView imageView; @@ -81,11 +90,23 @@ public class OpenProposalListItem implements BsqStateListener { DaoFacade daoFacade, BsqWalletService bsqWalletService, BsqFormatter bsqFormatter) { + this.proposal = proposal; this.daoFacade = daoFacade; this.bsqWalletService = bsqWalletService; this.bsqFormatter = bsqFormatter; - this.proposal = proposal; + init(); + } + + OpenProposalListItem(Ballot ballot, + DaoFacade daoFacade, + BsqWalletService bsqWalletService, + BsqFormatter bsqFormatter) { + this.ballot = ballot; + this.proposal = ballot.getProposal(); + this.daoFacade = daoFacade; + this.bsqWalletService = bsqWalletService; + this.bsqFormatter = bsqFormatter; init(); } @@ -144,6 +165,26 @@ public void onPhaseChanged(DaoPhase.Phase phase) { button.setVisible(false); button.setManaged(false); } + + + // ballot + if (ballot != null) { + final Vote vote = ballot.getVote(); + if (vote != null) { + imageView.setVisible(true); + if (vote instanceof BooleanVote) { + if (((BooleanVote) vote).isAccepted()) { + imageView.setId("accepted"); + } else { + imageView.setId("rejected"); + } + }/* else { + // not impl. + }*/ + } else { + imageView.setVisible(false); + } + } } @@ -241,4 +282,12 @@ private void updateConfidence(TransactionConfidence.ConfidenceType confidenceTyp txConfidenceIndicator.setPrefSize(24, 24); } + + public Optional getBooleanVote() { + return Optional.ofNullable(ballot) + .map(Ballot::getVote) + .filter(Objects::nonNull) + .filter(vote -> vote instanceof BooleanVote) + .map(v -> (BooleanVote) v); + } } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/open/OpenProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/open/OpenProposalsView.java index 1374f622f7f..8b230ec86b8 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/open/OpenProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/open/OpenProposalsView.java @@ -17,37 +17,56 @@ package bisq.desktop.main.dao.proposal.open; -import bisq.desktop.Navigation; import bisq.desktop.common.view.ActivatableView; import bisq.desktop.common.view.FxmlView; import bisq.desktop.components.AutoTooltipLabel; import bisq.desktop.components.AutoTooltipTableColumn; +import bisq.desktop.components.BusyAnimation; import bisq.desktop.components.HyperlinkWithIcon; +import bisq.desktop.components.InputTextField; import bisq.desktop.components.TableGroupHeadline; -import bisq.desktop.main.MainView; -import bisq.desktop.main.dao.DaoView; +import bisq.desktop.components.TitledGroupBg; import bisq.desktop.main.dao.proposal.ProposalDisplay; import bisq.desktop.main.dao.proposal.ProposalWindow; -import bisq.desktop.main.dao.voting.VotingView; -import bisq.desktop.main.dao.voting.active.ActiveBallotsView; import bisq.desktop.main.overlays.popups.Popup; +import bisq.desktop.util.GUIUtil; +import bisq.desktop.util.Layout; +import bisq.desktop.util.validation.BsqValidator; +import bisq.core.btc.exceptions.TransactionVerificationException; +import bisq.core.btc.exceptions.WalletException; +import bisq.core.btc.wallet.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; +import bisq.core.dao.state.BsqStateListener; +import bisq.core.dao.state.blockchain.Block; import bisq.core.dao.state.period.DaoPhase; +import bisq.core.dao.voting.ballot.Ballot; +import bisq.core.dao.voting.ballot.vote.BooleanVote; +import bisq.core.dao.voting.myvote.MyVote; import bisq.core.dao.voting.proposal.Proposal; import bisq.core.locale.Res; import bisq.core.util.BSFormatter; import bisq.core.util.BsqFormatter; +import bisq.common.util.Tuple2; +import bisq.common.util.Tuple3; + +import org.bitcoinj.core.Coin; +import org.bitcoinj.core.InsufficientMoneyException; +import org.bitcoinj.core.Transaction; + import javax.inject.Inject; import javafx.scene.control.Button; +import javafx.scene.control.Control; +import javafx.scene.control.Label; import javafx.scene.control.ScrollPane; import javafx.scene.control.TableCell; import javafx.scene.control.TableColumn; import javafx.scene.control.TableView; import javafx.scene.control.Tooltip; +import javafx.scene.image.ImageView; import javafx.scene.layout.GridPane; import javafx.scene.layout.Priority; @@ -57,6 +76,7 @@ import org.fxmisc.easybind.Subscription; import javafx.beans.property.ReadOnlyObjectWrapper; +import javafx.beans.value.ChangeListener; import javafx.collections.FXCollections; import javafx.collections.ListChangeListener; @@ -65,39 +85,46 @@ import javafx.util.Callback; +import java.util.ArrayList; import java.util.Comparator; import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; -import static bisq.desktop.util.FormBuilder.addButtonAfterGroup; +import static bisq.desktop.util.FormBuilder.*; @FxmlView -public class OpenProposalsView extends ActivatableView { +public class OpenProposalsView extends ActivatableView implements BsqBalanceListener, BsqStateListener { private final DaoFacade daoFacade; private final BsqWalletService bsqWalletService; private final BsqFormatter bsqFormatter; private final BSFormatter btcFormatter; - private final ObservableList proposalBaseProposalListItems = FXCollections.observableArrayList(); - private final SortedList sortedList = new SortedList<>(proposalBaseProposalListItems); - private TableView proposalTableView; + private final ObservableList listItems = FXCollections.observableArrayList(); + private final SortedList sortedList = new SortedList<>(listItems); + private TableView tableView; private Subscription selectedProposalSubscription; private ProposalDisplay proposalDisplay; private int gridRow = 0; - private GridPane detailsGridPane, gridPane; - private OpenProposalListItem selectedBaseProposalListItem; - + private OpenProposalListItem selectedItem; + private GridPane proposalDisplayGridPane; private DaoPhase.Phase currentPhase; private Subscription phaseSubscription; private ScrollPane proposalDisplayView; private boolean proposalDisplayInitialized; - private ListChangeListener listChangeListener; - private final Navigation navigation; - - private Button button; + private Button removeProposalButton, acceptButton, rejectButton, ignoreButton, voteButton; + private InputTextField stakeInputTextField; + private BusyAnimation voteButtonBusyAnimation; + private Label voteButtonInfoLabel; + private ListChangeListener proposalListChangeListener; + private ListChangeListener ballotListChangeListener; + private ChangeListener stakeListener; + private List voteControls = new ArrayList<>(); + private TitledGroupBg voteTitledGroupBg; + private Label stakeLabel; /////////////////////////////////////////////////////////////////////////////////////////// @@ -108,14 +135,12 @@ public class OpenProposalsView extends ActivatableView { private OpenProposalsView(DaoFacade daoFacade, BsqWalletService bsqWalletService, BsqFormatter bsqFormatter, - BSFormatter btcFormatter, - Navigation navigation) { + BSFormatter btcFormatter) { this.daoFacade = daoFacade; this.bsqWalletService = bsqWalletService; this.bsqFormatter = bsqFormatter; this.btcFormatter = btcFormatter; - this.navigation = navigation; } @Override @@ -123,23 +148,46 @@ public void initialize() { super.initialize(); root.getStyleClass().add("vote-root"); - detailsGridPane = new GridPane(); + proposalDisplayGridPane = new GridPane(); + createProposalsTableView(); createEmptyProposalDisplay(); + createVoteView(); + + ballotListChangeListener = c -> updateListItems(); + proposalListChangeListener = c -> updateListItems(); - listChangeListener = c -> updateListItems(); + // ballot + stakeListener = (observable, oldValue, newValue) -> updateButtonStates(); } @Override protected void activate() { phaseSubscription = EasyBind.subscribe(daoFacade.phaseProperty(), this::onPhaseChanged); - selectedProposalSubscription = EasyBind.subscribe(proposalTableView.getSelectionModel().selectedItemProperty(), this::onSelectProposal); + selectedProposalSubscription = EasyBind.subscribe(tableView.getSelectionModel().selectedItemProperty(), this::onSelectProposal); - sortedList.comparatorProperty().bind(proposalTableView.comparatorProperty()); + sortedList.comparatorProperty().bind(tableView.comparatorProperty()); - updateListItems(); + daoFacade.getActiveOrMyUnconfirmedProposals().addListener(proposalListChangeListener); + daoFacade.getValidAndConfirmedBallots().addListener(ballotListChangeListener); - getProposals().addListener(listChangeListener); + stakeInputTextField.textProperty().addListener(stakeListener); + bsqWalletService.addBsqBalanceListener(this); + + onUpdateBalances(bsqWalletService.getAvailableBalance(), + bsqWalletService.getAvailableNonBsqBalance(), + bsqWalletService.getUnverifiedBalance(), + bsqWalletService.getLockedForVotingBalance(), + bsqWalletService.getLockupBondsBalance(), + bsqWalletService.getUnlockingBondsBalance()); + + voteButton.setOnAction(e -> onVote()); + + daoFacade.addBsqStateListener(this); + + updateListItems(); + updateButtonStates(); + stakeInputTextField.setText(""); } @Override @@ -149,11 +197,66 @@ protected void deactivate() { sortedList.comparatorProperty().unbind(); - proposalBaseProposalListItems.forEach(OpenProposalListItem::cleanup); - proposalTableView.getSelectionModel().clearSelection(); - selectedBaseProposalListItem = null; + listItems.forEach(OpenProposalListItem::cleanup); + tableView.getSelectionModel().clearSelection(); + selectedItem = null; + + daoFacade.getActiveOrMyUnconfirmedProposals().removeListener(proposalListChangeListener); + daoFacade.getValidAndConfirmedBallots().removeListener(ballotListChangeListener); - getProposals().removeListener(listChangeListener); + stakeInputTextField.textProperty().removeListener(stakeListener); + bsqWalletService.removeBsqBalanceListener(this); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // BsqBalanceListener + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public void onUpdateBalances(Coin confirmedBalance, + Coin availableNonBsqBalance, + Coin pendingBalance, + Coin lockedForVotingBalance, + Coin lockupBondsBalance, + Coin unlockingBondsBalance) { + if (isBlindVotePhase()) + stakeInputTextField.setPromptText(Res.get("dao.proposal.myVote.stake.prompt", + bsqFormatter.formatCoinWithCode(confirmedBalance))); + else + stakeInputTextField.setPromptText(""); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // BsqStateListener + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public void onNewBlockHeight(int blockHeight) { + } + + @Override + public void onEmptyBlockAdded(Block block) { + } + + @Override + public void onParseTxsComplete(Block block) { + stakeInputTextField.setText(""); + updateButtonStates(); + } + + @Override + public void onParseBlockChainComplete() { + GUIUtil.setFitToRowsForTableView(tableView, 33, 28, 80); + + // hack to get layout correct + if (!tableView.getItems().isEmpty()) { + onSelectProposal(tableView.getItems().get(0)); + onSelectProposal(null); + } + + updateListItems(); } @@ -161,17 +264,31 @@ protected void deactivate() { // Protected /////////////////////////////////////////////////////////////////////////////////////////// - private ObservableList getProposals() { - return daoFacade.getActiveOrMyUnconfirmedProposals(); + private void fillListItems() { + if (daoFacade.phaseProperty().get().ordinal() < DaoPhase.Phase.BLIND_VOTE.ordinal()) { + // proposal phase + List list = daoFacade.getActiveOrMyUnconfirmedProposals(); + listItems.setAll(list.stream() + .map(proposal -> new OpenProposalListItem(proposal, daoFacade, bsqWalletService, bsqFormatter)) + .collect(Collectors.toSet())); + } else { + // blind vote phase + List ballotList = daoFacade.getValidAndConfirmedBallots(); + listItems.setAll(ballotList.stream() + .map(ballot -> new OpenProposalListItem(ballot, daoFacade, bsqWalletService, bsqFormatter)) + .collect(Collectors.toSet())); + } + + updateButtonStates(); } private void updateListItems() { - proposalBaseProposalListItems.forEach(OpenProposalListItem::cleanup); - proposalBaseProposalListItems.clear(); + listItems.forEach(OpenProposalListItem::cleanup); + listItems.clear(); fillListItems(); - if (proposalBaseProposalListItems.isEmpty()) + if (listItems.isEmpty()) hideProposalDisplay(); } @@ -185,9 +302,28 @@ private void createAllFieldsOnProposalDisplay(Proposal proposal) { proposalDisplay.applyProposalPayload(proposal); proposalDisplayInitialized = true; - button = addButtonAfterGroup(detailsGridPane, proposalDisplay.incrementAndGetGridRow(), ""); - button.setOnAction(event -> onButtonClick()); + removeProposalButton = addButtonAfterGroup(proposalDisplayGridPane, proposalDisplay.incrementAndGetGridRow(), Res.get("shared.remove")); + removeProposalButton.setOnAction(event -> onRemoveProposal()); onPhaseChanged(daoFacade.phaseProperty().get()); + + Tuple3 tuple = add3ButtonsAfterGroup(proposalDisplayGridPane, + proposalDisplay.incrementAndGetGridRow(), + Res.get("dao.proposal.myVote.accept"), + Res.get("dao.proposal.myVote.reject"), + Res.get("dao.proposal.myVote.removeMyVote")); + acceptButton = tuple.first; + acceptButton.setDefaultButton(false); + rejectButton = tuple.second; + ignoreButton = tuple.third; + acceptButton.setOnAction(event -> onAccept()); + rejectButton.setOnAction(event -> onReject()); + ignoreButton.setOnAction(event -> onCancelVote()); + + voteControls.clear(); + voteControls.add(voteButton); + voteControls.add(acceptButton); + voteControls.add(rejectButton); + voteControls.add(ignoreButton); } private void hideProposalDisplay() { @@ -196,73 +332,204 @@ private void hideProposalDisplay() { proposalDisplayView.setVisible(false); proposalDisplayView.setManaged(false); } - if (button != null) { - button.setManaged(false); - button.setVisible(false); + if (removeProposalButton != null) { + removeProposalButton.setManaged(false); + removeProposalButton.setVisible(false); } - } - private void fillListItems() { - List list = getProposals(); - proposalBaseProposalListItems.setAll(list.stream() - .map(proposal -> new OpenProposalListItem(proposal, daoFacade, bsqWalletService, bsqFormatter)) - .collect(Collectors.toSet())); + if (acceptButton != null) { + acceptButton.setManaged(false); + acceptButton.setVisible(false); + } + if (rejectButton != null) { + rejectButton.setManaged(false); + rejectButton.setVisible(false); + } + if (ignoreButton != null) { + ignoreButton.setManaged(false); + ignoreButton.setVisible(false); + } } + /////////////////////////////////////////////////////////////////////////////////////////// + // Handlers + /////////////////////////////////////////////////////////////////////////////////////////// + private void onPhaseChanged(DaoPhase.Phase phase) { if (phase != null && !phase.equals(currentPhase)) { currentPhase = phase; - onSelectProposal(selectedBaseProposalListItem); + onSelectProposal(selectedItem); } - if (button != null) { + if (removeProposalButton != null) { //noinspection IfCanBeSwitch,IfCanBeSwitch,IfCanBeSwitch if (phase == DaoPhase.Phase.PROPOSAL) { - if (selectedBaseProposalListItem != null && selectedBaseProposalListItem.getProposal() != null) { - button.setText(Res.get("shared.remove")); - final boolean isMyProposal = daoFacade.isMyProposal(selectedBaseProposalListItem.getProposal()); - button.setVisible(isMyProposal); - button.setManaged(isMyProposal); + if (selectedItem != null && selectedItem.getProposal() != null) { + final boolean isMyProposal = daoFacade.isMyProposal(selectedItem.getProposal()); + removeProposalButton.setVisible(isMyProposal); + removeProposalButton.setManaged(isMyProposal); } - } else if (phase == DaoPhase.Phase.BLIND_VOTE) { - button.setText(Res.get("dao.proposal.active.vote")); - button.setVisible(true); - button.setManaged(true); } else { - button.setVisible(false); - button.setManaged(false); + removeProposalButton.setVisible(false); + removeProposalButton.setManaged(false); } } - } + updateButtonStates(); - /////////////////////////////////////////////////////////////////////////////////////////// - // Handlers - /////////////////////////////////////////////////////////////////////////////////////////// + boolean isBlindVotePhaseOrLater = daoFacade.phaseProperty().get().ordinal() >= DaoPhase.Phase.BLIND_VOTE.ordinal(); + voteTitledGroupBg.setVisible(isBlindVotePhaseOrLater); + voteTitledGroupBg.setManaged(isBlindVotePhaseOrLater); + stakeLabel.setVisible(isBlindVotePhaseOrLater); + stakeLabel.setManaged(isBlindVotePhaseOrLater); + stakeInputTextField.setVisible(isBlindVotePhaseOrLater); + stakeInputTextField.setManaged(isBlindVotePhaseOrLater); + } - private void onButtonClick() { + private void onRemoveProposal() { if (daoFacade.phaseProperty().get() == DaoPhase.Phase.PROPOSAL) { - final Proposal proposal = selectedBaseProposalListItem.getProposal(); + final Proposal proposal = selectedItem.getProposal(); if (daoFacade.removeMyProposal(proposal)) { hideProposalDisplay(); } else { new Popup<>().warning(Res.get("dao.proposal.active.remove.failed")).show(); } - proposalTableView.getSelectionModel().clearSelection(); - } else if (daoFacade.phaseProperty().get() == DaoPhase.Phase.BLIND_VOTE) { - navigation.navigateTo(MainView.class, DaoView.class, VotingView.class, ActiveBallotsView.class); + tableView.getSelectionModel().clearSelection(); } } private void onSelectProposal(OpenProposalListItem item) { - selectedBaseProposalListItem = item; - if (selectedBaseProposalListItem != null) - createAllFieldsOnProposalDisplay(selectedBaseProposalListItem.getProposal()); + selectedItem = item; + if (selectedItem != null) + createAllFieldsOnProposalDisplay(selectedItem.getProposal()); else hideProposalDisplay(); onPhaseChanged(daoFacade.phaseProperty().get()); + + updateButtonStates(); + } + + private void onAccept() { + daoFacade.setVote(getBallotListItem().getBallot(), new BooleanVote(true)); + updateStateAfterVote(); + } + + private void onReject() { + daoFacade.setVote(getBallotListItem().getBallot(), new BooleanVote(false)); + updateStateAfterVote(); + } + + private void onCancelVote() { + daoFacade.setVote(getBallotListItem().getBallot(), null); + updateStateAfterVote(); + } + + private void onVote() { + // TODO verify stake + Coin stake = bsqFormatter.parseToCoin(stakeInputTextField.getText()); + final Coin blindVoteFee = daoFacade.getBlindVoteFeeForCycle(); + Transaction dummyTx = null; + try { + // We create a dummy tx to get the mining blindVoteFee for confirmation popup + dummyTx = daoFacade.getDummyBlindVoteTx(stake, blindVoteFee); + } catch (InsufficientMoneyException | WalletException | TransactionVerificationException exception) { + new Popup<>().warning(exception.toString()).show(); + } + + if (dummyTx != null) { + Coin miningFee = dummyTx.getFee(); + int txSize = dummyTx.bitcoinSerialize().length; + GUIUtil.showBsqFeeInfoPopup(blindVoteFee, miningFee, txSize, bsqFormatter, btcFormatter, + Res.get("dao.blindVote"), () -> publishBlindVote(stake)); + } + } + + private void publishBlindVote(Coin stake) { + voteButtonBusyAnimation.play(); + voteButtonInfoLabel.setText(Res.get("dao.blindVote.startPublishing")); + daoFacade.publishBlindVote(stake, + () -> { + voteButtonBusyAnimation.stop(); + voteButtonInfoLabel.setText(""); + new Popup().feedback(Res.get("dao.blindVote.success")) + .show(); + }, exception -> { + voteButtonBusyAnimation.stop(); + voteButtonInfoLabel.setText(""); + new Popup<>().warning(exception.toString()).show(); + }); + } + + + private void updateStateAfterVote() { + updateButtonStates(); + //hideProposalDisplay(); + //proposalTableView.getSelectionModel().clearSelection(); + tableView.refresh(); + } + + private OpenProposalListItem getBallotListItem() { + return selectedItem; + } + + private void updateButtonStates() { + boolean isBlindVotePhase = isBlindVotePhase(); + voteControls.forEach(control -> { + control.setVisible(isBlindVotePhase); + control.setManaged(isBlindVotePhase); + }); + + boolean hasVoted = listItems.stream() + .filter(e -> e.getBallot() != null) + .map(OpenProposalListItem::getBallot) + .anyMatch(e -> e.getVote() != null); + voteButton.setDisable(!hasVoted || + !stakeInputTextField.getValidator().validate(stakeInputTextField.getText()).isValid); + + List myVoteListForCycle = daoFacade.getMyVoteListForCycle(); + boolean hasAlreadyVoted = !myVoteListForCycle.isEmpty(); + if (isBlindVotePhase && selectedItem != null && acceptButton != null) { + Optional optionalVote = selectedItem.getBooleanVote(); + boolean isPresent = optionalVote.isPresent(); + boolean isAccepted = isPresent && optionalVote.get().isAccepted(); + boolean isBlindVotePhaseButNotLastBlock = isBlindVotePhaseButNotLastBlock(); + boolean doDisable = hasAlreadyVoted || !isBlindVotePhaseButNotLastBlock; + acceptButton.setDisable(doDisable || (isPresent && isAccepted)); + rejectButton.setDisable(doDisable || (isPresent && !isAccepted)); + ignoreButton.setDisable(doDisable || !isPresent); + stakeInputTextField.setDisable(doDisable); + } else { + stakeInputTextField.setDisable(true); + } + + if (hasAlreadyVoted) { + voteTitledGroupBg.setText(Res.get("dao.proposal.votes.header.voted")); + if (myVoteListForCycle.size() == 1) { + myVoteListForCycle.stream().findAny() + .ifPresent(myVote -> { + Coin stake = Coin.valueOf(myVote.getBlindVote().getStake()); + stakeInputTextField.setText(bsqFormatter.formatCoinWithCode(stake)); + }); + } else { + String msg = "We found multiple MyVote entries in that cycle. That is not supported by the UI."; + log.warn(msg); + new Popup<>().error(msg).show(); + } + voteButton.setVisible(false); + voteButton.setManaged(false); + + } + } + + private boolean isBlindVotePhase() { + return daoFacade.phaseProperty().get() == DaoPhase.Phase.BLIND_VOTE; + } + + private boolean isBlindVotePhaseButNotLastBlock() { + int getLastBlockOfBlindVotePhase = daoFacade.getLastBlockOfPhase(daoFacade.getChainHeight(), DaoPhase.Phase.BLIND_VOTE); + return isBlindVotePhase() && daoFacade.getChainHeight() < getLastBlockOfBlindVotePhase; } @@ -271,52 +538,65 @@ private void onSelectProposal(OpenProposalListItem item) { /////////////////////////////////////////////////////////////////////////////////////////// private void createProposalsTableView() { - createProposalsTableView(Res.get("dao.proposal.active.header"), -10); - } - - private void createProposalsTableView(String header, double top) { - TableGroupHeadline proposalsHeadline = new TableGroupHeadline(header); - GridPane.setRowIndex(proposalsHeadline, ++gridRow); - GridPane.setMargin(proposalsHeadline, new Insets(top, -10, -10, -10)); + TableGroupHeadline proposalsHeadline = new TableGroupHeadline(Res.get("dao.proposal.active.header")); + GridPane.setRowIndex(proposalsHeadline, gridRow); + GridPane.setMargin(proposalsHeadline, new Insets(0, -10, -10, -10)); GridPane.setColumnSpan(proposalsHeadline, 2); root.getChildren().add(proposalsHeadline); - proposalTableView = new TableView<>(); - proposalTableView.setPlaceholder(new AutoTooltipLabel(Res.get("table.placeholder.noData"))); - proposalTableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); - proposalTableView.setPrefHeight(200); + tableView = new TableView<>(); + tableView.setPlaceholder(new AutoTooltipLabel(Res.get("table.placeholder.noData"))); + tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); + tableView.setMinHeight(80); + tableView.setMaxHeight(80); - createProposalColumns(proposalTableView); - GridPane.setRowIndex(proposalTableView, gridRow); - GridPane.setMargin(proposalTableView, new Insets(top + 20, -10, 5, -10)); - GridPane.setColumnSpan(proposalTableView, 2); - GridPane.setHgrow(proposalTableView, Priority.ALWAYS); - root.getChildren().add(proposalTableView); + createProposalColumns(); + GridPane.setRowIndex(tableView, gridRow); + GridPane.setHgrow(tableView, Priority.ALWAYS); + GridPane.setMargin(tableView, new Insets(20, -10, 5, -10)); + GridPane.setColumnSpan(tableView, 2); + root.getChildren().add(tableView); - proposalTableView.setItems(sortedList); + tableView.setItems(sortedList); } private void createEmptyProposalDisplay() { - proposalDisplay = new ProposalDisplay(detailsGridPane, bsqFormatter, bsqWalletService, daoFacade); + proposalDisplay = new ProposalDisplay(proposalDisplayGridPane, bsqFormatter, bsqWalletService, daoFacade); proposalDisplayView = proposalDisplay.getView(); - GridPane.setMargin(proposalDisplayView, new Insets(10, -10, 0, -10)); + GridPane.setMargin(proposalDisplayView, new Insets(0, -10, 0, -10)); GridPane.setRowIndex(proposalDisplayView, ++gridRow); GridPane.setColumnSpan(proposalDisplayView, 2); + GridPane.setHgrow(proposalDisplayView, Priority.ALWAYS); root.getChildren().add(proposalDisplayView); } + private void createVoteView() { + voteTitledGroupBg = addTitledGroupBg(root, ++gridRow, 1, + Res.get("dao.proposal.votes.header"), Layout.GROUP_DISTANCE - 20); + Tuple2 tuple2 = addLabelInputTextField(root, gridRow, + Res.getWithCol("dao.proposal.myVote.stake"), Layout.FIRST_ROW_AND_GROUP_DISTANCE - 20); + stakeLabel = tuple2.first; + stakeInputTextField = tuple2.second; + stakeInputTextField.setValidator(new BsqValidator(bsqFormatter)); + + Tuple3 tuple = addButtonBusyAnimationLabelAfterGroup(root, ++gridRow, + Res.get("dao.proposal.myVote.button")); + voteButton = tuple.first; + voteControls.add(voteButton); + voteButtonBusyAnimation = tuple.second; + voteButtonInfoLabel = tuple.third; + } + /////////////////////////////////////////////////////////////////////////////////////////// // TableColumns /////////////////////////////////////////////////////////////////////////////////////////// - private void createProposalColumns(TableView tableView) { - TableColumn dateColumn = new AutoTooltipTableColumn(Res.get("shared.dateTime")) { - { - setMinWidth(190); - setMaxWidth(190); - } - }; + private void createProposalColumns() { + TableColumn dateColumn = new AutoTooltipTableColumn(Res.get("shared.dateTime")); + dateColumn.setMinWidth(190); + dateColumn.setMinWidth(190); + dateColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); dateColumn.setCellFactory( new Callback, TableCell nameColumn = new AutoTooltipTableColumn<>(Res.get("shared.name")); + nameColumn.setMinWidth(60); nameColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); nameColumn.setCellFactory( new Callback, TableCell uidColumn = new AutoTooltipTableColumn<>(Res.get("shared.id")); + uidColumn.setMinWidth(60); uidColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); uidColumn.setCellFactory( new Callback, TableCell confidenceColumn = new TableColumn<>(Res.get("shared.confirmations")); confidenceColumn.setMinWidth(130); confidenceColumn.setMaxWidth(confidenceColumn.getMinWidth()); - confidenceColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - confidenceColumn.setCellFactory(new Callback, TableCell>() { @@ -433,9 +713,7 @@ public void updateItem(final OpenProposalListItem item, boolean empty) { TableColumn actionColumn = new TableColumn<>(); actionColumn.setMinWidth(130); actionColumn.setMaxWidth(actionColumn.getMinWidth()); - actionColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - actionColumn.setCellFactory(new Callback, TableCell>() { @@ -443,36 +721,27 @@ public void updateItem(final OpenProposalListItem item, boolean empty) { public TableCell call(TableColumn column) { return new TableCell() { - Button button; + ImageView imageView; @Override public void updateItem(final OpenProposalListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { - OpenProposalListItem openProposalListItem = item; - if (button == null) { - button = openProposalListItem.getButton(); - button.setOnAction(e -> { - OpenProposalsView.this.selectedBaseProposalListItem = item; - OpenProposalsView.this.onButtonClick(); - }); - setGraphic(button); + if (imageView == null) { + imageView = item.getImageView(); + setGraphic(imageView); } - openProposalListItem.onPhaseChanged(currentPhase); + item.onPhaseChanged(currentPhase); } else { setGraphic(null); - if (button != null) { - button.setOnAction(null); - button = null; - } + if (imageView != null) + imageView = null; } } }; } }); - actionColumn.setComparator(Comparator.comparing(OpenProposalListItem::getConfirmations)); tableView.getColumns().add(actionColumn); } } - diff --git a/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java b/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java index 41df1372bf6..f0a2d5b50eb 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java @@ -329,7 +329,6 @@ private void handleError(Throwable t) { if (t instanceof InsufficientMoneyException) { final Coin missingCoin = ((InsufficientMoneyException) t).missing; final String missing = missingCoin != null ? missingCoin.toFriendlyString() : "null"; - //noinspection unchecked new Popup<>().warning(Res.get("popup.warning.insufficientBtcFundsForBsqTx", missing)) .actionButtonTextWithGoTo("navigation.funds.depositFunds") .onAction(() -> navigation.navigateTo(MainView.class, FundsView.class, DepositView.class)) diff --git a/src/main/java/bisq/desktop/util/GUIUtil.java b/src/main/java/bisq/desktop/util/GUIUtil.java index 18168075685..ceed04e2458 100644 --- a/src/main/java/bisq/desktop/util/GUIUtil.java +++ b/src/main/java/bisq/desktop/util/GUIUtil.java @@ -583,6 +583,8 @@ public static void showBsqFeeInfoPopup(Coin fee, Coin miningFee, int txSize, Bsq public static void setFitToRowsForTableView(TableView tableView, int rowHeight, int headerHeight, int minHeight) { int size = tableView.getItems().size(); int height = Math.max(minHeight, size * rowHeight + headerHeight); + tableView.setMaxHeight(-1); + tableView.setMinHeight(-1); tableView.setMaxHeight(height); tableView.setMinHeight(height); } From d28205d96088f74157dc50fd7f8ecb601c375d50 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Thu, 2 Aug 2018 11:24:34 +0200 Subject: [PATCH 173/197] Fix screen update --- .../main/dao/proposal/open/OpenProposalsView.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/open/OpenProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/open/OpenProposalsView.java index 8b230ec86b8..2490a223d21 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/open/OpenProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/open/OpenProposalsView.java @@ -248,7 +248,7 @@ public void onParseTxsComplete(Block block) { @Override public void onParseBlockChainComplete() { - GUIUtil.setFitToRowsForTableView(tableView, 33, 28, 80); + GUIUtil.setFitToRowsForTableView(tableView, 34, 28, 80); // hack to get layout correct if (!tableView.getItems().isEmpty()) { @@ -280,6 +280,14 @@ private void fillListItems() { } updateButtonStates(); + + GUIUtil.setFitToRowsForTableView(tableView, 33, 28, 80); + + // hack to get layout correct + if (!tableView.getItems().isEmpty()) { + onSelectProposal(tableView.getItems().get(0)); + onSelectProposal(null); + } } private void updateListItems() { From 608e80965b63174f1c1d97a2810c9ec5d0099d53 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sat, 4 Aug 2018 22:07:41 +0200 Subject: [PATCH 174/197] Improve proposal and voting views --- src/main/java/bisq/desktop/bisq.css | 159 +++++------ .../bisq/desktop/components/MenuItem.java | 7 +- .../components/SeparatedPhaseBars.java | 68 +++-- .../desktop/components/TxIdTextField.java | 36 +-- .../main/dao/proposal/CycleOverview.java | 151 ++++++++++ .../main/dao/proposal/ProposalDisplay.java | 21 +- .../main/dao/proposal/ProposalView.java | 30 +- .../dashboard/ProposalDashboardView.java | 77 +----- .../dao/proposal/make/MakeProposalView.java | 48 ++-- .../proposal/open/OpenProposalListItem.java | 55 ++-- .../dao/proposal/open/OpenProposalsView.java | 259 +++++++++++------- .../combo/VotesPerProposalListItem.java | 6 +- .../proposals/ProposalResultsListItem.java | 2 +- .../VoteResultsForProposalListItem.java | 6 +- .../voting/dashboard/VotingDashboardView.java | 5 +- .../desktop/main/dao/wallet/tx/BsqTxView.java | 2 +- 16 files changed, 549 insertions(+), 383 deletions(-) create mode 100644 src/main/java/bisq/desktop/main/dao/proposal/CycleOverview.java diff --git a/src/main/java/bisq/desktop/bisq.css b/src/main/java/bisq/desktop/bisq.css index 7582f5b45c6..a293366c8c6 100644 --- a/src/main/java/bisq/desktop/bisq.css +++ b/src/main/java/bisq/desktop/bisq.css @@ -326,83 +326,6 @@ bg color of non edit textFields: fafafa -fx-text-fill: -bs-red-soft; } -.dao-tx-type-trade-fee-icon, -.dao-tx-type-trade-fee-icon:hover { - -fx-text-fill: #689f43; -} - -.dao-tx-type-unverified-icon, -.dao-tx-type-unverified-icon:hover { - -fx-text-fill: #ffac00; -} - -.dao-tx-type-invalid-icon, -.dao-tx-type-invalid-icon:hover { - -fx-text-fill: #ff4500; -} - -.dao-tx-type-self-icon, -.dao-tx-type-self-icon:hover { - -fx-text-fill: #818181; -} - -.dao-tx-type-proposal-fee-icon, -.dao-tx-type-proposal-fee-icon:hover { - -fx-text-fill: #6c8b3b; -} - -.dao-tx-type-genesis-icon, -.dao-tx-type-genesis-icon:hover { - -fx-text-fill: -fx-accent; -} - -.dao-tx-type-received-funds-icon, -.dao-tx-type-received-funds-icon:hover { - -fx-text-fill: -bs-green-soft; -} - -.dao-tx-type-sent-funds-icon, -.dao-tx-type-sent-funds-icon:hover { - -fx-text-fill: -bs-red-soft; -} - -.dao-tx-type-vote-icon, -.dao-tx-type-vote-icon:hover { - -fx-text-fill: #0a4576; -} - -.dao-tx-type-vote-reveal-icon, -.dao-tx-type-vote-reveal-icon:hover { - -fx-text-fill: #4AC5FF; -} - -.dao-tx-type-issuance-icon, -.dao-tx-type-issuance-icon:hover { - -fx-text-fill: #04a908; -} - -.dao-tx-type-lockup-icon, -.dao-tx-type-lockup-icon:hover { - -fx-text-fill: #203e7f; -} - -.dao-tx-type-unlock-icon, -.dao-tx-type-unlock-icon:hover { - -fx-text-fill: #438e6c; -} - -.dao-accepted-icon { - -fx-text-fill: -bs-green; -} - -.dao-rejected-icon { - -fx-text-fill: -bs-error-red; -} - -.dao-ignored-icon { - -fx-text-fill: -bs-medium-grey; -} - .version { -fx-text-fill: black; -fx-underline: false; @@ -1358,6 +1281,83 @@ textfield */ * * ********************************************************************************************************************/ +.dao-tx-type-trade-fee-icon, +.dao-tx-type-trade-fee-icon:hover { + -fx-text-fill: #689f43; +} + +.dao-tx-type-unverified-icon, +.dao-tx-type-unverified-icon:hover { + -fx-text-fill: #ffac00; +} + +.dao-tx-type-invalid-icon, +.dao-tx-type-invalid-icon:hover { + -fx-text-fill: #ff4500; +} + +.dao-tx-type-self-icon, +.dao-tx-type-self-icon:hover { + -fx-text-fill: #818181; +} + +.dao-tx-type-proposal-fee-icon, +.dao-tx-type-proposal-fee-icon:hover { + -fx-text-fill: #6c8b3b; +} + +.dao-tx-type-genesis-icon, +.dao-tx-type-genesis-icon:hover { + -fx-text-fill: -fx-accent; +} + +.dao-tx-type-received-funds-icon, +.dao-tx-type-received-funds-icon:hover { + -fx-text-fill: -bs-green-soft; +} + +.dao-tx-type-sent-funds-icon, +.dao-tx-type-sent-funds-icon:hover { + -fx-text-fill: -bs-red-soft; +} + +.dao-tx-type-vote-icon, +.dao-tx-type-vote-icon:hover { + -fx-text-fill: #0a4576; +} + +.dao-tx-type-vote-reveal-icon, +.dao-tx-type-vote-reveal-icon:hover { + -fx-text-fill: #4AC5FF; +} + +.dao-tx-type-issuance-icon, +.dao-tx-type-issuance-icon:hover { + -fx-text-fill: #04a908; +} + +.dao-tx-type-lockup-icon, +.dao-tx-type-lockup-icon:hover { + -fx-text-fill: #203e7f; +} + +.dao-tx-type-unlock-icon, +.dao-tx-type-unlock-icon:hover { + -fx-text-fill: #438e6c; +} + +.dao-accepted-icon { + -fx-text-fill: -bs-green; +} + +.dao-rejected-icon { + -fx-text-fill: -bs-error-red; +} + +.dao-ignored-icon { + -fx-text-fill: -bs-medium-grey; +} + .compensation-root { -fx-background-insets: 0, 0 0 0 0 } @@ -1371,6 +1371,11 @@ textfield */ -fx-background-color: transparent; } +.dao-remove-proposal-icon { + -fx-text-fill: -fx-accent; +} + + /* .vote-result-table-row-accepted { -fx-background-color: rgba(0, 255, 0, 0.4); diff --git a/src/main/java/bisq/desktop/components/MenuItem.java b/src/main/java/bisq/desktop/components/MenuItem.java index 353df7e9635..1cb87270aee 100644 --- a/src/main/java/bisq/desktop/components/MenuItem.java +++ b/src/main/java/bisq/desktop/components/MenuItem.java @@ -57,7 +57,7 @@ public MenuItem(Navigation navigation, this.baseNavPath = baseNavPath; setToggleGroup(toggleGroup); - setText(title); + setLabelText(title); setId("account-settings-item-background-active"); setPrefHeight(40); setPrefWidth(240); @@ -109,9 +109,14 @@ private Class[] getNavPathClasses() { list.toArray(array); return array; } + public void deactivate() { setOnAction(null); selectedProperty().removeListener(selectedPropertyChangeListener); disableProperty().removeListener(disablePropertyChangeListener); } + + public void setLabelText(String value) { + setText(value); + } } diff --git a/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java b/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java index 4d9e5ddf262..ac6e1f999bc 100644 --- a/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java +++ b/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java @@ -22,11 +22,9 @@ import javafx.scene.control.Label; import javafx.scene.control.ProgressBar; -import javafx.scene.layout.AnchorPane; import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; -import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.beans.property.DoubleProperty; @@ -35,6 +33,7 @@ import javafx.beans.property.SimpleIntegerProperty; import java.util.List; +import java.util.concurrent.atomic.AtomicReference; import lombok.Getter; import lombok.Setter; @@ -42,10 +41,10 @@ @Slf4j public class SeparatedPhaseBars extends VBox { - + private double labelMinWidth = 150; + private double breakMinWidth = 20; private int totalDuration; private List items; - private VBox vBoxLabels; public SeparatedPhaseBars(List items) { this.items = items; @@ -60,8 +59,7 @@ public SeparatedPhaseBars(List items) { getChildren().add(progressBars); items.forEach(item -> { - Label titleLabel = new Label(Res.get("dao.phase.short." + item.phase)); - titleLabel.setMinWidth(10); + Label titleLabel = new Label(Res.get("dao.phase.separatedPhaseBar." + item.phase)); titleLabel.setEllipsisString(""); titleLabel.setAlignment(Pos.CENTER); item.setTitleLabel(titleLabel); @@ -70,7 +68,6 @@ public SeparatedPhaseBars(List items) { ProgressBar progressBar = new ProgressBar(); progressBar.setMinHeight(9); progressBar.setMaxHeight(9); - progressBar.setMinWidth(10); progressBar.setStyle("-fx-accent: -bs-green;"); progressBar.progressProperty().bind(item.progressProperty); progressBar.setOpacity(item.isShowBlocks() ? 1 : 0.25); @@ -87,41 +84,42 @@ public void updateWidth() { updateWidth(getWidth()); } - private void addLabels() { - Label titleLabel = new Label(Res.get("dao.proposal.active.phase")); - - Label startLabel = new Label(Res.get("dao.proposal.active.startBlock")); - AnchorPane startLabelPane = new AnchorPane(); - AnchorPane.setLeftAnchor(startLabel, 0d); - startLabelPane.getChildren().add(startLabel); - - Label endLabel = new Label(Res.get("dao.proposal.active.endBlock")); - AnchorPane endLabelPane = new AnchorPane(); - AnchorPane.setRightAnchor(endLabel, 0d); - endLabelPane.getChildren().add(endLabel); - - ProgressBar progressBar = new ProgressBar(); - progressBar.setMinHeight(9); - progressBar.setMaxHeight(9); - progressBar.setVisible(false); - - vBoxLabels = new VBox(); - vBoxLabels.setSpacing(5); - vBoxLabels.getChildren().addAll(titleLabel, progressBar, startLabelPane, endLabelPane); - vBoxLabels.setAlignment(Pos.CENTER); - vBoxLabels.setPadding(new Insets(0, 10, 0, 0)); - getChildren().add(vBoxLabels); - } - private void updateWidth(double availableWidth) { if (availableWidth > 0) { totalDuration = items.stream().mapToInt(SeparatedPhaseBarsItem::getDuration).sum(); if (totalDuration > 0) { + // We want to have a min. width for the breaks and for the phases which are important to the user but + // quite short (blind vote, vote reveal, result). If we display it correctly most of the space is + // consumed by the proposal phase. We we apply a min and max width and adjust the available width so + // we have all phases displayed so that the text is fully readable. The proposal phase is shorter as + // it would be with correct display but we take that into account to have a better overall overview. final double finalAvailableWidth = availableWidth; + AtomicReference adjustedAvailableWidth = new AtomicReference<>(availableWidth); items.forEach(item -> { - final double width = (double) item.duration / (double) totalDuration * finalAvailableWidth; - item.getProgressBar().setPrefWidth(width); + double calculatedWidth = (double) item.duration / (double) totalDuration * finalAvailableWidth; + double minWidth = item.phase.name().startsWith("BREAK") ? breakMinWidth : labelMinWidth; + double maxWidth = item.phase.name().startsWith("BREAK") ? breakMinWidth : calculatedWidth; + if (calculatedWidth < minWidth) { + double missing = minWidth - calculatedWidth; + adjustedAvailableWidth.set(adjustedAvailableWidth.get() - missing); + } else if (calculatedWidth > maxWidth) { + double remaining = calculatedWidth - maxWidth; + adjustedAvailableWidth.set(adjustedAvailableWidth.get() + remaining); + } + }); + + items.forEach(item -> { + double calculatedWidth = (double) item.duration / (double) totalDuration * adjustedAvailableWidth.get(); + double minWidth = item.phase.name().startsWith("BREAK") ? breakMinWidth : labelMinWidth; + double maxWidth = item.phase.name().startsWith("BREAK") ? breakMinWidth : calculatedWidth; + double width = calculatedWidth; + if (calculatedWidth < minWidth) { + width = minWidth; + } else if (calculatedWidth > maxWidth) { + width = maxWidth; + } item.getTitleLabel().setPrefWidth(width); + item.getProgressBar().setPrefWidth(width); }); } } diff --git a/src/main/java/bisq/desktop/components/TxIdTextField.java b/src/main/java/bisq/desktop/components/TxIdTextField.java index b847d67fb7b..851f2cfce60 100644 --- a/src/main/java/bisq/desktop/components/TxIdTextField.java +++ b/src/main/java/bisq/desktop/components/TxIdTextField.java @@ -23,6 +23,7 @@ import bisq.core.btc.listeners.TxConfidenceListener; import bisq.core.btc.wallet.BtcWalletService; import bisq.core.locale.Res; +import bisq.core.user.BlockChainExplorer; import bisq.core.user.Preferences; import bisq.common.util.Utilities; @@ -37,12 +38,9 @@ import javafx.scene.control.Tooltip; import javafx.scene.layout.AnchorPane; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import lombok.Setter; public class TxIdTextField extends AnchorPane { - private static final Logger log = LoggerFactory.getLogger(TxIdTextField.class); - private static Preferences preferences; public static void setPreferences(Preferences preferences) { @@ -61,6 +59,8 @@ public static void setWalletService(BtcWalletService walletService) { private final Label copyIcon; private final Label blockExplorerIcon; private TxConfidenceListener txConfidenceListener; + @Setter + private boolean isBsq; /////////////////////////////////////////////////////////////////////////////////////////// @@ -70,12 +70,13 @@ public static void setWalletService(BtcWalletService walletService) { public TxIdTextField() { txConfidenceIndicator = new TxConfidenceIndicator(); txConfidenceIndicator.setFocusTraversable(false); - txConfidenceIndicator.setPrefSize(24, 24); + txConfidenceIndicator.setMaxSize(20, 20); txConfidenceIndicator.setId("funds-confidence"); txConfidenceIndicator.setLayoutY(1); txConfidenceIndicator.setProgress(0); txConfidenceIndicator.setVisible(false); AnchorPane.setRightAnchor(txConfidenceIndicator, 0.0); + AnchorPane.setTopAnchor(txConfidenceIndicator, 3.0); progressIndicatorTooltip = new Tooltip("-"); txConfidenceIndicator.setTooltip(progressIndicatorTooltip); @@ -106,23 +107,23 @@ public TxIdTextField() { getChildren().addAll(textField, copyIcon, blockExplorerIcon, txConfidenceIndicator); } - public void setup(String txID) { + public void setup(String txId) { if (txConfidenceListener != null) walletService.removeTxConfidenceListener(txConfidenceListener); - txConfidenceListener = new TxConfidenceListener(txID) { + txConfidenceListener = new TxConfidenceListener(txId) { @Override public void onTransactionConfidenceChanged(TransactionConfidence confidence) { updateConfidence(confidence); } }; walletService.addTxConfidenceListener(txConfidenceListener); - updateConfidence(walletService.getConfidenceForTxId(txID)); + updateConfidence(walletService.getConfidenceForTxId(txId)); - textField.setText(txID); - textField.setOnMouseClicked(mouseEvent -> openBlockExplorer(txID)); - blockExplorerIcon.setOnMouseClicked(mouseEvent -> openBlockExplorer(txID)); - copyIcon.setOnMouseClicked(e -> Utilities.copyToClipboard(txID)); + textField.setText(txId); + textField.setOnMouseClicked(mouseEvent -> openBlockExplorer(txId)); + blockExplorerIcon.setOnMouseClicked(mouseEvent -> openBlockExplorer(txId)); + copyIcon.setOnMouseClicked(e -> Utilities.copyToClipboard(txId)); } public void cleanup() { @@ -135,14 +136,17 @@ public void cleanup() { textField.setText(""); } - /////////////////////////////////////////////////////////////////////////////////////////// // Private /////////////////////////////////////////////////////////////////////////////////////////// - private void openBlockExplorer(String txID) { - if (preferences != null) - GUIUtil.openWebPage(preferences.getBlockChainExplorer().txUrl + txID); + private void openBlockExplorer(String txId) { + if (preferences != null) { + BlockChainExplorer blockChainExplorer = isBsq ? + preferences.getBsqBlockChainExplorer() : + preferences.getBlockChainExplorer(); + GUIUtil.openWebPage(blockChainExplorer.txUrl + txId); + } } private void updateConfidence(TransactionConfidence confidence) { diff --git a/src/main/java/bisq/desktop/main/dao/proposal/CycleOverview.java b/src/main/java/bisq/desktop/main/dao/proposal/CycleOverview.java new file mode 100644 index 00000000000..a388d6636d6 --- /dev/null +++ b/src/main/java/bisq/desktop/main/dao/proposal/CycleOverview.java @@ -0,0 +1,151 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.desktop.main.dao.proposal; + +import bisq.desktop.components.SeparatedPhaseBars; +import bisq.desktop.util.Layout; + +import bisq.core.dao.DaoFacade; +import bisq.core.dao.state.BsqStateListener; +import bisq.core.dao.state.blockchain.Block; +import bisq.core.dao.state.period.DaoPhase; +import bisq.core.locale.Res; + +import javax.inject.Inject; + +import javafx.scene.layout.GridPane; + +import javafx.geometry.Insets; + +import org.fxmisc.easybind.EasyBind; +import org.fxmisc.easybind.Subscription; + +import java.util.Arrays; +import java.util.List; + +import lombok.extern.slf4j.Slf4j; + +import static bisq.desktop.util.FormBuilder.addTitledGroupBg; + +@Slf4j +public class CycleOverview implements BsqStateListener { + private final DaoFacade daoFacade; + private SeparatedPhaseBars separatedPhaseBars; + private List phaseBarsItems; + private Subscription phaseSubscription; + + @Inject + private CycleOverview(DaoFacade daoFacade) { + this.daoFacade = daoFacade; + } + + public int addGroup(GridPane gridPane, int gridRow) { + addTitledGroupBg(gridPane, gridRow, 1, Res.get("dao.cycle.headline")); + separatedPhaseBars = createSeparatedPhaseBars(); + GridPane.setColumnSpan(separatedPhaseBars, 2); + GridPane.setColumnIndex(separatedPhaseBars, 0); + GridPane.setMargin(separatedPhaseBars, new Insets(Layout.FIRST_ROW_DISTANCE - 6, 0, 0, 0)); + GridPane.setRowIndex(separatedPhaseBars, gridRow); + gridPane.getChildren().add(separatedPhaseBars); + return gridRow; + } + + public void activate() { + daoFacade.addBsqStateListener(this); + + phaseSubscription = EasyBind.subscribe(daoFacade.phaseProperty(), phase -> { + phaseBarsItems.forEach(item -> { + if (item.getPhase() == phase) { + item.setActive(); + } else { + item.setInActive(); + } + }); + + }); + + applyData(daoFacade.getChainHeight()); + } + + public void deactivate() { + daoFacade.removeBsqStateListener(this); + + phaseSubscription.unsubscribe(); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // BsqStateListener + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public void onNewBlockHeight(int height) { + applyData(height); + } + + @Override + public void onEmptyBlockAdded(Block block) { + } + + @Override + public void onParseTxsComplete(Block block) { + } + + @Override + public void onParseBlockChainComplete() { + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Private + /////////////////////////////////////////////////////////////////////////////////////////// + + private SeparatedPhaseBars createSeparatedPhaseBars() { + phaseBarsItems = Arrays.asList( + new SeparatedPhaseBars.SeparatedPhaseBarsItem(DaoPhase.Phase.PROPOSAL, true), + new SeparatedPhaseBars.SeparatedPhaseBarsItem(DaoPhase.Phase.BREAK1, false), + new SeparatedPhaseBars.SeparatedPhaseBarsItem(DaoPhase.Phase.BLIND_VOTE, true), + new SeparatedPhaseBars.SeparatedPhaseBarsItem(DaoPhase.Phase.BREAK2, false), + new SeparatedPhaseBars.SeparatedPhaseBarsItem(DaoPhase.Phase.VOTE_REVEAL, true), + new SeparatedPhaseBars.SeparatedPhaseBarsItem(DaoPhase.Phase.BREAK3, false), + new SeparatedPhaseBars.SeparatedPhaseBarsItem(DaoPhase.Phase.RESULT, false), + new SeparatedPhaseBars.SeparatedPhaseBarsItem(DaoPhase.Phase.BREAK4, false)); + return new SeparatedPhaseBars(phaseBarsItems); + } + + private void applyData(int height) { + if (height > 0) { + phaseBarsItems.forEach(item -> { + int firstBlock = daoFacade.getFirstBlockOfPhase(height, item.getPhase()); + int lastBlock = daoFacade.getLastBlockOfPhase(height, item.getPhase()); + final int duration = daoFacade.getDurationForPhase(item.getPhase()); + item.setPeriodRange(firstBlock, lastBlock, duration); + double progress = 0; + if (height >= firstBlock && height <= lastBlock) { + progress = (double) (height - firstBlock + 1) / (double) duration; + } else if (height < firstBlock) { + progress = 0; + } else if (height > lastBlock) { + progress = 1; + } + item.getProgressProperty().set(progress); + }); + separatedPhaseBars.updateWidth(); + } + } +} diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java index 224b1f23e80..4ec4d088de5 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java @@ -68,7 +68,6 @@ import java.util.Arrays; import java.util.List; import java.util.Objects; -import java.util.UUID; import java.util.stream.Collectors; import lombok.Getter; @@ -288,9 +287,11 @@ public BondedRole fromString(String string) { break; } - if (!isMakeProposalScreen) + if (!isMakeProposalScreen) { txIdTextField = addLabelTxIdTextField(gridPane, ++gridRow, Res.get("dao.proposal.display.txId"), "").second; + txIdTextField.setBsq(true); + } if (isMakeProposalScreen) { proposalFeeTextField = addLabelTextField(gridPane, ++gridRow, Res.get("dao.proposal.display.proposalFee")).second; @@ -438,20 +439,4 @@ public ScrollPane getView() { return scrollPane; } - - public void fillWithMock() { - if (uidTextField != null) - uidTextField.setText(UUID.randomUUID().toString()); - nameTextField.setText("Manfred Karrer"); - linkInputTextField.setText("https://github.com/bisq-network/compensation/issues/12"); - if (requestedBsqTextField != null) - requestedBsqTextField.setText("14000"); - if (bsqAddressTextField != null) - bsqAddressTextField.setText("B" + bsqWalletService.getUnusedAddress().toBase58()); - - if (paramComboBox != null) - paramComboBox.getSelectionModel().select(8); // PROPOSAL_FEE - if (paramValueTextField != null) - paramValueTextField.setText("333"); - } } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalView.java index 73bb249310c..bb755fc2c05 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalView.java @@ -32,6 +32,8 @@ import bisq.desktop.main.dao.proposal.make.MakeProposalView; import bisq.desktop.main.dao.proposal.open.OpenProposalsView; +import bisq.core.dao.DaoFacade; +import bisq.core.dao.state.period.DaoPhase; import bisq.core.locale.Res; import javax.inject.Inject; @@ -44,6 +46,8 @@ import javafx.scene.layout.AnchorPane; import javafx.scene.layout.VBox; +import javafx.beans.value.ChangeListener; + import java.util.Arrays; import java.util.List; @@ -52,9 +56,10 @@ public class ProposalView extends ActivatableViewAndModel { private final ViewLoader viewLoader; private final Navigation navigation; + private final DaoFacade daoFacade; private MenuItem dashboard, make, open, closed; - private Navigation.Listener listener; + private Navigation.Listener navigationListener; @FXML private VBox leftVBox; @@ -62,16 +67,18 @@ public class ProposalView extends ActivatableViewAndModel { private AnchorPane content; private Class selectedViewClass; + private ChangeListener phaseChangeListener; @Inject - private ProposalView(CachingViewLoader viewLoader, Navigation navigation) { + private ProposalView(CachingViewLoader viewLoader, Navigation navigation, DaoFacade daoFacade) { this.viewLoader = viewLoader; this.navigation = navigation; + this.daoFacade = daoFacade; } @Override public void initialize() { - listener = viewPath -> { + navigationListener = viewPath -> { if (viewPath.size() != 4 || viewPath.indexOf(ProposalView.class) != 2) return; @@ -79,13 +86,20 @@ public void initialize() { loadView(selectedViewClass); }; + phaseChangeListener = (observable, oldValue, newValue) -> { + if (newValue == DaoPhase.Phase.BLIND_VOTE) + open.setLabelText(Res.get("dao.proposal.menuItem.vote")); + else + open.setLabelText(Res.get("dao.proposal.menuItem.browse")); + }; + ToggleGroup toggleGroup = new ToggleGroup(); final List> baseNavPath = Arrays.asList(MainView.class, DaoView.class, ProposalView.class); dashboard = new MenuItem(navigation, toggleGroup, Res.get("shared.dashboard"), ProposalDashboardView.class, AwesomeIcon.DASHBOARD, baseNavPath); make = new MenuItem(navigation, toggleGroup, Res.get("dao.proposal.menuItem.make"), MakeProposalView.class, AwesomeIcon.EDIT, baseNavPath); - open = new MenuItem(navigation, toggleGroup, Res.get("dao.proposal.menuItem.open"), + open = new MenuItem(navigation, toggleGroup, Res.get("dao.proposal.menuItem.browse"), OpenProposalsView.class, AwesomeIcon.LIST_UL, baseNavPath); closed = new MenuItem(navigation, toggleGroup, Res.get("dao.proposal.menuItem.closed"), ClosedProposalsView.class, AwesomeIcon.LIST_ALT, baseNavPath); @@ -94,12 +108,14 @@ public void initialize() { @Override protected void activate() { + daoFacade.phaseProperty().addListener(phaseChangeListener); + dashboard.activate(); make.activate(); open.activate(); closed.activate(); - navigation.addListener(listener); + navigation.addListener(navigationListener); ViewPath viewPath = navigation.getCurrentPath(); if (viewPath.size() == 3 && viewPath.indexOf(ProposalView.class) == 2 || viewPath.size() == 2 && viewPath.indexOf(DaoView.class) == 1) { @@ -117,7 +133,9 @@ protected void activate() { @SuppressWarnings("Duplicates") @Override protected void deactivate() { - navigation.removeListener(listener); + daoFacade.phaseProperty().removeListener(phaseChangeListener); + + navigation.removeListener(navigationListener); dashboard.deactivate(); make.deactivate(); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java index f9d7ccec550..0f960e2395a 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/dashboard/ProposalDashboardView.java @@ -19,7 +19,7 @@ import bisq.desktop.common.view.ActivatableView; import bisq.desktop.common.view.FxmlView; -import bisq.desktop.components.SeparatedPhaseBars; +import bisq.desktop.main.dao.proposal.CycleOverview; import bisq.desktop.util.Layout; import bisq.core.dao.DaoFacade; @@ -34,14 +34,7 @@ import javafx.scene.control.TextField; import javafx.scene.layout.GridPane; -import javafx.geometry.Insets; - -import org.fxmisc.easybind.EasyBind; -import org.fxmisc.easybind.Subscription; - -import java.util.Arrays; import java.util.Date; -import java.util.List; import static bisq.desktop.util.FormBuilder.addLabelTextField; import static bisq.desktop.util.FormBuilder.addMultilineLabel; @@ -53,13 +46,10 @@ @FxmlView public class ProposalDashboardView extends ActivatableView implements BsqStateListener { private final DaoFacade daoFacade; + private final CycleOverview cycleOverview; private final BSFormatter formatter; - private List phaseBarsItems; - private DaoPhase.Phase currentPhase; - private Subscription phaseSubscription; private int gridRow = 0; - private SeparatedPhaseBars separatedPhaseBars; private TextField currentPhaseTextField, currentBlockHeightTextField, proposalTextField, blindVoteTextField, voteRevealTextField, voteResultTextField; @@ -68,21 +58,15 @@ public class ProposalDashboardView extends ActivatableView imple /////////////////////////////////////////////////////////////////////////////////////////// @Inject - public ProposalDashboardView(DaoFacade daoFacade, BSFormatter formatter) { + public ProposalDashboardView(DaoFacade daoFacade, CycleOverview cycleOverview, BSFormatter formatter) { this.daoFacade = daoFacade; + this.cycleOverview = cycleOverview; this.formatter = formatter; } @Override public void initialize() { - // cycle bar - addTitledGroupBg(root, gridRow, 1, Res.get("dao.cycle.headline")); - separatedPhaseBars = createSeparatedPhaseBars(); - GridPane.setColumnSpan(separatedPhaseBars, 2); - GridPane.setColumnIndex(separatedPhaseBars, 0); - GridPane.setMargin(separatedPhaseBars, new Insets(Layout.FIRST_ROW_DISTANCE - 6, 0, 0, 0)); - GridPane.setRowIndex(separatedPhaseBars, gridRow); - root.getChildren().add(separatedPhaseBars); + gridRow = cycleOverview.addGroup(root, gridRow); addTitledGroupBg(root, ++gridRow, 6, Res.get("dao.cycle.overview.headline"), Layout.GROUP_DISTANCE); currentBlockHeightTextField = addLabelTextField(root, gridRow, Res.get("dao.cycle.currentBlockHeight"), @@ -101,19 +85,8 @@ public void initialize() { protected void activate() { super.activate(); - phaseSubscription = EasyBind.subscribe(daoFacade.phaseProperty(), phase -> { - if (!phase.equals(this.currentPhase)) { - this.currentPhase = phase; - } - phaseBarsItems.forEach(item -> { - if (item.getPhase() == phase) { - item.setActive(); - } else { - item.setInActive(); - } - }); - - }); + cycleOverview.activate(); + daoFacade.addBsqStateListener(this); applyData(daoFacade.getChainHeight()); @@ -122,8 +95,10 @@ protected void activate() { @Override protected void deactivate() { super.deactivate(); + + cycleOverview.deactivate(); + daoFacade.removeBsqStateListener(this); - phaseSubscription.unsubscribe(); } @@ -154,25 +129,6 @@ public void onParseBlockChainComplete() { /////////////////////////////////////////////////////////////////////////////////////////// private void applyData(int height) { - if (height > 0) { - phaseBarsItems.forEach(item -> { - int firstBlock = daoFacade.getFirstBlockOfPhase(height, item.getPhase()); - int lastBlock = daoFacade.getLastBlockOfPhase(height, item.getPhase()); - final int duration = daoFacade.getDurationForPhase(item.getPhase()); - item.setPeriodRange(firstBlock, lastBlock, duration); - double progress = 0; - if (height >= firstBlock && height <= lastBlock) { - progress = (double) (height - firstBlock + 1) / (double) duration; - } else if (height < firstBlock) { - progress = 0; - } else if (height > lastBlock) { - progress = 1; - } - item.getProgressProperty().set(progress); - }); - separatedPhaseBars.updateWidth(); - } - currentBlockHeightTextField.setText(String.valueOf(daoFacade.getChainHeight())); currentPhaseTextField.setText(Res.get("dao.phase." + daoFacade.phaseProperty().get().name())); proposalTextField.setText(getPhaseDuration(height, DaoPhase.Phase.PROPOSAL)); @@ -181,19 +137,6 @@ private void applyData(int height) { voteResultTextField.setText(getPhaseDuration(height, DaoPhase.Phase.RESULT)); } - private SeparatedPhaseBars createSeparatedPhaseBars() { - phaseBarsItems = Arrays.asList( - new SeparatedPhaseBars.SeparatedPhaseBarsItem(DaoPhase.Phase.PROPOSAL, true), - new SeparatedPhaseBars.SeparatedPhaseBarsItem(DaoPhase.Phase.BREAK1, false), - new SeparatedPhaseBars.SeparatedPhaseBarsItem(DaoPhase.Phase.BLIND_VOTE, true), - new SeparatedPhaseBars.SeparatedPhaseBarsItem(DaoPhase.Phase.BREAK2, false), - new SeparatedPhaseBars.SeparatedPhaseBarsItem(DaoPhase.Phase.VOTE_REVEAL, true), - new SeparatedPhaseBars.SeparatedPhaseBarsItem(DaoPhase.Phase.BREAK3, false), - new SeparatedPhaseBars.SeparatedPhaseBarsItem(DaoPhase.Phase.RESULT, false), - new SeparatedPhaseBars.SeparatedPhaseBarsItem(DaoPhase.Phase.BREAK4, false)); - return new SeparatedPhaseBars(phaseBarsItems); - } - private String getPhaseDuration(int height, DaoPhase.Phase phase) { final long start = daoFacade.getFirstBlockOfPhase(height, phase); final long end = daoFacade.getLastBlockOfPhase(height, phase); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index da4248eb043..03b95349441 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -20,6 +20,7 @@ import bisq.desktop.common.view.ActivatableView; import bisq.desktop.common.view.FxmlView; import bisq.desktop.components.InputTextField; +import bisq.desktop.main.dao.proposal.CycleOverview; import bisq.desktop.main.dao.proposal.ProposalDisplay; import bisq.desktop.main.overlays.popups.Popup; import bisq.desktop.util.FormBuilder; @@ -86,15 +87,18 @@ public class MakeProposalView extends ActivatableView implements private final BsqWalletService bsqWalletService; private final WalletsSetup walletsSetup; private final P2PService p2PService; + private final CycleOverview cycleOverview; private final BSFormatter btcFormatter; private final BsqFormatter bsqFormatter; private ProposalDisplay proposalDisplay; - private Button createButton; + private Button makeProposalButton; private ComboBox proposalTypeComboBox; private ChangeListener proposalTypeChangeListener; @Nullable private ProposalType selectedProposalType; + private int gridRow; + private int alwaysVisibleGridRowIndex; /////////////////////////////////////////////////////////////////////////////////////////// @@ -107,12 +111,14 @@ private MakeProposalView(DaoFacade daoFacade, WalletsSetup walletsSetup, P2PService p2PService, FeeService feeService, + CycleOverview cycleOverview, BSFormatter btcFormatter, BsqFormatter bsqFormatter) { this.daoFacade = daoFacade; this.bsqWalletService = bsqWalletService; this.walletsSetup = walletsSetup; this.p2PService = p2PService; + this.cycleOverview = cycleOverview; this.btcFormatter = btcFormatter; this.bsqFormatter = bsqFormatter; } @@ -120,9 +126,11 @@ private MakeProposalView(DaoFacade daoFacade, @Override public void initialize() { - addTitledGroupBg(root, 0, 1, Res.get("dao.proposal.create.selectProposalType")); - proposalTypeComboBox = FormBuilder.addLabelComboBox(root, 0, - Res.getWithCol("dao.proposal.create.proposalType"), Layout.FIRST_ROW_DISTANCE).second; + gridRow = cycleOverview.addGroup(root, gridRow); + + addTitledGroupBg(root, ++gridRow, 1, Res.get("dao.proposal.create.selectProposalType"), Layout.GROUP_DISTANCE); + proposalTypeComboBox = FormBuilder.addLabelComboBox(root, gridRow, + Res.getWithCol("dao.proposal.create.proposalType"), Layout.FIRST_ROW_AND_GROUP_DISTANCE).second; proposalTypeComboBox.setConverter(new StringConverter() { @Override public String toString(ProposalType proposalType) { @@ -140,6 +148,7 @@ public ProposalType fromString(String string) { removeProposalDisplay(); addProposalDisplay(); }; + alwaysVisibleGridRowIndex = gridRow + 1; //TODO remove filter once all are implemented List proposalTypes = Arrays.stream(ProposalType.values()) @@ -151,21 +160,26 @@ public ProposalType fromString(String string) { @Override protected void activate() { + cycleOverview.activate(); + daoFacade.addBsqStateListener(this); - onNewBlockHeight(daoFacade.getChainHeight()); proposalTypeComboBox.getSelectionModel().selectedItemProperty().addListener(proposalTypeChangeListener); + if (makeProposalButton != null) + setMakeProposalButtonHandler(); - if (createButton != null) - setCreateButtonHandler(); + onNewBlockHeight(daoFacade.getChainHeight()); } @Override protected void deactivate() { + cycleOverview.deactivate(); + daoFacade.removeBsqStateListener(this); + proposalTypeComboBox.getSelectionModel().selectedItemProperty().removeListener(proposalTypeChangeListener); - if (createButton != null) - createButton.setOnAction(null); + if (makeProposalButton != null) + makeProposalButton.setOnAction(null); } @@ -308,13 +322,11 @@ private ProposalWithTransaction getProposalWithTransaction(ProposalType type) private void addProposalDisplay() { if (selectedProposalType != null) { proposalDisplay = new ProposalDisplay(root, bsqFormatter, bsqWalletService, daoFacade); - proposalDisplay.createAllFields(Res.get("dao.proposal.create.createNew"), 1, Layout.GROUP_DISTANCE, + proposalDisplay.createAllFields(Res.get("dao.proposal.create.createNew"), alwaysVisibleGridRowIndex, Layout.GROUP_DISTANCE, selectedProposalType, true); - // proposalDisplay.fillWithMock(); - - createButton = addButtonAfterGroup(root, proposalDisplay.incrementAndGetGridRow(), Res.get("dao.proposal.create.create.button")); - setCreateButtonHandler(); + makeProposalButton = addButtonAfterGroup(root, proposalDisplay.incrementAndGetGridRow(), Res.get("dao.proposal.create.create.button")); + setMakeProposalButtonHandler(); proposalDisplay.addInputChangedListener(this::updateButtonState); updateButtonState(); } @@ -323,15 +335,15 @@ private void addProposalDisplay() { private void removeProposalDisplay() { if (proposalDisplay != null) { proposalDisplay.removeAllFields(); - GUIUtil.removeChildrenFromGridPaneRows(root, 1, proposalDisplay.getGridRow()); + GUIUtil.removeChildrenFromGridPaneRows(root, alwaysVisibleGridRowIndex, proposalDisplay.getGridRow()); proposalDisplay.removeInputChangedListener(this::updateButtonState); proposalDisplay.removeListeners(); proposalDisplay = null; } } - private void setCreateButtonHandler() { - createButton.setOnAction(event -> { + private void setMakeProposalButtonHandler() { + makeProposalButton.setOnAction(event -> { if (GUIUtil.isReadyForTxBroadcast(p2PService, walletsSetup)) { publishMyProposal(selectedProposalType); } else { @@ -354,7 +366,7 @@ private void updateButtonState() { inputsValid.set(inputsValid.get() && comboBox.getSelectionModel().getSelectedItem() != null); }); - createButton.setDisable(!inputsValid.get()); + makeProposalButton.setDisable(!inputsValid.get()); } } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/open/OpenProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/open/OpenProposalListItem.java index 5f51ee6ed7e..8a2282ddae1 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/open/OpenProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/open/OpenProposalListItem.java @@ -17,7 +17,6 @@ package bisq.desktop.main.dao.proposal.open; -import bisq.desktop.components.AutoTooltipButton; import bisq.desktop.components.indicator.TxConfidenceIndicator; import bisq.core.btc.listeners.TxConfidenceListener; @@ -37,8 +36,11 @@ import org.bitcoinj.core.Transaction; import org.bitcoinj.core.TransactionConfidence; +import de.jensd.fx.fontawesome.AwesomeDude; +import de.jensd.fx.fontawesome.AwesomeIcon; + +import javafx.scene.control.Label; import javafx.scene.control.Tooltip; -import javafx.scene.image.ImageView; import javafx.beans.value.ChangeListener; @@ -67,9 +69,7 @@ public class OpenProposalListItem implements BsqStateListener { private Ballot ballot; @Getter - private ImageView imageView; - @Getter - private AutoTooltipButton button; + private Label icon; @Getter private TxConfidenceIndicator txConfidenceIndicator; @@ -81,7 +81,6 @@ public class OpenProposalListItem implements BsqStateListener { private ChangeListener phaseChangeListener; private ChangeListener chainHeightListener; - /////////////////////////////////////////////////////////////////////////////////////////// // Constructor, lifecycle /////////////////////////////////////////////////////////////////////////////////////////// @@ -150,40 +149,35 @@ public void cleanup() { public void onPhaseChanged(DaoPhase.Phase phase) { //noinspection IfCanBeSwitch if (phase == DaoPhase.Phase.PROPOSAL) { - imageView.setId("image-remove"); - button.setGraphic(imageView); - button.setText(Res.get("shared.remove")); - final boolean isMyProposal = daoFacade.isMyProposal(proposal); - button.setVisible(isMyProposal); - button.setManaged(isMyProposal); - } else if (phase == DaoPhase.Phase.BLIND_VOTE) { - button.setGraphic(null); - button.setText(Res.get("dao.proposal.active.vote")); - button.setVisible(true); - button.setManaged(true); - } else { - button.setVisible(false); - button.setManaged(false); + icon = AwesomeDude.createIconLabel(AwesomeIcon.FILE_TEXT); + icon.getStyleClass().addAll("icon", "dao-remove-proposal-icon"); + boolean isMyProposal = daoFacade.isMyProposal(proposal); + icon.setVisible(isMyProposal); + icon.setManaged(isMyProposal); + } else if (icon != null) { + icon.setVisible(true); + icon.setManaged(true); } - // ballot if (ballot != null) { final Vote vote = ballot.getVote(); if (vote != null) { - imageView.setVisible(true); + // TODO make Vote BooleanVote if (vote instanceof BooleanVote) { if (((BooleanVote) vote).isAccepted()) { - imageView.setId("accepted"); + icon = AwesomeDude.createIconLabel(AwesomeIcon.THUMBS_UP); + icon.getStyleClass().addAll("icon", "dao-accepted-icon"); } else { - imageView.setId("rejected"); + icon = AwesomeDude.createIconLabel(AwesomeIcon.THUMBS_DOWN); + icon.getStyleClass().addAll("icon", "dao-rejected-icon"); } - }/* else { - // not impl. - }*/ + } } else { - imageView.setVisible(false); + icon = AwesomeDude.createIconLabel(AwesomeIcon.MINUS); + icon.getStyleClass().addAll("icon", "dao-ignored-icon"); } + icon.layout(); } } @@ -200,9 +194,6 @@ private void init() { txConfidenceIndicator.setPrefSize(24, 24); txConfidenceIndicator.setTooltip(tooltip); - - imageView = new ImageView(); - chainHeightListener = (observable, oldValue, newValue) -> setupConfidence(); bsqWalletService.getChainHeightProperty().addListener(chainHeightListener); setupConfidence(); @@ -213,8 +204,6 @@ private void init() { daoFacade.phaseProperty().addListener(phaseChangeListener); - button = new AutoTooltipButton(); - button.setMinWidth(70); onPhaseChanged(daoFacade.phaseProperty().get()); } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/open/OpenProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/open/OpenProposalsView.java index 8b230ec86b8..45bbe026d6b 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/open/OpenProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/open/OpenProposalsView.java @@ -26,6 +26,8 @@ import bisq.desktop.components.InputTextField; import bisq.desktop.components.TableGroupHeadline; import bisq.desktop.components.TitledGroupBg; +import bisq.desktop.components.TxIdTextField; +import bisq.desktop.main.dao.proposal.CycleOverview; import bisq.desktop.main.dao.proposal.ProposalDisplay; import bisq.desktop.main.dao.proposal.ProposalWindow; import bisq.desktop.main.overlays.popups.Popup; @@ -58,6 +60,7 @@ import javax.inject.Inject; +import javafx.scene.Node; import javafx.scene.control.Button; import javafx.scene.control.Control; import javafx.scene.control.Label; @@ -66,7 +69,6 @@ import javafx.scene.control.TableColumn; import javafx.scene.control.TableView; import javafx.scene.control.Tooltip; -import javafx.scene.image.ImageView; import javafx.scene.layout.GridPane; import javafx.scene.layout.Priority; @@ -95,9 +97,9 @@ @FxmlView public class OpenProposalsView extends ActivatableView implements BsqBalanceListener, BsqStateListener { - private final DaoFacade daoFacade; private final BsqWalletService bsqWalletService; + private final CycleOverview cycleOverview; private final BsqFormatter bsqFormatter; private final BSFormatter btcFormatter; @@ -123,8 +125,10 @@ public class OpenProposalsView extends ActivatableView implement private ListChangeListener ballotListChangeListener; private ChangeListener stakeListener; private List voteControls = new ArrayList<>(); + private List voteFields = new ArrayList<>(); private TitledGroupBg voteTitledGroupBg; - private Label stakeLabel; + private Label stakeLabel, revealTxIdLabel, blindVoteTxIdLabel; + private TxIdTextField revealTxIdTextField, blindVoteTxIdTextField; /////////////////////////////////////////////////////////////////////////////////////////// @@ -134,11 +138,13 @@ public class OpenProposalsView extends ActivatableView implement @Inject private OpenProposalsView(DaoFacade daoFacade, BsqWalletService bsqWalletService, + CycleOverview cycleOverview, BsqFormatter bsqFormatter, BSFormatter btcFormatter) { this.daoFacade = daoFacade; this.bsqWalletService = bsqWalletService; + this.cycleOverview = cycleOverview; this.bsqFormatter = bsqFormatter; this.btcFormatter = btcFormatter; } @@ -146,8 +152,11 @@ private OpenProposalsView(DaoFacade daoFacade, @Override public void initialize() { super.initialize(); + root.getStyleClass().add("vote-root"); + gridRow = cycleOverview.addGroup(root, gridRow); + proposalDisplayGridPane = new GridPane(); createProposalsTableView(); @@ -158,11 +167,13 @@ public void initialize() { proposalListChangeListener = c -> updateListItems(); // ballot - stakeListener = (observable, oldValue, newValue) -> updateButtonStates(); + stakeListener = (observable, oldValue, newValue) -> updateViews(); } @Override protected void activate() { + cycleOverview.activate(); + phaseSubscription = EasyBind.subscribe(daoFacade.phaseProperty(), this::onPhaseChanged); selectedProposalSubscription = EasyBind.subscribe(tableView.getSelectionModel().selectedItemProperty(), this::onSelectProposal); @@ -170,9 +181,11 @@ protected void activate() { daoFacade.getActiveOrMyUnconfirmedProposals().addListener(proposalListChangeListener); daoFacade.getValidAndConfirmedBallots().addListener(ballotListChangeListener); + daoFacade.addBsqStateListener(this); + bsqWalletService.addBsqBalanceListener(this); stakeInputTextField.textProperty().addListener(stakeListener); - bsqWalletService.addBsqBalanceListener(this); + voteButton.setOnAction(e -> onVote()); onUpdateBalances(bsqWalletService.getAvailableBalance(), bsqWalletService.getAvailableNonBsqBalance(), @@ -181,31 +194,36 @@ protected void activate() { bsqWalletService.getLockupBondsBalance(), bsqWalletService.getUnlockingBondsBalance()); - voteButton.setOnAction(e -> onVote()); - - daoFacade.addBsqStateListener(this); - updateListItems(); - updateButtonStates(); - stakeInputTextField.setText(""); + updateViews(); } @Override protected void deactivate() { + cycleOverview.deactivate(); + phaseSubscription.unsubscribe(); selectedProposalSubscription.unsubscribe(); sortedList.comparatorProperty().unbind(); - listItems.forEach(OpenProposalListItem::cleanup); - tableView.getSelectionModel().clearSelection(); - selectedItem = null; - daoFacade.getActiveOrMyUnconfirmedProposals().removeListener(proposalListChangeListener); daoFacade.getValidAndConfirmedBallots().removeListener(ballotListChangeListener); - - stakeInputTextField.textProperty().removeListener(stakeListener); + daoFacade.removeBsqStateListener(this); bsqWalletService.removeBsqBalanceListener(this); + + if (stakeInputTextField != null) { + stakeInputTextField.textProperty().removeListener(stakeListener); + stakeInputTextField.clear(); + } + if (voteButton != null) + voteButton.setOnAction(null); + if (removeProposalButton != null) + removeProposalButton.setOnAction(null); + + listItems.forEach(OpenProposalListItem::cleanup); + tableView.getSelectionModel().clearSelection(); + selectedItem = null; } @@ -220,7 +238,7 @@ public void onUpdateBalances(Coin confirmedBalance, Coin lockedForVotingBalance, Coin lockupBondsBalance, Coin unlockingBondsBalance) { - if (isBlindVotePhase()) + if (isBlindVotePhaseButNotLastBlock()) stakeInputTextField.setPromptText(Res.get("dao.proposal.myVote.stake.prompt", bsqFormatter.formatCoinWithCode(confirmedBalance))); else @@ -242,20 +260,11 @@ public void onEmptyBlockAdded(Block block) { @Override public void onParseTxsComplete(Block block) { - stakeInputTextField.setText(""); - updateButtonStates(); + updateViews(); } @Override public void onParseBlockChainComplete() { - GUIUtil.setFitToRowsForTableView(tableView, 33, 28, 80); - - // hack to get layout correct - if (!tableView.getItems().isEmpty()) { - onSelectProposal(tableView.getItems().get(0)); - onSelectProposal(null); - } - updateListItems(); } @@ -279,7 +288,7 @@ private void fillListItems() { .collect(Collectors.toSet())); } - updateButtonStates(); + updateViews(); } private void updateListItems() { @@ -290,6 +299,15 @@ private void updateListItems() { if (listItems.isEmpty()) hideProposalDisplay(); + + + if (!tableView.getItems().isEmpty()) { + onSelectProposal(tableView.getItems().get(0)); + onSelectProposal(null); + } + + GUIUtil.setFitToRowsForTableView(tableView, 33, 28, 80); + root.layout(); } private void createAllFieldsOnProposalDisplay(Proposal proposal) { @@ -359,32 +377,19 @@ private void hideProposalDisplay() { private void onPhaseChanged(DaoPhase.Phase phase) { if (phase != null && !phase.equals(currentPhase)) { currentPhase = phase; + stakeInputTextField.clear(); onSelectProposal(selectedItem); } if (removeProposalButton != null) { - //noinspection IfCanBeSwitch,IfCanBeSwitch,IfCanBeSwitch - if (phase == DaoPhase.Phase.PROPOSAL) { - if (selectedItem != null && selectedItem.getProposal() != null) { - final boolean isMyProposal = daoFacade.isMyProposal(selectedItem.getProposal()); - removeProposalButton.setVisible(isMyProposal); - removeProposalButton.setManaged(isMyProposal); - } - } else { - removeProposalButton.setVisible(false); - removeProposalButton.setManaged(false); - } + boolean doShowRemoveButton = phase == DaoPhase.Phase.PROPOSAL && + selectedItem != null && + daoFacade.isMyProposal(selectedItem.getProposal()); + removeProposalButton.setVisible(doShowRemoveButton); + removeProposalButton.setManaged(doShowRemoveButton); } - updateButtonStates(); - - boolean isBlindVotePhaseOrLater = daoFacade.phaseProperty().get().ordinal() >= DaoPhase.Phase.BLIND_VOTE.ordinal(); - voteTitledGroupBg.setVisible(isBlindVotePhaseOrLater); - voteTitledGroupBg.setManaged(isBlindVotePhaseOrLater); - stakeLabel.setVisible(isBlindVotePhaseOrLater); - stakeLabel.setManaged(isBlindVotePhaseOrLater); - stakeInputTextField.setVisible(isBlindVotePhaseOrLater); - stakeInputTextField.setManaged(isBlindVotePhaseOrLater); + updateViews(); } private void onRemoveProposal() { @@ -408,7 +413,7 @@ private void onSelectProposal(OpenProposalListItem item) { onPhaseChanged(daoFacade.phaseProperty().get()); - updateButtonStates(); + updateViews(); } private void onAccept() { @@ -455,6 +460,7 @@ private void publishBlindVote(Coin stake) { voteButtonInfoLabel.setText(""); new Popup().feedback(Res.get("dao.blindVote.success")) .show(); + updateViews(); }, exception -> { voteButtonBusyAnimation.stop(); voteButtonInfoLabel.setText(""); @@ -464,9 +470,7 @@ private void publishBlindVote(Coin stake) { private void updateStateAfterVote() { - updateButtonStates(); - //hideProposalDisplay(); - //proposalTableView.getSelectionModel().clearSelection(); + updateViews(); tableView.refresh(); } @@ -474,13 +478,8 @@ private OpenProposalListItem getBallotListItem() { return selectedItem; } - private void updateButtonStates() { - boolean isBlindVotePhase = isBlindVotePhase(); - voteControls.forEach(control -> { - control.setVisible(isBlindVotePhase); - control.setManaged(isBlindVotePhase); - }); - + private void updateViews() { + boolean isBlindVotePhaseButNotLastBlock = isBlindVotePhaseButNotLastBlock(); boolean hasVoted = listItems.stream() .filter(e -> e.getBallot() != null) .map(OpenProposalListItem::getBallot) @@ -490,28 +489,72 @@ private void updateButtonStates() { List myVoteListForCycle = daoFacade.getMyVoteListForCycle(); boolean hasAlreadyVoted = !myVoteListForCycle.isEmpty(); - if (isBlindVotePhase && selectedItem != null && acceptButton != null) { + if (selectedItem != null && acceptButton != null) { Optional optionalVote = selectedItem.getBooleanVote(); boolean isPresent = optionalVote.isPresent(); boolean isAccepted = isPresent && optionalVote.get().isAccepted(); - boolean isBlindVotePhaseButNotLastBlock = isBlindVotePhaseButNotLastBlock(); boolean doDisable = hasAlreadyVoted || !isBlindVotePhaseButNotLastBlock; - acceptButton.setDisable(doDisable || (isPresent && isAccepted)); - rejectButton.setDisable(doDisable || (isPresent && !isAccepted)); - ignoreButton.setDisable(doDisable || !isPresent); - stakeInputTextField.setDisable(doDisable); + acceptButton.setDisable(hasAlreadyVoted || (isPresent && isAccepted)); + rejectButton.setDisable(hasAlreadyVoted || (isPresent && !isAccepted)); + ignoreButton.setDisable(hasAlreadyVoted || !isPresent); + stakeInputTextField.setMouseTransparent(doDisable); } else { - stakeInputTextField.setDisable(true); + stakeInputTextField.setMouseTransparent(true); } + boolean showVoteFields = isBlindVotePhaseButNotLastBlock || hasAlreadyVoted; + + voteFields.forEach(node -> { + node.setVisible(showVoteFields); + node.setManaged(showVoteFields); + }); + voteControls.forEach(control -> { + control.setVisible(isBlindVotePhaseButNotLastBlock); + control.setManaged(isBlindVotePhaseButNotLastBlock); + }); + + + blindVoteTxIdTextField.setup(""); + revealTxIdTextField.setup(""); + + blindVoteTxIdLabel.setVisible(false); + blindVoteTxIdLabel.setManaged(false); + blindVoteTxIdTextField.setVisible(false); + blindVoteTxIdTextField.setManaged(false); + revealTxIdLabel.setVisible(false); + revealTxIdLabel.setManaged(false); + revealTxIdTextField.setVisible(false); + revealTxIdTextField.setManaged(false); + if (hasAlreadyVoted) { voteTitledGroupBg.setText(Res.get("dao.proposal.votes.header.voted")); if (myVoteListForCycle.size() == 1) { - myVoteListForCycle.stream().findAny() - .ifPresent(myVote -> { - Coin stake = Coin.valueOf(myVote.getBlindVote().getStake()); - stakeInputTextField.setText(bsqFormatter.formatCoinWithCode(stake)); - }); + Optional optionalMyVote = myVoteListForCycle.stream() + .filter(myVote -> daoFacade.isTxInCorrectCycle(myVote.getHeight(), daoFacade.getChainHeight())) + .findAny(); + if (optionalMyVote.isPresent()) { + MyVote myVote = optionalMyVote.get(); + Coin stake = Coin.valueOf(myVote.getBlindVote().getStake()); + stakeInputTextField.setText(bsqFormatter.formatCoinWithCode(stake)); + + if (myVote.getTxId() != null) { + blindVoteTxIdTextField.setup(myVote.getTxId()); + blindVoteTxIdLabel.setVisible(true); + blindVoteTxIdLabel.setManaged(true); + blindVoteTxIdTextField.setVisible(true); + blindVoteTxIdTextField.setManaged(true); + } + + if (myVote.getRevealTxId() != null) { + revealTxIdTextField.setup(myVote.getRevealTxId()); + revealTxIdLabel.setVisible(true); + revealTxIdLabel.setManaged(true); + revealTxIdTextField.setVisible(true); + revealTxIdTextField.setManaged(true); + } + } else { + stakeInputTextField.clear(); + } } else { String msg = "We found multiple MyVote entries in that cycle. That is not supported by the UI."; log.warn(msg); @@ -519,17 +562,11 @@ private void updateButtonStates() { } voteButton.setVisible(false); voteButton.setManaged(false); - } } - private boolean isBlindVotePhase() { - return daoFacade.phaseProperty().get() == DaoPhase.Phase.BLIND_VOTE; - } - private boolean isBlindVotePhaseButNotLastBlock() { - int getLastBlockOfBlindVotePhase = daoFacade.getLastBlockOfPhase(daoFacade.getChainHeight(), DaoPhase.Phase.BLIND_VOTE); - return isBlindVotePhase() && daoFacade.getChainHeight() < getLastBlockOfBlindVotePhase; + return daoFacade.isInPhaseButNotLastBlock(DaoPhase.Phase.BLIND_VOTE); } @@ -539,21 +576,19 @@ private boolean isBlindVotePhaseButNotLastBlock() { private void createProposalsTableView() { TableGroupHeadline proposalsHeadline = new TableGroupHeadline(Res.get("dao.proposal.active.header")); - GridPane.setRowIndex(proposalsHeadline, gridRow); - GridPane.setMargin(proposalsHeadline, new Insets(0, -10, -10, -10)); + GridPane.setRowIndex(proposalsHeadline, ++gridRow); + GridPane.setMargin(proposalsHeadline, new Insets(Layout.GROUP_DISTANCE, -10, -10, -10)); GridPane.setColumnSpan(proposalsHeadline, 2); root.getChildren().add(proposalsHeadline); tableView = new TableView<>(); tableView.setPlaceholder(new AutoTooltipLabel(Res.get("table.placeholder.noData"))); tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); - tableView.setMinHeight(80); - tableView.setMaxHeight(80); createProposalColumns(); GridPane.setRowIndex(tableView, gridRow); GridPane.setHgrow(tableView, Priority.ALWAYS); - GridPane.setMargin(tableView, new Insets(20, -10, 5, -10)); + GridPane.setMargin(tableView, new Insets(Layout.FIRST_ROW_AND_GROUP_DISTANCE, -10, 5, -10)); GridPane.setColumnSpan(tableView, 2); root.getChildren().add(tableView); @@ -571,20 +606,40 @@ private void createEmptyProposalDisplay() { } private void createVoteView() { - voteTitledGroupBg = addTitledGroupBg(root, ++gridRow, 1, + voteTitledGroupBg = addTitledGroupBg(root, ++gridRow, 3, Res.get("dao.proposal.votes.header"), Layout.GROUP_DISTANCE - 20); - Tuple2 tuple2 = addLabelInputTextField(root, gridRow, + voteFields.add(voteTitledGroupBg); + + Tuple2 stakeTuple = addLabelInputTextField(root, gridRow, Res.getWithCol("dao.proposal.myVote.stake"), Layout.FIRST_ROW_AND_GROUP_DISTANCE - 20); - stakeLabel = tuple2.first; - stakeInputTextField = tuple2.second; + stakeLabel = stakeTuple.first; + stakeInputTextField = stakeTuple.second; stakeInputTextField.setValidator(new BsqValidator(bsqFormatter)); - - Tuple3 tuple = addButtonBusyAnimationLabelAfterGroup(root, ++gridRow, + voteFields.add(stakeLabel); + voteFields.add(stakeInputTextField); + + Tuple2 blindVoteTxIdTuple = addLabelTxIdTextField(root, ++gridRow, + Res.getWithCol("dao.proposal.myVote.blindVoteTxId")); + blindVoteTxIdLabel = blindVoteTxIdTuple.first; + blindVoteTxIdTextField = blindVoteTxIdTuple.second; + blindVoteTxIdTextField.setBsq(true); + voteFields.add(blindVoteTxIdLabel); + voteFields.add(blindVoteTxIdTextField); + + Tuple2 revealTxIdTuple = addLabelTxIdTextField(root, ++gridRow, + Res.getWithCol("dao.proposal.myVote.revealTxId")); + revealTxIdLabel = revealTxIdTuple.first; + revealTxIdTextField = revealTxIdTuple.second; + revealTxIdTextField.setBsq(true); + voteFields.add(revealTxIdLabel); + voteFields.add(revealTxIdTextField); + + Tuple3 voteButtonTuple = addButtonBusyAnimationLabelAfterGroup(root, ++gridRow, Res.get("dao.proposal.myVote.button")); - voteButton = tuple.first; + voteButton = voteButtonTuple.first; voteControls.add(voteButton); - voteButtonBusyAnimation = tuple.second; - voteButtonInfoLabel = tuple.third; + voteButtonBusyAnimation = voteButtonTuple.second; + voteButtonInfoLabel = voteButtonTuple.third; } @@ -593,7 +648,7 @@ private void createVoteView() { /////////////////////////////////////////////////////////////////////////////////////////// private void createProposalColumns() { - TableColumn dateColumn = new AutoTooltipTableColumn(Res.get("shared.dateTime")); + TableColumn dateColumn = new AutoTooltipTableColumn<>(Res.get("shared.dateTime")); dateColumn.setMinWidth(190); dateColumn.setMinWidth(190); @@ -711,7 +766,7 @@ public void updateItem(final OpenProposalListItem item, boolean empty) { tableView.getColumns().add(confidenceColumn); TableColumn actionColumn = new TableColumn<>(); - actionColumn.setMinWidth(130); + actionColumn.setMinWidth(40); actionColumn.setMaxWidth(actionColumn.getMinWidth()); actionColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); actionColumn.setCellFactory(new Callback, @@ -721,22 +776,22 @@ public void updateItem(final OpenProposalListItem item, boolean empty) { public TableCell call(TableColumn column) { return new TableCell() { - ImageView imageView; + Label icon; @Override public void updateItem(final OpenProposalListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { - if (imageView == null) { - imageView = item.getImageView(); - setGraphic(imageView); + if (icon == null) { + item.onPhaseChanged(currentPhase); + icon = item.getIcon(); + setGraphic(icon); } - item.onPhaseChanged(currentPhase); } else { setGraphic(null); - if (imageView != null) - imageView = null; + if (icon != null) + icon = null; } } }; diff --git a/src/main/java/bisq/desktop/main/dao/results/combo/VotesPerProposalListItem.java b/src/main/java/bisq/desktop/main/dao/results/combo/VotesPerProposalListItem.java index cd1fad5a003..2a039c3f527 100644 --- a/src/main/java/bisq/desktop/main/dao/results/combo/VotesPerProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/results/combo/VotesPerProposalListItem.java @@ -65,11 +65,11 @@ public Tuple2 getIconStyleTuple(String blindVoteTxId) { } if (isAccepted.isPresent()) { if (isAccepted.get()) - return new Tuple2<>(AwesomeIcon.OK_SIGN, "dao-accepted-icon"); + return new Tuple2<>(AwesomeIcon.THUMBS_UP, "dao-accepted-icon"); else - return new Tuple2<>(AwesomeIcon.REMOVE_SIGN, "dao-rejected-icon"); + return new Tuple2<>(AwesomeIcon.THUMBS_DOWN, "dao-rejected-icon"); } else { - return new Tuple2<>(AwesomeIcon.MINUS_SIGN, "dao-ignored-icon"); + return new Tuple2<>(AwesomeIcon.MINUS, "dao-ignored-icon"); } } } diff --git a/src/main/java/bisq/desktop/main/dao/results/proposals/ProposalResultsListItem.java b/src/main/java/bisq/desktop/main/dao/results/proposals/ProposalResultsListItem.java index bcc4a9ee7c3..a1ab72747c7 100644 --- a/src/main/java/bisq/desktop/main/dao/results/proposals/ProposalResultsListItem.java +++ b/src/main/java/bisq/desktop/main/dao/results/proposals/ProposalResultsListItem.java @@ -73,7 +73,7 @@ public String getQuorum() { } public AwesomeIcon getIcon() { - return evaluatedProposal.isAccepted() ? AwesomeIcon.OK_SIGN : AwesomeIcon.REMOVE_SIGN; + return evaluatedProposal.isAccepted() ? AwesomeIcon.THUMBS_UP : AwesomeIcon.THUMBS_DOWN; } public String getColorStyleClass() { diff --git a/src/main/java/bisq/desktop/main/dao/results/proposals/VoteResultsForProposalListItem.java b/src/main/java/bisq/desktop/main/dao/results/proposals/VoteResultsForProposalListItem.java index 880d06a014a..828bcb35f67 100644 --- a/src/main/java/bisq/desktop/main/dao/results/proposals/VoteResultsForProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/results/proposals/VoteResultsForProposalListItem.java @@ -72,11 +72,11 @@ public Tuple2 getIconStyleTuple() { .findAny(); if (isAccepted.isPresent()) { if (isAccepted.get()) - return new Tuple2<>(AwesomeIcon.OK_SIGN, "dao-accepted-icon"); + return new Tuple2<>(AwesomeIcon.THUMBS_UP, "dao-accepted-icon"); else - return new Tuple2<>(AwesomeIcon.REMOVE_SIGN, "dao-rejected-icon"); + return new Tuple2<>(AwesomeIcon.THUMBS_DOWN, "dao-rejected-icon"); } else { - return new Tuple2<>(AwesomeIcon.MINUS_SIGN, "dao-ignored-icon"); + return new Tuple2<>(AwesomeIcon.MINUS, "dao-ignored-icon"); } } diff --git a/src/main/java/bisq/desktop/main/dao/voting/dashboard/VotingDashboardView.java b/src/main/java/bisq/desktop/main/dao/voting/dashboard/VotingDashboardView.java index a3b90950f20..8619c2e6f31 100644 --- a/src/main/java/bisq/desktop/main/dao/voting/dashboard/VotingDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/voting/dashboard/VotingDashboardView.java @@ -18,6 +18,7 @@ package bisq.desktop.main.dao.voting.dashboard; import bisq.desktop.common.view.FxmlView; +import bisq.desktop.main.dao.proposal.CycleOverview; import bisq.desktop.main.dao.proposal.dashboard.ProposalDashboardView; import bisq.core.dao.DaoFacade; @@ -34,8 +35,8 @@ public class VotingDashboardView extends ProposalDashboardView { /////////////////////////////////////////////////////////////////////////////////////////// @Inject - private VotingDashboardView(DaoFacade daoFacade, BSFormatter formatter) { - super(daoFacade, formatter); + private VotingDashboardView(DaoFacade daoFacade, CycleOverview cycleOverview, BSFormatter formatter) { + super(daoFacade, cycleOverview, formatter); } @Override diff --git a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java index f1d9952934e..d77a236a550 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java @@ -548,7 +548,7 @@ public void updateItem(final BsqTxListItem item, boolean empty) { String formattedDate = bsqFormatter.formatDateTime(new Date(blockTimeInSec * 1000)); toolTipText = Res.get("dao.tx.issuance.tooltip", formattedDate); } else { - awesomeIcon = AwesomeIcon.SHARE; + awesomeIcon = AwesomeIcon.FILE_TEXT; style = "dao-tx-type-proposal-fee-icon"; } break; From 242fe68df8fbf94c668f609af5495512e6084922 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sun, 5 Aug 2018 22:49:59 +0200 Subject: [PATCH 175/197] Remove views --- .../main/dao/results/BaseResultsGridPane.java | 104 ---- .../main/dao/results/BaseResultsListItem.java | 48 -- .../dao/results/BaseResultsTableView.java | 110 ---- .../desktop/main/dao/results/ResultsView.fxml | 45 -- .../desktop/main/dao/results/ResultsView.java | 542 ------------------ .../main/dao/results/SelectionListener.java | 28 - .../EvaluatedProposalWithDecryptedVotes.java | 40 -- .../combo/VotesPerProposalListItem.java | 75 --- .../combo/VotesPerProposalTableView.java | 197 ------- .../proposals/ProposalResultsGridPane.java | 398 ------------- .../VoteResultsForProposalWindow.java | 271 --------- .../results/votes/VoteResultsGridPane.java | 425 -------------- .../results/votes/VoteResultsListItem.java | 124 ---- .../main/dao/voting/BaseBallotListItem.java | 96 ---- .../desktop/main/dao/voting/VotingView.fxml | 36 -- .../desktop/main/dao/voting/VotingView.java | 130 ----- .../voting/active/ActiveBallotListItem.java | 49 -- .../dao/voting/active/ActiveBallotsView.fxml | 33 -- .../dao/voting/active/ActiveBallotsView.java | 395 ------------- .../voting/closed/ClosedBallotListItem.java | 50 -- .../dao/voting/closed/ClosedBallotsView.fxml | 34 -- .../dao/voting/closed/ClosedBallotsView.java | 155 ----- .../dao/voting/closed/VotingHistoryView.fxml | 32 -- .../dao/voting/closed/VotingHistoryView.java | 50 -- .../voting/dashboard/VotingDashboardView.fxml | 32 -- .../voting/dashboard/VotingDashboardView.java | 57 -- .../main/dao/voting/vote/VoteView.fxml | 33 -- .../main/dao/voting/vote/VoteView.java | 50 -- 28 files changed, 3639 deletions(-) delete mode 100644 src/main/java/bisq/desktop/main/dao/results/BaseResultsGridPane.java delete mode 100644 src/main/java/bisq/desktop/main/dao/results/BaseResultsListItem.java delete mode 100644 src/main/java/bisq/desktop/main/dao/results/BaseResultsTableView.java delete mode 100644 src/main/java/bisq/desktop/main/dao/results/ResultsView.fxml delete mode 100644 src/main/java/bisq/desktop/main/dao/results/ResultsView.java delete mode 100644 src/main/java/bisq/desktop/main/dao/results/SelectionListener.java delete mode 100644 src/main/java/bisq/desktop/main/dao/results/combo/EvaluatedProposalWithDecryptedVotes.java delete mode 100644 src/main/java/bisq/desktop/main/dao/results/combo/VotesPerProposalListItem.java delete mode 100644 src/main/java/bisq/desktop/main/dao/results/combo/VotesPerProposalTableView.java delete mode 100644 src/main/java/bisq/desktop/main/dao/results/proposals/ProposalResultsGridPane.java delete mode 100644 src/main/java/bisq/desktop/main/dao/results/proposals/VoteResultsForProposalWindow.java delete mode 100644 src/main/java/bisq/desktop/main/dao/results/votes/VoteResultsGridPane.java delete mode 100644 src/main/java/bisq/desktop/main/dao/results/votes/VoteResultsListItem.java delete mode 100644 src/main/java/bisq/desktop/main/dao/voting/BaseBallotListItem.java delete mode 100644 src/main/java/bisq/desktop/main/dao/voting/VotingView.fxml delete mode 100644 src/main/java/bisq/desktop/main/dao/voting/VotingView.java delete mode 100644 src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotListItem.java delete mode 100644 src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.fxml delete mode 100644 src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.java delete mode 100644 src/main/java/bisq/desktop/main/dao/voting/closed/ClosedBallotListItem.java delete mode 100644 src/main/java/bisq/desktop/main/dao/voting/closed/ClosedBallotsView.fxml delete mode 100644 src/main/java/bisq/desktop/main/dao/voting/closed/ClosedBallotsView.java delete mode 100644 src/main/java/bisq/desktop/main/dao/voting/closed/VotingHistoryView.fxml delete mode 100644 src/main/java/bisq/desktop/main/dao/voting/closed/VotingHistoryView.java delete mode 100644 src/main/java/bisq/desktop/main/dao/voting/dashboard/VotingDashboardView.fxml delete mode 100644 src/main/java/bisq/desktop/main/dao/voting/dashboard/VotingDashboardView.java delete mode 100644 src/main/java/bisq/desktop/main/dao/voting/vote/VoteView.fxml delete mode 100644 src/main/java/bisq/desktop/main/dao/voting/vote/VoteView.java diff --git a/src/main/java/bisq/desktop/main/dao/results/BaseResultsGridPane.java b/src/main/java/bisq/desktop/main/dao/results/BaseResultsGridPane.java deleted file mode 100644 index aaea38ed17f..00000000000 --- a/src/main/java/bisq/desktop/main/dao/results/BaseResultsGridPane.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.desktop.main.dao.results; - -import bisq.desktop.components.AutoTooltipLabel; -import bisq.desktop.components.TableGroupHeadline; -import bisq.desktop.main.dao.results.model.ResultsOfCycle; - -import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.DaoFacade; -import bisq.core.locale.Res; -import bisq.core.util.BsqFormatter; - -import javafx.scene.control.TableView; -import javafx.scene.layout.GridPane; -import javafx.scene.layout.Priority; - -import javafx.geometry.Insets; - -import javafx.beans.value.ChangeListener; -import javafx.beans.value.ObservableValue; - -import javafx.collections.FXCollections; -import javafx.collections.ObservableList; -import javafx.collections.transformation.SortedList; - -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public abstract class BaseResultsGridPane extends GridPane { - @Getter - protected final BsqWalletService bsqWalletService; - protected final DaoFacade daoFacade; - protected final BsqFormatter bsqFormatter; - - protected final ObservableList itemList = FXCollections.observableArrayList(); - private final SortedList sortedList = new SortedList<>(itemList); - protected ResultsOfCycle resultsOfCycle; - protected TableView tableView; - private TableGroupHeadline headline; - - protected abstract String getTitle(); - - protected abstract void fillList(); - - protected abstract void createColumns(TableView tableView); - - public BaseResultsGridPane(BsqWalletService bsqWalletService, DaoFacade daoFacade, - BsqFormatter bsqFormatter, int columnIndex) { - this.bsqWalletService = bsqWalletService; - this.daoFacade = daoFacade; - this.bsqFormatter = bsqFormatter; - - headline = new TableGroupHeadline(getTitle()); - GridPane.setMargin(headline, new Insets(15, -10, -10, -10)); - GridPane.setColumnIndex(headline, columnIndex); - getChildren().add(headline); - - tableView = new TableView<>(); - tableView.setPlaceholder(new AutoTooltipLabel(Res.get("table.placeholder.noData"))); - tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); - - createColumns(tableView); - GridPane.setMargin(tableView, new Insets(35, -10, 5, -10)); - GridPane.setColumnIndex(tableView, columnIndex); - getChildren().add(tableView); - - GridPane.setHgrow(headline, Priority.ALWAYS); - GridPane.setHgrow(tableView, Priority.ALWAYS); - - tableView.getSelectionModel().selectedItemProperty().addListener(new ChangeListener() { - @Override - public void changed(ObservableValue observable, R oldValue, R newValue) { - onSelected(newValue); - } - }); - } - - protected abstract void onSelected(R item); - - public void createAllFields(ResultsOfCycle resultsOfCycle) { - this.resultsOfCycle = resultsOfCycle; - - tableView.setItems(sortedList); - sortedList.comparatorProperty().bind(tableView.comparatorProperty()); - fillList(); - } -} diff --git a/src/main/java/bisq/desktop/main/dao/results/BaseResultsListItem.java b/src/main/java/bisq/desktop/main/dao/results/BaseResultsListItem.java deleted file mode 100644 index 6506dcb5960..00000000000 --- a/src/main/java/bisq/desktop/main/dao/results/BaseResultsListItem.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.desktop.main.dao.results; - -import bisq.core.dao.voting.voteresult.DecryptedVote; -import bisq.core.dao.voting.voteresult.EvaluatedProposal; - -import javafx.scene.control.TableRow; - -public class BaseResultsListItem { - private TableRow tableRow; - - public void setTableRow(TableRow tableRow) { - this.tableRow = tableRow; - } - - public void resetTableRow() { - if (tableRow != null) { - tableRow.setStyle(null); - tableRow.requestLayout(); - - } - } - - public void applyVoteAndProposal(DecryptedVote decryptedVote, EvaluatedProposal evaluatedProposal) { - String rowBgColor = decryptedVote.getVote(evaluatedProposal.getProposalTxId()) - .map(booleanVote -> booleanVote.isAccepted() ? - "-fx-background-color: rgba(0, 255, 0, 0.4)" : - "-fx-background-color: rgba(255, 0, 0, 0.23)") - .orElse("-fx-background-color: rgba(182, 182, 182, 0.4)"); - tableRow.setStyle(rowBgColor); - } -} diff --git a/src/main/java/bisq/desktop/main/dao/results/BaseResultsTableView.java b/src/main/java/bisq/desktop/main/dao/results/BaseResultsTableView.java deleted file mode 100644 index 2b862f8f4c0..00000000000 --- a/src/main/java/bisq/desktop/main/dao/results/BaseResultsTableView.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.desktop.main.dao.results; - -import bisq.desktop.components.AutoTooltipLabel; -import bisq.desktop.components.TableGroupHeadline; -import bisq.desktop.main.dao.results.model.ResultsOfCycle; -import bisq.desktop.util.GUIUtil; - -import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.DaoFacade; -import bisq.core.locale.Res; -import bisq.core.util.BsqFormatter; - -import javafx.scene.control.TableView; -import javafx.scene.layout.GridPane; -import javafx.scene.layout.Priority; - -import javafx.geometry.Insets; - -import javafx.collections.FXCollections; -import javafx.collections.ObservableList; -import javafx.collections.transformation.SortedList; - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public abstract class BaseResultsTableView { - protected final GridPane gridPane; - protected final BsqWalletService bsqWalletService; - protected final DaoFacade daoFacade; - protected final BsqFormatter bsqFormatter; - - protected int gridRow; - protected int gridRowStartIndex; - - - protected final ObservableList itemList = FXCollections.observableArrayList(); - private final SortedList sortedList = new SortedList<>(itemList); - protected ResultsOfCycle resultsOfCycle; - protected TableView tableView; - - protected abstract String getTitle(); - - protected abstract void fillList(); - - protected abstract void createColumns(TableView tableView); - - public BaseResultsTableView(GridPane gridPane, BsqWalletService bsqWalletService, DaoFacade daoFacade, BsqFormatter bsqFormatter) { - this.gridPane = gridPane; - this.bsqWalletService = bsqWalletService; - this.daoFacade = daoFacade; - this.bsqFormatter = bsqFormatter; - } - - public int createAllFields(int gridRowStartIndex, ResultsOfCycle resultsOfCycle) { - this.resultsOfCycle = resultsOfCycle; - this.gridRowStartIndex = gridRowStartIndex; - this.gridRow = gridRowStartIndex; - - removeAllFields(); - createTableView(); - fillList(); - GUIUtil.setFitToRowsForTableView(tableView, 33, 28, 80); - - return gridRow; - } - - private void createTableView() { - TableGroupHeadline headline = new TableGroupHeadline(getTitle()); - GridPane.setRowIndex(headline, gridRow); - GridPane.setMargin(headline, new Insets(15, -10, -10, -10)); - GridPane.setColumnSpan(headline, 2); - gridPane.getChildren().add(headline); - - tableView = new TableView<>(); - tableView.setPlaceholder(new AutoTooltipLabel(Res.get("table.placeholder.noData"))); - tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); - - createColumns(tableView); - GridPane.setRowIndex(tableView, gridRow); - GridPane.setMargin(tableView, new Insets(35, -10, 5, -10)); - GridPane.setColumnSpan(tableView, 2); - GridPane.setHgrow(tableView, Priority.SOMETIMES); - gridPane.getChildren().add(tableView); - - tableView.setItems(sortedList); - sortedList.comparatorProperty().bind(tableView.comparatorProperty()); - } - - private void removeAllFields() { - GUIUtil.removeChildrenFromGridPaneRows(gridPane, gridRowStartIndex, gridRow); - gridRow = gridRowStartIndex; - } -} diff --git a/src/main/java/bisq/desktop/main/dao/results/ResultsView.fxml b/src/main/java/bisq/desktop/main/dao/results/ResultsView.fxml deleted file mode 100644 index 6960acea524..00000000000 --- a/src/main/java/bisq/desktop/main/dao/results/ResultsView.fxml +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - - - - - diff --git a/src/main/java/bisq/desktop/main/dao/results/ResultsView.java b/src/main/java/bisq/desktop/main/dao/results/ResultsView.java deleted file mode 100644 index 4e0ac0170e8..00000000000 --- a/src/main/java/bisq/desktop/main/dao/results/ResultsView.java +++ /dev/null @@ -1,542 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.desktop.main.dao.results; - - -import bisq.desktop.common.model.Activatable; -import bisq.desktop.common.view.ActivatableViewAndModel; -import bisq.desktop.common.view.FxmlView; -import bisq.desktop.components.AutoTooltipLabel; -import bisq.desktop.components.AutoTooltipTableColumn; -import bisq.desktop.components.TableGroupHeadline; -import bisq.desktop.components.TitledGroupBg; -import bisq.desktop.main.dao.results.model.ResultsOfCycle; -import bisq.desktop.main.dao.results.proposals.ProposalResultsGridPane; -import bisq.desktop.main.dao.results.votes.VoteResultsGridPane; -import bisq.desktop.util.FormBuilder; -import bisq.desktop.util.GUIUtil; - -import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.DaoFacade; -import bisq.core.dao.state.BsqStateListener; -import bisq.core.dao.state.BsqStateService; -import bisq.core.dao.state.blockchain.Block; -import bisq.core.dao.state.ext.Param; -import bisq.core.dao.state.period.Cycle; -import bisq.core.dao.state.period.CycleService; -import bisq.core.dao.voting.blindvote.BlindVoteConsensus; -import bisq.core.dao.voting.proposal.Proposal; -import bisq.core.dao.voting.proposal.ProposalConsensus; -import bisq.core.dao.voting.proposal.ProposalService; -import bisq.core.dao.voting.proposal.storage.appendonly.ProposalPayload; -import bisq.core.dao.voting.voteresult.DecryptedVote; -import bisq.core.dao.voting.voteresult.EvaluatedProposal; -import bisq.core.dao.voting.voteresult.VoteResultService; -import bisq.core.locale.Res; -import bisq.core.user.Preferences; -import bisq.core.util.BsqFormatter; - -import org.bitcoinj.core.Coin; - -import javax.inject.Inject; - -import javafx.fxml.FXML; - -import javafx.scene.control.ScrollPane; -import javafx.scene.control.TableCell; -import javafx.scene.control.TableColumn; -import javafx.scene.control.TableView; -import javafx.scene.layout.AnchorPane; -import javafx.scene.layout.ColumnConstraints; -import javafx.scene.layout.GridPane; -import javafx.scene.layout.HBox; -import javafx.scene.layout.Priority; - -import javafx.geometry.HPos; -import javafx.geometry.Insets; - -import javafx.beans.property.ReadOnlyObjectWrapper; -import javafx.beans.value.ChangeListener; - -import javafx.collections.FXCollections; -import javafx.collections.ObservableList; -import javafx.collections.transformation.SortedList; - -import javafx.util.Callback; - -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.stream.Collectors; - -import static bisq.desktop.util.FormBuilder.addLabelTextField; - -@FxmlView -public class ResultsView extends ActivatableViewAndModel implements BsqStateListener, SelectionListener { - @FXML - private ScrollPane scrollPane; - - private final DaoFacade daoFacade; - // TODO use daoFacade once dev work completed - private final BsqStateService bsqStateService; - private final CycleService cycleService; - private final VoteResultService voteResultService; - private final ProposalService proposalService; - private final BsqWalletService bsqWalletService; - private final Preferences preferences; - private final BsqFormatter bsqFormatter; - - private int gridRow = 0; - private TableView tableView; - private final ObservableList itemList = FXCollections.observableArrayList(); - private final SortedList sortedList = new SortedList<>(itemList); - private ChangeListener selectedItemListener; - private ProposalResultsGridPane proposalResultsGridPane; - private VoteResultsGridPane voteResultsGridPane; - private GridPane gridPane; - private HBox hBox; - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Constructor, lifecycle - /////////////////////////////////////////////////////////////////////////////////////////// - - @Inject - private ResultsView(DaoFacade daoFacade, - BsqStateService bsqStateService, - CycleService cycleService, - VoteResultService voteResultService, - ProposalService proposalService, - BsqWalletService bsqWalletService, - Preferences preferences, - BsqFormatter bsqFormatter) { - this.daoFacade = daoFacade; - this.bsqStateService = bsqStateService; - this.cycleService = cycleService; - this.voteResultService = voteResultService; - this.proposalService = proposalService; - this.bsqWalletService = bsqWalletService; - this.preferences = preferences; - this.bsqFormatter = bsqFormatter; - } - - @Override - public void initialize() { - daoFacade.addBsqStateListener(this); - - createCyclesTable(); - - hBox = new HBox(); - hBox.setSpacing(30); - hBox.setFillHeight(true); - - proposalResultsGridPane = new ProposalResultsGridPane(this, bsqWalletService, daoFacade, bsqFormatter, - bsqStateService); - hBox.getChildren().add(proposalResultsGridPane); - - voteResultsGridPane = new VoteResultsGridPane(this, bsqWalletService, daoFacade, bsqStateService, preferences, bsqFormatter); - hBox.getChildren().add(voteResultsGridPane); - - HBox.setHgrow(proposalResultsGridPane, Priority.ALWAYS); - HBox.setHgrow(voteResultsGridPane, Priority.ALWAYS); - - selectedItemListener = (observable, oldValue, newValue) -> onResultsListItemSelected(newValue); - } - - @Override - protected void activate() { - tableView.getSelectionModel().selectedItemProperty().addListener(selectedItemListener); - fillCycleList(); - } - - @Override - protected void deactivate() { - tableView.getSelectionModel().selectedItemProperty().removeListener(selectedItemListener); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // SelectionListener - /////////////////////////////////////////////////////////////////////////////////////////// - - @Override - public void onSelectedEvaluatedProposal(EvaluatedProposal evaluatedProposal) { - voteResultsGridPane.onSelectedEvaluatedProposal(evaluatedProposal); - } - - @Override - public void onSelectedDecryptedVote(DecryptedVote decryptedVote) { - proposalResultsGridPane.onSelectedDecryptedVote(decryptedVote); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // BsqStateListener - /////////////////////////////////////////////////////////////////////////////////////////// - - @Override - public void onNewBlockHeight(int blockHeight) { - fillCycleList(); - } - - @Override - public void onEmptyBlockAdded(Block block) { - } - - @Override - public void onParseTxsComplete(Block block) { - } - - @Override - public void onParseBlockChainComplete() { - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // UI handlers - /////////////////////////////////////////////////////////////////////////////////////////// - - private void onResultsListItemSelected(ResultsListItem item) { - //removeDetailsViews(); - if (item != null) { - ResultsOfCycle resultsOfCycle = item.getResultsOfCycle(); - - GUIUtil.removeChildrenFromGridPaneRows(gridPane, 1, gridRow); - gridRow = 1; - - // gridRow = votesPerProposalTableView.createAllFields(++gridRow, resultsOfCycle); - proposalResultsGridPane.createAllFields(resultsOfCycle); - voteResultsGridPane.createAllFields(resultsOfCycle); - - gridPane.getChildren().add(hBox); - - GridPane.setRowIndex(hBox, gridRow); - GridPane.setMargin(hBox, new Insets(0, 0, 0, 0)); - GridPane.setColumnSpan(hBox, 2); - - // addParams(resultsOfCycle); - } - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Create views - /////////////////////////////////////////////////////////////////////////////////////////// - - private void createCyclesTable() { - gridPane = new GridPane(); - - gridPane.setHgap(5); - gridPane.setVgap(5); - - gridPane.setPadding(new Insets(15, 25, 10, 25)); - - ColumnConstraints columnConstraints1 = new ColumnConstraints(); - columnConstraints1.setHalignment(HPos.RIGHT); - columnConstraints1.setHgrow(Priority.SOMETIMES); - - columnConstraints1.setMinWidth(140); - - ColumnConstraints columnConstraints2 = new ColumnConstraints(); - columnConstraints2.setHgrow(Priority.ALWAYS); - columnConstraints1.setMinWidth(300); - - gridPane.getColumnConstraints().addAll(columnConstraints1, columnConstraints2); - scrollPane.setContent(gridPane); - - TableGroupHeadline headline = new TableGroupHeadline(Res.get("dao.results.cycles.header")); - GridPane.setRowIndex(headline, gridRow); - GridPane.setMargin(headline, new Insets(0, -10, -10, -10)); - GridPane.setColumnSpan(headline, 2); - gridPane.getChildren().add(headline); - - tableView = new TableView<>(); - tableView.setPlaceholder(new AutoTooltipLabel(Res.get("table.placeholder.noData"))); - tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); - - createColumns(tableView); - - GridPane.setRowIndex(tableView, gridRow); - GridPane.setMargin(tableView, new Insets(20, -10, 5, -10)); - GridPane.setColumnSpan(tableView, 2); - gridPane.getChildren().add(tableView); - - tableView.setItems(sortedList); - sortedList.comparatorProperty().bind(tableView.comparatorProperty()); - } - - private void addParams(ResultsOfCycle resultsOfCycle) { - //TODO - AtomicInteger rowSpan = new AtomicInteger(2); - TitledGroupBg header = FormBuilder.addTitledGroupBg(gridPane, ++gridRow, rowSpan.get(), Res.get("dao.results.cycle.header"), 20); - - int height = resultsOfCycle.getCycle().getHeightOfFirstBlock(); - gridRow--; // first item use same gridRow as header. as we use a ++ in the loop adjust by --. - Arrays.stream(Param.values()).forEach(param -> { - String label = null; - long paramValue = bsqStateService.getParamValue(param, height); - boolean isDefaultValue = param.getDefaultValue() == paramValue; - String value = null; - int top = (param == Param.BSQ_MAKER_FEE_IN_PERCENT) ? 40 : 0; - switch (param) { - case UNDEFINED: - // ignore - break; - - case BSQ_MAKER_FEE_IN_PERCENT: - case BSQ_TAKER_FEE_IN_PERCENT: - case BTC_MAKER_FEE_IN_PERCENT: - case BTC_TAKER_FEE_IN_PERCENT: - label = Res.getWithCol("dao.param." + param.name()); - value = bsqFormatter.formatToPercentWithSymbol(paramValue / 10000d); - break; - - case PROPOSAL_FEE: - label = Res.getWithCol("dao.param." + param.name()); - value = bsqFormatter.formatCoinWithCode(ProposalConsensus.getFee(bsqStateService, height)); - break; - case BLIND_VOTE_FEE: - label = Res.getWithCol("dao.param." + param.name()); - value = bsqFormatter.formatCoinWithCode(BlindVoteConsensus.getFee(bsqStateService, height)); - break; - - case QUORUM_PROPOSAL: - case QUORUM_COMP_REQUEST: - case QUORUM_CHANGE_PARAM: - case QUORUM_REMOVE_ASSET: - case QUORUM_CONFISCATION: - label = Res.getWithCol("dao.param." + param.name()); - value = bsqFormatter.formatCoinWithCode(Coin.valueOf(paramValue)); - break; - case THRESHOLD_PROPOSAL: - - case THRESHOLD_COMP_REQUEST: - case THRESHOLD_CHANGE_PARAM: - case THRESHOLD_REMOVE_ASSET: - case THRESHOLD_CONFISCATION: - label = Res.getWithCol("dao.param." + param.name()); - value = bsqFormatter.formatToPercentWithSymbol(paramValue / 10000d); - break; - - case PHASE_UNDEFINED: - // ignore - break; - - case PHASE_PROPOSAL: - case PHASE_BREAK1: - case PHASE_BLIND_VOTE: - case PHASE_BREAK2: - case PHASE_VOTE_REVEAL: - case PHASE_BREAK3: - case PHASE_RESULT: - case PHASE_BREAK4: - String phase = Res.get("dao.phase." + param.name()); - label = Res.getWithCol("dao.results.cycle.duration.label", phase); - value = Res.get("dao.results.cycle.duration.value", paramValue); - break; - } - if (value != null) { - String postFix = isDefaultValue ? - Res.get("dao.results.cycle.value.postFix.isDefaultValue") : - Res.get("dao.results.cycle.value.postFix.hasChanged"); - value += " " + postFix; - addLabelTextField(gridPane, ++gridRow, label, value, top); - rowSpan.getAndIncrement(); - } - }); - - GridPane.setRowSpan(header, rowSpan.get()); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Private - /////////////////////////////////////////////////////////////////////////////////////////// - - private void fillCycleList() { - itemList.clear(); - bsqStateService.getCycles().forEach(this::addCycleListItem); - Collections.reverse(itemList); - GUIUtil.setFitToRowsForTableView(tableView, 24, 28, 80); - } - - private void addCycleListItem(Cycle cycle) { - List proposalsForCycle = proposalService.getAppendOnlyStoreList().stream() - .filter(proposalPayload -> cycleService.isTxInCycle(cycle, proposalPayload.getProposal().getTxId())) - .map(ProposalPayload::getProposal) - .collect(Collectors.toList()); - - List evaluatedProposalsForCycle = voteResultService.getAllEvaluatedProposals().stream() - .filter(evaluatedProposal -> cycleService.isTxInCycle(cycle, evaluatedProposal.getProposal().getTxId())) - .collect(Collectors.toList()); - - List decryptedVotesForCycle = voteResultService.getAllDecryptedVotes().stream() - .filter(decryptedVote -> cycleService.isTxInCycle(cycle, decryptedVote.getBlindVoteTxId())) - .filter(decryptedVote -> cycleService.isTxInCycle(cycle, decryptedVote.getVoteRevealTxId())) - .collect(Collectors.toList()); - - long cycleStartTime = bsqStateService.getBlockAtHeight(cycle.getHeightOfFirstBlock()) - .map(e -> e.getTime() * 1000) - .orElse(0L); - int cycleIndex = cycleService.getCycleIndex(cycle); - ResultsOfCycle resultsOfCycle = new ResultsOfCycle(cycle, - cycleIndex, - cycleStartTime, - proposalsForCycle, - evaluatedProposalsForCycle, - decryptedVotesForCycle); - ResultsListItem resultsListItem = new ResultsListItem(resultsOfCycle, bsqStateService, bsqFormatter); - itemList.add(resultsListItem); - } - - private void removeDetailsViews() { - GUIUtil.removeChildrenFromGridPaneRows(gridPane, 1, gridRow); - gridRow = 0; - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // TableColumns - /////////////////////////////////////////////////////////////////////////////////////////// - - private void createColumns(TableView tableView) { - TableColumn cycleColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.cycles.table.header.cycle")); - cycleColumn.setMinWidth(160); - cycleColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - cycleColumn.setCellFactory( - new Callback, TableCell>() { - @Override - public TableCell call( - TableColumn column) { - return new TableCell() { - @Override - public void updateItem(final ResultsListItem item, boolean empty) { - super.updateItem(item, empty); - if (item != null) - setText(item.getCycle()); - else - setText(""); - } - }; - } - }); - cycleColumn.setComparator(Comparator.comparing(ResultsListItem::getCycleStartTime)); - tableView.getColumns().add(cycleColumn); - - TableColumn proposalsColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.cycles.table.header.numProposals")); - proposalsColumn.setMinWidth(90); - proposalsColumn.setMaxWidth(90); - proposalsColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - proposalsColumn.setCellFactory( - new Callback, TableCell>() { - @Override - public TableCell call( - TableColumn column) { - return new TableCell() { - @Override - public void updateItem(final ResultsListItem item, boolean empty) { - super.updateItem(item, empty); - if (item != null) - setText(item.getNumProposals()); - else - setText(""); - } - }; - } - }); - proposalsColumn.setComparator(Comparator.comparing(ResultsListItem::getNumProposals)); - tableView.getColumns().add(proposalsColumn); - - TableColumn votesColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.cycles.table.header.numVotes")); - votesColumn.setMinWidth(70); - votesColumn.setMaxWidth(70); - votesColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - votesColumn.setCellFactory( - new Callback, TableCell>() { - @Override - public TableCell call( - TableColumn column) { - return new TableCell() { - @Override - public void updateItem(final ResultsListItem item, boolean empty) { - super.updateItem(item, empty); - if (item != null) - setText(item.getNumVotesAsString()); - else - setText(""); - } - }; - } - }); - votesColumn.setComparator(Comparator.comparing(ResultsListItem::getNumProposals)); - tableView.getColumns().add(votesColumn); - - TableColumn stakeColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.cycles.table.header.stake")); - stakeColumn.setMinWidth(70); - stakeColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - stakeColumn.setCellFactory( - new Callback, TableCell>() { - @Override - public TableCell call( - TableColumn column) { - return new TableCell() { - @Override - public void updateItem(final ResultsListItem item, boolean empty) { - super.updateItem(item, empty); - if (item != null) - setText(item.getStake()); - else - setText(""); - } - }; - } - }); - stakeColumn.setComparator(Comparator.comparing(ResultsListItem::getNumProposals)); - tableView.getColumns().add(stakeColumn); - - TableColumn issuanceColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.cycles.table.header.issuance")); - issuanceColumn.setMinWidth(70); - issuanceColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - issuanceColumn.setCellFactory( - new Callback, TableCell>() { - @Override - public TableCell call( - TableColumn column) { - return new TableCell() { - @Override - public void updateItem(final ResultsListItem item, boolean empty) { - super.updateItem(item, empty); - if (item != null) - setText(item.getIssuance()); - else - setText(""); - } - }; - } - }); - issuanceColumn.setComparator(Comparator.comparing(ResultsListItem::getNumProposals)); - tableView.getColumns().add(issuanceColumn); - } -} diff --git a/src/main/java/bisq/desktop/main/dao/results/SelectionListener.java b/src/main/java/bisq/desktop/main/dao/results/SelectionListener.java deleted file mode 100644 index 7a57dc21e8f..00000000000 --- a/src/main/java/bisq/desktop/main/dao/results/SelectionListener.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.desktop.main.dao.results; - -import bisq.core.dao.voting.voteresult.DecryptedVote; -import bisq.core.dao.voting.voteresult.EvaluatedProposal; - -public interface SelectionListener { - - void onSelectedEvaluatedProposal(EvaluatedProposal evaluatedProposal); - - void onSelectedDecryptedVote(DecryptedVote decryptedVote); -} diff --git a/src/main/java/bisq/desktop/main/dao/results/combo/EvaluatedProposalWithDecryptedVotes.java b/src/main/java/bisq/desktop/main/dao/results/combo/EvaluatedProposalWithDecryptedVotes.java deleted file mode 100644 index 1adcc630270..00000000000 --- a/src/main/java/bisq/desktop/main/dao/results/combo/EvaluatedProposalWithDecryptedVotes.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.desktop.main.dao.results.combo; - -import bisq.core.dao.voting.voteresult.DecryptedVote; -import bisq.core.dao.voting.voteresult.EvaluatedProposal; - -import java.util.HashMap; -import java.util.Map; - -import lombok.Data; - -@Data -public class EvaluatedProposalWithDecryptedVotes { - private final EvaluatedProposal evaluatedProposal; - private Map decryptedVotesByBlindVoteTxId = new HashMap<>(); - - public EvaluatedProposalWithDecryptedVotes(EvaluatedProposal evaluatedProposal) { - this.evaluatedProposal = evaluatedProposal; - } - - public void addDecryptedVote(DecryptedVote decryptedVote) { - decryptedVotesByBlindVoteTxId.put(decryptedVote.getBlindVoteTxId(), decryptedVote); - } -} diff --git a/src/main/java/bisq/desktop/main/dao/results/combo/VotesPerProposalListItem.java b/src/main/java/bisq/desktop/main/dao/results/combo/VotesPerProposalListItem.java deleted file mode 100644 index 2a039c3f527..00000000000 --- a/src/main/java/bisq/desktop/main/dao/results/combo/VotesPerProposalListItem.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.desktop.main.dao.results.combo; - -import bisq.core.dao.voting.ballot.Ballot; -import bisq.core.dao.voting.ballot.vote.BooleanVote; -import bisq.core.dao.voting.proposal.Proposal; -import bisq.core.dao.voting.voteresult.DecryptedVote; - -import bisq.common.util.Tuple2; - -import de.jensd.fx.fontawesome.AwesomeIcon; - -import java.util.Map; -import java.util.Optional; - -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class VotesPerProposalListItem { - @Getter - private final EvaluatedProposalWithDecryptedVotes evaluatedProposalWithDecryptedVotes; - @Getter - private final Proposal proposal; - private final String proposalTxId; - - public VotesPerProposalListItem(EvaluatedProposalWithDecryptedVotes evaluatedProposalWithDecryptedVotes) { - this.evaluatedProposalWithDecryptedVotes = evaluatedProposalWithDecryptedVotes; - proposal = evaluatedProposalWithDecryptedVotes.getEvaluatedProposal().getProposal(); - proposalTxId = proposal.getTxId(); - } - - public String getProposalInfo() { - return proposal.getName(); - } - - public Tuple2 getIconStyleTuple(String blindVoteTxId) { - Optional isAccepted = Optional.empty(); - Map map = evaluatedProposalWithDecryptedVotes.getDecryptedVotesByBlindVoteTxId(); - if (map.containsKey(blindVoteTxId)) { - DecryptedVote decryptedVote = map.get(blindVoteTxId); - isAccepted = decryptedVote.getBallotList().stream() - .filter(ballot -> ballot.getProposalTxId().equals(proposalTxId)) - .map(Ballot::getVote) - .filter(vote -> vote instanceof BooleanVote) - .map(vote -> (BooleanVote) vote) - .map(BooleanVote::isAccepted) - .findAny(); - } - if (isAccepted.isPresent()) { - if (isAccepted.get()) - return new Tuple2<>(AwesomeIcon.THUMBS_UP, "dao-accepted-icon"); - else - return new Tuple2<>(AwesomeIcon.THUMBS_DOWN, "dao-rejected-icon"); - } else { - return new Tuple2<>(AwesomeIcon.MINUS, "dao-ignored-icon"); - } - } -} diff --git a/src/main/java/bisq/desktop/main/dao/results/combo/VotesPerProposalTableView.java b/src/main/java/bisq/desktop/main/dao/results/combo/VotesPerProposalTableView.java deleted file mode 100644 index d53316ea3d3..00000000000 --- a/src/main/java/bisq/desktop/main/dao/results/combo/VotesPerProposalTableView.java +++ /dev/null @@ -1,197 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.desktop.main.dao.results.combo; - -import bisq.desktop.components.AutoTooltipTableColumn; -import bisq.desktop.main.dao.proposal.ProposalWindow; -import bisq.desktop.main.dao.results.BaseResultsTableView; -import bisq.desktop.main.dao.results.model.ResultsOfCycle; -import bisq.desktop.util.GUIUtil; - -import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.DaoFacade; -import bisq.core.dao.state.BsqStateService; -import bisq.core.dao.voting.voteresult.DecryptedVote; -import bisq.core.dao.voting.voteresult.EvaluatedProposal; -import bisq.core.locale.Res; -import bisq.core.util.BsqFormatter; - -import bisq.common.util.Tuple2; - -import org.bitcoinj.core.Coin; - -import de.jensd.fx.fontawesome.AwesomeDude; -import de.jensd.fx.fontawesome.AwesomeIcon; - -import javafx.scene.control.Hyperlink; -import javafx.scene.control.Label; -import javafx.scene.control.TableCell; -import javafx.scene.control.TableColumn; -import javafx.scene.control.TableView; -import javafx.scene.control.Tooltip; -import javafx.scene.layout.GridPane; - -import javafx.beans.property.ReadOnlyObjectWrapper; - -import javafx.util.Callback; - -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; -import java.util.Map; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.stream.Collectors; - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class VotesPerProposalTableView extends BaseResultsTableView { - - private final BsqStateService bsqStateService; - - public VotesPerProposalTableView(GridPane gridPane, BsqWalletService bsqWalletService, DaoFacade daoFacade, - BsqStateService bsqStateService, BsqFormatter bsqFormatter) { - super(gridPane, bsqWalletService, daoFacade, bsqFormatter); - this.bsqStateService = bsqStateService; - } - - @Override - protected String getTitle() { - return Res.get("dao.results.combo.header"); - } - - @Override - protected void fillList() { - //TODO move to domain - Map map = resultsOfCycle.getEvaluatedProposals().stream() - .collect(Collectors.toMap(EvaluatedProposal::getProposalTxId, - EvaluatedProposalWithDecryptedVotes::new)); - - resultsOfCycle.getDecryptedVotesForCycle() - .forEach(decryptedVote -> { - decryptedVote.getBallotList().stream().forEach(ballot -> { - EvaluatedProposalWithDecryptedVotes evaluatedProposalWithDecryptedVotes = map.get(ballot.getProposalTxId()); - evaluatedProposalWithDecryptedVotes.addDecryptedVote(decryptedVote); - }); - }); - - itemList.setAll(map.values().stream() - .map(VotesPerProposalListItem::new) - .collect(Collectors.toList())); - - itemList.sort(Comparator.comparing(votesPerProposalListItem -> votesPerProposalListItem.getProposal().getCreationDate())); - } - - - public int createAllFields(int gridRowStartIndex, ResultsOfCycle resultsOfCycle) { - super.createAllFields(gridRowStartIndex, resultsOfCycle); - - createColumnsFromData(tableView); - - GUIUtil.setFitToRowsForTableView(tableView, 30, 28, 80); - - return gridRow; - } - - private void createColumnsFromData(TableView tableView) { - TableColumn votesColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.combo.table.proposals")); - votesColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - votesColumn.setSortable(false); - votesColumn.setMinWidth(150); - votesColumn.setCellFactory( - new Callback, TableCell>() { - - @Override - public TableCell call( - TableColumn column) { - return new TableCell() { - private Hyperlink hyperlinkWithIcon; - - @Override - public void updateItem(final VotesPerProposalListItem item, boolean empty) { - super.updateItem(item, empty); - if (item != null && !empty) { - hyperlinkWithIcon = new Hyperlink(item.getProposalInfo()); - hyperlinkWithIcon.setOnAction(event -> new ProposalWindow(bsqFormatter, - bsqWalletService, - item.getEvaluatedProposalWithDecryptedVotes().getEvaluatedProposal().getProposal(), - daoFacade) - .show()); - hyperlinkWithIcon.setTooltip(new Tooltip(Res.get("tooltip.openPopupForDetails"))); - - setGraphic(hyperlinkWithIcon); - } else { - setGraphic(null); - if (hyperlinkWithIcon != null) - hyperlinkWithIcon.setOnAction(null); - } - } - }; - } - }); - tableView.getColumns().add(votesColumn); - - List list = new ArrayList<>(resultsOfCycle.getDecryptedVotesForCycle()); - list.sort(Comparator.comparing(DecryptedVote::getBlindVoteTxId)); - AtomicInteger index = new AtomicInteger(); - list.forEach(decryptedVote -> { - index.getAndIncrement(); - String stake = bsqFormatter.formatCoinWithCode(Coin.valueOf(decryptedVote.getStake() + decryptedVote.getMerit(bsqStateService))); - String header = "Vote " + index.get() + " (" + stake + ")"; - TableColumn column = new AutoTooltipTableColumn<>(header); - column.setSortable(false); - column.setMinWidth(150); - column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - column.setCellFactory( - new Callback, TableCell>() { - - @Override - public TableCell call( - TableColumn column) { - return new TableCell() { - private Label icon; - - @Override - public void updateItem(final VotesPerProposalListItem item, boolean empty) { - super.updateItem(item, empty); - - if (item != null && !empty) { - String blindVoteTxId = decryptedVote.getBlindVoteTxId(); - Tuple2 iconStyleTuple = item.getIconStyleTuple(blindVoteTxId); - icon = new Label(); - AwesomeDude.setIcon(icon, iconStyleTuple.first); - icon.getStyleClass().add(iconStyleTuple.second); - setGraphic(icon); - } else { - setGraphic(null); - } - } - }; - } - }); - tableView.getColumns().add(column); - }); - } - - @Override - protected void createColumns(TableView tableView) { - // do nothing as we create the columns dynamically - } -} diff --git a/src/main/java/bisq/desktop/main/dao/results/proposals/ProposalResultsGridPane.java b/src/main/java/bisq/desktop/main/dao/results/proposals/ProposalResultsGridPane.java deleted file mode 100644 index 58f4dcfdd70..00000000000 --- a/src/main/java/bisq/desktop/main/dao/results/proposals/ProposalResultsGridPane.java +++ /dev/null @@ -1,398 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.desktop.main.dao.results.proposals; - -import bisq.desktop.components.AutoTooltipTableColumn; -import bisq.desktop.main.dao.results.BaseResultsGridPane; -import bisq.desktop.main.dao.results.SelectionListener; - -import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.DaoFacade; -import bisq.core.dao.state.BsqStateService; -import bisq.core.dao.voting.voteresult.DecryptedVote; -import bisq.core.locale.Res; -import bisq.core.util.BsqFormatter; - -import de.jensd.fx.fontawesome.AwesomeDude; -import de.jensd.fx.fontawesome.AwesomeIcon; - -import javafx.scene.control.Button; -import javafx.scene.control.Label; -import javafx.scene.control.TableCell; -import javafx.scene.control.TableColumn; -import javafx.scene.control.TableView; -import javafx.scene.control.Tooltip; - -import javafx.beans.property.ReadOnlyObjectWrapper; - -import javafx.util.Callback; - -import java.util.Comparator; -import java.util.stream.Collectors; - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class ProposalResultsGridPane extends BaseResultsGridPane { - - private SelectionListener selectionListener; - private final BsqStateService bsqStateService; - - public ProposalResultsGridPane(SelectionListener selectionListener, - BsqWalletService bsqWalletService, DaoFacade daoFacade, BsqFormatter bsqFormatter, - BsqStateService bsqStateService) { - super(bsqWalletService, daoFacade, bsqFormatter, 0); - this.selectionListener = selectionListener; - this.bsqStateService = bsqStateService; - } - - @Override - protected void onSelected(ProposalResultsListItem item) { - itemList.forEach(ProposalResultsListItem::resetTableRow); - - if (item != null) - selectionListener.onSelectedEvaluatedProposal(item.getEvaluatedProposal()); - } - - public void onSelectedDecryptedVote(DecryptedVote decryptedVote) { - itemList.forEach(item -> item.applyVoteAndProposal(decryptedVote, item.getEvaluatedProposal())); - } - - @Override - protected void fillList() { - itemList.forEach(ProposalResultsListItem::resetTableRow); - - itemList.setAll(resultsOfCycle.getEvaluatedProposals().stream() - .map(e -> new ProposalResultsListItem(e, bsqFormatter)) - .collect(Collectors.toList())); - - itemList.sort(Comparator.comparing(proposalResultsListItem -> proposalResultsListItem.getEvaluatedProposal().getProposal().getCreationDate())); - } - - @Override - protected String getTitle() { - return Res.get("dao.results.proposals.header"); - } - - @Override - protected void createColumns(TableView tableView) { - TableColumn nameColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.proposals.table.header.proposalOwnerName")); - nameColumn.setMinWidth(110); - nameColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - nameColumn.setCellFactory( - new Callback, TableCell>() { - @Override - public TableCell call( - TableColumn column) { - return new TableCell() { - - @Override - public void updateItem(final ProposalResultsListItem item, boolean empty) { - super.updateItem(item, empty); - if (item != null) { - item.setTableRow(getTableRow()); - setText(item.getProposalOwnerName()); - } else { - setText(""); - } - } - }; - } - }); - nameColumn.setComparator(Comparator.comparing(ProposalResultsListItem::getProposalOwnerName)); - tableView.getColumns().add(nameColumn); - - - TableColumn issuanceColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.proposals.table.header.issuance")); - issuanceColumn.setMinWidth(100); - issuanceColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - issuanceColumn.setCellFactory( - new Callback, TableCell>() { - @Override - public TableCell call( - TableColumn column) { - return new TableCell() { - @Override - public void updateItem(final ProposalResultsListItem item, boolean empty) { - super.updateItem(item, empty); - if (item != null) - setText(item.getIssuance()); - else - setText(""); - } - }; - } - }); - issuanceColumn.setComparator(Comparator.comparing(ProposalResultsListItem::getThreshold)); - tableView.getColumns().add(issuanceColumn); - - TableColumn resultColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.proposals.table.header.result")); - resultColumn.setMinWidth(60); - resultColumn.setMaxWidth(60); - resultColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - resultColumn.setCellFactory(new Callback, - TableCell>() { - @Override - public TableCell call(TableColumn column) { - return new TableCell() { - Label icon; - - @Override - public void updateItem(final ProposalResultsListItem item, boolean empty) { - super.updateItem(item, empty); - - if (item != null && !empty) { - icon = new Label(); - AwesomeDude.setIcon(icon, item.getIcon()); - icon.getStyleClass().add(item.getColorStyleClass()); - setGraphic(icon); - } else { - setGraphic(null); - if (icon != null) - icon = null; - } - } - }; - } - }); - tableView.getColumns().add(resultColumn); - - - TableColumn detailsColumn = new TableColumn<>(); - detailsColumn.setMinWidth(60); - detailsColumn.setMaxWidth(60); - detailsColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - detailsColumn.setCellFactory(new Callback, - TableCell>() { - @Override - public TableCell call(TableColumn column) { - return new TableCell() { - Label icon; - Button button; - - @Override - public void updateItem(final ProposalResultsListItem item, boolean empty) { - super.updateItem(item, empty); - - if (item != null && !empty) { - icon = new Label(); - AwesomeDude.setIcon(icon, AwesomeIcon.INFO_SIGN); - icon.setTooltip(new Tooltip(Res.get("tooltip.openPopupForDetails"))); - icon.getStyleClass().add("info-icon"); - - button = new Button("", icon); - button.getStyleClass().add("info-icon-button"); - button.setOnAction(e -> { - new VoteResultsForProposalWindow(resultsOfCycle, - item.getEvaluatedProposal().getProposal(), - bsqStateService, - bsqFormatter) - .show(); - }); - setGraphic(button); - } else { - setGraphic(null); - if (icon != null) - icon = null; - if (button != null) - button = null; - } - } - }; - } - }); - tableView.getColumns().add(detailsColumn); - - - - - /* TableColumn idColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.proposals.table.header.proposalId")); - idColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - idColumn.setMinWidth(100); - idColumn.setCellFactory( - new Callback, TableCell>() { - - @Override - public TableCell call(TableColumn column) { - return new TableCell() { - private Hyperlink field; - - @Override - public void updateItem(final ProposalResultsListItem item, boolean empty) { - super.updateItem(item, empty); - - // cycleDetailsWindow.show(item.getEvaluatedProposal()) - if (item != null && !empty) { - field = new Hyperlink(item.getProposalId()); - - //TODO setId or getStyleClass.add does not apply color... - //field.getStyleClass().add(item.getColorStyleClass()); - //field.setId(item.getColorStyleClass()); - field.setStyle(item.getColorStyle()); - field.setOnAction(event -> new ProposalWindow(bsqFormatter, - bsqWalletService, - item.getEvaluatedProposal().getProposal(), - daoFacade) - .show()); - field.setTooltip(new Tooltip(Res.get("tooltip.openPopupForDetails"))); - setGraphic(field); - } else { - setGraphic(null); - if (field != null) - field.setOnAction(null); - } - } - }; - } - }); - idColumn.setComparator(Comparator.comparing(ProposalResultsListItem::getProposalOwnerName)); - tableView.getColumns().add(idColumn);*/ - - /* TableColumn acceptedColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.proposals.table.header.accepted")); - acceptedColumn.setMinWidth(80); - acceptedColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - acceptedColumn.setCellFactory( - new Callback, TableCell>() { - private Hyperlink field; - - @Override - public TableCell call( - TableColumn column) { - return new TableCell() { - @Override - public void updateItem(final ProposalResultsListItem item, boolean empty) { - super.updateItem(item, empty); - if (item != null && !empty) { - field = new Hyperlink(item.getAccepted()); - field.setStyle(item.getColorStyle()); - field.setOnAction(event -> new VoteResultsForProposalWindow(resultsOfCycle, - item.getEvaluatedProposal().getProposal(), - bsqStateService, - bsqFormatter) - .show()); - field.setTooltip(new Tooltip(Res.get("tooltip.openPopupForDetails"))); - setGraphic(field); - } else { - setGraphic(null); - - //TODO does get called on active items somehow... - //if (field != null) - // field.setOnAction(null); - } - } - }; - } - }); - acceptedColumn.setComparator(Comparator.comparing(ProposalResultsListItem::getAccepted)); - tableView.getColumns().add(acceptedColumn); - - TableColumn rejectedColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.proposals.table.header.rejected")); - rejectedColumn.setMinWidth(80); - rejectedColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - rejectedColumn.setCellFactory( - new Callback, TableCell>() { - private Hyperlink field; - - @Override - public TableCell call( - TableColumn column) { - return new TableCell() { - @Override - public void updateItem(final ProposalResultsListItem item, boolean empty) { - super.updateItem(item, empty); - if (item != null && !empty) { - field = new Hyperlink(item.getRejected()); - field.setStyle(item.getColorStyle()); - field.setOnAction(event -> new VoteResultsForProposalWindow(resultsOfCycle, - item.getEvaluatedProposal().getProposal(), - bsqStateService, - bsqFormatter) - .show()); - field.setTooltip(new Tooltip(Res.get("tooltip.openPopupForDetails"))); - setGraphic(field); - } else { - setGraphic(null); - //TODO does get called on active items somehow... - //if (field != null) - // field.setOnAction(null); - } - } - }; - } - }); - rejectedColumn.setComparator(Comparator.comparing(ProposalResultsListItem::getRejected)); - tableView.getColumns().add(rejectedColumn);*/ - - /* TableColumn thresholdColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.proposals.table.header.threshold")); - thresholdColumn.setMinWidth(100); - thresholdColumn.setMaxWidth(100); - thresholdColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - thresholdColumn.setCellFactory( - new Callback, TableCell>() { - @Override - public TableCell call( - TableColumn column) { - return new TableCell() { - @Override - public void updateItem(final ProposalResultsListItem item, boolean empty) { - super.updateItem(item, empty); - if (item != null) - setText(item.getThreshold()); - else - setText(""); - } - }; - } - }); - thresholdColumn.setComparator(Comparator.comparing(ProposalResultsListItem::getThreshold)); - tableView.getColumns().add(thresholdColumn);*/ - - /* TableColumn quorumColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.proposals.table.header.quorum")); - quorumColumn.setMinWidth(130); - quorumColumn.setMaxWidth(130); - quorumColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - quorumColumn.setCellFactory( - new Callback, TableCell>() { - @Override - public TableCell call( - TableColumn column) { - return new TableCell() { - @Override - public void updateItem(final ProposalResultsListItem item, boolean empty) { - super.updateItem(item, empty); - if (item != null) - setText(item.getQuorum()); - else - setText(""); - } - }; - } - }); - quorumColumn.setComparator(Comparator.comparing(ProposalResultsListItem::getThreshold)); - tableView.getColumns().add(quorumColumn);*/ - } -} diff --git a/src/main/java/bisq/desktop/main/dao/results/proposals/VoteResultsForProposalWindow.java b/src/main/java/bisq/desktop/main/dao/results/proposals/VoteResultsForProposalWindow.java deleted file mode 100644 index 041c7cab4fc..00000000000 --- a/src/main/java/bisq/desktop/main/dao/results/proposals/VoteResultsForProposalWindow.java +++ /dev/null @@ -1,271 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.desktop.main.dao.results.proposals; - -import bisq.desktop.components.AutoTooltipLabel; -import bisq.desktop.components.AutoTooltipTableColumn; -import bisq.desktop.components.TableGroupHeadline; -import bisq.desktop.main.MainView; -import bisq.desktop.main.dao.results.model.ResultsOfCycle; -import bisq.desktop.main.overlays.Overlay; -import bisq.desktop.util.FormBuilder; -import bisq.desktop.util.GUIUtil; - -import bisq.core.dao.state.BsqStateService; -import bisq.core.dao.voting.proposal.Proposal; -import bisq.core.locale.Res; -import bisq.core.util.BsqFormatter; - -import bisq.common.util.Tuple2; - -import de.jensd.fx.fontawesome.AwesomeDude; -import de.jensd.fx.fontawesome.AwesomeIcon; - -import javafx.scene.control.Button; -import javafx.scene.control.Label; -import javafx.scene.control.TableCell; -import javafx.scene.control.TableColumn; -import javafx.scene.control.TableView; -import javafx.scene.layout.GridPane; - -import javafx.geometry.HPos; -import javafx.geometry.Insets; - -import javafx.beans.property.ReadOnlyObjectWrapper; - -import javafx.collections.FXCollections; -import javafx.collections.ObservableList; -import javafx.collections.transformation.SortedList; - -import javafx.util.Callback; - -import java.util.Comparator; - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class VoteResultsForProposalWindow extends Overlay { - private Proposal proposal; - private BsqStateService bsqStateService; - private final BsqFormatter bsqFormatter; - - private TableView tableView; - private int gridRow = 0; - private final ObservableList itemList = FXCollections.observableArrayList(); - private final SortedList sortedList = new SortedList<>(itemList); - protected ResultsOfCycle resultsOfCycle; - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Public API - /////////////////////////////////////////////////////////////////////////////////////////// - - public VoteResultsForProposalWindow(ResultsOfCycle resultsOfCycle, - Proposal proposal, - BsqStateService bsqStateService, - BsqFormatter bsqFormatter) { - this.resultsOfCycle = resultsOfCycle; - this.proposal = proposal; - this.bsqStateService = bsqStateService; - this.bsqFormatter = bsqFormatter; - type = Type.Confirmation; - } - - @Override - public void show() { - width = MainView.getRootContainer().getWidth() - 20; - - createGridPane(); - addContent(); - display(); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Protected - /////////////////////////////////////////////////////////////////////////////////////////// - - @Override - protected void createGridPane() { - super.createGridPane(); - - gridPane.setPadding(new Insets(35, 40, 30, 40)); - gridPane.getStyleClass().add("grid-pane"); - } - - private void addContent() { - TableGroupHeadline headline = new TableGroupHeadline(Res.get("dao.results.proposals.voting.detail.header")); - GridPane.setRowIndex(headline, gridRow); - GridPane.setMargin(headline, new Insets(0, -10, -10, -10)); - GridPane.setColumnSpan(headline, 2); - gridPane.getChildren().add(headline); - - // For some weird reason the stage key handler (ESC, ENTER) does not work as soon a tableView gets added... - tableView = new TableView<>(); - tableView.setPlaceholder(new AutoTooltipLabel(Res.get("table.placeholder.noData"))); - tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); - - createColumns(tableView); - GridPane.setRowIndex(tableView, gridRow); - GridPane.setMargin(tableView, new Insets(20, -10, 5, -10)); - GridPane.setColumnSpan(tableView, 2); - gridPane.getChildren().add(tableView); - - tableView.setItems(sortedList); - sortedList.comparatorProperty().bind(tableView.comparatorProperty()); - - fillList(); - - GUIUtil.setFitToRowsForTableView(tableView, 24, 28, 150); - - // Somehow setting the margin for closeButton does not work here as expected. adding a row does give us the desired layout... - ++rowIndex; - Button closeButton = FormBuilder.addButton(gridPane, ++rowIndex, Res.get("shared.close")); - GridPane.setHalignment(closeButton, HPos.RIGHT); - closeButton.setOnAction(e -> { - closeHandlerOptional.ifPresent(Runnable::run); - hide(); - }); - } - - private void fillList() { - itemList.clear(); - - resultsOfCycle.getEvaluatedProposals().stream() - .filter(evaluatedProposal -> evaluatedProposal.getProposal().equals(proposal)) - .forEach(evaluatedProposal -> { - resultsOfCycle.getDecryptedVotesForCycle().forEach(decryptedVote -> { - itemList.add(new VoteResultsForProposalListItem(evaluatedProposal.getProposal(), decryptedVote, - bsqStateService, bsqFormatter)); - }); - }); - - itemList.sort(Comparator.comparing(item -> item.getBlindVoteTxId())); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // TableColumns - /////////////////////////////////////////////////////////////////////////////////////////// - - private void createColumns(TableView tableView) { - TableColumn blindVoteTxIdColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.blindVoteTxId")); - blindVoteTxIdColumn.setSortable(false); - blindVoteTxIdColumn.setMinWidth(150); - blindVoteTxIdColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - blindVoteTxIdColumn.setCellFactory( - new Callback, TableCell>() { - @Override - public TableCell call( - TableColumn column) { - return new TableCell() { - @Override - public void updateItem(final VoteResultsForProposalListItem item, boolean empty) { - super.updateItem(item, empty); - if (item != null) - setText(item.getBlindVoteTxId()); - else - setText(""); - } - }; - } - }); - tableView.getColumns().add(blindVoteTxIdColumn); - - TableColumn voteColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.vote")); - voteColumn.setSortable(false); - voteColumn.setMinWidth(150); - voteColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - voteColumn.setCellFactory( - new Callback, TableCell>() { - @Override - public TableCell call( - TableColumn column) { - return new TableCell() { - private Label icon; - - @Override - public void updateItem(final VoteResultsForProposalListItem item, boolean empty) { - super.updateItem(item, empty); - - if (item != null && !empty) { - Tuple2 iconStyleTuple = item.getIconStyleTuple(); - icon = new Label(); - AwesomeDude.setIcon(icon, iconStyleTuple.first); - icon.getStyleClass().add(iconStyleTuple.second); - setGraphic(icon); - } else { - setGraphic(null); - } - } - }; - } - }); - tableView.getColumns().add(voteColumn); - - TableColumn meritColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.merit")); - meritColumn.setSortable(false); - meritColumn.setMinWidth(150); - meritColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - meritColumn.setCellFactory( - new Callback, TableCell>() { - @Override - public TableCell call( - TableColumn column) { - return new TableCell() { - @Override - public void updateItem(final VoteResultsForProposalListItem item, boolean empty) { - super.updateItem(item, empty); - if (item != null) - setText(item.getMerit()); - else - setText(""); - } - }; - } - }); - tableView.getColumns().add(meritColumn); - - TableColumn stakeColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.stake")); - stakeColumn.setSortable(false); - stakeColumn.setMinWidth(150); - stakeColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - stakeColumn.setCellFactory( - new Callback, TableCell>() { - @Override - public TableCell call( - TableColumn column) { - return new TableCell() { - @Override - public void updateItem(final VoteResultsForProposalListItem item, boolean empty) { - super.updateItem(item, empty); - if (item != null) - setText(item.getStake()); - else - setText(""); - } - }; - } - }); - tableView.getColumns().add(stakeColumn); - } -} diff --git a/src/main/java/bisq/desktop/main/dao/results/votes/VoteResultsGridPane.java b/src/main/java/bisq/desktop/main/dao/results/votes/VoteResultsGridPane.java deleted file mode 100644 index a2564fac77d..00000000000 --- a/src/main/java/bisq/desktop/main/dao/results/votes/VoteResultsGridPane.java +++ /dev/null @@ -1,425 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.desktop.main.dao.results.votes; - -import bisq.desktop.components.AutoTooltipTableColumn; -import bisq.desktop.main.dao.results.BaseResultsGridPane; -import bisq.desktop.main.dao.results.SelectionListener; -import bisq.desktop.util.GUIUtil; - -import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.DaoFacade; -import bisq.core.dao.state.BsqStateService; -import bisq.core.dao.voting.voteresult.DecryptedVote; -import bisq.core.dao.voting.voteresult.EvaluatedProposal; -import bisq.core.locale.Res; -import bisq.core.user.Preferences; -import bisq.core.util.BsqFormatter; - -import de.jensd.fx.fontawesome.AwesomeDude; -import de.jensd.fx.fontawesome.AwesomeIcon; - -import javafx.scene.control.Button; -import javafx.scene.control.Label; -import javafx.scene.control.TableCell; -import javafx.scene.control.TableColumn; -import javafx.scene.control.TableView; -import javafx.scene.control.Tooltip; - -import javafx.beans.property.ReadOnlyObjectWrapper; - -import javafx.util.Callback; - -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.stream.Collectors; - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class VoteResultsGridPane extends BaseResultsGridPane { - private SelectionListener selectionListener; - private final BsqStateService bsqStateService; - private final Preferences preferences; - - public VoteResultsGridPane(SelectionListener selectionListener, - BsqWalletService bsqWalletService, DaoFacade daoFacade, - BsqStateService bsqStateService, Preferences preferences, BsqFormatter bsqFormatter) { - super(bsqWalletService, daoFacade, bsqFormatter, 1); - this.selectionListener = selectionListener; - - this.bsqStateService = bsqStateService; - this.preferences = preferences; - } - - @Override - protected void onSelected(VoteResultsListItem item) { - itemList.forEach(VoteResultsListItem::resetTableRow); - - if (item != null) - selectionListener.onSelectedDecryptedVote(item.getDecryptedVote()); - } - - public void onSelectedEvaluatedProposal(EvaluatedProposal evaluatedProposal) { - itemList.forEach(item -> item.applyVoteAndProposal(item.getDecryptedVote(), evaluatedProposal)); - } - - @Override - protected void fillList() { - itemList.forEach(VoteResultsListItem::resetTableRow); - - List decryptedVotesForCycle = new ArrayList<>(resultsOfCycle.getDecryptedVotesForCycle()); - decryptedVotesForCycle.sort(Comparator.comparing(DecryptedVote::getBlindVoteTxId)); - AtomicInteger index = new AtomicInteger(); - itemList.setAll(decryptedVotesForCycle.stream() - .map(decryptedVote -> { - int id = index.incrementAndGet(); - return new VoteResultsListItem(id, decryptedVote, bsqStateService, bsqFormatter); - }) - .collect(Collectors.toList())); - } - - @Override - protected String getTitle() { - return Res.get("dao.results.votes.header"); - } - - @Override - protected void createColumns(TableView tableView) { - TableColumn stakeAndMeritColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.stakeAndMerit")); - stakeAndMeritColumn.setMinWidth(90); - stakeAndMeritColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - stakeAndMeritColumn.setCellFactory( - new Callback, TableCell>() { - - - @Override - public TableCell call( - TableColumn column) { - return new TableCell() { - @Override - public void updateItem(final VoteResultsListItem item, boolean empty) { - super.updateItem(item, empty); - if (item != null) { - item.setTableRow(getTableRow()); - setText(item.getStakeAndMerit()); - } else { - setText(""); - } - } - }; - } - }); - stakeAndMeritColumn.setComparator(Comparator.comparing(VoteResultsListItem::getStakeAsCoin)); - tableView.getColumns().add(stakeAndMeritColumn); - - TableColumn stakeColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.stake")); - stakeColumn.setMinWidth(90); - stakeColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - stakeColumn.setCellFactory( - new Callback, TableCell>() { - @Override - public TableCell call( - TableColumn column) { - return new TableCell() { - @Override - public void updateItem(final VoteResultsListItem item, boolean empty) { - super.updateItem(item, empty); - if (item != null) - setText(item.getStake()); - else - setText(""); - } - }; - } - }); - stakeColumn.setComparator(Comparator.comparing(VoteResultsListItem::getStakeAsCoin)); - tableView.getColumns().add(stakeColumn); - - TableColumn meritColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.merit")); - meritColumn.setMinWidth(90); - meritColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - meritColumn.setCellFactory( - new Callback, TableCell>() { - @Override - public TableCell call( - TableColumn column) { - return new TableCell() { - @Override - public void updateItem(final VoteResultsListItem item, boolean empty) { - super.updateItem(item, empty); - if (item != null) - setText(item.getMerit()); - else - setText(""); - } - }; - } - }); - meritColumn.setComparator(Comparator.comparing(VoteResultsListItem::getMeritAsCoin)); - tableView.getColumns().add(meritColumn); - - - TableColumn detailsColumn = new TableColumn<>(); - detailsColumn.setMinWidth(60); - detailsColumn.setMaxWidth(60); - detailsColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - detailsColumn.setCellFactory(new Callback, - TableCell>() { - @Override - public TableCell call(TableColumn column) { - return new TableCell() { - Label icon; - Button button; - - @Override - public void updateItem(final VoteResultsListItem item, boolean empty) { - super.updateItem(item, empty); - - if (item != null && !empty) { - icon = new Label(); - AwesomeDude.setIcon(icon, AwesomeIcon.INFO_SIGN); - icon.setTooltip(new Tooltip(Res.get("tooltip.openPopupForDetails"))); - icon.getStyleClass().add("info-icon"); - - button = new Button("", icon); - button.getStyleClass().add("info-icon-button"); - button.setOnAction(e -> { - /* new VoteResultsForProposalWindow(resultsOfCycle, - item.getEvaluatedProposal().getProposal(), - bsqStateService, - bsqFormatter) - .show();*/ - }); - setGraphic(button); - } else { - setGraphic(null); - if (icon != null) - icon = null; - if (button != null) - button = null; - } - } - }; - } - }); - tableView.getColumns().add(detailsColumn); - - /* - - TableColumn indexColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.id")); - indexColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - indexColumn.setMinWidth(70); - indexColumn.setCellFactory( - new Callback, TableCell>() { - @Override - public TableCell call( - TableColumn column) { - return new TableCell() { - @Override - public void updateItem(final VoteResultsListItem item, boolean empty) { - super.updateItem(item, empty); - if (item != null) - setText(item.getId()); - else - setText(""); - } - }; - } - }); - indexColumn.setComparator(Comparator.comparing(VoteResultsListItem::getStakeAsCoin)); - tableView.getColumns().add(indexColumn); - - TableColumn stakeColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.stake")); - stakeColumn.setMinWidth(70); - stakeColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - stakeColumn.setCellFactory( - new Callback, TableCell>() { - @Override - public TableCell call( - TableColumn column) { - return new TableCell() { - @Override - public void updateItem(final VoteResultsListItem item, boolean empty) { - super.updateItem(item, empty); - if (item != null) - setText(item.getStake()); - else - setText(""); - } - }; - } - }); - stakeColumn.setComparator(Comparator.comparing(VoteResultsListItem::getStakeAsCoin)); - tableView.getColumns().add(stakeColumn); - - TableColumn meritColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.merit")); - meritColumn.setMinWidth(70); - meritColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - meritColumn.setCellFactory( - new Callback, TableCell>() { - @Override - public TableCell call( - TableColumn column) { - return new TableCell() { - @Override - public void updateItem(final VoteResultsListItem item, boolean empty) { - super.updateItem(item, empty); - if (item != null) - setText(item.getMerit()); - else - setText(""); - } - }; - } - }); - meritColumn.setComparator(Comparator.comparing(VoteResultsListItem::getMeritAsCoin)); - tableView.getColumns().add(meritColumn); - - TableColumn acceptedColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.accepted")); - acceptedColumn.setMinWidth(70); - acceptedColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - acceptedColumn.setCellFactory( - new Callback, TableCell>() { - @Override - public TableCell call( - TableColumn column) { - return new TableCell() { - @Override - public void updateItem(final VoteResultsListItem item, boolean empty) { - super.updateItem(item, empty); - if (item != null) - setText(item.getNumAcceptedVotes()); - else - setText(""); - } - }; - } - }); - acceptedColumn.setComparator(Comparator.comparing(VoteResultsListItem::getNumAcceptedVotes)); - tableView.getColumns().add(acceptedColumn); - - TableColumn rejectedColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.rejected")); - rejectedColumn.setMinWidth(70); - rejectedColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - rejectedColumn.setCellFactory( - new Callback, TableCell>() { - @Override - public TableCell call( - TableColumn column) { - return new TableCell() { - @Override - public void updateItem(final VoteResultsListItem item, boolean empty) { - super.updateItem(item, empty); - if (item != null) - setText(item.getNumRejectedVotes()); - else - setText(""); - } - }; - } - }); - rejectedColumn.setComparator(Comparator.comparing(VoteResultsListItem::getNumRejectedVotes)); - tableView.getColumns().add(rejectedColumn); - - TableColumn blindVoteTxIdColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.blindVoteTxId")); - blindVoteTxIdColumn.setMinWidth(120); - blindVoteTxIdColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - blindVoteTxIdColumn.setCellFactory( - new Callback, TableCell>() { - - @Override - public TableCell call( - TableColumn column) { - return new TableCell() { - private HyperlinkWithIcon hyperlinkWithIcon; - - @Override - public void updateItem(final VoteResultsListItem item, boolean empty) { - super.updateItem(item, empty); - - if (item != null && !empty) { - String txId = item.getBlindVoteTxId(); - hyperlinkWithIcon = new HyperlinkWithIcon(txId, AwesomeIcon.EXTERNAL_LINK); - hyperlinkWithIcon.setOnAction(event -> openTxInBlockExplorer(txId)); - hyperlinkWithIcon.setTooltip(new Tooltip(Res.get("tooltip.openBlockchainForTx", txId))); - setGraphic(hyperlinkWithIcon); - } else { - setGraphic(null); - if (hyperlinkWithIcon != null) - hyperlinkWithIcon.setOnAction(null); - } - } - }; - } - }); - blindVoteTxIdColumn.setComparator(Comparator.comparing(VoteResultsListItem::getBlindVoteTxId)); - tableView.getColumns().add(blindVoteTxIdColumn); - - TableColumn voteRevealTxIdColumn = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.voteRevealTxId")); - voteRevealTxIdColumn.setMinWidth(120); - voteRevealTxIdColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - voteRevealTxIdColumn.setCellFactory( - new Callback, TableCell>() { - @Override - public TableCell call( - TableColumn column) { - return new TableCell() { - private HyperlinkWithIcon hyperlinkWithIcon; - - @Override - public void updateItem(final VoteResultsListItem item, boolean empty) { - super.updateItem(item, empty); - - if (item != null && !empty) { - String txId = item.getVoteRevealTxId(); - hyperlinkWithIcon = new HyperlinkWithIcon(txId, AwesomeIcon.EXTERNAL_LINK); - hyperlinkWithIcon.setOnAction(event -> openTxInBlockExplorer(txId)); - hyperlinkWithIcon.setTooltip(new Tooltip(Res.get("tooltip.openBlockchainForTx", txId))); - setGraphic(hyperlinkWithIcon); - } else { - setGraphic(null); - if (hyperlinkWithIcon != null) - hyperlinkWithIcon.setOnAction(null); - } - } - }; - } - }); - voteRevealTxIdColumn.setComparator(Comparator.comparing(VoteResultsListItem::getVoteRevealTxId)); - tableView.getColumns().add(voteRevealTxIdColumn);*/ - } - - private void openTxInBlockExplorer(String txId) { - if (txId != null) - GUIUtil.openWebPage(preferences.getBsqBlockChainExplorer().txUrl + txId); - } -} diff --git a/src/main/java/bisq/desktop/main/dao/results/votes/VoteResultsListItem.java b/src/main/java/bisq/desktop/main/dao/results/votes/VoteResultsListItem.java deleted file mode 100644 index d8b1b589116..00000000000 --- a/src/main/java/bisq/desktop/main/dao/results/votes/VoteResultsListItem.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.desktop.main.dao.results.votes; - -import bisq.desktop.main.dao.results.BaseResultsListItem; - -import bisq.core.dao.state.BsqStateService; -import bisq.core.dao.voting.ballot.vote.BooleanVote; -import bisq.core.dao.voting.ballot.vote.LongVote; -import bisq.core.dao.voting.proposal.Proposal; -import bisq.core.dao.voting.voteresult.DecryptedVote; -import bisq.core.locale.Res; -import bisq.core.util.BsqFormatter; - -import org.bitcoinj.core.Coin; - -import com.google.common.base.Joiner; - -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import lombok.Getter; - -public class VoteResultsListItem extends BaseResultsListItem { - private final BsqStateService bsqStateService; - private final BsqFormatter bsqFormatter; - private int id; - @Getter - private final DecryptedVote decryptedVote; - - public VoteResultsListItem(int id, DecryptedVote decryptedVote, BsqStateService bsqStateService, BsqFormatter bsqFormatter) { - this.id = id; - this.decryptedVote = decryptedVote; - this.bsqStateService = bsqStateService; - this.bsqFormatter = bsqFormatter; - } - - public String getBlindVoteTxId() { - return decryptedVote.getBlindVoteTxId(); - } - - public String getVoteRevealTxId() { - return decryptedVote.getVoteRevealTxId(); - } - - public String getStake() { - return bsqFormatter.formatCoinWithCode(getStakeAsCoin()); - } - - public String getStakeAndMerit() { - return bsqFormatter.formatCoinWithCode(getStakeAndMeritAsCoin()); - } - - public Coin getStakeAndMeritAsCoin() { - return getMeritAsCoin().add(getStakeAsCoin()); - } - - - public Coin getStakeAsCoin() { - return Coin.valueOf(decryptedVote.getStake()); - } - - public String getMerit() { - return bsqFormatter.formatCoinWithCode(getMeritAsCoin()); - } - - public Coin getMeritAsCoin() { - return Coin.valueOf(decryptedVote.getMerit(bsqStateService)); - } - - public String getNumAcceptedVotes() { - return String.valueOf(getBooleanVoteStream() - .filter(BooleanVote::isAccepted) - .collect(Collectors.toList()) - .size()); - } - - public String getNumRejectedVotes() { - return String.valueOf(getBooleanVoteStream() - .filter(booleanVote -> !booleanVote.isAccepted()) - .collect(Collectors.toList()) - .size()); - } - - private Stream getBooleanVoteStream() { - return decryptedVote.getBallotList().getList().stream() - .filter(ballot -> ballot.getVote() instanceof BooleanVote) - .map(ballot -> (BooleanVote) ballot.getVote()); - } - - public String getBallotList() { - return Joiner.on(", ").join(decryptedVote.getBallotList().getList().stream() - .map(ballot -> { - Proposal proposal = ballot.getProposal(); - String proposalUid = proposal.getShortId(); - if (ballot.getVote() instanceof BooleanVote) - return proposalUid + ": " + ((BooleanVote) ballot.getVote()).isAccepted(); - else if (ballot.getVote() instanceof LongVote) - return proposalUid + ": " + ((LongVote) ballot.getVote()).getValue(); - else - return proposalUid; - }) - .collect(Collectors.toList())); - } - - public String getId() { - return Res.get("dao.results.votes.table.cell.id", id); - } -} diff --git a/src/main/java/bisq/desktop/main/dao/voting/BaseBallotListItem.java b/src/main/java/bisq/desktop/main/dao/voting/BaseBallotListItem.java deleted file mode 100644 index 37ec10675d4..00000000000 --- a/src/main/java/bisq/desktop/main/dao/voting/BaseBallotListItem.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.desktop.main.dao.voting; - -import bisq.desktop.main.dao.BaseProposalListItem; - -import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.DaoFacade; -import bisq.core.dao.state.period.DaoPhase; -import bisq.core.dao.voting.ballot.Ballot; -import bisq.core.dao.voting.ballot.vote.BooleanVote; -import bisq.core.dao.voting.ballot.vote.Vote; -import bisq.core.dao.voting.proposal.Proposal; -import bisq.core.util.BsqFormatter; - -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.ToString; -import lombok.extern.slf4j.Slf4j; - -@ToString -@Slf4j -@EqualsAndHashCode(callSuper = true) -public class BaseBallotListItem extends BaseProposalListItem { - @Getter - private final Ballot ballot; - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Constructor, lifecycle - /////////////////////////////////////////////////////////////////////////////////////////// - - protected BaseBallotListItem(Ballot ballot, - DaoFacade daoFacade, - BsqWalletService bsqWalletService, - BsqFormatter bsqFormatter) { - super(daoFacade, - bsqWalletService, - bsqFormatter); - - this.ballot = ballot; - - init(); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Protected - /////////////////////////////////////////////////////////////////////////////////////////// - - @Override - protected void init() { - super.init(); - } - - @Override - public void onPhaseChanged(DaoPhase.Phase phase) { - super.onPhaseChanged(phase); - - final Vote vote = ballot.getVote(); - if (vote != null) { - imageView.setVisible(true); - if (vote instanceof BooleanVote) { - if (((BooleanVote) vote).isAccepted()) { - imageView.setId("accepted"); - } else { - imageView.setId("rejected"); - } - }/* else { - // not impl. - }*/ - } else { - imageView.setVisible(false); - } - } - - @Override - public Proposal getProposal() { - return ballot.getProposal(); - } -} diff --git a/src/main/java/bisq/desktop/main/dao/voting/VotingView.fxml b/src/main/java/bisq/desktop/main/dao/voting/VotingView.fxml deleted file mode 100644 index a5bf85f199a..00000000000 --- a/src/main/java/bisq/desktop/main/dao/voting/VotingView.fxml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/src/main/java/bisq/desktop/main/dao/voting/VotingView.java b/src/main/java/bisq/desktop/main/dao/voting/VotingView.java deleted file mode 100644 index 43ed3a09a78..00000000000 --- a/src/main/java/bisq/desktop/main/dao/voting/VotingView.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.desktop.main.dao.voting; - -import bisq.desktop.Navigation; -import bisq.desktop.common.view.ActivatableViewAndModel; -import bisq.desktop.common.view.CachingViewLoader; -import bisq.desktop.common.view.FxmlView; -import bisq.desktop.common.view.View; -import bisq.desktop.common.view.ViewLoader; -import bisq.desktop.common.view.ViewPath; -import bisq.desktop.components.MenuItem; -import bisq.desktop.main.MainView; -import bisq.desktop.main.dao.DaoView; -import bisq.desktop.main.dao.voting.active.ActiveBallotsView; -import bisq.desktop.main.dao.voting.closed.ClosedBallotsView; -import bisq.desktop.main.dao.voting.dashboard.VotingDashboardView; - -import bisq.core.locale.Res; - -import javax.inject.Inject; - -import de.jensd.fx.fontawesome.AwesomeIcon; - -import javafx.fxml.FXML; - -import javafx.scene.control.ToggleGroup; -import javafx.scene.layout.AnchorPane; -import javafx.scene.layout.VBox; - -import java.util.Arrays; -import java.util.List; - -@FxmlView -public class VotingView extends ActivatableViewAndModel { - - private final ViewLoader viewLoader; - private final Navigation navigation; - - private MenuItem dashboard, activeBallots, closedBallots; - private Navigation.Listener listener; - - @FXML - private VBox leftVBox; - @FXML - private AnchorPane content; - - private Class selectedViewClass; - - @Inject - private VotingView(CachingViewLoader viewLoader, Navigation navigation) { - this.viewLoader = viewLoader; - this.navigation = navigation; - } - - @Override - public void initialize() { - listener = viewPath -> { - if (viewPath.size() != 4 || viewPath.indexOf(VotingView.class) != 2) - return; - - selectedViewClass = viewPath.tip(); - loadView(selectedViewClass); - }; - - ToggleGroup toggleGroup = new ToggleGroup(); - final List> baseNavPath = Arrays.asList(MainView.class, DaoView.class, VotingView.class); - dashboard = new MenuItem(navigation, toggleGroup, Res.get("shared.dashboard"), - VotingDashboardView.class, AwesomeIcon.DASHBOARD, baseNavPath); - activeBallots = new MenuItem(navigation, toggleGroup, Res.get("dao.voting.menuItem.activeBallots"), - ActiveBallotsView.class, AwesomeIcon.LIST_UL, baseNavPath); - closedBallots = new MenuItem(navigation, toggleGroup, Res.get("dao.voting.menuItem.closedBallots"), - ClosedBallotsView.class, AwesomeIcon.LIST_ALT, baseNavPath); - leftVBox.getChildren().addAll(dashboard, activeBallots, closedBallots); - } - - @Override - protected void activate() { - dashboard.activate(); - activeBallots.activate(); - closedBallots.activate(); - - navigation.addListener(listener); - ViewPath viewPath = navigation.getCurrentPath(); - if (viewPath.size() == 3 && viewPath.indexOf(VotingView.class) == 2 || - viewPath.size() == 2 && viewPath.indexOf(DaoView.class) == 1) { - if (selectedViewClass == null) - selectedViewClass = ActiveBallotsView.class; - - loadView(selectedViewClass); - - } else if (viewPath.size() == 4 && viewPath.indexOf(VotingView.class) == 2) { - selectedViewClass = viewPath.get(3); - loadView(selectedViewClass); - } - } - - @Override - protected void deactivate() { - navigation.removeListener(listener); - - dashboard.deactivate(); - activeBallots.deactivate(); - closedBallots.deactivate(); - } - - private void loadView(Class viewClass) { - View view = viewLoader.load(viewClass); - content.getChildren().setAll(view.getRoot()); - - if (view instanceof VotingDashboardView) dashboard.setSelected(true); - else if (view instanceof ActiveBallotsView) activeBallots.setSelected(true); - else if (view instanceof ClosedBallotsView) closedBallots.setSelected(true); - } -} diff --git a/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotListItem.java b/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotListItem.java deleted file mode 100644 index f421a621274..00000000000 --- a/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotListItem.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.desktop.main.dao.voting.active; - -import bisq.desktop.main.dao.voting.BaseBallotListItem; - -import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.DaoFacade; -import bisq.core.dao.voting.ballot.Ballot; -import bisq.core.util.BsqFormatter; - -import lombok.EqualsAndHashCode; -import lombok.ToString; -import lombok.extern.slf4j.Slf4j; - -@ToString -@Slf4j -@EqualsAndHashCode(callSuper = true) -class ActiveBallotListItem extends BaseBallotListItem { - - /////////////////////////////////////////////////////////////////////////////////////////// - // Constructor, lifecycle - /////////////////////////////////////////////////////////////////////////////////////////// - - ActiveBallotListItem(Ballot ballot, - DaoFacade daoFacade, - BsqWalletService bsqWalletService, - BsqFormatter bsqFormatter) { - super(ballot, - daoFacade, - bsqWalletService, - bsqFormatter); - } -} diff --git a/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.fxml b/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.fxml deleted file mode 100644 index e2c84c86546..00000000000 --- a/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.fxml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - diff --git a/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.java b/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.java deleted file mode 100644 index 8377983eda5..00000000000 --- a/src/main/java/bisq/desktop/main/dao/voting/active/ActiveBallotsView.java +++ /dev/null @@ -1,395 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.desktop.main.dao.voting.active; - -import bisq.desktop.common.view.FxmlView; -import bisq.desktop.components.BusyAnimation; -import bisq.desktop.components.InputTextField; -import bisq.desktop.main.dao.BaseProposalListItem; -import bisq.desktop.main.dao.BaseProposalView; -import bisq.desktop.main.overlays.popups.Popup; -import bisq.desktop.util.GUIUtil; -import bisq.desktop.util.Layout; -import bisq.desktop.util.validation.BsqValidator; - -import bisq.core.btc.exceptions.TransactionVerificationException; -import bisq.core.btc.exceptions.WalletException; -import bisq.core.btc.wallet.BsqBalanceListener; -import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.DaoFacade; -import bisq.core.dao.state.BsqStateListener; -import bisq.core.dao.state.blockchain.Block; -import bisq.core.dao.state.period.DaoPhase; -import bisq.core.dao.voting.ballot.Ballot; -import bisq.core.dao.voting.ballot.vote.BooleanVote; -import bisq.core.dao.voting.proposal.Proposal; -import bisq.core.locale.Res; -import bisq.core.util.BSFormatter; -import bisq.core.util.BsqFormatter; - -import bisq.common.util.Tuple2; -import bisq.common.util.Tuple3; - -import org.bitcoinj.core.Coin; -import org.bitcoinj.core.InsufficientMoneyException; -import org.bitcoinj.core.Transaction; - -import javax.inject.Inject; - -import javafx.scene.control.Button; -import javafx.scene.control.Label; -import javafx.scene.control.TableCell; -import javafx.scene.control.TableColumn; -import javafx.scene.control.TableView; -import javafx.scene.image.ImageView; - -import javafx.beans.property.ReadOnlyObjectWrapper; -import javafx.beans.value.ChangeListener; - -import javafx.collections.ListChangeListener; - -import javafx.util.Callback; - -import java.util.List; -import java.util.stream.Collectors; - -import static bisq.desktop.util.FormBuilder.add3ButtonsAfterGroup; -import static bisq.desktop.util.FormBuilder.addButtonBusyAnimationLabelAfterGroup; -import static bisq.desktop.util.FormBuilder.addLabelInputTextField; -import static bisq.desktop.util.FormBuilder.addTitledGroupBg; - -@FxmlView -public class ActiveBallotsView extends BaseProposalView implements BsqBalanceListener, BsqStateListener { - private Button acceptButton, rejectButton, removeMyVoteButton, voteButton; - private InputTextField stakeInputTextField; - private BusyAnimation voteButtonBusyAnimation; - private Label voteButtonInfoLabel; - private ListChangeListener listChangeListener; - private ChangeListener stakeListener; - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Constructor, lifecycle - /////////////////////////////////////////////////////////////////////////////////////////// - - @Inject - private ActiveBallotsView(DaoFacade daoFacade, - BsqWalletService bsqWalletService, - BsqFormatter bsqFormatter, - BSFormatter btcFormatter) { - - super(daoFacade, bsqWalletService, bsqFormatter, btcFormatter); - } - - @Override - public void initialize() { - super.initialize(); - - createProposalsTableView(); - createVoteView(); - createEmptyProposalDisplay(); - - stakeListener = (observable, oldValue, newValue) -> updateButtons(); - listChangeListener = c -> updateListItems(); - } - - @Override - protected void activate() { - super.activate(); - - stakeInputTextField.textProperty().addListener(stakeListener); - daoFacade.getValidAndConfirmedBallots().addListener(listChangeListener); - bsqWalletService.addBsqBalanceListener(this); - - onUpdateBalances(bsqWalletService.getAvailableBalance(), - bsqWalletService.getAvailableNonBsqBalance(), - bsqWalletService.getUnverifiedBalance(), - bsqWalletService.getLockedForVotingBalance(), - bsqWalletService.getLockupBondsBalance(), - bsqWalletService.getUnlockingBondsBalance()); - - voteButton.setOnAction(e -> onVote()); - - daoFacade.addBsqStateListener(this); - - updateButtons(); - } - - - @Override - protected void deactivate() { - super.deactivate(); - - stakeInputTextField.textProperty().removeListener(stakeListener); - daoFacade.getValidAndConfirmedBallots().removeListener(listChangeListener); - bsqWalletService.removeBsqBalanceListener(this); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // BsqBalanceListener - /////////////////////////////////////////////////////////////////////////////////////////// - - @Override - public void onUpdateBalances(Coin confirmedBalance, - Coin availableNonBsqBalance, - Coin pendingBalance, - Coin lockedForVotingBalance, - Coin lockupBondsBalance, - Coin unlockingBondsBalance) { - stakeInputTextField.setPromptText(Res.get("dao.proposal.myVote.stake.prompt", - bsqFormatter.formatCoinWithCode(confirmedBalance))); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // BsqStateListener - /////////////////////////////////////////////////////////////////////////////////////////// - - @Override - public void onNewBlockHeight(int blockHeight) { - } - - @Override - public void onEmptyBlockAdded(Block block) { - } - - @Override - public void onParseTxsComplete(Block block) { - updateButtons(); - } - - @Override - public void onParseBlockChainComplete() { - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Protected - /////////////////////////////////////////////////////////////////////////////////////////// - - @Override - protected void fillListItems() { - List list = daoFacade.getValidAndConfirmedBallots(); - proposalBaseProposalListItems.setAll(list.stream() - .map(ballot -> new ActiveBallotListItem(ballot, daoFacade, bsqWalletService, bsqFormatter)) - .collect(Collectors.toSet())); - updateButtons(); - } - - @Override - protected void createAllFieldsOnProposalDisplay(Proposal proposal) { - super.createAllFieldsOnProposalDisplay(proposal); - - Tuple3 tuple = add3ButtonsAfterGroup(detailsGridPane, - proposalDisplay.incrementAndGetGridRow(), - Res.get("dao.proposal.myVote.accept"), - Res.get("dao.proposal.myVote.reject"), - Res.get("dao.proposal.myVote.removeMyVote")); - acceptButton = tuple.first; - acceptButton.setDefaultButton(false); - rejectButton = tuple.second; - removeMyVoteButton = tuple.third; - acceptButton.setOnAction(event -> onAccept()); - rejectButton.setOnAction(event -> onReject()); - removeMyVoteButton.setOnAction(event -> onCancelVote()); - } - - @Override - protected void hideProposalDisplay() { - super.hideProposalDisplay(); - - if (acceptButton != null) { - acceptButton.setManaged(false); - acceptButton.setVisible(false); - } - if (rejectButton != null) { - rejectButton.setManaged(false); - rejectButton.setVisible(false); - } - if (removeMyVoteButton != null) { - removeMyVoteButton.setManaged(false); - removeMyVoteButton.setVisible(false); - } - } - - @Override - protected void onPhaseChanged(DaoPhase.Phase phase) { - super.onPhaseChanged(phase); - - updateButtons(); - } - - @Override - protected void onSelectProposal(BaseProposalListItem item) { - super.onSelectProposal(item); - - updateButtons(); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Handlers - /////////////////////////////////////////////////////////////////////////////////////////// - - private void onAccept() { - daoFacade.setVote(getBallotListItem().getBallot(), new BooleanVote(true)); - updateStateAfterVote(); - } - - private void onReject() { - daoFacade.setVote(getBallotListItem().getBallot(), new BooleanVote(false)); - updateStateAfterVote(); - } - - private void onCancelVote() { - daoFacade.setVote(getBallotListItem().getBallot(), null); - updateStateAfterVote(); - } - - private void onVote() { - // TODO verify stake - Coin stake = bsqFormatter.parseToCoin(stakeInputTextField.getText()); - final Coin blindVoteFee = daoFacade.getBlindVoteFeeForCycle(); - Transaction dummyTx = null; - try { - // We create a dummy tx to get the mining blindVoteFee for confirmation popup - dummyTx = daoFacade.getDummyBlindVoteTx(stake, blindVoteFee); - } catch (InsufficientMoneyException | WalletException | TransactionVerificationException exception) { - new Popup<>().warning(exception.toString()).show(); - } - - if (dummyTx != null) { - Coin miningFee = dummyTx.getFee(); - int txSize = dummyTx.bitcoinSerialize().length; - GUIUtil.showBsqFeeInfoPopup(blindVoteFee, miningFee, txSize, bsqFormatter, btcFormatter, - Res.get("dao.blindVote"), () -> publishBlindVote(stake)); - } - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Private - /////////////////////////////////////////////////////////////////////////////////////////// - - private void publishBlindVote(Coin stake) { - voteButtonBusyAnimation.play(); - voteButtonInfoLabel.setText(Res.get("dao.blindVote.startPublishing")); - daoFacade.publishBlindVote(stake, - () -> { - voteButtonBusyAnimation.stop(); - voteButtonInfoLabel.setText(""); - new Popup().feedback(Res.get("dao.blindVote.success")) - .show(); - }, exception -> { - voteButtonBusyAnimation.stop(); - voteButtonInfoLabel.setText(""); - new Popup<>().warning(exception.toString()).show(); - }); - } - - - private void updateStateAfterVote() { - hideProposalDisplay(); - proposalTableView.getSelectionModel().clearSelection(); - proposalTableView.refresh(); - } - - private ActiveBallotListItem getBallotListItem() { - return (ActiveBallotListItem) selectedBaseProposalListItem; - } - - private void updateButtons() { - final boolean isBlindVotePhase = daoFacade.phaseProperty().get() == DaoPhase.Phase.BLIND_VOTE; - stakeInputTextField.setDisable(!isBlindVotePhase); - voteButton.setDisable(!isBlindVotePhase && - stakeInputTextField.getValidator().validate(stakeInputTextField.getText()).isValid); - - if (acceptButton != null) acceptButton.setDisable(!isBlindVotePhase); - if (rejectButton != null) rejectButton.setDisable(!isBlindVotePhase); - if (removeMyVoteButton != null) removeMyVoteButton.setDisable(!isBlindVotePhase); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Create views - /////////////////////////////////////////////////////////////////////////////////////////// - - private void createVoteView() { - addTitledGroupBg(root, ++gridRow, 1, - Res.get("dao.proposal.votes.header"), Layout.GROUP_DISTANCE - 20); - final Tuple2 tuple2 = addLabelInputTextField(root, gridRow, - Res.getWithCol("dao.proposal.myVote.stake"), Layout.FIRST_ROW_AND_GROUP_DISTANCE - 20); - stakeInputTextField = tuple2.second; - stakeInputTextField.setValidator(new BsqValidator(bsqFormatter)); - - Tuple3 tuple = addButtonBusyAnimationLabelAfterGroup(root, ++gridRow, - Res.get("dao.proposal.myVote.button")); - voteButton = tuple.first; - voteButtonBusyAnimation = tuple.second; - voteButtonInfoLabel = tuple.third; - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // TableColumns - /////////////////////////////////////////////////////////////////////////////////////////// - - @Override - protected void createProposalColumns(TableView tableView) { - super.createProposalColumns(tableView); - createConfidenceColumn(tableView); - - TableColumn actionColumn = new TableColumn<>(); - actionColumn.setMinWidth(130); - actionColumn.setMaxWidth(actionColumn.getMinWidth()); - - actionColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - - actionColumn.setCellFactory(new Callback, - TableCell>() { - - @Override - public TableCell call(TableColumn column) { - return new TableCell() { - ImageView imageView; - - @Override - public void updateItem(final BaseProposalListItem item, boolean empty) { - super.updateItem(item, empty); - - if (item != null && !empty) { - ActiveBallotListItem activeBallotListItem = (ActiveBallotListItem) item; - if (imageView == null) { - imageView = activeBallotListItem.getImageView(); - setGraphic(imageView); - } - activeBallotListItem.onPhaseChanged(currentPhase); - } else { - setGraphic(null); - if (imageView != null) - imageView = null; - } - } - }; - } - }); - tableView.getColumns().add(actionColumn); - } -} diff --git a/src/main/java/bisq/desktop/main/dao/voting/closed/ClosedBallotListItem.java b/src/main/java/bisq/desktop/main/dao/voting/closed/ClosedBallotListItem.java deleted file mode 100644 index a1c4c38f425..00000000000 --- a/src/main/java/bisq/desktop/main/dao/voting/closed/ClosedBallotListItem.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.desktop.main.dao.voting.closed; - -import bisq.desktop.main.dao.voting.BaseBallotListItem; - -import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.DaoFacade; -import bisq.core.dao.voting.ballot.Ballot; -import bisq.core.util.BsqFormatter; - -import lombok.EqualsAndHashCode; -import lombok.ToString; -import lombok.extern.slf4j.Slf4j; - -@ToString -@Slf4j -@EqualsAndHashCode(callSuper = true) -class ClosedBallotListItem extends BaseBallotListItem { - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Constructor, lifecycle - /////////////////////////////////////////////////////////////////////////////////////////// - - public ClosedBallotListItem(Ballot ballot, - DaoFacade daoFacade, - BsqWalletService bsqWalletService, - BsqFormatter bsqFormatter) { - super(ballot, - daoFacade, - bsqWalletService, - bsqFormatter); - } -} diff --git a/src/main/java/bisq/desktop/main/dao/voting/closed/ClosedBallotsView.fxml b/src/main/java/bisq/desktop/main/dao/voting/closed/ClosedBallotsView.fxml deleted file mode 100644 index bd54b16c97a..00000000000 --- a/src/main/java/bisq/desktop/main/dao/voting/closed/ClosedBallotsView.fxml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/src/main/java/bisq/desktop/main/dao/voting/closed/ClosedBallotsView.java b/src/main/java/bisq/desktop/main/dao/voting/closed/ClosedBallotsView.java deleted file mode 100644 index adacb084380..00000000000 --- a/src/main/java/bisq/desktop/main/dao/voting/closed/ClosedBallotsView.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.desktop.main.dao.voting.closed; - -import bisq.desktop.common.view.FxmlView; -import bisq.desktop.main.dao.BaseProposalListItem; -import bisq.desktop.main.dao.BaseProposalView; - -import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.DaoFacade; -import bisq.core.dao.voting.ballot.Ballot; -import bisq.core.util.BSFormatter; -import bisq.core.util.BsqFormatter; - -import javax.inject.Inject; - -import javafx.scene.control.TableCell; -import javafx.scene.control.TableColumn; -import javafx.scene.control.TableView; -import javafx.scene.image.ImageView; - -import javafx.beans.property.ReadOnlyObjectWrapper; - -import javafx.collections.ListChangeListener; - -import javafx.util.Callback; - -import java.util.Comparator; -import java.util.List; -import java.util.stream.Collectors; - -@FxmlView -public class ClosedBallotsView extends BaseProposalView { - private ListChangeListener listChangeListener; - - /////////////////////////////////////////////////////////////////////////////////////////// - // Constructor, lifecycle - /////////////////////////////////////////////////////////////////////////////////////////// - - @Inject - private ClosedBallotsView(DaoFacade daoFacade, - BsqWalletService bsqWalletService, - BsqFormatter bsqFormatter, - BSFormatter btcFormatter) { - - super(daoFacade, bsqWalletService, bsqFormatter, btcFormatter); - } - - @Override - public void initialize() { - super.initialize(); - - createProposalsTableView(); - createEmptyProposalDisplay(); - - listChangeListener = c -> updateListItems(); - } - - @Override - protected void activate() { - super.activate(); - - daoFacade.getClosedBallots().addListener(listChangeListener); - } - - - @Override - protected void deactivate() { - super.deactivate(); - - daoFacade.getClosedBallots().removeListener(listChangeListener); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Protected - /////////////////////////////////////////////////////////////////////////////////////////// - - @Override - protected void fillListItems() { - List list = daoFacade.getClosedBallots(); - proposalBaseProposalListItems.setAll(list.stream() - .map(ballot -> new ClosedBallotListItem(ballot, daoFacade, bsqWalletService, bsqFormatter)) - .collect(Collectors.toSet())); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Private - /////////////////////////////////////////////////////////////////////////////////////////// - - - /////////////////////////////////////////////////////////////////////////////////////////// - // TableColumns - /////////////////////////////////////////////////////////////////////////////////////////// - - @Override - protected void createProposalColumns(TableView tableView) { - super.createProposalColumns(tableView); - createConfidenceColumn(tableView); - - TableColumn actionColumn = new TableColumn<>(); - actionColumn.setMinWidth(130); - actionColumn.setMaxWidth(actionColumn.getMinWidth()); - - actionColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - - actionColumn.setCellFactory(new Callback, - TableCell>() { - - @Override - public TableCell call(TableColumn column) { - return new TableCell() { - ImageView imageView; - - @Override - public void updateItem(final BaseProposalListItem item, boolean empty) { - super.updateItem(item, empty); - - if (item != null && !empty) { - ClosedBallotListItem closedBallotListItem = (ClosedBallotListItem) item; - if (imageView == null) { - imageView = closedBallotListItem.getImageView(); - setGraphic(imageView); - } - closedBallotListItem.onPhaseChanged(currentPhase); - } else { - setGraphic(null); - if (imageView != null) - imageView = null; - } - } - }; - } - }); - actionColumn.setComparator(Comparator.comparing(BaseProposalListItem::getConfirmations)); - tableView.getColumns().add(actionColumn); - } -} diff --git a/src/main/java/bisq/desktop/main/dao/voting/closed/VotingHistoryView.fxml b/src/main/java/bisq/desktop/main/dao/voting/closed/VotingHistoryView.fxml deleted file mode 100644 index a08e3faa5c1..00000000000 --- a/src/main/java/bisq/desktop/main/dao/voting/closed/VotingHistoryView.fxml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - diff --git a/src/main/java/bisq/desktop/main/dao/voting/closed/VotingHistoryView.java b/src/main/java/bisq/desktop/main/dao/voting/closed/VotingHistoryView.java deleted file mode 100644 index 2569a9c5b31..00000000000 --- a/src/main/java/bisq/desktop/main/dao/voting/closed/VotingHistoryView.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.desktop.main.dao.voting.closed; - -import bisq.desktop.common.view.ActivatableView; -import bisq.desktop.common.view.FxmlView; - -import javax.inject.Inject; - -import javafx.scene.layout.GridPane; - -@FxmlView -public class VotingHistoryView extends ActivatableView { - - /////////////////////////////////////////////////////////////////////////////////////////// - // Constructor, lifecycle - /////////////////////////////////////////////////////////////////////////////////////////// - - @Inject - private VotingHistoryView() { - } - - @Override - public void initialize() { - } - - @Override - protected void activate() { - } - - @Override - protected void deactivate() { - } -} - diff --git a/src/main/java/bisq/desktop/main/dao/voting/dashboard/VotingDashboardView.fxml b/src/main/java/bisq/desktop/main/dao/voting/dashboard/VotingDashboardView.fxml deleted file mode 100644 index 8dcdc823735..00000000000 --- a/src/main/java/bisq/desktop/main/dao/voting/dashboard/VotingDashboardView.fxml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - diff --git a/src/main/java/bisq/desktop/main/dao/voting/dashboard/VotingDashboardView.java b/src/main/java/bisq/desktop/main/dao/voting/dashboard/VotingDashboardView.java deleted file mode 100644 index 8619c2e6f31..00000000000 --- a/src/main/java/bisq/desktop/main/dao/voting/dashboard/VotingDashboardView.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.desktop.main.dao.voting.dashboard; - -import bisq.desktop.common.view.FxmlView; -import bisq.desktop.main.dao.proposal.CycleOverview; -import bisq.desktop.main.dao.proposal.dashboard.ProposalDashboardView; - -import bisq.core.dao.DaoFacade; -import bisq.core.util.BSFormatter; - -import javax.inject.Inject; - -@FxmlView -public class VotingDashboardView extends ProposalDashboardView { - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Constructor, lifecycle - /////////////////////////////////////////////////////////////////////////////////////////// - - @Inject - private VotingDashboardView(DaoFacade daoFacade, CycleOverview cycleOverview, BSFormatter formatter) { - super(daoFacade, cycleOverview, formatter); - } - - @Override - public void initialize() { - super.initialize(); - } - - @Override - protected void activate() { - super.activate(); - } - - @Override - protected void deactivate() { - super.deactivate(); - } -} - diff --git a/src/main/java/bisq/desktop/main/dao/voting/vote/VoteView.fxml b/src/main/java/bisq/desktop/main/dao/voting/vote/VoteView.fxml deleted file mode 100644 index af532cb4d3e..00000000000 --- a/src/main/java/bisq/desktop/main/dao/voting/vote/VoteView.fxml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - diff --git a/src/main/java/bisq/desktop/main/dao/voting/vote/VoteView.java b/src/main/java/bisq/desktop/main/dao/voting/vote/VoteView.java deleted file mode 100644 index 802f527b3d4..00000000000 --- a/src/main/java/bisq/desktop/main/dao/voting/vote/VoteView.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.desktop.main.dao.voting.vote; - -import bisq.desktop.common.view.ActivatableView; -import bisq.desktop.common.view.FxmlView; - -import javax.inject.Inject; - -import javafx.scene.layout.GridPane; - -@FxmlView -public class VoteView extends ActivatableView { - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Constructor, lifecycle - /////////////////////////////////////////////////////////////////////////////////////////// - - @Inject - private VoteView() { - } - - @Override - public void initialize() { - } - - @Override - protected void activate() { - } - - @Override - protected void deactivate() { - } -} From bd80e9d97d0a5a8285d74243d071794b1adb468d Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sun, 5 Aug 2018 22:57:36 +0200 Subject: [PATCH 176/197] Add result view and show merit --- .../java/bisq/desktop/main/dao/DaoView.java | 15 +- .../main/dao/proposal/ProposalDisplay.java | 113 ++- .../main/dao/proposal/ProposalView.java | 16 +- .../proposal/closed/ClosedProposalsView.java | 65 -- .../dao/proposal/open/OpenProposalsView.java | 131 ++- .../ClosedProposalListItem.java | 2 +- .../result/CycleListItem.java} | 14 +- .../result/ProposalListItem.java} | 66 +- .../result}/ResultsOfCycle.java | 2 +- .../result/VoteListItem.java} | 21 +- .../VoteResultView.fxml} | 2 +- .../dao/proposal/result/VoteResultView.java | 826 ++++++++++++++++++ 12 files changed, 1109 insertions(+), 164 deletions(-) delete mode 100644 src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java rename src/main/java/bisq/desktop/main/dao/proposal/{closed => result}/ClosedProposalListItem.java (97%) rename src/main/java/bisq/desktop/main/dao/{results/ResultsListItem.java => proposal/result/CycleListItem.java} (89%) rename src/main/java/bisq/desktop/main/dao/{results/proposals/ProposalResultsListItem.java => proposal/result/ProposalListItem.java} (52%) rename src/main/java/bisq/desktop/main/dao/{results/model => proposal/result}/ResultsOfCycle.java (98%) rename src/main/java/bisq/desktop/main/dao/{results/proposals/VoteResultsForProposalListItem.java => proposal/result/VoteListItem.java} (84%) rename src/main/java/bisq/desktop/main/dao/proposal/{closed/ClosedProposalsView.fxml => result/VoteResultView.fxml} (97%) create mode 100644 src/main/java/bisq/desktop/main/dao/proposal/result/VoteResultView.java diff --git a/src/main/java/bisq/desktop/main/dao/DaoView.java b/src/main/java/bisq/desktop/main/dao/DaoView.java index ed99ba512bd..21b289f260d 100644 --- a/src/main/java/bisq/desktop/main/dao/DaoView.java +++ b/src/main/java/bisq/desktop/main/dao/DaoView.java @@ -27,7 +27,6 @@ import bisq.desktop.main.MainView; import bisq.desktop.main.dao.bonding.BondingView; import bisq.desktop.main.dao.proposal.ProposalView; -import bisq.desktop.main.dao.results.ResultsView; import bisq.desktop.main.dao.wallet.BsqWalletView; import bisq.desktop.main.dao.wallet.dashboard.BsqDashboardView; @@ -54,8 +53,6 @@ public class DaoView extends ActivatableViewAndModel { @FXML private Tab proposalsTab; @FXML - private Tab resultsTab; - @FXML private Tab bondingTab; private Navigation.Listener navigationListener; @@ -66,7 +63,6 @@ public class DaoView extends ActivatableViewAndModel { private Tab selectedTab; private BsqWalletView bsqWalletView; - @Inject private DaoView(CachingViewLoader viewLoader, Navigation navigation) { this.viewLoader = viewLoader; @@ -77,19 +73,16 @@ private DaoView(CachingViewLoader viewLoader, Navigation navigation) { public void initialize() { bsqWalletTab = new Tab(Res.get("dao.tab.bsqWallet")); proposalsTab = new Tab(Res.get("dao.tab.proposals")); - resultsTab = new Tab(Res.get("dao.tab.results")); bondingTab = new Tab(Res.get("dao.tab.bonding")); bsqWalletTab.setClosable(false); proposalsTab.setClosable(false); - resultsTab.setClosable(false); bondingTab.setClosable(false); - root.getTabs().addAll(bsqWalletTab, proposalsTab, resultsTab, bondingTab); + root.getTabs().addAll(bsqWalletTab, proposalsTab, bondingTab); if (!BisqEnvironment.isDAOActivatedAndBaseCurrencySupportingBsq() || !DevEnv.isDaoPhase2Activated()) { bondingTab.setDisable(true); - resultsTab.setDisable(true); proposalsTab.setDisable(true); } @@ -111,8 +104,6 @@ public void initialize() { navigation.navigateTo(MainView.class, DaoView.class, BsqWalletView.class, selectedViewClass); } else if (newValue == proposalsTab) { navigation.navigateTo(MainView.class, DaoView.class, ProposalView.class); - } else if (newValue == resultsTab) { - navigation.navigateTo(MainView.class, DaoView.class, ResultsView.class); } else if (newValue == bondingTab) { navigation.navigateTo(MainView.class, DaoView.class, BondingView.class); } @@ -130,8 +121,6 @@ protected void activate() { navigation.navigateTo(MainView.class, DaoView.class, BsqWalletView.class); else if (selectedItem == proposalsTab) navigation.navigateTo(MainView.class, DaoView.class, ProposalView.class); - else if (selectedItem == resultsTab) - navigation.navigateTo(MainView.class, DaoView.class, ResultsView.class); else if (selectedItem == bondingTab) navigation.navigateTo(MainView.class, DaoView.class, BondingView.class); } @@ -150,8 +139,6 @@ private void loadView(Class viewClass) { bsqWalletView = (BsqWalletView) view; } else if (view instanceof ProposalView) { selectedTab = proposalsTab; - } else if (view instanceof ResultsView) { - selectedTab = resultsTab; } else if (view instanceof BondingView) { selectedTab = bondingTab; } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java index 4ec4d088de5..478e0df6f35 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java @@ -32,6 +32,9 @@ import bisq.core.dao.role.BondedRoleType; import bisq.core.dao.state.blockchain.Tx; import bisq.core.dao.state.ext.Param; +import bisq.core.dao.voting.ballot.Ballot; +import bisq.core.dao.voting.ballot.vote.BooleanVote; +import bisq.core.dao.voting.ballot.vote.Vote; import bisq.core.dao.voting.proposal.Proposal; import bisq.core.dao.voting.proposal.ProposalType; import bisq.core.dao.voting.proposal.compensation.CompensationConsensus; @@ -39,6 +42,8 @@ import bisq.core.dao.voting.proposal.confiscatebond.ConfiscateBondProposal; import bisq.core.dao.voting.proposal.param.ChangeParamProposal; import bisq.core.dao.voting.proposal.role.BondedRoleProposal; +import bisq.core.dao.voting.voteresult.EvaluatedProposal; +import bisq.core.dao.voting.voteresult.ProposalVoteResult; import bisq.core.locale.Res; import bisq.core.util.BsqFormatter; import bisq.core.util.validation.InputValidator; @@ -46,6 +51,8 @@ import bisq.common.util.Tuple2; +import org.bitcoinj.core.Coin; + import javafx.scene.control.ComboBox; import javafx.scene.control.Label; import javafx.scene.control.ScrollPane; @@ -87,7 +94,8 @@ public class ProposalDisplay { @Nullable private TextField uidTextField, proposalFeeTextField; - private TextField proposalTypeTextField; + private TextField proposalTypeTextField, myVoteTextField, voteResultTextField; + private Label myVoteLabel, voteResultLabel; public InputTextField nameTextField; public InputTextField linkInputTextField; @Nullable @@ -112,6 +120,7 @@ public class ProposalDisplay { private List comboBoxes = new ArrayList<>(); private final ChangeListener focusOutListener; private final ChangeListener inputListener; + private int titledGroupBgRowSpan; // TODO get that warning at closing the window... @@ -147,34 +156,32 @@ public void createAllFields(String title, int gridRowStartIndex, double top, Pro removeAllFields(); this.gridRowStartIndex = gridRowStartIndex; this.gridRow = gridRowStartIndex; - int rowSpan = 4; + titledGroupBgRowSpan = 6; switch (proposalType) { case COMPENSATION_REQUEST: - rowSpan = 5; + titledGroupBgRowSpan += 1; break; case BONDED_ROLE: - rowSpan = 4; break; case REMOVE_ALTCOIN: break; case CHANGE_PARAM: - rowSpan = 5; + titledGroupBgRowSpan += 1; break; case GENERIC: break; case CONFISCATE_BOND: - rowSpan = 4; break; } // at isMakeProposalScreen we show fee but no uid and txID (+1) // otherwise we don't show fee but show uid and txID (+2) if (isMakeProposalScreen) - rowSpan += 1; + titledGroupBgRowSpan += 1; else - rowSpan += 2; + titledGroupBgRowSpan += 2; - addTitledGroupBg(gridPane, gridRow, rowSpan, title, top); + addTitledGroupBg(gridPane, gridRow, titledGroupBgRowSpan, title, top); double proposalTypeTop = top == Layout.GROUP_DISTANCE ? Layout.FIRST_ROW_AND_GROUP_DISTANCE : Layout.FIRST_ROW_DISTANCE; proposalTypeTextField = addLabelTextField(gridPane, gridRow, Res.getWithCol("dao.proposal.display.type"), proposalType.getDisplayName(), proposalTypeTop).second; @@ -298,9 +305,97 @@ public BondedRole fromString(String string) { proposalFeeTextField.setText(bsqFormatter.formatCoinWithCode(daoFacade.getProposalFee(daoFacade.getChainHeight()))); } + Tuple2 tuple2 = addLabelTextField(gridPane, ++gridRow, Res.get("dao.proposal.display.myVote")); + myVoteLabel = tuple2.first; + myVoteLabel.setVisible(false); + myVoteLabel.setManaged(false); + myVoteTextField = tuple2.second; + myVoteTextField.setVisible(false); + myVoteTextField.setManaged(false); + + tuple2 = addLabelTextField(gridPane, ++gridRow, Res.get("dao.proposal.display.voteResult")); + voteResultLabel = tuple2.first; + voteResultLabel.setVisible(false); + voteResultLabel.setManaged(false); + voteResultTextField = tuple2.second; + voteResultTextField.setVisible(false); + voteResultTextField.setManaged(false); + addListeners(); } + public void applyBallot(@Nullable Ballot ballot) { + String myVote = Res.get("dao.proposal.display.myVote.ignored"); + boolean isNotNull = ballot != null; + Vote vote = isNotNull ? ballot.getVote() : null; + if (vote != null) { + if (vote instanceof BooleanVote) { + BooleanVote booleanVote = (BooleanVote) vote; + myVote = booleanVote.isAccepted() ? Res.get("dao.proposal.display.myVote.accepted") : + Res.get("dao.proposal.display.myVote.rejected"); + + + } + } + myVoteTextField.setText(myVote); + + myVoteLabel.setVisible(isNotNull); + myVoteLabel.setManaged(isNotNull); + myVoteTextField.setVisible(isNotNull); + myVoteTextField.setManaged(isNotNull); + } + + public void applyEvaluatedProposal(@Nullable EvaluatedProposal evaluatedProposal) { + boolean isEvaluatedProposalNotNull = evaluatedProposal != null; + if (isEvaluatedProposalNotNull) { + String result = evaluatedProposal.isAccepted() ? Res.get("dao.proposal.voteResult.success") : + Res.get("dao.proposal.voteResult.failed"); + ProposalVoteResult proposalVoteResult = evaluatedProposal.getProposalVoteResult(); + String threshold = (proposalVoteResult.getThreshold() / 100D) + "%"; + String requiredThreshold = (evaluatedProposal.getRequiredThreshold() / 100D) + "%"; + String quorum = bsqFormatter.formatCoinWithCode(Coin.valueOf(proposalVoteResult.getQuorum())); + String requiredQuorum = bsqFormatter.formatCoinWithCode(Coin.valueOf(evaluatedProposal.getRequiredQuorum())); + String summary = Res.get("dao.proposal.voteResult.summary", result, + threshold, requiredThreshold, quorum, requiredQuorum); + voteResultTextField.setText(summary); + } + voteResultLabel.setVisible(isEvaluatedProposalNotNull); + voteResultLabel.setManaged(isEvaluatedProposalNotNull); + voteResultTextField.setVisible(isEvaluatedProposalNotNull); + voteResultTextField.setManaged(isEvaluatedProposalNotNull); + } + + public void applyBallotAndVoteWeight(@Nullable Ballot ballot, long merit, long stake) { + boolean ballotIsNotNull = ballot != null; + boolean hasVoted = stake > 0; + if (hasVoted) { + String myVote = Res.get("dao.proposal.display.myVote.ignored"); + Vote vote = ballotIsNotNull ? ballot.getVote() : null; + if (vote != null) { + if (vote instanceof BooleanVote) { + BooleanVote booleanVote = (BooleanVote) vote; + myVote = booleanVote.isAccepted() ? Res.get("dao.proposal.display.myVote.accepted") : + Res.get("dao.proposal.display.myVote.rejected"); + + + } + } + + String meritString = bsqFormatter.formatCoinWithCode(Coin.valueOf(merit)); + String stakeString = bsqFormatter.formatCoinWithCode(Coin.valueOf(stake)); + String weight = bsqFormatter.formatCoinWithCode(Coin.valueOf(merit + stake)); + String myVoteSummary = Res.get("dao.proposal.myVote.summary", myVote, + weight, meritString, stakeString); + myVoteTextField.setText(myVoteSummary); + } + + boolean show = ballotIsNotNull && hasVoted; + myVoteLabel.setVisible(show); + myVoteLabel.setManaged(show); + myVoteTextField.setVisible(show); + myVoteTextField.setManaged(show); + } + public void applyProposalPayload(Proposal proposal) { proposalTypeTextField.setText(proposal.getType().getDisplayName()); if (uidTextField != null) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalView.java index bb755fc2c05..accdfd4b842 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalView.java @@ -27,10 +27,10 @@ import bisq.desktop.components.MenuItem; import bisq.desktop.main.MainView; import bisq.desktop.main.dao.DaoView; -import bisq.desktop.main.dao.proposal.closed.ClosedProposalsView; import bisq.desktop.main.dao.proposal.dashboard.ProposalDashboardView; import bisq.desktop.main.dao.proposal.make.MakeProposalView; import bisq.desktop.main.dao.proposal.open.OpenProposalsView; +import bisq.desktop.main.dao.proposal.result.VoteResultView; import bisq.core.dao.DaoFacade; import bisq.core.dao.state.period.DaoPhase; @@ -58,7 +58,7 @@ public class ProposalView extends ActivatableViewAndModel { private final Navigation navigation; private final DaoFacade daoFacade; - private MenuItem dashboard, make, open, closed; + private MenuItem dashboard, make, open, result; private Navigation.Listener navigationListener; @FXML @@ -101,9 +101,9 @@ public void initialize() { MakeProposalView.class, AwesomeIcon.EDIT, baseNavPath); open = new MenuItem(navigation, toggleGroup, Res.get("dao.proposal.menuItem.browse"), OpenProposalsView.class, AwesomeIcon.LIST_UL, baseNavPath); - closed = new MenuItem(navigation, toggleGroup, Res.get("dao.proposal.menuItem.closed"), - ClosedProposalsView.class, AwesomeIcon.LIST_ALT, baseNavPath); - leftVBox.getChildren().addAll(dashboard, make, open, closed); + result = new MenuItem(navigation, toggleGroup, Res.get("dao.proposal.menuItem.result"), + VoteResultView.class, AwesomeIcon.LIST_ALT, baseNavPath); + leftVBox.getChildren().addAll(dashboard, make, open, result); } @Override @@ -113,7 +113,7 @@ protected void activate() { dashboard.activate(); make.activate(); open.activate(); - closed.activate(); + result.activate(); navigation.addListener(navigationListener); ViewPath viewPath = navigation.getCurrentPath(); @@ -140,7 +140,7 @@ protected void deactivate() { dashboard.deactivate(); make.deactivate(); open.deactivate(); - closed.deactivate(); + result.deactivate(); } private void loadView(Class viewClass) { @@ -150,7 +150,7 @@ private void loadView(Class viewClass) { if (view instanceof ProposalDashboardView) dashboard.setSelected(true); else if (view instanceof MakeProposalView) make.setSelected(true); else if (view instanceof OpenProposalsView) open.setSelected(true); - else if (view instanceof ClosedProposalsView) closed.setSelected(true); + else if (view instanceof VoteResultView) result.setSelected(true); } } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java deleted file mode 100644 index 996fd1d98f1..00000000000 --- a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.desktop.main.dao.proposal.closed; - -import bisq.desktop.common.view.FxmlView; -import bisq.desktop.main.dao.proposal.ProposalItemsView; - -import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.DaoFacade; -import bisq.core.dao.voting.proposal.Proposal; -import bisq.core.util.BSFormatter; -import bisq.core.util.BsqFormatter; - -import javax.inject.Inject; - -import javafx.collections.ObservableList; - -import java.util.List; -import java.util.stream.Collectors; - -@FxmlView -public class ClosedProposalsView extends ProposalItemsView { - - /////////////////////////////////////////////////////////////////////////////////////////// - // Constructor, lifecycle - /////////////////////////////////////////////////////////////////////////////////////////// - - @Inject - private ClosedProposalsView(DaoFacade daoFacade, - BsqWalletService bsqWalletService, - BsqFormatter bsqFormatter, - BSFormatter btcFormatter) { - - super(daoFacade, bsqWalletService, bsqFormatter, btcFormatter); - } - - @Override - protected ObservableList getProposals() { - return daoFacade.getClosedProposals(); - } - - @Override - protected void fillListItems() { - List list = getProposals(); - proposalBaseProposalListItems.setAll(list.stream() - .map(proposal -> new ClosedProposalListItem(proposal, daoFacade, bsqWalletService, bsqFormatter)) - .collect(Collectors.toSet())); - } -} - diff --git a/src/main/java/bisq/desktop/main/dao/proposal/open/OpenProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/open/OpenProposalsView.java index 45bbe026d6b..6539aeb5364 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/open/OpenProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/open/OpenProposalsView.java @@ -47,10 +47,13 @@ import bisq.core.dao.voting.ballot.vote.BooleanVote; import bisq.core.dao.voting.myvote.MyVote; import bisq.core.dao.voting.proposal.Proposal; +import bisq.core.dao.voting.voteresult.EvaluatedProposal; +import bisq.core.dao.voting.voteresult.VoteResultService; import bisq.core.locale.Res; import bisq.core.util.BSFormatter; import bisq.core.util.BsqFormatter; +import bisq.common.app.DevEnv; import bisq.common.util.Tuple2; import bisq.common.util.Tuple3; @@ -62,12 +65,12 @@ import javafx.scene.Node; import javafx.scene.control.Button; -import javafx.scene.control.Control; import javafx.scene.control.Label; import javafx.scene.control.ScrollPane; import javafx.scene.control.TableCell; import javafx.scene.control.TableColumn; import javafx.scene.control.TableView; +import javafx.scene.control.TextField; import javafx.scene.control.Tooltip; import javafx.scene.layout.GridPane; import javafx.scene.layout.Priority; @@ -93,6 +96,8 @@ import java.util.Optional; import java.util.stream.Collectors; +import javax.annotation.Nullable; + import static bisq.desktop.util.FormBuilder.*; @FxmlView @@ -100,6 +105,7 @@ public class OpenProposalsView extends ActivatableView implement private final DaoFacade daoFacade; private final BsqWalletService bsqWalletService; private final CycleOverview cycleOverview; + private final VoteResultService voteResultService; private final BsqFormatter bsqFormatter; private final BSFormatter btcFormatter; @@ -124,11 +130,12 @@ public class OpenProposalsView extends ActivatableView implement private ListChangeListener proposalListChangeListener; private ListChangeListener ballotListChangeListener; private ChangeListener stakeListener; - private List voteControls = new ArrayList<>(); + private List