mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-06-26 07:40:35 -04:00
Trade process error handling
This commit is contained in:
parent
3f6f8dd160
commit
ca3d1c96f2
56 changed files with 306 additions and 243 deletions
|
@ -158,7 +158,7 @@ public class BitsquareApp extends Application {
|
|||
primaryStage.show();
|
||||
|
||||
//TODO just temp.
|
||||
// showDebugWindow();
|
||||
showDebugWindow();
|
||||
} catch (Throwable throwable) {
|
||||
showErrorPopup(throwable, true);
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ import org.bitcoinj.utils.Fiat;
|
|||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
|
@ -145,7 +146,9 @@ class TakeOfferDataModel implements Activatable, DataModel {
|
|||
};
|
||||
updateBalance(walletService.getBalanceForAddress(addressEntry.getAddress()));
|
||||
|
||||
tradeManager.onCheckOfferAvailability(offer);
|
||||
// delay a bit to get the listeners called
|
||||
offer.resetState();
|
||||
Platform.runLater(() -> tradeManager.onCheckOfferAvailability(offer));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" tabClosingPolicy="UNAVAILABLE"
|
||||
xmlns:fx="http://javafx.com/fxml">
|
||||
|
||||
<Tab fx:id="offersTab" text="Open offers"/>
|
||||
<Tab fx:id="openOffersTab" text="Open offers"/>
|
||||
<Tab fx:id="openTradesTab" text="Open trades"/>
|
||||
<Tab fx:id="closedTradesTab" text="History"/>
|
||||
|
||||
|
|
|
@ -28,7 +28,6 @@ import io.bitsquare.gui.main.MainView;
|
|||
import io.bitsquare.gui.main.portfolio.closedtrades.ClosedTradesView;
|
||||
import io.bitsquare.gui.main.portfolio.openoffer.OpenOffersView;
|
||||
import io.bitsquare.gui.main.portfolio.pendingtrades.PendingTradesView;
|
||||
import io.bitsquare.trade.TradeManager;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
|
@ -39,7 +38,7 @@ import javafx.scene.control.*;
|
|||
@FxmlView
|
||||
public class PortfolioView extends ActivatableViewAndModel<TabPane, Activatable> {
|
||||
|
||||
@FXML Tab offersTab, openTradesTab, closedTradesTab;
|
||||
@FXML Tab openOffersTab, openTradesTab, closedTradesTab;
|
||||
|
||||
private Tab currentTab;
|
||||
private Navigation.Listener navigationListener;
|
||||
|
@ -49,7 +48,7 @@ public class PortfolioView extends ActivatableViewAndModel<TabPane, Activatable>
|
|||
private final Navigation navigation;
|
||||
|
||||
@Inject
|
||||
public PortfolioView(CachingViewLoader viewLoader, Navigation navigation, TradeManager tradeManager) {
|
||||
public PortfolioView(CachingViewLoader viewLoader, Navigation navigation) {
|
||||
this.viewLoader = viewLoader;
|
||||
this.navigation = navigation;
|
||||
}
|
||||
|
@ -57,12 +56,14 @@ public class PortfolioView extends ActivatableViewAndModel<TabPane, Activatable>
|
|||
@Override
|
||||
public void initialize() {
|
||||
navigationListener = viewPath -> {
|
||||
log.debug("navigationListener");
|
||||
if (viewPath.size() == 3 && viewPath.indexOf(PortfolioView.class) == 1)
|
||||
loadView(viewPath.tip());
|
||||
};
|
||||
|
||||
tabChangeListener = (ov, oldValue, newValue) -> {
|
||||
if (newValue == offersTab)
|
||||
log.debug("tabChangeListener");
|
||||
if (newValue == openOffersTab)
|
||||
navigation.navigateTo(MainView.class, PortfolioView.class, OpenOffersView.class);
|
||||
else if (newValue == openTradesTab)
|
||||
navigation.navigateTo(MainView.class, PortfolioView.class, PendingTradesView.class);
|
||||
|
@ -76,10 +77,12 @@ public class PortfolioView extends ActivatableViewAndModel<TabPane, Activatable>
|
|||
root.getSelectionModel().selectedItemProperty().addListener(tabChangeListener);
|
||||
navigation.addListener(navigationListener);
|
||||
|
||||
/* if (tradeManager.getPendingTrades().size() == 0)
|
||||
navigation.navigateTo(MainView.class, PortfolioView.class, OffersView.class);
|
||||
else
|
||||
navigation.navigateTo(MainView.class, PortfolioView.class, PendingTradesView.class);*/
|
||||
if (root.getSelectionModel().getSelectedItem() == openOffersTab)
|
||||
navigation.navigateTo(MainView.class, PortfolioView.class, OpenOffersView.class);
|
||||
else if (root.getSelectionModel().getSelectedItem() == openTradesTab)
|
||||
navigation.navigateTo(MainView.class, PortfolioView.class, PendingTradesView.class);
|
||||
else if (root.getSelectionModel().getSelectedItem() == closedTradesTab)
|
||||
navigation.navigateTo(MainView.class, PortfolioView.class, ClosedTradesView.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -96,7 +99,7 @@ public class PortfolioView extends ActivatableViewAndModel<TabPane, Activatable>
|
|||
|
||||
View view = viewLoader.load(viewClass);
|
||||
|
||||
if (view instanceof OpenOffersView) currentTab = offersTab;
|
||||
if (view instanceof OpenOffersView) currentTab = openOffersTab;
|
||||
else if (view instanceof PendingTradesView) currentTab = openTradesTab;
|
||||
else if (view instanceof ClosedTradesView) currentTab = closedTradesTab;
|
||||
|
||||
|
|
|
@ -92,6 +92,10 @@ public class BuyerSubView extends TradeSubView {
|
|||
tradeStepDetailsView.deactivate();
|
||||
|
||||
switch (state) {
|
||||
case UNDEFINED:
|
||||
/* showItem(waitTxInBlockchain);
|
||||
((WaitTxInBlockchainView) tradeStepDetailsView).setInfoLabelText("Trade is in an incomplete state.");*/
|
||||
break;
|
||||
case WAIT_FOR_BLOCKCHAIN_CONFIRMATION:
|
||||
showItem(waitTxInBlockchain);
|
||||
|
||||
|
@ -144,6 +148,14 @@ public class BuyerSubView extends TradeSubView {
|
|||
"You can review the details to that trade any time in the closed trades screen.");
|
||||
completedView.setWithdrawAmountTextFieldText(model.getPayoutAmount());
|
||||
break;
|
||||
case CLOSED:
|
||||
showItem(waitTxInBlockchain);
|
||||
((WaitTxInBlockchainView) tradeStepDetailsView).setInfoLabelText("Trade is closed");
|
||||
break;
|
||||
case FAULT:
|
||||
showItem(waitTxInBlockchain);
|
||||
((WaitTxInBlockchainView) tradeStepDetailsView).setInfoLabelText("Error occured");
|
||||
break;
|
||||
/*case MESSAGE_SENDING_FAILED:
|
||||
Popups.openWarningPopup("Sending message to trading peer failed.", model.getErrorMessage());
|
||||
break;
|
||||
|
|
|
@ -108,12 +108,12 @@ class PendingTradesDataModel implements Activatable, DataModel {
|
|||
|
||||
private void onListChanged() {
|
||||
list.clear();
|
||||
list.addAll(tradeManager.getPendingTrades().stream().map(PendingTradesListItem::new).collect(Collectors.toList()));
|
||||
list.addAll(tradeManager.getPendingTrades().stream().filter(e -> !e.isFaultState())
|
||||
.map(PendingTradesListItem::new).collect(Collectors.toList()));
|
||||
|
||||
// we sort by date, earliest first
|
||||
list.sort((o1, o2) -> o2.getTrade().getDate().compareTo(o1.getTrade().getDate()));
|
||||
|
||||
log.debug("onListChanged {}", list.size());
|
||||
if (list.size() > 0)
|
||||
onSelectTrade(list.get(0));
|
||||
else if (list.size() == 0)
|
||||
|
@ -131,7 +131,6 @@ class PendingTradesDataModel implements Activatable, DataModel {
|
|||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void onSelectTrade(PendingTradesListItem item) {
|
||||
log.debug("selectTrade {} {}", item != null, item != null ? item.getTrade().getId() : "null");
|
||||
// clean up previous selectedItem
|
||||
unbindStates();
|
||||
|
||||
|
@ -176,7 +175,6 @@ class PendingTradesDataModel implements Activatable, DataModel {
|
|||
toAddress,
|
||||
trade,
|
||||
() -> {
|
||||
log.debug("requestWithdraw was successful");
|
||||
Platform.runLater(() -> navigation.navigateTo(MainView.class, PortfolioView.class, ClosedTradesView.class));
|
||||
},
|
||||
(errorMessage, throwable) -> {
|
||||
|
|
|
@ -53,44 +53,30 @@ import org.slf4j.LoggerFactory;
|
|||
public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTradesDataModel> implements ViewModel {
|
||||
private static final Logger log = LoggerFactory.getLogger(PendingTradesViewModel.class);
|
||||
|
||||
/* enum ViewState {
|
||||
UNDEFINED,
|
||||
WAIT_FOR_BLOCKCHAIN_CONFIRMATION,
|
||||
WAIT_FOR_FIAT_PAYMENT_STARTED,
|
||||
REQUEST_CONFIRM_FIAT_PAYMENT_RECEIVED,
|
||||
SELLER_REQUEST_PAYOUT_FINALIZE_MSG_SENT,
|
||||
SELLER_PAYOUT_FINALIZED,
|
||||
SELLER_COMPLETED,
|
||||
|
||||
WAIT_FOR_BLOCKCHAIN_CONFIRMATION,
|
||||
BUYER_START_PAYMENT,
|
||||
BUYER_WAIT_CONFIRM_PAYMENT_RECEIVED,
|
||||
BUYER_PAYOUT_FINALIZED,
|
||||
BUYER_COMPLETED,
|
||||
|
||||
MESSAGE_SENDING_FAILED,
|
||||
TIMEOUT,
|
||||
EXCEPTION
|
||||
}*/
|
||||
|
||||
interface State {
|
||||
}
|
||||
|
||||
enum BuyerState implements State {
|
||||
UNDEFINED,
|
||||
WAIT_FOR_BLOCKCHAIN_CONFIRMATION,
|
||||
REQUEST_START_FIAT_PAYMENT,
|
||||
WAIT_FOR_FIAT_PAYMENT_RECEIPT,
|
||||
WAIT_FOR_UNLOCK_PAYOUT,
|
||||
REQUEST_WITHDRAWAL
|
||||
REQUEST_WITHDRAWAL,
|
||||
CLOSED,
|
||||
FAULT
|
||||
}
|
||||
|
||||
enum SellerState implements State {
|
||||
UNDEFINED,
|
||||
WAIT_FOR_BLOCKCHAIN_CONFIRMATION,
|
||||
WAIT_FOR_FIAT_PAYMENT_STARTED,
|
||||
REQUEST_CONFIRM_FIAT_PAYMENT_RECEIVED,
|
||||
WAIT_FOR_PAYOUT_TX,
|
||||
WAIT_FOR_UNLOCK_PAYOUT,
|
||||
REQUEST_WITHDRAWAL
|
||||
REQUEST_WITHDRAWAL,
|
||||
CLOSED,
|
||||
FAULT
|
||||
}
|
||||
|
||||
private final BSFormatter formatter;
|
||||
|
@ -98,8 +84,8 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
|
|||
private final InvalidationListener buyerStateListener;
|
||||
private final BtcAddressValidator btcAddressValidator;
|
||||
|
||||
private final ObjectProperty<BuyerState> buyerState = new SimpleObjectProperty<>(BuyerState.WAIT_FOR_BLOCKCHAIN_CONFIRMATION);
|
||||
private final ObjectProperty<SellerState> sellerState = new SimpleObjectProperty<>(SellerState.WAIT_FOR_BLOCKCHAIN_CONFIRMATION);
|
||||
private final ObjectProperty<BuyerState> buyerState = new SimpleObjectProperty<>(BuyerState.UNDEFINED);
|
||||
private final ObjectProperty<SellerState> sellerState = new SimpleObjectProperty<>(SellerState.UNDEFINED);
|
||||
|
||||
private final StringProperty txId = new SimpleStringProperty();
|
||||
private final BooleanProperty withdrawalButtonDisable = new SimpleBooleanProperty(true);
|
||||
|
@ -191,6 +177,10 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
|
|||
|
||||
public void onWithdrawRequest(String withdrawToAddress) {
|
||||
dataModel.onWithdrawRequest(withdrawToAddress);
|
||||
if (dataModel.getSellerProcessState().get() instanceof SellerTradeState.ProcessState)
|
||||
sellerState.setValue(SellerState.CLOSED);
|
||||
else
|
||||
buyerState.setValue(BuyerState.CLOSED);
|
||||
}
|
||||
|
||||
public void withdrawAddressFocusOut(String text) {
|
||||
|
@ -338,6 +328,8 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
|
|||
if (processState != null) {
|
||||
switch (processState) {
|
||||
case UNDEFINED:
|
||||
sellerState.set(SellerState.UNDEFINED);
|
||||
break;
|
||||
|
||||
case DEPOSIT_PUBLISHED_MSG_RECEIVED:
|
||||
sellerState.set(SellerState.WAIT_FOR_BLOCKCHAIN_CONFIRMATION);
|
||||
|
@ -373,17 +365,10 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
|
|||
break;
|
||||
|
||||
|
||||
/* case PAYOUT_BROAD_CASTED_FAILED:
|
||||
// sellerState.set(SellerState.EXCEPTION);
|
||||
case FAULT:
|
||||
sellerState.set(SellerState.FAULT);
|
||||
break;
|
||||
|
||||
case MESSAGE_SENDING_FAILED:
|
||||
//sellerState.set(SellerState.MESSAGE_SENDING_FAILED);
|
||||
break;
|
||||
case EXCEPTION:
|
||||
// sellerState.set(SellerState.EXCEPTION);
|
||||
break;*/
|
||||
|
||||
default:
|
||||
log.warn("unhandled processState " + processState);
|
||||
break;
|
||||
|
@ -402,6 +387,7 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
|
|||
if (processState != null) {
|
||||
switch (processState) {
|
||||
case UNDEFINED:
|
||||
sellerState.set(SellerState.UNDEFINED);
|
||||
break;
|
||||
|
||||
|
||||
|
@ -436,18 +422,10 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
|
|||
break;
|
||||
|
||||
|
||||
/* case PAYOUT_BROAD_CASTED_FAILED:
|
||||
// buyerState.set(BuyerState.EXCEPTION);
|
||||
case FAULT:
|
||||
sellerState.set(SellerState.FAULT);
|
||||
break;
|
||||
|
||||
|
||||
case MESSAGE_SENDING_FAILED:
|
||||
// buyerState.set(BuyerState.MESSAGE_SENDING_FAILED);
|
||||
break;
|
||||
case EXCEPTION:
|
||||
// buyerState.set(BuyerState.EXCEPTION);
|
||||
break;
|
||||
*/
|
||||
default:
|
||||
log.warn("unhandled viewState " + processState);
|
||||
break;
|
||||
|
|
|
@ -92,6 +92,10 @@ public class SellerSubView extends TradeSubView {
|
|||
tradeStepDetailsView.deactivate();
|
||||
|
||||
switch (viewState) {
|
||||
case UNDEFINED:
|
||||
/* showItem(waitTxInBlockchain);
|
||||
((WaitTxInBlockchainView) tradeStepDetailsView).setInfoLabelText("Trade is in an incomplete state.");*/
|
||||
break;
|
||||
case WAIT_FOR_BLOCKCHAIN_CONFIRMATION:
|
||||
showItem(waitTxInBlockchain);
|
||||
|
||||
|
@ -173,6 +177,15 @@ public class SellerSubView extends TradeSubView {
|
|||
|
||||
completedView.setWithdrawAmountTextFieldText(model.getPayoutAmount());
|
||||
break;
|
||||
case CLOSED:
|
||||
showItem(waitTxInBlockchain);
|
||||
((WaitTxInBlockchainView) tradeStepDetailsView).setInfoLabelText("Trade is closed");
|
||||
break;
|
||||
case FAULT:
|
||||
showItem(waitTxInBlockchain);
|
||||
((WaitTxInBlockchainView) tradeStepDetailsView).setInfoLabelText("Error occured");
|
||||
break;
|
||||
|
||||
/* case MESSAGE_SENDING_FAILED:
|
||||
Popups.openWarningPopup("Sending message to trading peer failed.", model.getErrorMessage());
|
||||
break;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue