From 284031185363570b3c2a06af6a9d11855461dbeb Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Thu, 25 Sep 2014 14:29:48 +0200 Subject: [PATCH] Clean up pending trades --- .../gui/main/orders/offer/OfferListItem.java | 3 +- .../orders/pending/PendingTradesListItem.java | 42 +- .../orders/pending/PendingTradesModel.java | 169 +++--- .../main/orders/pending/PendingTradesPM.java | 103 ++-- .../orders/pending/PendingTradesView.fxml | 16 +- .../orders/pending/PendingTradesViewCB.java | 502 +++++++++--------- .../gui/main/trade/orderbook/OrderBookPM.java | 4 +- .../main/trade/orderbook/OrderBookViewCB.java | 2 - .../io/bitsquare/gui/util/BSFormatter.java | 17 +- src/main/java/io/bitsquare/trade/Offer.java | 4 + src/main/java/io/bitsquare/trade/Trade.java | 12 +- .../java/io/bitsquare/trade/TradeManager.java | 9 +- 12 files changed, 434 insertions(+), 449 deletions(-) diff --git a/src/main/java/io/bitsquare/gui/main/orders/offer/OfferListItem.java b/src/main/java/io/bitsquare/gui/main/orders/offer/OfferListItem.java index 912ec21825..1a7fd7b431 100644 --- a/src/main/java/io/bitsquare/gui/main/orders/offer/OfferListItem.java +++ b/src/main/java/io/bitsquare/gui/main/orders/offer/OfferListItem.java @@ -40,8 +40,7 @@ public class OfferListItem { this.amount.set(BSFormatter.formatCoin( offer.getAmount()) + " (" + BSFormatter.formatCoin(offer.getMinAmount()) + ")"); - this.volume.set(BSFormatter.formatVolumeWithMinVolume( - offer.getOfferVolume(), offer.getMinOfferVolume())); + this.volume.set(BSFormatter.formatVolumeWithMinVolume(offer)); this.offerId = offer.getId(); } diff --git a/src/main/java/io/bitsquare/gui/main/orders/pending/PendingTradesListItem.java b/src/main/java/io/bitsquare/gui/main/orders/pending/PendingTradesListItem.java index f0b25752e9..226a033c1a 100644 --- a/src/main/java/io/bitsquare/gui/main/orders/pending/PendingTradesListItem.java +++ b/src/main/java/io/bitsquare/gui/main/orders/pending/PendingTradesListItem.java @@ -17,22 +17,17 @@ package io.bitsquare.gui.main.orders.pending; -import io.bitsquare.locale.Country; -import io.bitsquare.trade.Offer; import io.bitsquare.trade.Trade; -import javafx.beans.property.ObjectProperty; -import javafx.beans.property.SimpleObjectProperty; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; -// TODO don't use inheritance -public class PendingTradesListItem { +/** + * We could remove that wrapper if it is not needed for additional UI only fields. + */ +class PendingTradesListItem { private static final Logger log = LoggerFactory.getLogger(PendingTradesListItem.class); - private final Offer offer; - private final ObjectProperty bankAccountCountry = new SimpleObjectProperty<>(); private final Trade trade; @@ -40,20 +35,8 @@ public class PendingTradesListItem { // Constructor /////////////////////////////////////////////////////////////////////////////////////////// - public PendingTradesListItem(Trade trade) { + PendingTradesListItem(Trade trade) { this.trade = trade; - - this.offer = trade.getOffer(); - setBankAccountCountry(offer.getBankAccountCountry()); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Setters - /////////////////////////////////////////////////////////////////////////////////////////// - - void setBankAccountCountry(Country bankAccountCountry) { - this.bankAccountCountry.set(bankAccountCountry); } @@ -61,20 +44,7 @@ public class PendingTradesListItem { // Getters /////////////////////////////////////////////////////////////////////////////////////////// - public Trade getTrade() { + Trade getTrade() { return trade; } - - Offer getOffer() { - return offer; - } - - Country getBankAccountCountry() { - return bankAccountCountry.get(); - } - - ObjectProperty bankAccountCountryProperty() { - return bankAccountCountry; - } - } diff --git a/src/main/java/io/bitsquare/gui/main/orders/pending/PendingTradesModel.java b/src/main/java/io/bitsquare/gui/main/orders/pending/PendingTradesModel.java index 4f88f7599e..c410bcf55e 100644 --- a/src/main/java/io/bitsquare/gui/main/orders/pending/PendingTradesModel.java +++ b/src/main/java/io/bitsquare/gui/main/orders/pending/PendingTradesModel.java @@ -23,6 +23,7 @@ import io.bitsquare.btc.listeners.TxConfidenceListener; import io.bitsquare.gui.UIModel; import io.bitsquare.trade.Trade; import io.bitsquare.trade.TradeManager; +import io.bitsquare.user.User; import com.google.bitcoin.core.Coin; import com.google.bitcoin.core.TransactionConfidence; @@ -31,12 +32,11 @@ import com.google.inject.Inject; import java.util.Optional; -import javafx.beans.property.IntegerProperty; import javafx.beans.property.ObjectProperty; -import javafx.beans.property.SimpleIntegerProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; +import javafx.beans.value.ChangeListener; import javafx.collections.FXCollections; import javafx.collections.MapChangeListener; import javafx.collections.ObservableList; @@ -44,20 +44,26 @@ import javafx.collections.ObservableList; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class PendingTradesModel extends UIModel { +class PendingTradesModel extends UIModel { private static final Logger log = LoggerFactory.getLogger(PendingTradesModel.class); private final TradeManager tradeManager; - private WalletFacade walletFacade; - private final ObservableList pendingTrades = FXCollections.observableArrayList(); + private final WalletFacade walletFacade; + private final User user; - private PendingTradesListItem currentItem; + private final ObservableList list = FXCollections.observableArrayList(); + + private PendingTradesListItem selectedItem; private boolean isOfferer; - final IntegerProperty selectedIndex = new SimpleIntegerProperty(-1); + private TxConfidenceListener txConfidenceListener; + private ChangeListener stateChangeListener; + private ChangeListener faultChangeListener; + private MapChangeListener mapChangeListener; + + final StringProperty txId = new SimpleStringProperty(); final ObjectProperty tradeState = new SimpleObjectProperty<>(); final ObjectProperty fault = new SimpleObjectProperty<>(); - final StringProperty txId = new SimpleStringProperty(); /////////////////////////////////////////////////////////////////////////////////////////// @@ -65,9 +71,10 @@ public class PendingTradesModel extends UIModel { /////////////////////////////////////////////////////////////////////////////////////////// @Inject - public PendingTradesModel(TradeManager tradeManager, WalletFacade walletFacade) { + PendingTradesModel(TradeManager tradeManager, WalletFacade walletFacade, User user) { this.tradeManager = tradeManager; this.walletFacade = walletFacade; + this.user = user; } @@ -77,35 +84,51 @@ public class PendingTradesModel extends UIModel { @Override public void initialize() { - super.initialize(); - // transform trades to list of PendingTradesListItems and keep it updated - tradeManager.getTrades().values().stream().forEach(e -> pendingTrades.add(new PendingTradesListItem(e))); - tradeManager.getTrades().addListener((MapChangeListener) change -> { + stateChangeListener = (ov, oldValue, newValue) -> tradeState.set(newValue); + faultChangeListener = (ov, oldValue, newValue) -> fault.set(newValue); + + mapChangeListener = change -> { if (change.wasAdded()) - pendingTrades.add(new PendingTradesListItem(change.getValueAdded())); - else if (change.wasAdded()) - pendingTrades.remove(new PendingTradesListItem(change.getValueRemoved())); - }); + list.add(new PendingTradesListItem(change.getValueAdded())); + else if (change.wasRemoved()) + list.remove(new PendingTradesListItem(change.getValueRemoved())); + }; + + super.initialize(); } @Override public void activate() { super.activate(); - // TODO Check if we can really use tradeManager.getPendingTrade() - Optional currentTradeItemOptional = pendingTrades.stream().filter((e) -> - tradeManager.getCurrentPendingTrade() != null && - e.getTrade().getId().equals(tradeManager.getCurrentPendingTrade().getId())).findFirst(); + list.clear(); + // transform trades to list of PendingTradesListItems and keep it updated + tradeManager.getTrades().values().stream() + .filter(e -> e.getState() != Trade.State.CLOSED) + .forEach(e -> list.add(new PendingTradesListItem(e))); + tradeManager.getTrades().addListener(mapChangeListener); + + // we sort by date + list.sort((o1, o2) -> o2.getTrade().getDate().compareTo(o1.getTrade().getDate())); + + // select either currentPendingTrade or first in the list + Optional currentTradeItemOptional = list.stream() + .filter((e) -> tradeManager.getCurrentPendingTrade() != null && + tradeManager.getCurrentPendingTrade().getId().equals(e.getTrade().getId())) + .findFirst(); if (currentTradeItemOptional.isPresent()) selectPendingTrade(currentTradeItemOptional.get()); - else if (pendingTrades.size() > 0) - selectPendingTrade(pendingTrades.get(0)); + else if (list.size() > 0) + selectPendingTrade(list.get(0)); } @SuppressWarnings("EmptyMethod") @Override public void deactivate() { super.deactivate(); + + tradeManager.getTrades().removeListener(mapChangeListener); + selectPendingTrade(null); } @SuppressWarnings("EmptyMethod") @@ -119,79 +142,87 @@ public class PendingTradesModel extends UIModel { // Methods /////////////////////////////////////////////////////////////////////////////////////////// - public void selectPendingTrade(PendingTradesListItem item) { - if (item != null) { - currentItem = item; - isOfferer = tradeManager.isTradeMyOffer(currentItem.getTrade()); + void selectPendingTrade(PendingTradesListItem item) { + // clean up previous selectedItem + if (selectedItem != null) { + Trade trade = getTrade(); + trade.stateProperty().removeListener(stateChangeListener); + trade.faultProperty().removeListener(faultChangeListener); + + if (txConfidenceListener != null) + walletFacade.removeTxConfidenceListener(txConfidenceListener); + } + + selectedItem = item; + + if (selectedItem != null) { + isOfferer = getTrade().getOffer().getMessagePublicKey().equals(user.getMessagePublicKey()); // we want to re-trigger a change if the state is the same but different trades tradeState.set(null); - selectedIndex.set(pendingTrades.indexOf(item)); - Trade currentTrade = currentItem.getTrade(); - if (currentTrade.getDepositTx() != null) { - walletFacade.addTxConfidenceListener(new TxConfidenceListener(currentItem.getTrade() - .getDepositTx().getHashAsString()) { - @Override - public void onTransactionConfidenceChanged(TransactionConfidence confidence) { - updateConfidence(confidence); - } - }); - updateConfidence(walletFacade.getConfidenceForTxId(currentItem.getTrade().getDepositTx() - .getHashAsString())); - } + Trade trade = getTrade(); + txId.set(trade.getDepositTx().getHashAsString()); - if (currentItem.getTrade().getDepositTx() != null) - txId.set(currentItem.getTrade().getDepositTx().getHashAsString()); - else - txId.set(""); + txConfidenceListener = new TxConfidenceListener(txId.get()) { + @Override + public void onTransactionConfidenceChanged(TransactionConfidence confidence) { + updateConfidence(confidence); + } + }; + walletFacade.addTxConfidenceListener(txConfidenceListener); + updateConfidence(walletFacade.getConfidenceForTxId(txId.get())); - currentTrade.stateProperty().addListener((ov, oldValue, newValue) -> tradeState.set(newValue)); - tradeState.set(currentTrade.stateProperty().get()); + trade.stateProperty().addListener(stateChangeListener); + tradeState.set(trade.stateProperty().get()); - currentTrade.faultProperty().addListener((ov, oldValue, newValue) -> fault.set(newValue)); - fault.set(currentTrade.faultProperty().get()); + trade.faultProperty().addListener(faultChangeListener); + fault.set(trade.faultProperty().get()); + } + else { + txId.set(null); + tradeState.set(null); } } - public void paymentStarted() { - tradeManager.bankTransferInited(currentItem.getTrade().getId()); + void fiatPaymentStarted() { + tradeManager.fiatPaymentStarted(getTrade().getId()); } - public void paymentReceived() { - tradeManager.onFiatReceived(currentItem.getTrade().getId()); + void fiatPaymentReceived() { + tradeManager.fiatPaymentReceived(getTrade().getId()); } - /////////////////////////////////////////////////////////////////////////////////////////// - // Setters - /////////////////////////////////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////////////////////////////////////////////// // Getters /////////////////////////////////////////////////////////////////////////////////////////// - ObservableList getPendingTrades() { - return pendingTrades; + ObservableList getList() { + return list; } - public boolean isOfferer() { + boolean isOfferer() { return isOfferer; } - public Trade getTrade() { - return currentItem.getTrade(); + Trade getTrade() { + return selectedItem.getTrade(); } - public Coin getTotalFees() { - Coin tradeFee = isOfferer() ? FeePolicy.CREATE_OFFER_FEE : FeePolicy.TAKE_OFFER_FEE; - return tradeFee.add(FeePolicy.TX_FEE); + Coin getTotalFees() { + return FeePolicy.TX_FEE.add(isOfferer() ? FeePolicy.CREATE_OFFER_FEE : FeePolicy.TAKE_OFFER_FEE); } - public WalletFacade getWalletFacade() { + WalletFacade getWalletFacade() { return walletFacade; } + PendingTradesListItem getSelectedItem() { + return selectedItem; + } + + /////////////////////////////////////////////////////////////////////////////////////////// // Private /////////////////////////////////////////////////////////////////////////////////////////// @@ -199,8 +230,12 @@ public class PendingTradesModel extends UIModel { private void updateConfidence(TransactionConfidence confidence) { if (confidence != null && confidence.getConfidenceType() == TransactionConfidence.ConfidenceType.BUILDING - && currentItem.getTrade().getState() == Trade.State.DEPOSIT_PUBLISHED) - currentItem.getTrade().setState(Trade.State.DEPOSIT_CONFIRMED); + && getTrade().getState() == Trade.State.DEPOSIT_PUBLISHED) { + // only set it once when actual state is DEPOSIT_PUBLISHED, and remove listener afterwards + getTrade().setState(Trade.State.DEPOSIT_CONFIRMED); + walletFacade.removeTxConfidenceListener(txConfidenceListener); + txConfidenceListener = null; + } } } diff --git a/src/main/java/io/bitsquare/gui/main/orders/pending/PendingTradesPM.java b/src/main/java/io/bitsquare/gui/main/orders/pending/PendingTradesPM.java index dc742d868a..1dd2674898 100644 --- a/src/main/java/io/bitsquare/gui/main/orders/pending/PendingTradesPM.java +++ b/src/main/java/io/bitsquare/gui/main/orders/pending/PendingTradesPM.java @@ -21,27 +21,24 @@ import io.bitsquare.btc.WalletFacade; import io.bitsquare.gui.PresentationModel; import io.bitsquare.gui.util.BSFormatter; import io.bitsquare.locale.BSResources; -import io.bitsquare.trade.Direction; -import io.bitsquare.trade.Trade; import com.google.inject.Inject; -import javafx.beans.property.IntegerProperty; +import javafx.beans.InvalidationListener; import javafx.beans.property.ObjectProperty; -import javafx.beans.property.SimpleIntegerProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; import javafx.collections.ObservableList; +import javafx.collections.transformation.SortedList; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class PendingTradesPM extends PresentationModel { private static final Logger log = LoggerFactory.getLogger(PendingTradesPM.class); - private BSFormatter formatter; - private BSResources resources; - + private final BSFormatter formatter; + private InvalidationListener stateChangeListener; enum State { TAKER_SELLER_WAIT_TX_CONF, @@ -55,25 +52,20 @@ public class PendingTradesPM extends PresentationModel { OFFERER_BUYER_COMPLETED, } - - final StringProperty amount = new SimpleStringProperty(); - final StringProperty price = new SimpleStringProperty(); - final StringProperty volume = new SimpleStringProperty(); - final IntegerProperty selectedIndex = new SimpleIntegerProperty(-1); - final ObjectProperty state = new SimpleObjectProperty<>(); - final ObjectProperty tradeState = new SimpleObjectProperty<>(); - final ObjectProperty fault = new SimpleObjectProperty<>(); final StringProperty txId = new SimpleStringProperty(); + final ObjectProperty state = new SimpleObjectProperty<>(); + final ObjectProperty fault = new SimpleObjectProperty<>(); + /////////////////////////////////////////////////////////////////////////////////////////// // Constructor /////////////////////////////////////////////////////////////////////////////////////////// @Inject - public PendingTradesPM(PendingTradesModel model, BSFormatter formatter, BSResources resources) { + PendingTradesPM(PendingTradesModel model, BSFormatter formatter) { super(model); + this.formatter = formatter; - this.resources = resources; } @@ -83,12 +75,7 @@ public class PendingTradesPM extends PresentationModel { @Override public void initialize() { - selectedIndex.bind(model.selectedIndex); - txId.bind(model.txId); - model.tradeState.addListener((ov, oldValue, newValue) -> { - updateState(); - }); - fault.bind(model.fault); + stateChangeListener = (ov) -> updateState(); super.initialize(); } @@ -97,6 +84,10 @@ public class PendingTradesPM extends PresentationModel { public void activate() { super.activate(); + txId.bind(model.txId); + fault.bind(model.fault); + + model.tradeState.addListener(stateChangeListener); updateState(); } @@ -104,6 +95,11 @@ public class PendingTradesPM extends PresentationModel { @Override public void deactivate() { super.deactivate(); + + txId.unbind(); + fault.unbind(); + + model.tradeState.removeListener(stateChangeListener); } @SuppressWarnings("EmptyMethod") @@ -117,17 +113,16 @@ public class PendingTradesPM extends PresentationModel { // Methods /////////////////////////////////////////////////////////////////////////////////////////// - - public void selectPendingTrade(PendingTradesListItem item) { + void selectPendingTrade(PendingTradesListItem item) { model.selectPendingTrade(item); } - public void paymentStarted() { - model.paymentStarted(); + void fiatPaymentStarted() { + model.fiatPaymentStarted(); } - public void paymentReceived() { - model.paymentReceived(); + void fiatPaymentReceived() { + model.fiatPaymentReceived(); } @@ -135,46 +130,36 @@ public class PendingTradesPM extends PresentationModel { // Getters /////////////////////////////////////////////////////////////////////////////////////////// - ObservableList getPendingTrades() { - return model.getPendingTrades(); + ObservableList getList() { + return new SortedList<>(model.getList()); } - - public boolean isOfferer() { + boolean isOfferer() { return model.isOfferer(); } - public WalletFacade getWalletFacade() { + WalletFacade getWalletFacade() { return model.getWalletFacade(); } + PendingTradesListItem getSelectedItem() { + return model.getSelectedItem(); + } + String getAmount(PendingTradesListItem item) { - return (item != null) ? BSFormatter.formatCoin(item.getOffer().getAmount()) + - " (" + BSFormatter.formatCoin(item.getOffer().getMinAmount()) + ")" : ""; + return (item != null) ? BSFormatter.formatAmountWithMinAmount(item.getTrade().getOffer()) : ""; } String getPrice(PendingTradesListItem item) { - return (item != null) ? BSFormatter.formatFiat(item.getOffer().getPrice()) : ""; + return (item != null) ? BSFormatter.formatFiat(item.getTrade().getOffer().getPrice()) : ""; } String getVolume(PendingTradesListItem item) { - return (item != null) ? BSFormatter.formatFiat(item.getOffer().getOfferVolume()) + - " (" + BSFormatter.formatFiat(item.getOffer().getMinOfferVolume()) + ")" : ""; - } - - String getBankAccountType(PendingTradesListItem item) { - return (item != null) ? BSResources.get(item.getOffer().getBankAccountType().toString()) : ""; + return (item != null) ? BSFormatter.formatVolumeWithMinVolume(item.getTrade().getOffer()) : ""; } String getDirectionLabel(PendingTradesListItem item) { - // mirror direction! - if (item != null) { - Direction direction = item.getOffer().getDirection() == Direction.BUY ? Direction.SELL : Direction.BUY; - return BSFormatter.formatDirection(direction, true); - } - else { - return ""; - } + return (item != null) ? BSFormatter.formatDirection(item.getTrade().getOffer().getMirroredDirection()) : ""; } String getPaymentMethod() { @@ -193,6 +178,13 @@ public class PendingTradesPM extends PresentationModel { return model.getTrade().getContract().getTakerBankAccount().getAccountSecondaryID(); } + String getDate(PendingTradesListItem item) { + return formatter.formatDateTime(item.getTrade().getDate()); + } + + String getTradeId(PendingTradesListItem item) { + return item.getTrade().getId(); + } String getTradeVolume() { return formatter.formatCoinWithCode(model.getTrade().getTradeAmount()); @@ -216,19 +208,18 @@ public class PendingTradesPM extends PresentationModel { /////////////////////////////////////////////////////////////////////////////////////////// private void updateState() { - log.debug("updateState " + model.tradeState.get()); if (model.tradeState.get() != null) { switch (model.tradeState.get()) { case DEPOSIT_PUBLISHED: state.set(model.isOfferer() ? State.OFFERER_BUYER_WAIT_TX_CONF : State.TAKER_SELLER_WAIT_TX_CONF); break; case DEPOSIT_CONFIRMED: - state.set(model.isOfferer() ? State.OFFERER_BUYER_START_PAYMENT : State - .TAKER_SELLER_WAIT_PAYMENT_STARTED); + state.set(model.isOfferer() ? State.OFFERER_BUYER_START_PAYMENT : + State.TAKER_SELLER_WAIT_PAYMENT_STARTED); break; case PAYMENT_STARTED: - state.set(model.isOfferer() ? State.OFFERER_BUYER_WAIT_CONFIRM_PAYMENT_RECEIVED : State - .TAKER_SELLER_CONFIRM_RECEIVE_PAYMENT); + state.set(model.isOfferer() ? State.OFFERER_BUYER_WAIT_CONFIRM_PAYMENT_RECEIVED : + State.TAKER_SELLER_CONFIRM_RECEIVE_PAYMENT); break; case PAYMENT_RECEIVED: case PAYOUT_PUBLISHED: diff --git a/src/main/java/io/bitsquare/gui/main/orders/pending/PendingTradesView.fxml b/src/main/java/io/bitsquare/gui/main/orders/pending/PendingTradesView.fxml index 8127523af5..c5de000674 100644 --- a/src/main/java/io/bitsquare/gui/main/orders/pending/PendingTradesView.fxml +++ b/src/main/java/io/bitsquare/gui/main/orders/pending/PendingTradesView.fxml @@ -42,12 +42,12 @@ - - - - - - + + + + + + @@ -141,8 +141,8 @@ { private static final Logger log = LoggerFactory.getLogger(PendingTradesViewCB.class); - public TitledGroupBg summaryGroupBg; - public Label btcLabel; - public TextField btcTextField; - public Label fiatLabel; - public TextField fiatTextField; - public Label feesLabel; - public TextField feesTextField; - public Label collateralLabel; - public TextField collateralTextField; - public InfoDisplay summaryInfoDisplay; - - @FXML TitledGroupBg titledGroupBg, paymentsGroupBg; + @FXML TitledGroupBg titledGroupBg, paymentsGroupBg, summaryGroupBg; @FXML ProcessStepBar processBar; - @FXML Label statusLabel, txIdLabel, paymentMethodLabel, holderNameLabel, primaryIdLabel, secondaryIdLabel; - @FXML TextField statusTextField, paymentMethodTextField; + @FXML Label statusLabel, txIdLabel, paymentMethodLabel, holderNameLabel, primaryIdLabel, secondaryIdLabel, + btcLabel, fiatLabel, feesLabel, collateralLabel; + @FXML TextField statusTextField, paymentMethodTextField, btcTextField, fiatTextField, feesTextField, + collateralTextField; @FXML TxIdTextField txIdTextField; - @FXML InfoDisplay infoDisplay, paymentsInfoDisplay; + @FXML InfoDisplay infoDisplay, paymentsInfoDisplay, summaryInfoDisplay; @FXML Button confirmPaymentReceiptButton, paymentsButton; @FXML TextFieldWithCopyIcon holderNameTextField, secondaryIdTextField, primaryIdTextField; @FXML TableView table; @FXML TableColumn priceColumn, amountColumn, volumeColumn, - directionColumn, countryColumn, bankAccountTypeColumn, selectColumn; + directionColumn, dateColumn, tradeIdColumn, selectColumn; + private ChangeListener selectedItemChangeListener; + private ListChangeListener listChangeListener; + private ChangeListener txIdChangeListener; + private ChangeListener offererStateChangeListener; + private ChangeListener takerStateChangeListener; + private ChangeListener faultChangeListener; /////////////////////////////////////////////////////////////////////////////////////////// @@ -80,7 +74,7 @@ public class PendingTradesViewCB extends CachedViewCB { /////////////////////////////////////////////////////////////////////////////////////////// @Inject - public PendingTradesViewCB(PendingTradesPM presentationModel) { + PendingTradesViewCB(PendingTradesPM presentationModel) { super(presentationModel); } @@ -91,33 +85,41 @@ public class PendingTradesViewCB extends CachedViewCB { @Override public void initialize(URL url, ResourceBundle rb) { + setTradeIdColumnCellFactory(); + setDirectionColumnCellFactory(); setAmountColumnCellFactory(); setPriceColumnCellFactory(); setVolumeColumnCellFactory(); - setCountryColumnCellFactory(); - setBankAccountTypeColumnCellFactory(); - setDirectionColumnCellFactory(); + setDateColumnCellFactory(); setSelectColumnCellFactory(); - table.setItems(presentationModel.getPendingTrades()); table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); - table.getSelectionModel().selectedItemProperty(). - addListener((obsValue, oldValue, newValue) -> { - if (oldValue != newValue) { - if (oldValue != null && newValue != null) - presentationModel.selectPendingTrade(newValue); - else if (newValue == null) - table.getSelectionModel().clearSelection(); - } - else { - log.error("####### should not happen!"); - } - }); + txIdChangeListener = (ov, oldValue, newValue) -> + txIdTextField.setup(presentationModel.getWalletFacade(), newValue); - // need runLater to avoid conflict with user initiated selection - presentationModel.selectedIndex.addListener((ov, oldValue, newValue) -> - Platform.runLater(() -> table.getSelectionModel().select((int) newValue))); + selectedItemChangeListener = (obsValue, oldValue, newValue) -> { + if (oldValue != newValue) { + if (oldValue != null && newValue != null) + presentationModel.selectPendingTrade(newValue); + else if (newValue == null) + table.getSelectionModel().clearSelection(); + } + else { + log.warn("should never happen!"); + } + }; + + listChangeListener = change -> { + change.next(); + if ((change.wasAdded() && change.getList().size() == 1) || + (change.wasRemoved() && change.getList().size() == 0)) + updateScreen(); + }; + + offererStateChangeListener = (ov, oldValue, newValue) -> applyOffererState(newValue); + takerStateChangeListener = (ov, oldValue, newValue) -> applyTakerState(newValue); + faultChangeListener = (ov, oldValue, newValue) -> onFault(newValue); super.initialize(url, rb); } @@ -126,39 +128,33 @@ public class PendingTradesViewCB extends CachedViewCB { public void activate() { super.activate(); - if (!presentationModel.getPendingTrades().isEmpty()) { - titledGroupBg.setVisible(true); - processBar.setVisible(true); - statusLabel.setVisible(true); - statusTextField.setVisible(true); - txIdLabel.setVisible(true); - txIdTextField.setVisible(true); - infoDisplay.setVisible(true); + table.setItems(presentationModel.getList()); - if (presentationModel.isOfferer()) - setupScreenForOfferer(); - else - setupScreenForTaker(); + presentationModel.getList().addListener(listChangeListener); + presentationModel.txId.addListener(txIdChangeListener); + presentationModel.fault.addListener(faultChangeListener); - presentationModel.txId.addListener((ov, oldValue, newValue) -> - txIdTextField.setup(presentationModel.getWalletFacade(), newValue)); - txIdTextField.setup(presentationModel.getWalletFacade(), presentationModel.txId.get()); - } - else { - titledGroupBg.setVisible(false); - processBar.setVisible(false); - statusLabel.setVisible(false); - statusTextField.setVisible(false); - txIdLabel.setVisible(false); - txIdTextField.setVisible(false); - infoDisplay.setVisible(false); - } + txIdTextField.setup(presentationModel.getWalletFacade(), presentationModel.txId.get()); + table.getSelectionModel().select(presentationModel.getSelectedItem()); + + // TODO Set focus does not work yet... + /* table.requestFocus(); + table.getFocusModel().focus( table.getSelectionModel().getSelectedIndex());*/ + + updateScreen(); } - @SuppressWarnings("EmptyMethod") @Override public void deactivate() { super.deactivate(); + + table.getSelectionModel().selectedItemProperty().removeListener(selectedItemChangeListener); + presentationModel.getList().removeListener(listChangeListener); + presentationModel.txId.removeListener(txIdChangeListener); + presentationModel.fault.removeListener(faultChangeListener); + + presentationModel.state.removeListener(offererStateChangeListener); + presentationModel.state.removeListener(takerStateChangeListener); } @SuppressWarnings("EmptyMethod") @@ -174,12 +170,12 @@ public class PendingTradesViewCB extends CachedViewCB { @FXML void onPaymentStarted() { - presentationModel.paymentStarted(); + presentationModel.fiatPaymentStarted(); } @FXML void onConfirmPaymentReceipt() { - presentationModel.paymentReceived(); + presentationModel.fiatPaymentReceived(); } @FXML @@ -202,10 +198,25 @@ public class PendingTradesViewCB extends CachedViewCB { // Private methods /////////////////////////////////////////////////////////////////////////////////////////// + private void updateScreen() { + boolean dataAvailable = !presentationModel.getList().isEmpty(); + titledGroupBg.setVisible(dataAvailable); + processBar.setVisible(dataAvailable); + statusLabel.setVisible(dataAvailable); + statusTextField.setVisible(dataAvailable); + txIdLabel.setVisible(dataAvailable); + txIdTextField.setVisible(dataAvailable); + infoDisplay.setVisible(dataAvailable); + + if (dataAvailable) { + if (presentationModel.isOfferer()) + setupScreenForOfferer(); + else + setupScreenForTaker(); + } + } private void setupScreenForOfferer() { - log.debug("setupScreenForOfferer"); - if (processBar.getProcessStepItems() == null) { List items = new ArrayList<>(); items.add(new ProcessStepItem("Wait for block chain confirmation")); @@ -215,115 +226,10 @@ public class PendingTradesViewCB extends CachedViewCB { processBar.setProcessStepItems(items); } - presentationModel.state.addListener((ov, oldValue, newValue) -> applyOffererState(newValue)); + presentationModel.state.addListener(offererStateChangeListener); applyOffererState(presentationModel.state.get()); } - private void applyOffererState(PendingTradesPM.State state) { - paymentsGroupBg.setVisible(false); - paymentMethodLabel.setVisible(false); - holderNameLabel.setVisible(false); - primaryIdLabel.setVisible(false); - secondaryIdLabel.setVisible(false); - paymentMethodTextField.setVisible(false); - paymentsInfoDisplay.setVisible(false); - paymentsButton.setVisible(false); - holderNameTextField.setVisible(false); - primaryIdTextField.setVisible(false); - secondaryIdTextField.setVisible(false); - - summaryGroupBg.setVisible(false); - btcLabel.setVisible(false); - btcTextField.setVisible(false); - fiatLabel.setVisible(false); - fiatTextField.setVisible(false); - feesLabel.setVisible(false); - feesTextField.setVisible(false); - collateralLabel.setVisible(false); - collateralTextField.setVisible(false); - summaryInfoDisplay.setVisible(false); - - if (state != null) { - switch (state) { - case OFFERER_BUYER_WAIT_TX_CONF: - processBar.setSelectedIndex(0); - statusTextField.setText("Deposit transaction is published. Waiting " + - "for at least 1 confirmation"); - infoDisplay.setText("Deposit transaction has bee published. You need to wait for at least one " + - "block " + - "chain confirmation. After that you need to make the payments transfer."); - break; - case OFFERER_BUYER_START_PAYMENT: - processBar.setSelectedIndex(1); - - statusTextField.setText("Deposit transaction has at least 1 confirmation. Start payment."); - infoDisplay.setText("Deposit transaction has at least one blockchain confirmation. You need to " + - "start " + - "the payment."); - - paymentsGroupBg.setVisible(true); - paymentMethodLabel.setVisible(true); - holderNameLabel.setVisible(true); - primaryIdLabel.setVisible(true); - secondaryIdLabel.setVisible(true); - paymentMethodTextField.setVisible(true); - paymentsInfoDisplay.setVisible(true); - holderNameTextField.setVisible(true); - primaryIdTextField.setVisible(true); - secondaryIdTextField.setVisible(true); - paymentsButton.setVisible(true); - - paymentMethodTextField.setText(presentationModel.getPaymentMethod()); - holderNameTextField.setText(presentationModel.getHolderName()); - primaryIdTextField.setText(presentationModel.getPrimaryId()); - secondaryIdTextField.setText(presentationModel.getSecondaryId()); - - - paymentsInfoDisplay.setText("Copy and paste the payments accounts data to your payments " + - "accounts web page and transfer the payment to the other trader. When the transfer is " + - "done confirm it with the 'Payment started' button."); - - break; - case OFFERER_BUYER_WAIT_CONFIRM_PAYMENT_RECEIVED: - processBar.setSelectedIndex(2); - - statusTextField.setText("Waiting until the other trader has received your payment."); - infoDisplay.setText("Waiting until the other trader has confirmed that he has received your " + - "payment."); - break; - case OFFERER_BUYER_COMPLETED: - processBar.setSelectedIndex(3); - - statusTextField.setText("Trade has successfully completed."); - infoDisplay.setText("Trade has successfully completed. You can find the details to that trade" + - " in the closed trades section."); - - summaryGroupBg.setVisible(true); - btcLabel.setVisible(true); - btcTextField.setVisible(true); - fiatLabel.setVisible(true); - fiatTextField.setVisible(true); - feesLabel.setVisible(true); - feesTextField.setVisible(true); - collateralLabel.setVisible(true); - collateralTextField.setVisible(true); - summaryInfoDisplay.setVisible(true); - - btcLabel.setText("You have bought:"); - fiatLabel.setText("You have paid:"); - btcTextField.setText(presentationModel.getTradeVolume()); - fiatTextField.setText(presentationModel.getFiatVolume()); - feesTextField.setText(presentationModel.getTotalFees()); - collateralTextField.setText(presentationModel.getCollateral()); - summaryInfoDisplay.setText("You can open that summary any time in the closed orders section."); - break; - } - } - else { - processBar.reset(); - } - } - private void setupScreenForTaker() { log.debug("setupScreenForTaker"); if (processBar.getProcessStepItems() == null) { @@ -335,37 +241,90 @@ public class PendingTradesViewCB extends CachedViewCB { processBar.setProcessStepItems(items); } - presentationModel.state.addListener((ov, oldValue, newValue) -> applyTakerState(newValue)); + presentationModel.state.addListener(takerStateChangeListener); applyTakerState(presentationModel.state.get()); } - private void applyTakerState(PendingTradesPM.State state) { - log.debug("#### state " + state); + private void applyOffererState(PendingTradesPM.State state) { + setPaymentsControlsVisible(false); + setSummaryControlsVisible(false); + processBar.reset(); + + if (state != null) { + switch (state) { + case OFFERER_BUYER_WAIT_TX_CONF: + processBar.setSelectedIndex(0); + statusTextField.setText("Deposit transaction is published. Waiting " + + "for at least 1 confirmation"); + infoDisplay.setText("Deposit transaction has bee published. You need to wait for at least one " + + "block chain confirmation. After that you need to make the payments transfer."); + break; + case OFFERER_BUYER_START_PAYMENT: + processBar.setSelectedIndex(1); + + setPaymentsControlsVisible(true); + + statusTextField.setText("Deposit transaction has at least 1 confirmation. Start payment."); + infoDisplay.setText("Deposit transaction has at least one blockchain confirmation. You need to " + + "start the payment."); + + paymentMethodTextField.setText(presentationModel.getPaymentMethod()); + holderNameTextField.setText(presentationModel.getHolderName()); + primaryIdTextField.setText(presentationModel.getPrimaryId()); + secondaryIdTextField.setText(presentationModel.getSecondaryId()); + paymentsInfoDisplay.setText("Copy and paste the payments accounts data to your payments " + + "accounts web page and transfer the payment to the other trader. When the transfer is " + + "done confirm it with the 'Payment started' button."); + break; + case OFFERER_BUYER_WAIT_CONFIRM_PAYMENT_RECEIVED: + processBar.setSelectedIndex(2); + + statusTextField.setText("Waiting until the other trader has received your payment."); + infoDisplay.setText("Waiting until the other trader has confirmed that he has received your " + + "payment."); + break; + case OFFERER_BUYER_COMPLETED: + processBar.setSelectedIndex(3); + + setSummaryControlsVisible(true); + + statusTextField.setText("Trade has successfully completed."); + infoDisplay.setText("Trade has successfully completed. You can find the details to that trade" + + " in the closed trades section."); + + btcLabel.setText("You have bought:"); + fiatLabel.setText("You have paid:"); + btcTextField.setText(presentationModel.getTradeVolume()); + fiatTextField.setText(presentationModel.getFiatVolume()); + feesTextField.setText(presentationModel.getTotalFees()); + collateralTextField.setText(presentationModel.getCollateral()); + summaryInfoDisplay.setText("You can open that summary any time in the closed orders section."); + break; + } + } + } + + + private void applyTakerState(PendingTradesPM.State state) { confirmPaymentReceiptButton.setVisible(false); - summaryGroupBg.setVisible(false); - btcLabel.setVisible(false); - btcTextField.setVisible(false); - fiatLabel.setVisible(false); - fiatTextField.setVisible(false); - feesLabel.setVisible(false); - feesTextField.setVisible(false); - collateralLabel.setVisible(false); - collateralTextField.setVisible(false); - summaryInfoDisplay.setVisible(false); + setSummaryControlsVisible(false); + + processBar.reset(); if (state != null) { switch (state) { case TAKER_SELLER_WAIT_TX_CONF: processBar.setSelectedIndex(0); + statusTextField.setText("Deposit transaction is published. Waiting for at least 1 confirmation"); infoDisplay.setText("Deposit transaction has bee published. He needs to wait for at least one " + - "blockchain " + - "confirmation."); + "blockchain confirmation."); break; case TAKER_SELLER_WAIT_PAYMENT_STARTED: processBar.setSelectedIndex(1); + statusTextField.setText("Deposit transaction has at least 1 confirmation. Waiting that other " + "trader starts payment."); infoDisplay.setText("Deposit transaction has at least one blockchain " + @@ -374,30 +333,24 @@ public class PendingTradesViewCB extends CachedViewCB { break; case TAKER_SELLER_CONFIRM_RECEIVE_PAYMENT: processBar.setSelectedIndex(2); + + confirmPaymentReceiptButton.setVisible(true); + statusTextField.setText("Payment is on the way. Check your payments account and confirm when you " + "have received the payment."); infoDisplay.setText("The other trader has started the payment. You need to check your payments " + "account and confirm the payment when the money has arrived there."); - confirmPaymentReceiptButton.setVisible(true); + break; case TAKER_SELLER_COMPLETED: processBar.setSelectedIndex(3); + setSummaryControlsVisible(true); + statusTextField.setText("Trade has successfully completed."); infoDisplay.setText("Trade has successfully completed. You can find the details to that trade" + " in the closed trades section."); - summaryGroupBg.setVisible(true); - btcLabel.setVisible(true); - btcTextField.setVisible(true); - fiatLabel.setVisible(true); - fiatTextField.setVisible(true); - feesLabel.setVisible(true); - feesTextField.setVisible(true); - collateralLabel.setVisible(true); - collateralTextField.setVisible(true); - summaryInfoDisplay.setVisible(true); - btcLabel.setText("You have sold:"); fiatLabel.setText("You have received:"); btcTextField.setText(presentationModel.getTradeVolume()); @@ -408,9 +361,38 @@ public class PendingTradesViewCB extends CachedViewCB { break; } } - else { - processBar.reset(); - } + } + + private void onFault(Throwable fault) { + // TODO + log.error(fault.toString()); + } + + private void setPaymentsControlsVisible(boolean visible) { + paymentsGroupBg.setVisible(visible); + paymentMethodLabel.setVisible(visible); + holderNameLabel.setVisible(visible); + primaryIdLabel.setVisible(visible); + secondaryIdLabel.setVisible(visible); + paymentMethodTextField.setVisible(visible); + paymentsInfoDisplay.setVisible(visible); + paymentsButton.setVisible(visible); + holderNameTextField.setVisible(visible); + primaryIdTextField.setVisible(visible); + secondaryIdTextField.setVisible(visible); + } + + private void setSummaryControlsVisible(boolean visible) { + summaryGroupBg.setVisible(visible); + btcLabel.setVisible(visible); + btcTextField.setVisible(visible); + fiatLabel.setVisible(visible); + fiatTextField.setVisible(visible); + feesLabel.setVisible(visible); + feesTextField.setVisible(visible); + collateralLabel.setVisible(visible); + collateralTextField.setVisible(visible); + summaryInfoDisplay.setVisible(visible); } @@ -418,6 +400,54 @@ public class PendingTradesViewCB extends CachedViewCB { // CellFactories /////////////////////////////////////////////////////////////////////////////////////////// + private void setDateColumnCellFactory() { + dateColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue())); + dateColumn.setCellFactory( + new Callback, TableCell>() { + @Override + public TableCell call( + TableColumn column) { + return new TableCell() { + @Override + public void updateItem(final PendingTradesListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null) + setText(presentationModel.getDate(item)); + else + setText(""); + } + }; + } + }); + } + + private void setTradeIdColumnCellFactory() { + tradeIdColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue())); + tradeIdColumn.setCellFactory( + new Callback, TableCell>() { + @Override + public TableCell call( + TableColumn column) { + return new TableCell() { + + @Override + public void updateItem(final PendingTradesListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null) { + setText(presentationModel.getTradeId(item)); + Tooltip.install(this, new Tooltip(presentationModel.getTradeId(item))); + } + else { + setText(""); + } + } + }; + } + }); + } + private void setAmountColumnCellFactory() { amountColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue())); amountColumn.setCellFactory( @@ -497,62 +527,8 @@ public class PendingTradesViewCB extends CachedViewCB { }); } - private void setCountryColumnCellFactory() { - countryColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue())); - countryColumn.setCellFactory( - new Callback, TableCell>() { - - @Override - public TableCell call( - TableColumn column) { - return new TableCell() { - final HBox hBox = new HBox(); - - { - hBox.setSpacing(3); - hBox.setAlignment(Pos.CENTER); - setGraphic(hBox); - } - - @Override - public void updateItem(final PendingTradesListItem item, boolean empty) { - super.updateItem(item, empty); - - hBox.getChildren().clear(); - if (item != null) { - Country country = item.getOffer().getBankAccountCountry(); - hBox.getChildren().add(ImageUtil.getCountryIconImageView(item - .getOffer().getBankAccountCountry())); - Tooltip.install(this, new Tooltip(country.getName())); - } - } - }; - } - }); - } - - private void setBankAccountTypeColumnCellFactory() { - bankAccountTypeColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue())); - bankAccountTypeColumn.setCellFactory( - new Callback, TableCell>() { - @Override - public TableCell call( - TableColumn column) { - return new TableCell() { - @Override - public void updateItem(final PendingTradesListItem item, boolean empty) { - super.updateItem(item, empty); - setText(presentationModel.getBankAccountType(item)); - } - }; - } - }); - } - private void setSelectColumnCellFactory() { - selectColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper(offer.getValue())); + selectColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue())); selectColumn.setCellFactory(new Callback, TableCell>() { @Override @@ -581,7 +557,5 @@ public class PendingTradesViewCB extends CachedViewCB { } }); } - - } diff --git a/src/main/java/io/bitsquare/gui/main/trade/orderbook/OrderBookPM.java b/src/main/java/io/bitsquare/gui/main/trade/orderbook/OrderBookPM.java index ee7a605fb7..cac6320cd5 100644 --- a/src/main/java/io/bitsquare/gui/main/trade/orderbook/OrderBookPM.java +++ b/src/main/java/io/bitsquare/gui/main/trade/orderbook/OrderBookPM.java @@ -201,9 +201,7 @@ class OrderBookPM extends PresentationModel { } String getDirectionLabel(Offer offer) { - // mirror direction! - Direction direction = offer.getDirection() == Direction.BUY ? Direction.SELL : Direction.BUY; - return BSFormatter.formatDirection(direction, true); + return BSFormatter.formatDirection(offer.getMirroredDirection()); } Direction getDirection() { diff --git a/src/main/java/io/bitsquare/gui/main/trade/orderbook/OrderBookViewCB.java b/src/main/java/io/bitsquare/gui/main/trade/orderbook/OrderBookViewCB.java index 73d7eed1f6..b8363c30a8 100644 --- a/src/main/java/io/bitsquare/gui/main/trade/orderbook/OrderBookViewCB.java +++ b/src/main/java/io/bitsquare/gui/main/trade/orderbook/OrderBookViewCB.java @@ -141,8 +141,6 @@ public class OrderBookViewCB extends CachedViewCB { SortedList offerList = presentationModel.getOfferList(); orderBookTable.setItems(offerList); offerList.comparatorProperty().bind(orderBookTable.comparatorProperty()); - - priceColumn.setSortType((presentationModel.getDirection() == Direction.BUY) ? TableColumn.SortType.ASCENDING : TableColumn.SortType.DESCENDING); orderBookTable.sort(); diff --git a/src/main/java/io/bitsquare/gui/util/BSFormatter.java b/src/main/java/io/bitsquare/gui/util/BSFormatter.java index dc4260a3f4..17f89870b2 100644 --- a/src/main/java/io/bitsquare/gui/util/BSFormatter.java +++ b/src/main/java/io/bitsquare/gui/util/BSFormatter.java @@ -21,6 +21,7 @@ import io.bitsquare.arbitrator.Arbitrator; import io.bitsquare.locale.BSResources; import io.bitsquare.locale.Country; import io.bitsquare.trade.Direction; +import io.bitsquare.trade.Offer; import io.bitsquare.user.User; import com.google.bitcoin.core.Coin; @@ -261,6 +262,10 @@ public class BSFormatter { } } + public static String formatDirection(Direction direction) { + return formatDirection(direction, true); + } + public static String formatDirection(Direction direction, boolean allUpperCase) { String result = (direction == Direction.BUY) ? "Buy" : "Sell"; if (allUpperCase) { @@ -269,6 +274,14 @@ public class BSFormatter { return result; } + public static String formatAmountWithMinAmount(Offer offer) { + return formatCoin(offer.getAmount()) + " (" + BSFormatter.formatCoin(offer.getMinAmount()) + ")"; + } + + public static String formatVolumeWithMinVolume(Offer offer) { + return BSFormatter.formatFiat(offer.getOfferVolume()) + + " (" + BSFormatter.formatFiat(offer.getMinOfferVolume()) + ")"; + } public static String countryLocalesToString(List countries) { return countries.stream().map(e -> e.getName()).collect(Collectors.joining(", ")); @@ -317,10 +330,6 @@ public class BSFormatter { return decimalFormat.format(value / 100) + " %"; } - public static String formatVolumeWithMinVolume(Fiat volume, Fiat minVolume) { - return formatFiat(volume) + " (" + formatFiat(minVolume) + ")"; - } - private static String cleanInput(String input) { input = input.replace(",", "."); // don't use String.valueOf(Double.parseDouble(input)) as return value as it gives scientific diff --git a/src/main/java/io/bitsquare/trade/Offer.java b/src/main/java/io/bitsquare/trade/Offer.java index 389c4743e4..2f8b221df4 100644 --- a/src/main/java/io/bitsquare/trade/Offer.java +++ b/src/main/java/io/bitsquare/trade/Offer.java @@ -135,6 +135,10 @@ public class Offer implements Serializable { return direction; } + public Direction getMirroredDirection() { + return direction == Direction.BUY ? Direction.SELL : Direction.BUY; + } + public BankAccountType getBankAccountType() { return bankAccountType; } diff --git a/src/main/java/io/bitsquare/trade/Trade.java b/src/main/java/io/bitsquare/trade/Trade.java index 639febba33..07908a10fa 100644 --- a/src/main/java/io/bitsquare/trade/Trade.java +++ b/src/main/java/io/bitsquare/trade/Trade.java @@ -23,6 +23,8 @@ import com.google.bitcoin.utils.Fiat; import java.io.Serializable; +import java.util.Date; + import javafx.beans.property.BooleanProperty; import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleBooleanProperty; @@ -46,11 +48,13 @@ public class Trade implements Serializable { PAYMENT_STARTED, PAYMENT_RECEIVED, /* For taker only*/ PAYOUT_PUBLISHED, - FAULT + FAULT, + CLOSED } private final Offer offer; + private final Date date; private String takeOfferFeeTxID; private Coin tradeAmount; private Contract contract; @@ -76,6 +80,7 @@ public class Trade implements Serializable { public Trade(Offer offer) { this.offer = offer; + date = new Date(); state = State.OPEN; } @@ -133,6 +138,7 @@ public class Trade implements Serializable { faultProperty().set(fault); } + /////////////////////////////////////////////////////////////////////////////////////////// // Getters /////////////////////////////////////////////////////////////////////////////////////////// @@ -181,6 +187,10 @@ public class Trade implements Serializable { return contractAsJson; } + public Date getDate() { + return date; + } + // When serialized those transient properties are not instantiated, so we need to instantiate them at first access public ObjectProperty depositTxProperty() { if (_depositTx == null) diff --git a/src/main/java/io/bitsquare/trade/TradeManager.java b/src/main/java/io/bitsquare/trade/TradeManager.java index 7583a80b47..f7238f25a1 100644 --- a/src/main/java/io/bitsquare/trade/TradeManager.java +++ b/src/main/java/io/bitsquare/trade/TradeManager.java @@ -86,7 +86,7 @@ public class TradeManager { private final ObservableMap offers = FXCollections.observableHashMap(); private final ObservableMap trades = FXCollections.observableHashMap(); - // TODO There might be multiple pending trades + // the latest pending trade private Trade currentPendingTrade; @@ -385,7 +385,7 @@ public class TradeManager { //TODO we don't support interruptions yet. // If the user has shut down the app we lose the offererAsBuyerProtocolMap // Also we don't support yet offline messaging (mail box) - public void bankTransferInited(String tradeId) { + public void fiatPaymentStarted(String tradeId) { if (offererAsBuyerProtocolMap.get(tradeId) != null) { offererAsBuyerProtocolMap.get(tradeId).onUIEventBankTransferInited(); trades.get(tradeId).setState(Trade.State.PAYMENT_STARTED); @@ -398,7 +398,7 @@ public class TradeManager { } } - public void onFiatReceived(String tradeId) { + public void fiatPaymentReceived(String tradeId) { takerAsSellerProtocolMap.get(tradeId).onUIEventFiatReceived(); trades.get(tradeId).setState(Trade.State.PAYMENT_RECEIVED); persistTrades(); @@ -454,9 +454,6 @@ public class TradeManager { return trades.containsKey(offer.getId()); } - public boolean isTradeMyOffer(Trade trade) { - return trade.getOffer().getMessagePublicKey().equals(user.getMessagePublicKey()); - } /////////////////////////////////////////////////////////////////////////////////////////// // Getters