mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-03-15 10:26:37 -04:00
Clean up pending trades
This commit is contained in:
parent
1a6fb9f5b5
commit
2840311853
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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<Country> 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<Country> bankAccountCountryProperty() {
|
||||
return bankAccountCountry;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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<PendingTradesListItem> pendingTrades = FXCollections.observableArrayList();
|
||||
private final WalletFacade walletFacade;
|
||||
private final User user;
|
||||
|
||||
private PendingTradesListItem currentItem;
|
||||
private final ObservableList<PendingTradesListItem> list = FXCollections.observableArrayList();
|
||||
|
||||
private PendingTradesListItem selectedItem;
|
||||
private boolean isOfferer;
|
||||
final IntegerProperty selectedIndex = new SimpleIntegerProperty(-1);
|
||||
|
||||
private TxConfidenceListener txConfidenceListener;
|
||||
private ChangeListener<Trade.State> stateChangeListener;
|
||||
private ChangeListener<Throwable> faultChangeListener;
|
||||
private MapChangeListener<String, Trade> mapChangeListener;
|
||||
|
||||
final StringProperty txId = new SimpleStringProperty();
|
||||
final ObjectProperty<Trade.State> tradeState = new SimpleObjectProperty<>();
|
||||
final ObjectProperty<Throwable> 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<String, Trade>) 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<PendingTradesListItem> 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<PendingTradesListItem> 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<PendingTradesListItem> getPendingTrades() {
|
||||
return pendingTrades;
|
||||
ObservableList<PendingTradesListItem> 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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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<PendingTradesModel> {
|
||||
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<PendingTradesModel> {
|
||||
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> state = new SimpleObjectProperty<>();
|
||||
final ObjectProperty<Trade.State> tradeState = new SimpleObjectProperty<>();
|
||||
final ObjectProperty<Throwable> fault = new SimpleObjectProperty<>();
|
||||
final StringProperty txId = new SimpleStringProperty();
|
||||
final ObjectProperty<State> state = new SimpleObjectProperty<>();
|
||||
final ObjectProperty<Throwable> 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<PendingTradesModel> {
|
||||
|
||||
@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<PendingTradesModel> {
|
||||
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<PendingTradesModel> {
|
||||
@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<PendingTradesModel> {
|
||||
// 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<PendingTradesModel> {
|
||||
// Getters
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ObservableList<PendingTradesListItem> getPendingTrades() {
|
||||
return model.getPendingTrades();
|
||||
ObservableList<PendingTradesListItem> 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<PendingTradesModel> {
|
||||
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<PendingTradesModel> {
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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:
|
||||
|
@ -42,12 +42,12 @@
|
||||
<Insets top="10.0" left="-10" right="-10" bottom="-15"/>
|
||||
</GridPane.margin>
|
||||
<columns>
|
||||
<TableColumn text="Amount in BTC (Min.)" fx:id="amountColumn" minWidth="130"/>
|
||||
<TableColumn text="Price" fx:id="priceColumn" minWidth="130"/>
|
||||
<TableColumn text="Amount in EUR (Min.)" fx:id="volumeColumn" minWidth="130"/>
|
||||
<TableColumn text="Country" fx:id="countryColumn" minWidth="60"/>
|
||||
<TableColumn text="Bank transfer type" fx:id="bankAccountTypeColumn" minWidth="130"/>
|
||||
<TableColumn text="Trade tye" fx:id="directionColumn" minWidth="80" sortable="false"/>
|
||||
<TableColumn text="Trade ID" fx:id="tradeIdColumn" minWidth="100" sortable="false"/>
|
||||
<TableColumn text="Date" fx:id="dateColumn" minWidth="130"/>
|
||||
<TableColumn text="Amount in BTC (Min.)" fx:id="amountColumn" minWidth="130" sortable="false"/>
|
||||
<TableColumn text="Price" fx:id="priceColumn" minWidth="100" sortable="false"/>
|
||||
<TableColumn text="Amount in EUR (Min.)" fx:id="volumeColumn" minWidth="130" sortable="false"/>
|
||||
<TableColumn text="Trade type" fx:id="directionColumn" minWidth="80" sortable="false"/>
|
||||
<TableColumn fx:id="selectColumn" minWidth="60" sortable="false" text=""/>
|
||||
</columns>
|
||||
</TableView>
|
||||
@ -141,8 +141,8 @@
|
||||
</TitledGroupBg>
|
||||
|
||||
<Label fx:id="btcLabel" GridPane.rowIndex="5" visible="false">
|
||||
<GridPane.margin>
|
||||
<Insets top="60.0"/>
|
||||
<GridPane.margin>
|
||||
<Insets top="60.0"/>
|
||||
</GridPane.margin>
|
||||
</Label>
|
||||
<TextField fx:id="btcTextField" GridPane.rowIndex="5" GridPane.columnIndex="1" editable="false"
|
||||
|
@ -26,8 +26,6 @@ import io.bitsquare.gui.components.processbar.ProcessStepBar;
|
||||
import io.bitsquare.gui.components.processbar.ProcessStepItem;
|
||||
import io.bitsquare.gui.main.help.Help;
|
||||
import io.bitsquare.gui.main.help.HelpId;
|
||||
import io.bitsquare.gui.util.ImageUtil;
|
||||
import io.bitsquare.locale.Country;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
@ -37,12 +35,11 @@ import java.util.ResourceBundle;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.ReadOnlyObjectWrapper;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.collections.ListChangeListener;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.layout.*;
|
||||
import javafx.util.Callback;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
@ -50,29 +47,26 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
public class PendingTradesViewCB extends CachedViewCB<PendingTradesPM> {
|
||||
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<PendingTradesListItem> table;
|
||||
@FXML TableColumn<PendingTradesListItem, PendingTradesListItem> priceColumn, amountColumn, volumeColumn,
|
||||
directionColumn, countryColumn, bankAccountTypeColumn, selectColumn;
|
||||
directionColumn, dateColumn, tradeIdColumn, selectColumn;
|
||||
private ChangeListener<PendingTradesListItem> selectedItemChangeListener;
|
||||
private ListChangeListener<PendingTradesListItem> listChangeListener;
|
||||
private ChangeListener<String> txIdChangeListener;
|
||||
private ChangeListener<PendingTradesPM.State> offererStateChangeListener;
|
||||
private ChangeListener<PendingTradesPM.State> takerStateChangeListener;
|
||||
private ChangeListener<Throwable> faultChangeListener;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -80,7 +74,7 @@ public class PendingTradesViewCB extends CachedViewCB<PendingTradesPM> {
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Inject
|
||||
public PendingTradesViewCB(PendingTradesPM presentationModel) {
|
||||
PendingTradesViewCB(PendingTradesPM presentationModel) {
|
||||
super(presentationModel);
|
||||
}
|
||||
|
||||
@ -91,33 +85,41 @@ public class PendingTradesViewCB extends CachedViewCB<PendingTradesPM> {
|
||||
|
||||
@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<PendingTradesPM> {
|
||||
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<PendingTradesPM> {
|
||||
|
||||
@FXML
|
||||
void onPaymentStarted() {
|
||||
presentationModel.paymentStarted();
|
||||
presentationModel.fiatPaymentStarted();
|
||||
}
|
||||
|
||||
@FXML
|
||||
void onConfirmPaymentReceipt() {
|
||||
presentationModel.paymentReceived();
|
||||
presentationModel.fiatPaymentReceived();
|
||||
}
|
||||
|
||||
@FXML
|
||||
@ -202,10 +198,25 @@ public class PendingTradesViewCB extends CachedViewCB<PendingTradesPM> {
|
||||
// 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<ProcessStepItem> items = new ArrayList<>();
|
||||
items.add(new ProcessStepItem("Wait for block chain confirmation"));
|
||||
@ -215,115 +226,10 @@ public class PendingTradesViewCB extends CachedViewCB<PendingTradesPM> {
|
||||
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<PendingTradesPM> {
|
||||
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<PendingTradesPM> {
|
||||
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<PendingTradesPM> {
|
||||
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<PendingTradesPM> {
|
||||
// CellFactories
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private void setDateColumnCellFactory() {
|
||||
dateColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue()));
|
||||
dateColumn.setCellFactory(
|
||||
new Callback<TableColumn<PendingTradesListItem, PendingTradesListItem>, TableCell<PendingTradesListItem,
|
||||
PendingTradesListItem>>() {
|
||||
@Override
|
||||
public TableCell<PendingTradesListItem, PendingTradesListItem> call(
|
||||
TableColumn<PendingTradesListItem, PendingTradesListItem> column) {
|
||||
return new TableCell<PendingTradesListItem, PendingTradesListItem>() {
|
||||
@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<TableColumn<PendingTradesListItem, PendingTradesListItem>, TableCell<PendingTradesListItem,
|
||||
PendingTradesListItem>>() {
|
||||
@Override
|
||||
public TableCell<PendingTradesListItem, PendingTradesListItem> call(
|
||||
TableColumn<PendingTradesListItem, PendingTradesListItem> column) {
|
||||
return new TableCell<PendingTradesListItem, PendingTradesListItem>() {
|
||||
|
||||
@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<PendingTradesPM> {
|
||||
});
|
||||
}
|
||||
|
||||
private void setCountryColumnCellFactory() {
|
||||
countryColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue()));
|
||||
countryColumn.setCellFactory(
|
||||
new Callback<TableColumn<PendingTradesListItem, PendingTradesListItem>, TableCell<PendingTradesListItem,
|
||||
PendingTradesListItem>>() {
|
||||
|
||||
@Override
|
||||
public TableCell<PendingTradesListItem, PendingTradesListItem> call(
|
||||
TableColumn<PendingTradesListItem, PendingTradesListItem> column) {
|
||||
return new TableCell<PendingTradesListItem, PendingTradesListItem>() {
|
||||
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<TableColumn<PendingTradesListItem, PendingTradesListItem>, TableCell<PendingTradesListItem,
|
||||
PendingTradesListItem>>() {
|
||||
@Override
|
||||
public TableCell<PendingTradesListItem, PendingTradesListItem> call(
|
||||
TableColumn<PendingTradesListItem, PendingTradesListItem> column) {
|
||||
return new TableCell<PendingTradesListItem, PendingTradesListItem>() {
|
||||
@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<TableColumn<PendingTradesListItem, PendingTradesListItem>,
|
||||
TableCell<PendingTradesListItem, PendingTradesListItem>>() {
|
||||
@Override
|
||||
@ -581,7 +557,5 @@ public class PendingTradesViewCB extends CachedViewCB<PendingTradesPM> {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -201,9 +201,7 @@ class OrderBookPM extends PresentationModel<OrderBookModel> {
|
||||
}
|
||||
|
||||
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() {
|
||||
|
@ -141,8 +141,6 @@ public class OrderBookViewCB extends CachedViewCB<OrderBookPM> {
|
||||
SortedList<OrderBookListItem> 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();
|
||||
|
@ -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<Country> 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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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<Transaction> depositTxProperty() {
|
||||
if (_depositTx == null)
|
||||
|
@ -86,7 +86,7 @@ public class TradeManager {
|
||||
private final ObservableMap<String, Offer> offers = FXCollections.observableHashMap();
|
||||
private final ObservableMap<String, Trade> 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
|
||||
|
Loading…
x
Reference in New Issue
Block a user