From f9a31f4b8af05fb28255416cf5db06896f3a363d Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Tue, 17 Nov 2015 20:54:03 +0100 Subject: [PATCH] impl. feedback from aaron. improve popups, add warning for remove offer, deactivate mainnet,... --- .../java/io/bitsquare/locale/CountryUtil.java | 2 +- .../payment/SepaAccountContractData.java | 17 +- .../java/io/bitsquare/trade/Contract.java | 57 ++++--- .../java/io/bitsquare/trade/offer/Offer.java | 15 +- .../buyer/SignAndPublishDepositTxAsBuyer.java | 11 +- .../tasks/offerer/CreateAndSignContract.java | 10 +- .../CreateAndSignDepositTxAsSeller.java | 5 + .../SignAndPublishDepositTxAsSeller.java | 8 +- .../tasks/taker/BroadcastTakeOfferFeeTx.java | 4 +- .../tasks/taker/VerifyAndSignContract.java | 10 +- .../src/main/java/io/bitsquare/user/User.java | 2 - .../java/io/bitsquare/app/BitsquareApp.java | 3 +- .../gui/components/BalanceTextField.java | 10 +- .../paymentmethods/PaymentMethodForm.java | 10 +- .../content/seedwords/SeedWordsView.java | 8 +- .../offer/createoffer/CreateOfferView.java | 19 ++- .../createoffer/CreateOfferViewModel.java | 2 +- .../main/offer/offerbook/OfferBookView.java | 30 ++-- .../offer/takeoffer/TakeOfferDataModel.java | 8 +- .../main/offer/takeoffer/TakeOfferView.java | 20 ++- .../offer/takeoffer/TakeOfferViewModel.java | 2 +- .../portfolio/openoffer/OpenOffersView.java | 35 +++-- .../pendingtrades/PendingTradesDataModel.java | 25 ++- .../pendingtrades/steps/CompletedView.java | 12 +- .../steps/ConfirmPaymentReceivedView.java | 30 ++-- .../pendingtrades/steps/StartPaymentView.java | 27 ++-- .../settings/application/PreferencesView.java | 2 +- .../settings/network/NetworkSettingsView.java | 18 ++- .../bitsquare/gui/popups/ContractPopup.java | 7 +- .../gui/popups/FirstTimeWebViewPopup.java | 4 +- .../gui/popups/OfferDetailsPopup.java | 148 +++++++++++------- .../java/io/bitsquare/gui/popups/Popup.java | 33 +++- .../gui/popups/TradeDetailsPopup.java | 51 +++--- .../io/bitsquare/gui/util/BSFormatter.java | 22 ++- gui/src/main/resources/html/tac.html | 2 +- gui/src/main/resources/html/tradeWallet.html | 11 +- .../io/bitsquare/p2p/peers/PeerGroup.java | 26 ++- 37 files changed, 425 insertions(+), 281 deletions(-) diff --git a/core/src/main/java/io/bitsquare/locale/CountryUtil.java b/core/src/main/java/io/bitsquare/locale/CountryUtil.java index 34ae47ab2a..d77357414f 100644 --- a/core/src/main/java/io/bitsquare/locale/CountryUtil.java +++ b/core/src/main/java/io/bitsquare/locale/CountryUtil.java @@ -150,7 +150,7 @@ public class CountryUtil { } public static String getNamesByCodesString(List countryCodes) { - return getNamesByCodes(countryCodes).stream().collect(Collectors.joining(", ")); + return getNamesByCodes(countryCodes).stream().collect(Collectors.joining(",\n")); } private static final String[] countryCodes = new String[]{"AE", "AL", "AR", "AT", "AU", "BA", "BE", "BG", "BH", diff --git a/core/src/main/java/io/bitsquare/payment/SepaAccountContractData.java b/core/src/main/java/io/bitsquare/payment/SepaAccountContractData.java index a50aeb2eea..cbd1c918ad 100644 --- a/core/src/main/java/io/bitsquare/payment/SepaAccountContractData.java +++ b/core/src/main/java/io/bitsquare/payment/SepaAccountContractData.java @@ -37,11 +37,14 @@ public class SepaAccountContractData extends PaymentAccountContractData implemen private String holderName; private String iban; private String bic; - private Set acceptedCountryCodes; + // Dont use a set here as we need a deterministic ordering, otherwise the contract hash does not match + private ArrayList acceptedCountryCodes; public SepaAccountContractData(String paymentMethod, String id, int maxTradePeriod) { super(paymentMethod, id, maxTradePeriod); - acceptedCountryCodes = CountryUtil.getAllSepaCountries().stream().map(e -> e.code).collect(Collectors.toSet()); + Set acceptedCountryCodesAsSet = CountryUtil.getAllSepaCountries().stream().map(e -> e.code).collect(Collectors.toSet()); + acceptedCountryCodes = new ArrayList<>(acceptedCountryCodesAsSet); + acceptedCountryCodes.sort((a, b) -> a.compareTo(b)); } public void setHolderName(String holderName) { @@ -69,17 +72,17 @@ public class SepaAccountContractData extends PaymentAccountContractData implemen } public void addAcceptedCountry(String countryCode) { - acceptedCountryCodes.add(countryCode); + if (!acceptedCountryCodes.contains(countryCode)) + acceptedCountryCodes.add(countryCode); } public void removeAcceptedCountry(String countryCode) { - acceptedCountryCodes.remove(countryCode); + if (acceptedCountryCodes.contains(countryCode)) + acceptedCountryCodes.remove(countryCode); } public List getAcceptedCountryCodes() { - List sortedList = new ArrayList<>(acceptedCountryCodes); - sortedList.sort((a, b) -> a.compareTo(b)); - return sortedList; + return acceptedCountryCodes; } @Override diff --git a/core/src/main/java/io/bitsquare/trade/Contract.java b/core/src/main/java/io/bitsquare/trade/Contract.java index 9fdc5cf846..4e73685294 100644 --- a/core/src/main/java/io/bitsquare/trade/Contract.java +++ b/core/src/main/java/io/bitsquare/trade/Contract.java @@ -38,11 +38,13 @@ public class Contract implements Serializable { @JsonExclude public static final long serialVersionUID = Version.NETWORK_PROTOCOL_VERSION; + public static final String TAC = "I commit to the trade conditions as defined above."; + public final Offer offer; private final long tradeAmount; public final String takeOfferFeeTxID; public final Address arbitratorAddress; - private final boolean isBuyerOffererOrSellerTaker; + private final boolean isBuyerOffererAndSellerTaker; private final String offererAccountId; private final String takerAccountId; private final PaymentAccountContractData offererPaymentAccountContractData; @@ -62,17 +64,13 @@ public class Contract implements Serializable { @JsonExclude private final byte[] takerBtcPubKey; - // TODO some basic TAC - public final String tac = "With my signature I commit to the trading agreement of Bitsquare and to fulfill the trade as defined there."; - - public Contract(Offer offer, Coin tradeAmount, String takeOfferFeeTxID, Address buyerAddress, Address sellerAddress, Address arbitratorAddress, - boolean isBuyerOffererOrSellerTaker, + boolean isBuyerOffererAndSellerTaker, String offererAccountId, String takerAccountId, PaymentAccountContractData offererPaymentAccountContractData, @@ -89,7 +87,7 @@ public class Contract implements Serializable { this.tradeAmount = tradeAmount.value; this.takeOfferFeeTxID = takeOfferFeeTxID; this.arbitratorAddress = arbitratorAddress; - this.isBuyerOffererOrSellerTaker = isBuyerOffererOrSellerTaker; + this.isBuyerOffererAndSellerTaker = isBuyerOffererAndSellerTaker; this.offererAccountId = offererAccountId; this.takerAccountId = takerAccountId; this.offererPaymentAccountContractData = offererPaymentAccountContractData; @@ -103,44 +101,44 @@ public class Contract implements Serializable { } public String getBuyerAccountId() { - return isBuyerOffererOrSellerTaker ? offererAccountId : takerAccountId; + return isBuyerOffererAndSellerTaker ? offererAccountId : takerAccountId; } public String getSellerAccountId() { - return isBuyerOffererOrSellerTaker ? takerAccountId : offererAccountId; + return isBuyerOffererAndSellerTaker ? takerAccountId : offererAccountId; } public String getBuyerPayoutAddressString() { - return isBuyerOffererOrSellerTaker ? offererPayoutAddressString : takerPayoutAddressString; + return isBuyerOffererAndSellerTaker ? offererPayoutAddressString : takerPayoutAddressString; } public String getSellerPayoutAddressString() { - return isBuyerOffererOrSellerTaker ? takerPayoutAddressString : offererPayoutAddressString; + return isBuyerOffererAndSellerTaker ? takerPayoutAddressString : offererPayoutAddressString; } public PubKeyRing getBuyerPubKeyRing() { - return isBuyerOffererOrSellerTaker ? offererPubKeyRing : takerPubKeyRing; + return isBuyerOffererAndSellerTaker ? offererPubKeyRing : takerPubKeyRing; } public PubKeyRing getSellerPubKeyRing() { - return isBuyerOffererOrSellerTaker ? takerPubKeyRing : offererPubKeyRing; + return isBuyerOffererAndSellerTaker ? takerPubKeyRing : offererPubKeyRing; } public byte[] getBuyerBtcPubKey() { - return isBuyerOffererOrSellerTaker ? offererBtcPubKey : takerBtcPubKey; + return isBuyerOffererAndSellerTaker ? offererBtcPubKey : takerBtcPubKey; } public byte[] getSellerBtcPubKey() { - return isBuyerOffererOrSellerTaker ? takerBtcPubKey : offererBtcPubKey; + return isBuyerOffererAndSellerTaker ? takerBtcPubKey : offererBtcPubKey; } public PaymentAccountContractData getBuyerPaymentAccountContractData() { - return isBuyerOffererOrSellerTaker ? offererPaymentAccountContractData : takerPaymentAccountContractData; + return isBuyerOffererAndSellerTaker ? offererPaymentAccountContractData : takerPaymentAccountContractData; } public PaymentAccountContractData getSellerPaymentAccountContractData() { - return isBuyerOffererOrSellerTaker ? takerPaymentAccountContractData : offererPaymentAccountContractData; + return isBuyerOffererAndSellerTaker ? takerPaymentAccountContractData : offererPaymentAccountContractData; } public String getPaymentMethodName() { @@ -166,17 +164,19 @@ public class Contract implements Serializable { @Override public String toString() { return "Contract{" + - "tac='" + tac + '\'' + - ", offer=" + offer + + "offer=" + offer + ", tradeAmount=" + tradeAmount + - ", isBuyerOffererOrSellerTaker=" + isBuyerOffererOrSellerTaker + ", takeOfferFeeTxID='" + takeOfferFeeTxID + '\'' + - ", offererAccountID='" + offererAccountId + '\'' + - ", takerAccountID='" + takerAccountId + '\'' + - ", offererPaymentAccount=" + offererPaymentAccountContractData + - ", takerPaymentAccount=" + takerPaymentAccountContractData + + ", arbitratorAddress=" + arbitratorAddress + + ", isBuyerOffererAndSellerTaker=" + isBuyerOffererAndSellerTaker + + ", offererAccountId='" + offererAccountId + '\'' + + ", takerAccountId='" + takerAccountId + '\'' + + ", offererPaymentAccountContractData=" + offererPaymentAccountContractData + + ", takerPaymentAccountContractData=" + takerPaymentAccountContractData + ", offererPubKeyRing=" + offererPubKeyRing + ", takerPubKeyRing=" + takerPubKeyRing + + ", buyerAddress=" + buyerAddress + + ", sellerAddress=" + sellerAddress + ", offererPayoutAddressString='" + offererPayoutAddressString + '\'' + ", takerPayoutAddressString='" + takerPayoutAddressString + '\'' + ", offererBtcPubKey=" + Arrays.toString(offererBtcPubKey) + @@ -192,7 +192,7 @@ public class Contract implements Serializable { Contract contract = (Contract) o; if (tradeAmount != contract.tradeAmount) return false; - if (isBuyerOffererOrSellerTaker != contract.isBuyerOffererOrSellerTaker) return false; + if (isBuyerOffererAndSellerTaker != contract.isBuyerOffererAndSellerTaker) return false; if (offer != null ? !offer.equals(contract.offer) : contract.offer != null) return false; if (takeOfferFeeTxID != null ? !takeOfferFeeTxID.equals(contract.takeOfferFeeTxID) : contract.takeOfferFeeTxID != null) return false; @@ -219,8 +219,7 @@ public class Contract implements Serializable { if (takerPayoutAddressString != null ? !takerPayoutAddressString.equals(contract.takerPayoutAddressString) : contract.takerPayoutAddressString != null) return false; if (!Arrays.equals(offererBtcPubKey, contract.offererBtcPubKey)) return false; - if (!Arrays.equals(takerBtcPubKey, contract.takerBtcPubKey)) return false; - return !(tac != null ? !tac.equals(contract.tac) : contract.tac != null); + return Arrays.equals(takerBtcPubKey, contract.takerBtcPubKey); } @@ -230,7 +229,7 @@ public class Contract implements Serializable { result = 31 * result + (int) (tradeAmount ^ (tradeAmount >>> 32)); result = 31 * result + (takeOfferFeeTxID != null ? takeOfferFeeTxID.hashCode() : 0); result = 31 * result + (arbitratorAddress != null ? arbitratorAddress.hashCode() : 0); - result = 31 * result + (isBuyerOffererOrSellerTaker ? 1 : 0); + result = 31 * result + (isBuyerOffererAndSellerTaker ? 1 : 0); result = 31 * result + (offererAccountId != null ? offererAccountId.hashCode() : 0); result = 31 * result + (takerAccountId != null ? takerAccountId.hashCode() : 0); result = 31 * result + (offererPaymentAccountContractData != null ? offererPaymentAccountContractData.hashCode() : 0); @@ -243,7 +242,7 @@ public class Contract implements Serializable { result = 31 * result + (takerPayoutAddressString != null ? takerPayoutAddressString.hashCode() : 0); result = 31 * result + (offererBtcPubKey != null ? Arrays.hashCode(offererBtcPubKey) : 0); result = 31 * result + (takerBtcPubKey != null ? Arrays.hashCode(takerBtcPubKey) : 0); - result = 31 * result + (tac != null ? tac.hashCode() : 0); return result; } + } diff --git a/core/src/main/java/io/bitsquare/trade/offer/Offer.java b/core/src/main/java/io/bitsquare/trade/offer/Offer.java index 94435a3934..7bd5d38335 100644 --- a/core/src/main/java/io/bitsquare/trade/offer/Offer.java +++ b/core/src/main/java/io/bitsquare/trade/offer/Offer.java @@ -53,6 +53,10 @@ public final class Offer implements PubKeyProtectedExpirablePayload { transient private static final Logger log = LoggerFactory.getLogger(Offer.class); public static final long TTL = 10 * 60 * 1000; // 10 min. + public final static String TAC_OFFERER = "When placing that offer I accept that anyone who fulfills my conditions can " + + "take that offer."; + public static final String TAC_TAKER = "With taking the offer I commit to the trade conditions as defined."; + public enum Direction {BUY, SELL} @@ -397,14 +401,21 @@ public final class Offer implements PubKeyProtectedExpirablePayload { ", fiatPrice=" + fiatPrice + ", amount=" + amount + ", minAmount=" + minAmount + - ", address=" + offererAddress + - ", pubKeyRing.hashCode()=" + pubKeyRing.hashCode() + + ", offererAddress=" + offererAddress + + ", pubKeyRing=" + pubKeyRing + ", paymentMethodName='" + paymentMethodName + '\'' + ", paymentMethodCountryCode='" + paymentMethodCountryCode + '\'' + ", offererPaymentAccountId='" + offererPaymentAccountId + '\'' + ", acceptedCountryCodes=" + acceptedCountryCodes + ", arbitratorAddresses=" + arbitratorAddresses + ", offerFeePaymentTxID='" + offerFeePaymentTxID + '\'' + + ", state=" + state + + ", stateProperty=" + stateProperty + + ", availabilityProtocol=" + availabilityProtocol + + ", errorMessageProperty=" + errorMessageProperty + + ", TAC_OFFERER=" + TAC_OFFERER + + ", TAC_TAKER=" + TAC_TAKER + '}'; } + } diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/SignAndPublishDepositTxAsBuyer.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/SignAndPublishDepositTxAsBuyer.java index 33fb81637e..df3fbbe2f7 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/SignAndPublishDepositTxAsBuyer.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/SignAndPublishDepositTxAsBuyer.java @@ -41,11 +41,12 @@ public class SignAndPublishDepositTxAsBuyer extends TradeTask { try { runInterceptHook(); - log.debug("getContractAsJson"); - log.debug("----------"); - log.debug(trade.getContractAsJson()); - log.debug("----------"); - + log.info("\n\n------------------------------------------------------------\n" + + "Contract as json\n" + + trade.getContractAsJson() + + "\n------------------------------------------------------------\n"); + + byte[] contractHash = Hash.getHash(trade.getContractAsJson()); trade.setContractHash(contractHash); processModel.getTradeWalletService().takerSignsAndPublishesDepositTx( diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/offerer/CreateAndSignContract.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/offerer/CreateAndSignContract.java index 2eaf014234..7ff23de682 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/offerer/CreateAndSignContract.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/offerer/CreateAndSignContract.java @@ -48,11 +48,11 @@ public class CreateAndSignContract extends TradeTask { TradingPeer taker = processModel.tradingPeer; PaymentAccountContractData offererPaymentAccountContractData = processModel.getPaymentAccountContractData(trade); PaymentAccountContractData takerPaymentAccountContractData = taker.getPaymentAccountContractData(); - boolean isBuyerOffererOrSellerTaker = trade instanceof BuyerAsOffererTrade; + boolean isBuyerOffererAndSellerTaker = trade instanceof BuyerAsOffererTrade; - Address buyerAddress = isBuyerOffererOrSellerTaker ? processModel.getMyAddress() : processModel.getTempTradingPeerAddress(); - Address sellerAddress = isBuyerOffererOrSellerTaker ? processModel.getTempTradingPeerAddress() : processModel.getMyAddress(); - log.debug("isBuyerOffererOrSellerTaker " + isBuyerOffererOrSellerTaker); + Address buyerAddress = isBuyerOffererAndSellerTaker ? processModel.getMyAddress() : processModel.getTempTradingPeerAddress(); + Address sellerAddress = isBuyerOffererAndSellerTaker ? processModel.getTempTradingPeerAddress() : processModel.getMyAddress(); + log.debug("isBuyerOffererAndSellerTaker " + isBuyerOffererAndSellerTaker); log.debug("buyerAddress " + buyerAddress); log.debug("sellerAddress " + sellerAddress); Contract contract = new Contract( @@ -62,7 +62,7 @@ public class CreateAndSignContract extends TradeTask { buyerAddress, sellerAddress, trade.getArbitratorAddress(), - isBuyerOffererOrSellerTaker, + isBuyerOffererAndSellerTaker, processModel.getAccountId(), taker.getAccountId(), offererPaymentAccountContractData, diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/seller/CreateAndSignDepositTxAsSeller.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/seller/CreateAndSignDepositTxAsSeller.java index dc8b059678..37e32fc66b 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/seller/CreateAndSignDepositTxAsSeller.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/seller/CreateAndSignDepositTxAsSeller.java @@ -44,6 +44,11 @@ public class CreateAndSignDepositTxAsSeller extends TradeTask { Coin sellerInputAmount = FeePolicy.SECURITY_DEPOSIT.add(FeePolicy.TX_FEE).add(trade.getTradeAmount()); Coin msOutputAmount = sellerInputAmount.add(FeePolicy.SECURITY_DEPOSIT); + log.info("\n\n------------------------------------------------------------\n" + + "Contract as json\n" + + trade.getContractAsJson() + + "\n------------------------------------------------------------\n"); + byte[] contractHash = Hash.getHash(trade.getContractAsJson()); trade.setContractHash(contractHash); PreparedDepositTxAndOffererInputs result = processModel.getTradeWalletService().offererCreatesAndSignsDepositTx( diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/seller/SignAndPublishDepositTxAsSeller.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/seller/SignAndPublishDepositTxAsSeller.java index 6b7ffaf24c..1fcaf413b4 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/seller/SignAndPublishDepositTxAsSeller.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/seller/SignAndPublishDepositTxAsSeller.java @@ -40,10 +40,10 @@ public class SignAndPublishDepositTxAsSeller extends TradeTask { protected void run() { try { runInterceptHook(); - log.debug("getContractAsJson"); - log.debug("----------"); - log.debug(trade.getContractAsJson()); - log.debug("----------"); + log.info("\n\n------------------------------------------------------------\n" + + "Contract as json\n" + + trade.getContractAsJson() + + "\n------------------------------------------------------------\n"); byte[] contractHash = Hash.getHash(trade.getContractAsJson()); trade.setContractHash(contractHash); diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/taker/BroadcastTakeOfferFeeTx.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/taker/BroadcastTakeOfferFeeTx.java index 7abd1d54d6..821cf17813 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/taker/BroadcastTakeOfferFeeTx.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/taker/BroadcastTakeOfferFeeTx.java @@ -41,7 +41,7 @@ public class BroadcastTakeOfferFeeTx extends TradeTask { new FutureCallback() { @Override public void onSuccess(Transaction transaction) { - log.debug("Take offer fee published successfully. Transaction ID = " + transaction.getHashAsString()); + log.debug("Trading fee published successfully. Transaction ID = " + transaction.getHashAsString()); trade.setState(Trade.State.TAKER_FEE_PAID); complete(); @@ -49,7 +49,7 @@ public class BroadcastTakeOfferFeeTx extends TradeTask { @Override public void onFailure(@NotNull Throwable t) { - appendToErrorMessage("Take offer fee payment failed. Maybe your network connection was lost. Please try again."); + appendToErrorMessage("Trading fee payment failed. Maybe your network connection was lost. Please try again."); failed(t); } }); diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/taker/VerifyAndSignContract.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/taker/VerifyAndSignContract.java index dca77bcec8..e609bab38a 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/taker/VerifyAndSignContract.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/taker/VerifyAndSignContract.java @@ -47,10 +47,10 @@ public class VerifyAndSignContract extends TradeTask { PaymentAccountContractData offererPaymentAccountContractData = offerer.getPaymentAccountContractData(); PaymentAccountContractData takerPaymentAccountContractData = processModel.getPaymentAccountContractData(trade); - boolean isBuyerOffererOrSellerTaker = trade instanceof SellerAsTakerTrade; - Address buyerAddress = isBuyerOffererOrSellerTaker ? processModel.getTempTradingPeerAddress() : processModel.getMyAddress(); - Address sellerAddress = isBuyerOffererOrSellerTaker ? processModel.getMyAddress() : processModel.getTempTradingPeerAddress(); - log.debug("isBuyerOffererOrSellerTaker " + isBuyerOffererOrSellerTaker); + boolean isBuyerOffererAndSellerTaker = trade instanceof SellerAsTakerTrade; + Address buyerAddress = isBuyerOffererAndSellerTaker ? processModel.getTempTradingPeerAddress() : processModel.getMyAddress(); + Address sellerAddress = isBuyerOffererAndSellerTaker ? processModel.getMyAddress() : processModel.getTempTradingPeerAddress(); + log.debug("isBuyerOffererAndSellerTaker " + isBuyerOffererAndSellerTaker); log.debug("buyerAddress " + buyerAddress); log.debug("sellerAddress " + sellerAddress); @@ -61,7 +61,7 @@ public class VerifyAndSignContract extends TradeTask { buyerAddress, sellerAddress, trade.getArbitratorAddress(), - isBuyerOffererOrSellerTaker, + isBuyerOffererAndSellerTaker, offerer.getAccountId(), processModel.getAccountId(), offererPaymentAccountContractData, diff --git a/core/src/main/java/io/bitsquare/user/User.java b/core/src/main/java/io/bitsquare/user/User.java index 3b422f1ed6..1e415d9718 100644 --- a/core/src/main/java/io/bitsquare/user/User.java +++ b/core/src/main/java/io/bitsquare/user/User.java @@ -67,7 +67,6 @@ public class User implements Serializable { private Alert displayedAlert; - @Nullable private List acceptedArbitrators = new ArrayList<>(); @Nullable private Arbitrator registeredArbitrator; @@ -244,7 +243,6 @@ public class User implements Serializable { return registeredArbitrator; } - @Nullable public List getAcceptedArbitrators() { return acceptedArbitrators; } diff --git a/gui/src/main/java/io/bitsquare/app/BitsquareApp.java b/gui/src/main/java/io/bitsquare/app/BitsquareApp.java index 47efdd9b40..a2299ff42e 100644 --- a/gui/src/main/java/io/bitsquare/app/BitsquareApp.java +++ b/gui/src/main/java/io/bitsquare/app/BitsquareApp.java @@ -167,7 +167,7 @@ public class BitsquareApp extends Application { showFPSWindow(); else if (new KeyCodeCombination(KeyCode.E, KeyCombination.SHORTCUT_DOWN).match(keyEvent)) showEmptyWalletPopup(); - else if (new KeyCodeCombination(KeyCode.A, KeyCombination.SHORTCUT_DOWN).match(keyEvent)) + else if (new KeyCodeCombination(KeyCode.M, KeyCombination.SHORTCUT_DOWN).match(keyEvent)) showSendAlertMessagePopup(); }); @@ -326,6 +326,7 @@ public class BitsquareApp extends Application { private void restart() { //TODO + stop(); //gracefulShutDown(UpdateFX::restartApp); } } diff --git a/gui/src/main/java/io/bitsquare/gui/components/BalanceTextField.java b/gui/src/main/java/io/bitsquare/gui/components/BalanceTextField.java index 2be02fa638..7ca5674032 100644 --- a/gui/src/main/java/io/bitsquare/gui/components/BalanceTextField.java +++ b/gui/src/main/java/io/bitsquare/gui/components/BalanceTextField.java @@ -32,6 +32,7 @@ import org.bitcoinj.core.Coin; public class BalanceTextField extends AnchorPane { private static WalletService walletService; + private BalanceListener balanceListener; public static void setWalletService(WalletService walletService) { BalanceTextField.walletService = walletService; @@ -61,15 +62,20 @@ public class BalanceTextField extends AnchorPane { public void setup(Address address, BSFormatter formatter) { this.formatter = formatter; - walletService.addBalanceListener(new BalanceListener(address) { + balanceListener = new BalanceListener(address) { @Override public void onBalanceChanged(Coin balance) { updateBalance(balance); } - }); + }; + walletService.addBalanceListener(balanceListener); updateBalance(walletService.getBalanceForAddress(address)); } + public void disarm() { + walletService.removeBalanceListener(balanceListener); + } + /////////////////////////////////////////////////////////////////////////////////////////// // Private methods diff --git a/gui/src/main/java/io/bitsquare/gui/components/paymentmethods/PaymentMethodForm.java b/gui/src/main/java/io/bitsquare/gui/components/paymentmethods/PaymentMethodForm.java index 4ea4ef6c8c..0f020e1bb0 100644 --- a/gui/src/main/java/io/bitsquare/gui/components/paymentmethods/PaymentMethodForm.java +++ b/gui/src/main/java/io/bitsquare/gui/components/paymentmethods/PaymentMethodForm.java @@ -111,12 +111,16 @@ public abstract class PaymentMethodForm { protected void addAllowedPeriod() { long hours = paymentAccount.getPaymentMethod().getMaxTradePeriod() / 6; String displayText = hours + " hours"; - if (hours == 24) + if (hours == 1) + displayText = "1 hour"; + else if (hours == 24) displayText = "1 day"; - if (hours > 24) + else if (hours > 24) displayText = hours / 24 + " days"; - addLabelTextField(gridPane, ++gridRow, "Max. allowed trade period:", displayText); + displayText += " (Max. permitted period until the trade needs to be completed)"; + + addLabelTextField(gridPane, ++gridRow, "Max. permitted trade period:", displayText); } abstract protected void autoFillNameTextField(); diff --git a/gui/src/main/java/io/bitsquare/gui/main/account/content/seedwords/SeedWordsView.java b/gui/src/main/java/io/bitsquare/gui/main/account/content/seedwords/SeedWordsView.java index be5c4d3203..c2ff517fe4 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/account/content/seedwords/SeedWordsView.java +++ b/gui/src/main/java/io/bitsquare/gui/main/account/content/seedwords/SeedWordsView.java @@ -202,10 +202,16 @@ public class SeedWordsView extends ActivatableView { log.debug("Wallet restored with seed words"); new Popup() + .information("Wallet restored successfully with the new seed words.\n\n" + + "You need to shut down and restart the application.") + .closeButtonText("Shut down") + .onClose(() -> BitsquareApp.shutDownHandler.run()).show(); + //TODO + /* new Popup() .information("Wallet restored successfully with the new seed words.\n\n" + "You need to restart now the application.") .closeButtonText("Restart") - .onClose(() -> BitsquareApp.restartDownHandler.run()).show(); + .onClose(() -> BitsquareApp.restartDownHandler.run()).show();*/ }), throwable -> UserThread.execute(() -> { log.error(throwable.getMessage()); diff --git a/gui/src/main/java/io/bitsquare/gui/main/offer/createoffer/CreateOfferView.java b/gui/src/main/java/io/bitsquare/gui/main/offer/createoffer/CreateOfferView.java index c6f32a8193..1ddb5b54ac 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/offer/createoffer/CreateOfferView.java +++ b/gui/src/main/java/io/bitsquare/gui/main/offer/createoffer/CreateOfferView.java @@ -37,7 +37,6 @@ import io.bitsquare.gui.main.account.settings.AccountSettingsView; import io.bitsquare.gui.main.offer.OfferView; import io.bitsquare.gui.main.portfolio.PortfolioView; import io.bitsquare.gui.main.portfolio.openoffer.OpenOffersView; -import io.bitsquare.gui.main.portfolio.pendingtrades.PendingTradesView; import io.bitsquare.gui.popups.OfferDetailsPopup; import io.bitsquare.gui.popups.Popup; import io.bitsquare.gui.util.BSFormatter; @@ -226,9 +225,13 @@ public class CreateOfferView extends ActivatableViewAndModel { new Popup().headLine(BSResources.get("createOffer.success.headline")) .message(BSResources.get("createOffer.success.info")) - .onClose(() -> { - navigation.navigateTo(MainView.class, PortfolioView.class, PendingTradesView.class); + .actionButtonText("Go to \"Open offers\"") + .onAction(() -> { close(); + UserThread.runAfter(() -> + navigation.navigateTo(MainView.class, PortfolioView.class, OpenOffersView.class), + 100, TimeUnit.MILLISECONDS); }) + .onClose(() -> close()) .show(); - }, 300, TimeUnit.MILLISECONDS); + }, 100, TimeUnit.MILLISECONDS); } }; } diff --git a/gui/src/main/java/io/bitsquare/gui/main/offer/createoffer/CreateOfferViewModel.java b/gui/src/main/java/io/bitsquare/gui/main/offer/createoffer/CreateOfferViewModel.java index 8ad8e8f1c8..30f7579fd7 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/offer/createoffer/CreateOfferViewModel.java +++ b/gui/src/main/java/io/bitsquare/gui/main/offer/createoffer/CreateOfferViewModel.java @@ -289,7 +289,7 @@ class CreateOfferViewModel extends ActivatableWithDataModel { - log.debug("Remove offer was successful"); - new Popup().information("You can withdraw the funds you paid in from the funds screens.").show(); - navigation.navigateTo(MainView.class, FundsView.class, WithdrawalView.class); - }, - (message) -> { - log.error(message); - new Popup().warning("Remove offer failed:\n" + message).show(); - }); - + new Popup().warning("Are you sure you want to remove that offer?\n" + + "The offer fee you have paid will be lost if you remove that offer.") + .actionButtonText("Remove offer") + .onAction(() -> doRemoveOffer(offer)) + .closeButtonText("Don't remove the offer") + .show(); } else { new Popup().warning("You need to wait until your client is authenticated in the network.\n" + "That might take up to about 2 minutes at startup.").show(); } } + private void doRemoveOffer(Offer offer) { + model.onRemoveOpenOffer(offer, + () -> { + log.debug("Remove offer was successful"); + new Popup().information("You can withdraw the funds you paid in from the funds screens.").show(); + navigation.navigateTo(MainView.class, FundsView.class, WithdrawalView.class); + }, + (message) -> { + log.error(message); + new Popup().warning("Remove offer failed:\n" + message).show(); + }); + } + private void showWarning(String masthead, String message, Class target) { new Popup().information(masthead + "\n\n" + message) .onAction(() -> { diff --git a/gui/src/main/java/io/bitsquare/gui/main/offer/takeoffer/TakeOfferDataModel.java b/gui/src/main/java/io/bitsquare/gui/main/offer/takeoffer/TakeOfferDataModel.java index 8873c339c8..cd8e01aaea 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/offer/takeoffer/TakeOfferDataModel.java +++ b/gui/src/main/java/io/bitsquare/gui/main/offer/takeoffer/TakeOfferDataModel.java @@ -127,6 +127,9 @@ class TakeOfferDataModel extends ActivatableDataModel { void initWithData(Offer offer) { this.offer = offer; + addressEntry = walletService.getAddressEntryByOfferId(offer.getId()); + checkNotNull(addressEntry, "addressEntry must not be null"); + ObservableList possiblePaymentAccounts = getPossiblePaymentAccounts(); checkArgument(!possiblePaymentAccounts.isEmpty(), "possiblePaymentAccounts.isEmpty()"); paymentAccount = possiblePaymentAccounts.get(0); @@ -136,9 +139,6 @@ class TakeOfferDataModel extends ActivatableDataModel { calculateVolume(); calculateTotalToPay(); - addressEntry = walletService.getAddressEntryByOfferId(offer.getId()); - checkNotNull(addressEntry, "addressEntry must not be null"); - balanceListener = new BalanceListener(addressEntry.getAddress()) { @Override public void onBalanceChanged(@NotNull Coin balance) { @@ -255,6 +255,8 @@ class TakeOfferDataModel extends ActivatableDataModel { amountAsCoin.get() != null && !amountAsCoin.get().isZero()) { volumeAsFiat.set(new ExchangeRate(offer.getPrice()).coinToFiat(amountAsCoin.get())); + + updateBalance(walletService.getBalanceForAddress(addressEntry.getAddress())); } } diff --git a/gui/src/main/java/io/bitsquare/gui/main/offer/takeoffer/TakeOfferView.java b/gui/src/main/java/io/bitsquare/gui/main/offer/takeoffer/TakeOfferView.java index 17c7eff4cb..3fe63652b1 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/offer/takeoffer/TakeOfferView.java +++ b/gui/src/main/java/io/bitsquare/gui/main/offer/takeoffer/TakeOfferView.java @@ -225,12 +225,16 @@ public class TakeOfferView extends ActivatableViewAndModel { new Popup().information(BSResources.get("takeOffer.success.info")) - .onClose(() -> { - navigation.navigateTo(MainView.class, PortfolioView.class, PendingTradesView.class); + .actionButtonText("Go to \"Open trades\"") + .onAction(() -> { close(); + UserThread.runAfter(() -> + navigation.navigateTo(MainView.class, PortfolioView.class, PendingTradesView.class), + 100, TimeUnit.MILLISECONDS); }) + .onClose(() -> close()) .show(); - }, 300, TimeUnit.MILLISECONDS); + }, 100, TimeUnit.MILLISECONDS); } }); @@ -322,7 +326,7 @@ public class TakeOfferView extends ActivatableViewAndModel model.onTakeOffer()).show(offer); + offerDetailsPopup.onTakeOffer(() -> model.onTakeOffer()).show(offer, model.dataModel.amountAsCoin.get()); } else { if (model.hasAcceptedArbitrators()) { model.onTakeOffer(); @@ -351,9 +355,13 @@ public class TakeOfferView extends ActivatableViewAndModel im "Please try to restart you application and check your network connection to see if you can resolve the issue."; break; case TAKER_FEE_PAID: - appendMsg = "\n\nThe take offer fee is already paid. In the worst case you have lost that fee. " + + appendMsg = "\n\nThe trading fee is already paid. In the worst case you have lost that fee. " + "We are sorry about that but keep in mind it is a very small amount.\n" + "Please try to restart you application and check your network connection to see if you can resolve the issue."; break; diff --git a/gui/src/main/java/io/bitsquare/gui/main/portfolio/openoffer/OpenOffersView.java b/gui/src/main/java/io/bitsquare/gui/main/portfolio/openoffer/OpenOffersView.java index 50ca36f1a9..70474d236f 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/portfolio/openoffer/OpenOffersView.java +++ b/gui/src/main/java/io/bitsquare/gui/main/portfolio/openoffer/OpenOffersView.java @@ -72,25 +72,34 @@ public class OpenOffersView extends ActivatableViewAndModel { - log.debug("Remove offer was successful"); - new Popup().information("You can withdraw the funds you paid in from the funds screens.") - .onClose(() -> navigation.navigateTo(MainView.class, FundsView.class, WithdrawalView.class)) - .show(); - }, - (message) -> { - log.error(message); - new Popup().warning("Remove offer failed:\n" + message).show(); - }); + new Popup().warning("Are you sure you want to remove that offer?\n" + + "The offer fee you have paid will be lost if you remove that offer.") + .actionButtonText("Remove offer") + .onAction(() -> doRemoveOpenOffer(openOffer)) + .closeButtonText("Don't remove the offer") + .show(); } else { new Popup().warning("You need to wait until your client is authenticated in the network.\n" + "That might take up to about 2 minutes at startup.").show(); } } + private void doRemoveOpenOffer(OpenOffer openOffer) { + model.onCancelOpenOffer(openOffer, + () -> { + log.debug("Remove offer was successful"); + new Popup().information("You can withdraw the funds you paid in from the funds screens.") + .onClose(() -> navigation.navigateTo(MainView.class, FundsView.class, WithdrawalView.class)) + .show(); + }, + (message) -> { + log.error(message); + new Popup().warning("Remove offer failed:\n" + message).show(); + }); + } + /* private void openOfferDetails(OpenOfferListItem item) { Offer offer = item.getOffer(); int rowIndex = 0; @@ -284,7 +293,7 @@ public class OpenOffersView extends ActivatableViewAndModel onCancelOpenOffer(item.getOpenOffer())); + button.setOnAction(event -> onRemoveOpenOffer(item.getOpenOffer())); setGraphic(button); } else { setGraphic(null); diff --git a/gui/src/main/java/io/bitsquare/gui/main/portfolio/pendingtrades/PendingTradesDataModel.java b/gui/src/main/java/io/bitsquare/gui/main/portfolio/pendingtrades/PendingTradesDataModel.java index 3dca2cfa92..4f7faf7dfe 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/portfolio/pendingtrades/PendingTradesDataModel.java +++ b/gui/src/main/java/io/bitsquare/gui/main/portfolio/pendingtrades/PendingTradesDataModel.java @@ -136,8 +136,7 @@ public class PendingTradesDataModel extends ActivatableDataModel { if (item == null) { trade = null; tradeProperty.set(null); - } - else { + } else { trade = item.getTrade(); tradeProperty.set(trade); @@ -169,17 +168,17 @@ public class PendingTradesDataModel extends ActivatableDataModel { } private void doWithdrawRequest(String toAddress, KeyParameter aesKey) { - tradeManager.onWithdrawRequest( - toAddress, - aesKey, - trade, - () -> { - UserThread.execute(() -> navigation.navigateTo(MainView.class, PortfolioView.class, ClosedTradesView.class)); - }, - (errorMessage, throwable) -> { - log.error(errorMessage); - new Popup().error("An error occurred:\n" + throwable.getMessage()).show(); - }); + if (toAddress != null && toAddress.length() > 0) { + tradeManager.onWithdrawRequest( + toAddress, + aesKey, + trade, + () -> UserThread.execute(() -> navigation.navigateTo(MainView.class, PortfolioView.class, ClosedTradesView.class)), + (errorMessage, throwable) -> { + log.error(errorMessage); + new Popup().error("An error occurred:\n" + throwable.getMessage()).show(); + }); + } } public void onOpenDispute() { diff --git a/gui/src/main/java/io/bitsquare/gui/main/portfolio/pendingtrades/steps/CompletedView.java b/gui/src/main/java/io/bitsquare/gui/main/portfolio/pendingtrades/steps/CompletedView.java index abb452a81f..bea996c7ea 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/portfolio/pendingtrades/steps/CompletedView.java +++ b/gui/src/main/java/io/bitsquare/gui/main/portfolio/pendingtrades/steps/CompletedView.java @@ -60,9 +60,11 @@ public class CompletedView extends TradeStepDetailsView { @Override public void doActivate() { super.doActivate(); - withdrawAddressTextField.focusedProperty().addListener(focusedPropertyListener); - withdrawAddressTextField.setValidator(model.getBtcAddressValidator()); - withdrawButton.disableProperty().bind(model.getWithdrawalButtonDisable()); + + // TODO valid. handler need improvement + //withdrawAddressTextField.focusedProperty().addListener(focusedPropertyListener); + //withdrawAddressTextField.setValidator(model.getBtcAddressValidator()); + // withdrawButton.disableProperty().bind(model.getWithdrawalButtonDisable()); // We need to handle both cases: Address not set and address already set (when returning from other view) // We get address validation after focus out, so first make sure we loose focus and then set it again as hint for user to put address in @@ -78,8 +80,8 @@ public class CompletedView extends TradeStepDetailsView { @Override public void doDeactivate() { super.doDeactivate(); - withdrawAddressTextField.focusedProperty().removeListener(focusedPropertyListener); - withdrawButton.disableProperty().unbind(); + //withdrawAddressTextField.focusedProperty().removeListener(focusedPropertyListener); + // withdrawButton.disableProperty().unbind(); } diff --git a/gui/src/main/java/io/bitsquare/gui/main/portfolio/pendingtrades/steps/ConfirmPaymentReceivedView.java b/gui/src/main/java/io/bitsquare/gui/main/portfolio/pendingtrades/steps/ConfirmPaymentReceivedView.java index 378b064f3d..b22d37d642 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/portfolio/pendingtrades/steps/ConfirmPaymentReceivedView.java +++ b/gui/src/main/java/io/bitsquare/gui/main/portfolio/pendingtrades/steps/ConfirmPaymentReceivedView.java @@ -111,19 +111,17 @@ public class ConfirmPaymentReceivedView extends TradeStepDetailsView { Preferences preferences = model.dataModel.getPreferences(); String key = PopupId.PAYMENT_RECEIVED; if (preferences.showAgain(key) && !BitsquareApp.DEV_MODE) { - new Popup().information("Please note that as soon you have confirmed that you have received the " + - "payment the locked Bitcoin will be released.\n" + - "There is no way to reverse a Bitcoin payment. Confirm only if you are sure.") - .onClose(() -> preferences.dontShowAgain(key)) + new Popup().headLine("Confirmation") + .message("Do you have received the payment from your trading partner?\n\n" + + "Please note that as soon you have confirmed the locked Bitcoin will be released.\n" + + "There is no way to reverse a Bitcoin payment.") + .dontShowAgainId(key, preferences) + .actionButtonText("Yes I have received the payment") + .closeButtonText("No") + .onAction(() -> confirmPaymentReceived()) .show(); } else { - confirmFiatReceivedButton.setDisable(true); - - statusProgressIndicator.setVisible(true); - statusProgressIndicator.setProgress(-1); - statusLabel.setText("Sending message to trading partner..."); - - model.fiatPaymentReceived(); + confirmPaymentReceived(); } } else { new Popup().warning("You need to wait until your client is authenticated in the network.\n" + @@ -131,6 +129,16 @@ public class ConfirmPaymentReceivedView extends TradeStepDetailsView { } } + private void confirmPaymentReceived() { + confirmFiatReceivedButton.setDisable(true); + + statusProgressIndicator.setVisible(true); + statusProgressIndicator.setProgress(-1); + statusLabel.setText("Sending message to trading partner..."); + + model.fiatPaymentReceived(); + } + /////////////////////////////////////////////////////////////////////////////////////////// // Setters diff --git a/gui/src/main/java/io/bitsquare/gui/main/portfolio/pendingtrades/steps/StartPaymentView.java b/gui/src/main/java/io/bitsquare/gui/main/portfolio/pendingtrades/steps/StartPaymentView.java index ec37b44e67..bd2324eb9b 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/portfolio/pendingtrades/steps/StartPaymentView.java +++ b/gui/src/main/java/io/bitsquare/gui/main/portfolio/pendingtrades/steps/StartPaymentView.java @@ -143,18 +143,15 @@ public class StartPaymentView extends TradeStepDetailsView { if (model.isAuthenticated()) { String key = PopupId.PAYMENT_SENT; if (preferences.showAgain(key) && !BitsquareApp.DEV_MODE) { - new Popup().information("You are confirming that you have transferred the payment to your trading partner.\n" + - "Please click the \"Payment started\" button only if you have completed the transfer.") - .onClose(() -> preferences.dontShowAgain(key)) + new Popup().headLine("Confirmation") + .message("Do you have transferred the payment to your trading partner?") + .dontShowAgainId(key, preferences) + .actionButtonText("Yes I have started the payment") + .closeButtonText("No") + .onAction(() -> confirmPaymentStarted()) .show(); } else { - paymentStartedButton.setDisable(true); - - statusProgressIndicator.setVisible(true); - statusProgressIndicator.setProgress(-1); - statusLabel.setText("Sending message to trading partner..."); - - model.fiatPaymentStarted(); + confirmPaymentStarted(); } } else { new Popup().warning("You need to wait until your client is authenticated in the network.\n" + @@ -162,6 +159,16 @@ public class StartPaymentView extends TradeStepDetailsView { } } + private void confirmPaymentStarted() { + paymentStartedButton.setDisable(true); + + statusProgressIndicator.setVisible(true); + statusProgressIndicator.setProgress(-1); + statusLabel.setText("Sending message to trading partner..."); + + model.fiatPaymentStarted(); + } + /////////////////////////////////////////////////////////////////////////////////////////// // Build view diff --git a/gui/src/main/java/io/bitsquare/gui/main/settings/application/PreferencesView.java b/gui/src/main/java/io/bitsquare/gui/main/settings/application/PreferencesView.java index b1b480a955..ebf7db7f90 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/settings/application/PreferencesView.java +++ b/gui/src/main/java/io/bitsquare/gui/main/settings/application/PreferencesView.java @@ -52,7 +52,7 @@ public class PreferencesView extends ActivatableViewAndModel selectNetwork()) + new Popup().warning("The application needs more tested before it can be used in mainnet.\n" + + "Please follow our mailing list to get informed when Bitsquare will be ready for mainnet.") .onClose(() -> UserThread.execute(() -> netWorkComboBox.getSelectionModel().select(preferences.getBitcoinNetwork()))) .show(); } else { @@ -166,10 +164,14 @@ public class NetworkSettingsView extends ActivatableViewAndModel BitsquareApp.restartDownHandler.run()) + //TODO restart + new Popup().warning("You need to shut down and restart the application to apply the change of the Bitcoin network.\n\n" + + "Do you want to shut down now?") + .onAction(() -> { + preferences.setBitcoinNetwork(netWorkComboBox.getSelectionModel().getSelectedItem()); + UserThread.runAfter(() -> BitsquareApp.shutDownHandler.run(), 1); + }) + .onClose(() -> netWorkComboBox.getSelectionModel().select(preferences.getBitcoinNetwork())) .show(); } } diff --git a/gui/src/main/java/io/bitsquare/gui/popups/ContractPopup.java b/gui/src/main/java/io/bitsquare/gui/popups/ContractPopup.java index 34ca084477..e5d2e1c26a 100644 --- a/gui/src/main/java/io/bitsquare/gui/popups/ContractPopup.java +++ b/gui/src/main/java/io/bitsquare/gui/popups/ContractPopup.java @@ -109,8 +109,7 @@ public class ContractPopup extends Popup { Layout.FIRST_ROW_DISTANCE).second.setMouseTransparent(false); addLabelTextField(gridPane, ++rowIndex, "Offer date:", formatter.formatDateTime(offer.getDate())); addLabelTextField(gridPane, ++rowIndex, "Trade date:", formatter.formatDateTime(dispute.getTradeDate())); - String direction = offer.getDirection() == Offer.Direction.BUY ? "Offerer as buyer / Taker as seller" : "Offerer as seller / Taker as buyer"; - addLabelTextField(gridPane, ++rowIndex, "Trade type:", direction); + addLabelTextField(gridPane, ++rowIndex, "Trade type:", formatter.getDirectionDescription(offer.getDirection())); addLabelTextField(gridPane, ++rowIndex, "Price:", formatter.formatFiat(offer.getPrice()) + " " + offer.getCurrencyCode()); addLabelTextField(gridPane, ++rowIndex, "Trade amount:", formatter.formatCoinWithCode(contract.getTradeAmount())); addLabelTextFieldWithCopyIcon(gridPane, ++rowIndex, "Buyer bitcoin address:", @@ -144,8 +143,8 @@ public class ContractPopup extends Popup { } //addLabelTextField(gridPane, ++rowIndex, "Buyer Bitsquare account ID:", contract.getBuyerAccountId()).second.setMouseTransparent(false); //addLabelTextField(gridPane, ++rowIndex, "Seller Bitsquare account ID:", contract.getSellerAccountId()).second.setMouseTransparent(false); - addLabelTxIdTextField(gridPane, ++rowIndex, "Create offer fee transaction ID:", offer.getOfferFeePaymentTxID()); - addLabelTxIdTextField(gridPane, ++rowIndex, "Take offer fee transaction ID:", contract.takeOfferFeeTxID); + addLabelTxIdTextField(gridPane, ++rowIndex, "Offer fee transaction ID:", offer.getOfferFeePaymentTxID()); + addLabelTxIdTextField(gridPane, ++rowIndex, "Trading fee transaction ID:", contract.takeOfferFeeTxID); if (dispute.getDepositTxSerialized() != null) addLabelTxIdTextField(gridPane, ++rowIndex, "Deposit transaction ID:", dispute.getDepositTxId()); if (dispute.getPayoutTxSerialized() != null) diff --git a/gui/src/main/java/io/bitsquare/gui/popups/FirstTimeWebViewPopup.java b/gui/src/main/java/io/bitsquare/gui/popups/FirstTimeWebViewPopup.java index 72650fc1af..ddaf5374cc 100644 --- a/gui/src/main/java/io/bitsquare/gui/popups/FirstTimeWebViewPopup.java +++ b/gui/src/main/java/io/bitsquare/gui/popups/FirstTimeWebViewPopup.java @@ -54,8 +54,8 @@ public class FirstTimeWebViewPopup extends WebViewPopup { return this; } - public FirstTimeWebViewPopup id(String id) { - this.id = id; + public FirstTimeWebViewPopup id(String dontShowAgainId) { + this.id = dontShowAgainId; return this; } diff --git a/gui/src/main/java/io/bitsquare/gui/popups/OfferDetailsPopup.java b/gui/src/main/java/io/bitsquare/gui/popups/OfferDetailsPopup.java index 886e32711c..0f7723ecc6 100644 --- a/gui/src/main/java/io/bitsquare/gui/popups/OfferDetailsPopup.java +++ b/gui/src/main/java/io/bitsquare/gui/popups/OfferDetailsPopup.java @@ -35,6 +35,8 @@ import javafx.scene.control.Button; import javafx.scene.control.CheckBox; import javafx.scene.control.TextField; import javafx.scene.control.Tooltip; +import org.bitcoinj.core.Coin; +import org.jetbrains.annotations.NotNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -52,6 +54,7 @@ public class OfferDetailsPopup extends Popup { private User user; private final Navigation navigation; private Offer offer; + private Coin tradeAmount; private Optional> placeOfferHandlerOptional = Optional.empty(); private Optional takeOfferHandlerOptional = Optional.empty(); @@ -68,6 +71,18 @@ public class OfferDetailsPopup extends Popup { this.navigation = navigation; } + public OfferDetailsPopup show(Offer offer, Coin tradeAmount) { + this.offer = offer; + this.tradeAmount = tradeAmount; + + rowIndex = -1; + width = 850; + createGridPane(); + addContent(); + createPopup(); + return this; + } + public OfferDetailsPopup show(Offer offer) { this.offer = offer; @@ -110,25 +125,36 @@ public class OfferDetailsPopup extends Popup { } private void addContent() { - int rows = 11; + int rows = 5; + if (!takeOfferHandlerOptional.isPresent()) + rows++; + + addTitledGroupBg(gridPane, ++rowIndex, rows, "Offer"); + addLabelTextField(gridPane, rowIndex, "Offer type:", formatter.getDirectionDescription(offer.getDirection()), Layout.FIRST_ROW_DISTANCE); + addLabelTextField(gridPane, ++rowIndex, "Currency:", offer.getCurrencyCode()); + addLabelTextField(gridPane, ++rowIndex, "Price:", formatter.formatFiat(offer.getPrice()) + " " + offer.getCurrencyCode() + "/" + "BTC"); + if (takeOfferHandlerOptional.isPresent()) { + addLabelTextField(gridPane, ++rowIndex, "Trade amount:", formatter.formatCoinWithCode(tradeAmount)); + } else { + addLabelTextField(gridPane, ++rowIndex, "Amount:", formatter.formatCoinWithCode(offer.getAmount())); + addLabelTextField(gridPane, ++rowIndex, "Min. amount:", formatter.formatCoinWithCode(offer.getMinAmount())); + } + addLabelTextField(gridPane, ++rowIndex, "Payment method:", BSResources.get(offer.getPaymentMethod().getId())); + + rows = 3; if (offer.getPaymentMethodCountryCode() != null) rows++; if (offer.getOfferFeePaymentTxID() != null) rows++; if (offer.getAcceptedCountryCodes() != null) rows++; - if (placeOfferHandlerOptional.isPresent()) - rows -= 2; + /* if (placeOfferHandlerOptional.isPresent()) + rows -= 2;*/ - addTitledGroupBg(gridPane, ++rowIndex, rows, "Offer details"); - addLabelTextField(gridPane, rowIndex, "Offer ID:", offer.getId(), Layout.FIRST_ROW_DISTANCE); + addTitledGroupBg(gridPane, ++rowIndex, rows, "Details", Layout.GROUP_DISTANCE); + addLabelTextField(gridPane, rowIndex, "Offer ID:", offer.getId(), Layout.FIRST_ROW_AND_GROUP_DISTANCE); addLabelTextField(gridPane, ++rowIndex, "Creation date:", formatter.formatDateTime(offer.getDate())); - addLabelTextField(gridPane, ++rowIndex, "Offer direction:", Offer.Direction.BUY.name()); - addLabelTextField(gridPane, ++rowIndex, "Currency:", offer.getCurrencyCode()); - addLabelTextField(gridPane, ++rowIndex, "Price:", formatter.formatFiat(offer.getPrice()) + " " + offer.getCurrencyCode() + "/" + "BTC"); - addLabelTextField(gridPane, ++rowIndex, "Amount:", formatter.formatCoinWithCode(offer.getAmount())); - addLabelTextField(gridPane, ++rowIndex, "Min. amount:", formatter.formatCoinWithCode(offer.getMinAmount())); - addLabelTextField(gridPane, ++rowIndex, "Payment method:", BSResources.get(offer.getPaymentMethod().getId())); + if (offer.getPaymentMethodCountryCode() != null) addLabelTextField(gridPane, ++rowIndex, "Offerers country of bank:", offer.getPaymentMethodCountryCode()); if (offer.getAcceptedCountryCodes() != null) { @@ -141,61 +167,27 @@ public class OfferDetailsPopup extends Popup { tooltip = new Tooltip(CountryUtil.getNamesByCodesString(offer.getAcceptedCountryCodes())); } TextField acceptedCountries = addLabelTextField(gridPane, ++rowIndex, "Accepted taker countries:", countries).second; - if (tooltip != null) acceptedCountries.setTooltip(new Tooltip()); + if (tooltip != null) { + acceptedCountries.setMouseTransparent(false); + acceptedCountries.setTooltip(tooltip); + } } addLabelTextField(gridPane, ++rowIndex, "Accepted arbitrators:", formatter.arbitratorAddressesToString(offer.getArbitratorAddresses())); if (offer.getOfferFeePaymentTxID() != null) - addLabelTxIdTextField(gridPane, ++rowIndex, "Create offer fee transaction ID:", offer.getOfferFeePaymentTxID()); + addLabelTxIdTextField(gridPane, ++rowIndex, "Offer fee transaction ID:", offer.getOfferFeePaymentTxID()); if (placeOfferHandlerOptional.isPresent()) { - Tuple2 tuple = add2ButtonsAfterGroup(gridPane, ++rowIndex, "Confirm place offer", "Cancel"); - Button placeButton = tuple.first; - placeButton.setOnAction(e -> { - if (user.getAcceptedArbitrators().size() > 0) { - placeOfferHandlerOptional.get().accept(offer); - } else { - new Popup().warning("You have no arbitrator selected.\n" + - "Please select at least one arbitrator.").show(); + addTitledGroupBg(gridPane, ++rowIndex, 1, "Commitment", Layout.GROUP_DISTANCE); + addLabelTextField(gridPane, rowIndex, "Please note:", Offer.TAC_OFFERER, Layout.FIRST_ROW_AND_GROUP_DISTANCE); - navigation.navigateTo(MainView.class, AccountView.class, AccountSettingsView.class, ArbitratorSelectionView.class); - } - hide(); - }); - - Button cancelButton = tuple.second; - cancelButton.setOnAction(e -> { - closeHandlerOptional.ifPresent(closeHandler -> closeHandler.run()); - hide(); - }); - - CheckBox checkBox = addCheckBox(gridPane, ++rowIndex, "Don't show again", 5); - checkBox.setSelected(!preferences.getShowPlaceOfferConfirmation()); - checkBox.setOnAction(e -> preferences.setShowPlaceOfferConfirmation(!checkBox.isSelected())); + Button cancelButton = addConfirmButton(true); + addCancelButton(cancelButton, true); } else if (takeOfferHandlerOptional.isPresent()) { - Tuple2 tuple = add2ButtonsAfterGroup(gridPane, ++rowIndex, "Confirm take offer", "Cancel"); - Button placeButton = tuple.first; - placeButton.setOnAction(e -> { - if (user.getAcceptedArbitrators().size() > 0) { - takeOfferHandlerOptional.get().run(); - } else { - new Popup().warning("You have no arbitrator selected.\n" + - "Please select at least one arbitrator.").show(); + addTitledGroupBg(gridPane, ++rowIndex, 1, "Contract", Layout.GROUP_DISTANCE); + addLabelTextField(gridPane, rowIndex, "Terms and conditions:", Offer.TAC_TAKER, Layout.FIRST_ROW_AND_GROUP_DISTANCE); - navigation.navigateTo(MainView.class, AccountView.class, AccountSettingsView.class, ArbitratorSelectionView.class); - } - hide(); - }); - - Button cancelButton = tuple.second; - cancelButton.setOnAction(e -> { - closeHandlerOptional.ifPresent(closeHandler -> closeHandler.run()); - hide(); - }); - - CheckBox checkBox = addCheckBox(gridPane, ++rowIndex, "Don't show again", 5); - checkBox.setPadding(new Insets(20, 0, 25, 0)); - checkBox.setSelected(!preferences.getShowTakeOfferConfirmation()); - checkBox.setOnAction(e -> preferences.setShowTakeOfferConfirmation(!checkBox.isSelected())); + Button cancelButton = addConfirmButton(false); + addCancelButton(cancelButton, false); } else { Button cancelButton = addButtonAfterGroup(gridPane, ++rowIndex, "Close"); cancelButton.setOnAction(e -> { @@ -204,4 +196,44 @@ public class OfferDetailsPopup extends Popup { }); } } + + @NotNull + private Button addConfirmButton(boolean isPlaceOffer) { + Tuple2 tuple = add2ButtonsAfterGroup(gridPane, + ++rowIndex, + isPlaceOffer ? "Confirm place offer" : "Confirm take offer", + "Cancel"); + Button placeButton = tuple.first; + placeButton.setOnAction(e -> { + if (user.getAcceptedArbitrators().size() > 0) { + if (isPlaceOffer) + placeOfferHandlerOptional.get().accept(offer); + else + takeOfferHandlerOptional.get().run(); + } else { + new Popup().warning("You have no arbitrator selected.\n" + + "Please select at least one arbitrator.").show(); + + navigation.navigateTo(MainView.class, AccountView.class, AccountSettingsView.class, ArbitratorSelectionView.class); + } + hide(); + }); + return tuple.second; + } + + private void addCancelButton(Button cancelButton, boolean isPlaceOffer) { + cancelButton.setOnAction(e -> { + closeHandlerOptional.ifPresent(closeHandler -> closeHandler.run()); + hide(); + }); + + CheckBox checkBox = addCheckBox(gridPane, ++rowIndex, "Don't show again", 5); + if (isPlaceOffer) { + checkBox.setSelected(!preferences.getShowPlaceOfferConfirmation()); + checkBox.setOnAction(e -> preferences.setShowPlaceOfferConfirmation(!checkBox.isSelected())); + } else { + checkBox.setSelected(!preferences.getShowTakeOfferConfirmation()); + checkBox.setOnAction(e -> preferences.setShowTakeOfferConfirmation(!checkBox.isSelected())); + } + } } diff --git a/gui/src/main/java/io/bitsquare/gui/popups/Popup.java b/gui/src/main/java/io/bitsquare/gui/popups/Popup.java index 14dfc4f312..b82eb4f996 100644 --- a/gui/src/main/java/io/bitsquare/gui/popups/Popup.java +++ b/gui/src/main/java/io/bitsquare/gui/popups/Popup.java @@ -21,15 +21,13 @@ import io.bitsquare.common.util.Utilities; import io.bitsquare.gui.main.MainView; import io.bitsquare.gui.util.Transitions; import io.bitsquare.locale.BSResources; +import io.bitsquare.user.Preferences; import javafx.geometry.HPos; import javafx.geometry.Insets; import javafx.geometry.Orientation; import javafx.geometry.Point2D; import javafx.scene.Scene; -import javafx.scene.control.Button; -import javafx.scene.control.Label; -import javafx.scene.control.ProgressIndicator; -import javafx.scene.control.Separator; +import javafx.scene.control.*; import javafx.scene.layout.*; import javafx.scene.paint.Color; import javafx.stage.Modality; @@ -43,6 +41,8 @@ import org.slf4j.LoggerFactory; import java.time.Duration; import java.util.Optional; +import static io.bitsquare.gui.util.FormBuilder.addCheckBox; + public class Popup { protected final Logger log = LoggerFactory.getLogger(this.getClass()); @@ -66,6 +66,8 @@ public class Popup { private boolean showProgressIndicator; private Button actionButton; protected Label headLineLabel; + private String dontShowAgainId; + private Preferences preferences; /////////////////////////////////////////////////////////////////////////////////////////// @@ -87,6 +89,7 @@ public class Popup { addReportErrorButtons(); addCloseButton(); + addDontShowAgainCheckBox(); createPopup(); return this; } @@ -164,6 +167,12 @@ public class Popup { return this; } + public Popup dontShowAgainId(String dontShowAgainId, Preferences preferences) { + this.dontShowAgainId = dontShowAgainId; + this.preferences = preferences; + return this; + } + /////////////////////////////////////////////////////////////////////////////////////////// // Protected /////////////////////////////////////////////////////////////////////////////////////////// @@ -297,6 +306,17 @@ public class Popup { gridPane.getChildren().add(progressIndicator); } + private void addDontShowAgainCheckBox() { + if (dontShowAgainId != null && preferences != null) { + CheckBox dontShowAgain = addCheckBox(gridPane, ++rowIndex, "Don't show again", 10); + GridPane.setHalignment(dontShowAgain, HPos.RIGHT); + dontShowAgain.setOnAction(e -> { + if (dontShowAgain.isSelected()) + preferences.dontShowAgain(dontShowAgainId); + }); + } + } + protected void addCloseButton() { closeButton = new Button(closeButtonText == null ? "Close" : closeButtonText); closeButton.setOnAction(event -> { @@ -333,12 +353,11 @@ public class Popup { GridPane.setColumnIndex(closeButton, 1); gridPane.getChildren().add(closeButton); } - } protected void setTruncatedMessage() { - if (message != null && message.length() > 500) - truncatedMessage = message.substring(0, 500) + "..."; + if (message != null && message.length() > 600) + truncatedMessage = message.substring(0, 600) + "..."; else truncatedMessage = message; } diff --git a/gui/src/main/java/io/bitsquare/gui/popups/TradeDetailsPopup.java b/gui/src/main/java/io/bitsquare/gui/popups/TradeDetailsPopup.java index 80f684cbca..0ee315e1c7 100644 --- a/gui/src/main/java/io/bitsquare/gui/popups/TradeDetailsPopup.java +++ b/gui/src/main/java/io/bitsquare/gui/popups/TradeDetailsPopup.java @@ -90,7 +90,15 @@ public class TradeDetailsPopup extends Popup { Offer offer = trade.getOffer(); Contract contract = trade.getContract(); - int rows = 7; + int rows = 5; + addTitledGroupBg(gridPane, ++rowIndex, rows, "Trade"); + addLabelTextField(gridPane, rowIndex, "Trade type:", formatter.getDirectionDescription(offer.getDirection()), Layout.FIRST_ROW_DISTANCE); + addLabelTextField(gridPane, ++rowIndex, "Currency:", offer.getCurrencyCode()); + addLabelTextField(gridPane, ++rowIndex, "Price:", formatter.formatFiat(offer.getPrice()) + " " + offer.getCurrencyCode()); + addLabelTextField(gridPane, ++rowIndex, "Trade amount:", formatter.formatCoinWithCode(trade.getTradeAmount())); + addLabelTextField(gridPane, ++rowIndex, "Payment method:", BSResources.get(offer.getPaymentMethod().getId())); + + rows = 4; PaymentAccountContractData buyerPaymentAccountContractData = null; PaymentAccountContractData sellerPaymentAccountContractData = null; @@ -98,6 +106,8 @@ public class TradeDetailsPopup extends Popup { rows++; if (contract != null) { + rows++; + buyerPaymentAccountContractData = contract.getBuyerPaymentAccountContractData(); sellerPaymentAccountContractData = contract.getSellerPaymentAccountContractData(); if (buyerPaymentAccountContractData != null) @@ -120,13 +130,9 @@ public class TradeDetailsPopup extends Popup { if (trade.errorMessageProperty().get() != null) rows += 2; - addTitledGroupBg(gridPane, ++rowIndex, rows, "Trade details"); - addLabelTextField(gridPane, rowIndex, "Trade ID:", trade.getId(), Layout.FIRST_ROW_DISTANCE); + addTitledGroupBg(gridPane, ++rowIndex, rows, "Details", Layout.GROUP_DISTANCE); + addLabelTextField(gridPane, rowIndex, "Trade ID:", trade.getId(), Layout.FIRST_ROW_AND_GROUP_DISTANCE); addLabelTextField(gridPane, ++rowIndex, "Trade date:", formatter.formatDateTime(trade.getDate())); - String direction = offer.getDirection() == Offer.Direction.BUY ? "Offerer as buyer / Taker as seller" : "Offerer as seller / Taker as buyer"; - addLabelTextField(gridPane, ++rowIndex, "Offer direction:", direction); - addLabelTextField(gridPane, ++rowIndex, "Price:", formatter.formatFiat(offer.getPrice()) + " " + offer.getCurrencyCode()); - addLabelTextField(gridPane, ++rowIndex, "Trade amount:", formatter.formatCoinWithCode(trade.getTradeAmount())); addLabelTextField(gridPane, ++rowIndex, "Selected arbitrator:", trade.getArbitratorAddress().getFullAddress()); if (contract != null) { @@ -144,15 +150,22 @@ public class TradeDetailsPopup extends Popup { addLabelTextField(gridPane, ++rowIndex, "Payment method:", BSResources.get(contract.getPaymentMethodName())); } - addLabelTxIdTextField(gridPane, ++rowIndex, "Create offer fee transaction ID:", offer.getOfferFeePaymentTxID()); + addLabelTxIdTextField(gridPane, ++rowIndex, "Offer fee transaction ID:", offer.getOfferFeePaymentTxID()); if (contract != null && contract.takeOfferFeeTxID != null) - addLabelTxIdTextField(gridPane, ++rowIndex, "Take offer fee transaction ID:", contract.takeOfferFeeTxID); + addLabelTxIdTextField(gridPane, ++rowIndex, "Trading fee transaction ID:", contract.takeOfferFeeTxID); if (trade.getDepositTx() != null) addLabelTxIdTextField(gridPane, ++rowIndex, "Deposit transaction ID:", trade.getDepositTx().getHashAsString()); if (trade.getPayoutTx() != null) addLabelTxIdTextField(gridPane, ++rowIndex, "Payout transaction ID:", trade.getPayoutTx().getHashAsString()); + if (contract != null) { + TextArea textArea = addLabelTextArea(gridPane, ++rowIndex, "Contract in JSON format:", trade.getContractAsJson()).second; + textArea.setText(trade.getContractAsJson()); + textArea.setPrefHeight(50); + textArea.setEditable(false); + } + if (trade.errorMessageProperty().get() != null) { TextArea textArea = addLabelTextArea(gridPane, ++rowIndex, "Error message:", "").second; textArea.setText(trade.errorMessageProperty().get()); @@ -169,26 +182,6 @@ public class TradeDetailsPopup extends Popup { TextField state = addLabelTextField(gridPane, ++rowIndex, "Trade state:").second; state.setText(trade.getState().getPhase().name()); - //TODO better msg display - /* switch (trade.getTradeState().getPhase()) { - case PREPARATION: - state.setText("Take offer fee is already paid."); - break; - case TAKER_FEE_PAID: - state.setText("Take offer fee is already paid."); - break; - case DEPOSIT_PAID: - case FIAT_SENT: - case FIAT_RECEIVED: - state.setText("Deposit is already paid."); - break; - case PAYOUT_PAID: - break; - case WITHDRAWN: - break; - case DISPUTE: - break; - }*/ } Button cancelButton = addButtonAfterGroup(gridPane, ++rowIndex, "Close"); diff --git a/gui/src/main/java/io/bitsquare/gui/util/BSFormatter.java b/gui/src/main/java/io/bitsquare/gui/util/BSFormatter.java index 022f0a6335..2c8c8c159d 100644 --- a/gui/src/main/java/io/bitsquare/gui/util/BSFormatter.java +++ b/gui/src/main/java/io/bitsquare/gui/util/BSFormatter.java @@ -125,8 +125,7 @@ public class BSFormatter { log.warn("Exception at formatBtc: " + t.toString()); return ""; } - } - else { + } else { return ""; } } @@ -141,8 +140,7 @@ public class BSFormatter { log.warn("Exception at formatBtcWithCode: " + t.toString()); return ""; } - } - else { + } else { return ""; } } @@ -155,8 +153,7 @@ public class BSFormatter { log.warn("Exception at parseToBtc: " + t.toString()); return Coin.ZERO; } - } - else { + } else { return Coin.ZERO; } } @@ -208,8 +205,7 @@ public class BSFormatter { log.warn("Exception at formatFiat: " + t.toString()); return ""; } - } - else { + } else { return ""; } } @@ -223,8 +219,7 @@ public class BSFormatter { log.warn("Exception at formatFiatWithCode: " + t.toString()); return ""; } - } - else { + } else { return ""; } } @@ -238,8 +233,7 @@ public class BSFormatter { return Fiat.valueOf(currencyCode, 0); } - } - else { + } else { return Fiat.valueOf(currencyCode, 0); } } @@ -374,4 +368,8 @@ public class BSFormatter { return ""; } } + + public String getDirectionDescription(Offer.Direction direction) { + return direction == Offer.Direction.BUY ? "Offerer as Bitcoin buyer / Taker as Bitcoin seller" : "Offerer as Bitcoin seller / Taker as Bitcoin buyer"; + } } diff --git a/gui/src/main/resources/html/tac.html b/gui/src/main/resources/html/tac.html index 0619a5ceee..102d612efe 100644 --- a/gui/src/main/resources/html/tac.html +++ b/gui/src/main/resources/html/tac.html @@ -17,7 +17,7 @@ arising from, out of or in connection with the software or the use or other deal 2. The user is responsible to use the software in compliance with local laws.

3. The user confirms that he has read and agreed to the rules defined in our -wiki regrading the dispute +Wiki regrading the dispute process.
\ No newline at end of file diff --git a/gui/src/main/resources/html/tradeWallet.html b/gui/src/main/resources/html/tradeWallet.html index 51d06bb350..6462e3c30b 100644 --- a/gui/src/main/resources/html/tradeWallet.html +++ b/gui/src/main/resources/html/tradeWallet.html @@ -23,13 +23,12 @@

Information

-Bitsquare does not use a global wallet.
-For every trade a dedicated wallet will be created. Funding of the wallet will be done just in time when it is needed. -For instance when you create an offer or -when you take an offer. Withdrawing from your funds can be done after a trade has been completed.
-That separation of addresses helps to protect users privacy and not leaking information of previous trades to new +Bitsquare does not use a single application wallet, but dedicated wallets for every trade.
+Funding of the wallet will be done when needed, for instance when you create or take an offer. +Withdrawing funds can be done after a trade is completed.
+Dedicated wallets help protect user privacy and prevent leaking information of previous trades to other traders.
-Please read more background information to that topic at the Bitsquare FAQ. \ No newline at end of file diff --git a/network/src/main/java/io/bitsquare/p2p/peers/PeerGroup.java b/network/src/main/java/io/bitsquare/p2p/peers/PeerGroup.java index f5a88ddde6..846696b8e7 100644 --- a/network/src/main/java/io/bitsquare/p2p/peers/PeerGroup.java +++ b/network/src/main/java/io/bitsquare/p2p/peers/PeerGroup.java @@ -646,16 +646,32 @@ public class PeerGroup implements MessageListener, ConnectionListener { // Reported peers /////////////////////////////////////////////////////////////////////////////////////////// - void addToReportedPeers(HashSet reportedPeers, Connection connection) { + void addToReportedPeers(HashSet newReportedPeers, Connection connection) { Log.traceCall(); // we disconnect misbehaving nodes trying to send too many peers // reported peers include the peers connected peers which is normally max. 8 but we give some headroom // for safety - if (reportedPeers.size() > 1100) { + if (newReportedPeers.size() > 1100) { connection.shutDown(); } else { - reportedPeers.remove(new ReportedPeer(getMyAddress(), new Date())); - this.reportedPeers.addAll(reportedPeers); + newReportedPeers.remove(new ReportedPeer(getMyAddress(), new Date())); + + //TODO if we have already peer, we mix date from old and new item + // + /* Map reportedPeersMap = new HashMap<>(); + reportedPeers.stream().forEach(e -> reportedPeersMap.put(e.address, e)); + + HashSet newAdjustedReportedPeers = new HashSet<>(); + newReportedPeers.stream() + .forEach(e -> { + if() + long adjustedTime = (e.lastActivityDate.getTime() + + reportedPeersMap.get(e.address).lastActivityDate.getTime()) / 2; + newAdjustedReportedPeers.add(new ReportedPeer(e.address, + new Date(adjustedTime))); + });*/ + + this.reportedPeers.addAll(newReportedPeers); purgeReportedPeersIfExceeds(); } @@ -670,6 +686,8 @@ public class PeerGroup implements MessageListener, ConnectionListener { "We remove random peers from the reported peers list.", MAX_REPORTED_PEERS, size); int diff = size - MAX_REPORTED_PEERS; List list = new LinkedList<>(getReportedNotConnectedPeerAddresses()); + + //TODO sort and remove oldest for (int i = 0; i < diff; i++) { ReportedPeer toRemove = getAndRemoveRandomReportedPeer(list); reportedPeers.remove(toRemove);