mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-08-06 05:34:50 -04:00
Refactor pending trades steps subviews
This commit is contained in:
parent
de79eba7f0
commit
e2e5a6864f
28 changed files with 1398 additions and 1097 deletions
|
@ -17,16 +17,16 @@
|
||||||
|
|
||||||
package io.bitsquare.gui.main.portfolio.pendingtrades;
|
package io.bitsquare.gui.main.portfolio.pendingtrades;
|
||||||
|
|
||||||
import io.bitsquare.gui.main.portfolio.pendingtrades.steps.*;
|
import io.bitsquare.gui.main.portfolio.pendingtrades.steps.TradeWizardItem;
|
||||||
import io.bitsquare.locale.BSResources;
|
import io.bitsquare.gui.main.portfolio.pendingtrades.steps.buyer.*;
|
||||||
import javafx.beans.value.ChangeListener;
|
import javafx.beans.value.ChangeListener;
|
||||||
|
|
||||||
public class BuyerSubView extends TradeSubView {
|
public class BuyerSubView extends TradeSubView {
|
||||||
private TradeWizardItem waitTxInBlockchain;
|
private TradeWizardItem step1;
|
||||||
private TradeWizardItem startPayment;
|
private TradeWizardItem step2;
|
||||||
private TradeWizardItem waitPaymentReceived;
|
private TradeWizardItem step3;
|
||||||
private TradeWizardItem waitPayoutUnlock;
|
private TradeWizardItem step4;
|
||||||
private TradeWizardItem completed;
|
private TradeWizardItem step5;
|
||||||
|
|
||||||
private final ChangeListener<PendingTradesViewModel.BuyerState> stateChangeListener;
|
private final ChangeListener<PendingTradesViewModel.BuyerState> stateChangeListener;
|
||||||
|
|
||||||
|
@ -55,16 +55,16 @@ public class BuyerSubView extends TradeSubView {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void addWizards() {
|
protected void addWizards() {
|
||||||
waitTxInBlockchain = new TradeWizardItem(WaitTxInBlockchainView.class, "Wait for blockchain confirmation");
|
step1 = new TradeWizardItem(BuyerStep1View.class, "Wait for blockchain confirmation");
|
||||||
startPayment = new TradeWizardItem(StartPaymentView.class, "Start payment");
|
step2 = new TradeWizardItem(BuyerStep2View.class, "Start payment");
|
||||||
waitPaymentReceived = new TradeWizardItem(WaitPaymentReceivedView.class, "Wait until payment arrived");
|
step3 = new TradeWizardItem(BuyerStep3View.class, "Wait until payment arrived");
|
||||||
waitPayoutUnlock = new TradeWizardItem(WaitPayoutLockTimeView.class, "Wait for payout unlock");
|
step4 = new TradeWizardItem(BuyerStep4View.class, "Wait for payout unlock");
|
||||||
completed = new TradeWizardItem(CompletedView.class, "Completed");
|
step5 = new TradeWizardItem(BuyerStep5View.class, "Completed");
|
||||||
|
|
||||||
if (model.getLockTime() > 0)
|
if (model.getLockTime() > 0)
|
||||||
leftVBox.getChildren().setAll(waitTxInBlockchain, startPayment, waitPaymentReceived, waitPayoutUnlock, completed);
|
leftVBox.getChildren().setAll(step1, step2, step3, step4, step5);
|
||||||
else
|
else
|
||||||
leftVBox.getChildren().setAll(waitTxInBlockchain, startPayment, waitPaymentReceived, completed);
|
leftVBox.getChildren().setAll(step1, step2, step3, step5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -72,17 +72,17 @@ public class BuyerSubView extends TradeSubView {
|
||||||
// State
|
// State
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
protected void applyState(PendingTradesViewModel.BuyerState state) {
|
private void applyState(PendingTradesViewModel.BuyerState state) {
|
||||||
log.debug("applyState " + state);
|
log.debug("applyState " + state);
|
||||||
|
|
||||||
waitTxInBlockchain.setDisabled();
|
step1.setDisabled();
|
||||||
startPayment.setDisabled();
|
step2.setDisabled();
|
||||||
waitPaymentReceived.setDisabled();
|
step3.setDisabled();
|
||||||
waitPayoutUnlock.setDisabled();
|
step4.setDisabled();
|
||||||
completed.setDisabled();
|
step5.setDisabled();
|
||||||
|
|
||||||
if (tradeStepDetailsView != null)
|
if (tradeStepView != null)
|
||||||
tradeStepDetailsView.doDeactivate();
|
tradeStepView.doDeactivate();
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case UNDEFINED:
|
case UNDEFINED:
|
||||||
|
@ -90,58 +90,48 @@ public class BuyerSubView extends TradeSubView {
|
||||||
leftVBox.getChildren().clear();
|
leftVBox.getChildren().clear();
|
||||||
break;
|
break;
|
||||||
case WAIT_FOR_BLOCKCHAIN_CONFIRMATION:
|
case WAIT_FOR_BLOCKCHAIN_CONFIRMATION:
|
||||||
showItem(waitTxInBlockchain);
|
showItem(step1);
|
||||||
|
|
||||||
((WaitTxInBlockchainView) tradeStepDetailsView).setInfoLabelText("Deposit transaction has been published. You need to wait for at least " +
|
|
||||||
"one blockchain confirmation.");
|
|
||||||
break;
|
break;
|
||||||
case REQUEST_START_FIAT_PAYMENT:
|
case REQUEST_START_FIAT_PAYMENT:
|
||||||
waitTxInBlockchain.setCompleted();
|
step1.setCompleted();
|
||||||
showItem(startPayment);
|
showItem(step2);
|
||||||
break;
|
break;
|
||||||
case WAIT_FOR_FIAT_PAYMENT_RECEIPT:
|
case WAIT_FOR_FIAT_PAYMENT_RECEIPT:
|
||||||
waitTxInBlockchain.setCompleted();
|
step1.setCompleted();
|
||||||
startPayment.setCompleted();
|
step2.setCompleted();
|
||||||
showItem(waitPaymentReceived);
|
showItem(step3);
|
||||||
|
|
||||||
((WaitPaymentReceivedView) tradeStepDetailsView).setInfoLabelText(BSResources.get("Waiting for the bitcoin sellers confirmation " +
|
|
||||||
"that the {0} payment has arrived.",
|
|
||||||
model.getCurrencyCode()));
|
|
||||||
break;
|
break;
|
||||||
case WAIT_FOR_UNLOCK_PAYOUT:
|
case WAIT_FOR_UNLOCK_PAYOUT:
|
||||||
if (model.getLockTime() > 0) {
|
if (model.getLockTime() > 0) {
|
||||||
waitTxInBlockchain.setCompleted();
|
step1.setCompleted();
|
||||||
startPayment.setCompleted();
|
step2.setCompleted();
|
||||||
waitPaymentReceived.setCompleted();
|
step3.setCompleted();
|
||||||
showItem(waitPayoutUnlock);
|
showItem(step4);
|
||||||
|
|
||||||
((WaitPayoutLockTimeView) tradeStepDetailsView).setInfoLabelText("The payout transaction is signed and finalized by both parties." +
|
|
||||||
"\nFor reducing bank charge back risks you need to wait until the payout gets unlocked to transfer your bitcoin.");
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case REQUEST_WITHDRAWAL:
|
case REQUEST_WITHDRAWAL:
|
||||||
waitTxInBlockchain.setCompleted();
|
step1.setCompleted();
|
||||||
startPayment.setCompleted();
|
step2.setCompleted();
|
||||||
waitPaymentReceived.setCompleted();
|
step3.setCompleted();
|
||||||
waitPayoutUnlock.setCompleted();
|
step4.setCompleted();
|
||||||
showItem(completed);
|
showItem(step5);
|
||||||
|
|
||||||
CompletedView completedView = (CompletedView) tradeStepDetailsView;
|
BuyerStep5View buyerStep5View = (BuyerStep5View) tradeStepView;
|
||||||
completedView.setBtcTradeAmountLabelText("You have bought:");
|
buyerStep5View.setBtcTradeAmountLabelText("You have bought:");
|
||||||
completedView.setFiatTradeAmountLabelText("You have paid:");
|
buyerStep5View.setFiatTradeAmountLabelText("You have paid:");
|
||||||
completedView.setBtcTradeAmountTextFieldText(model.getTradeVolume());
|
buyerStep5View.setBtcTradeAmountTextFieldText(model.getTradeVolume());
|
||||||
completedView.setFiatTradeAmountTextFieldText(model.getFiatVolume());
|
buyerStep5View.setFiatTradeAmountTextFieldText(model.getFiatVolume());
|
||||||
completedView.setFeesTextFieldText(model.getTotalFees());
|
buyerStep5View.setFeesTextFieldText(model.getTotalFees());
|
||||||
completedView.setSecurityDepositTextFieldText(model.getSecurityDeposit());
|
buyerStep5View.setSecurityDepositTextFieldText(model.getSecurityDeposit());
|
||||||
completedView.setWithdrawAmountTextFieldText(model.getPayoutAmount());
|
buyerStep5View.setWithdrawAmountTextFieldText(model.getPayoutAmount());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
log.warn("unhandled buyerState " + state);
|
log.warn("unhandled buyerState " + state);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tradeStepDetailsView != null)
|
if (tradeStepView != null)
|
||||||
tradeStepDetailsView.doActivate();
|
tradeStepView.doActivate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,6 @@ import javafx.collections.ObservableList;
|
||||||
import org.bitcoinj.core.BlockChainListener;
|
import org.bitcoinj.core.BlockChainListener;
|
||||||
import org.bitcoinj.core.Coin;
|
import org.bitcoinj.core.Coin;
|
||||||
import org.bitcoinj.core.Transaction;
|
import org.bitcoinj.core.Transaction;
|
||||||
import org.bitcoinj.core.TransactionOutput;
|
|
||||||
import org.spongycastle.crypto.params.KeyParameter;
|
import org.spongycastle.crypto.params.KeyParameter;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -208,6 +207,19 @@ public class PendingTradesDataModel extends ActivatableDataModel {
|
||||||
List<Transaction> candidates = new ArrayList<>();
|
List<Transaction> candidates = new ArrayList<>();
|
||||||
List<Transaction> transactions = walletService.getWallet().getRecentTransactions(100, true);
|
List<Transaction> transactions = walletService.getWallet().getRecentTransactions(100, true);
|
||||||
transactions.stream().forEach(transaction -> {
|
transactions.stream().forEach(transaction -> {
|
||||||
|
Coin valueSentFromMe = transaction.getValueSentFromMe(walletService.getWallet());
|
||||||
|
if (!valueSentFromMe.isZero()) {
|
||||||
|
// spending tx
|
||||||
|
// MS tx
|
||||||
|
candidates.addAll(transaction.getOutputs().stream()
|
||||||
|
.filter(transactionOutput -> !transactionOutput.isMine(walletService.getWallet()))
|
||||||
|
.filter(transactionOutput -> transactionOutput.getScriptPubKey().isPayToScriptHash())
|
||||||
|
.map(transactionOutput -> transaction)
|
||||||
|
.collect(Collectors.toList()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/*transactions.stream().forEach(transaction -> {
|
||||||
Coin valueSentFromMe = transaction.getValueSentFromMe(walletService.getWallet());
|
Coin valueSentFromMe = transaction.getValueSentFromMe(walletService.getWallet());
|
||||||
if (!valueSentFromMe.isZero()) {
|
if (!valueSentFromMe.isZero()) {
|
||||||
// spending tx
|
// spending tx
|
||||||
|
@ -220,15 +232,13 @@ public class PendingTradesDataModel extends ActivatableDataModel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});*/
|
||||||
|
|
||||||
if (candidates.size() == 1)
|
if (candidates.size() == 1)
|
||||||
doOpenDispute(isSupportTicket, candidates.get(0));
|
doOpenDispute(isSupportTicket, candidates.get(0));
|
||||||
else if (candidates.size() > 1)
|
else if (candidates.size() > 1)
|
||||||
new SelectDepositTxPopup().transactions(candidates)
|
new SelectDepositTxPopup().transactions(candidates)
|
||||||
.onSelect(transaction -> {
|
.onSelect(transaction -> doOpenDispute(isSupportTicket, transaction))
|
||||||
doOpenDispute(isSupportTicket, transaction);
|
|
||||||
})
|
|
||||||
.closeButtonText("Cancel")
|
.closeButtonText("Cancel")
|
||||||
.show();
|
.show();
|
||||||
else
|
else
|
||||||
|
@ -365,7 +375,10 @@ public class PendingTradesDataModel extends ActivatableDataModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
public PaymentAccountContractData getSellersPaymentAccountContractData() {
|
public PaymentAccountContractData getSellersPaymentAccountContractData() {
|
||||||
return trade.getContract().getSellerPaymentAccountContractData();
|
if (trade.getContract() != null)
|
||||||
|
return trade.getContract().getSellerPaymentAccountContractData();
|
||||||
|
else
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getReference() {
|
public String getReference() {
|
||||||
|
|
|
@ -22,8 +22,6 @@ import javafx.beans.property.ReadOnlyObjectProperty;
|
||||||
import org.bitcoinj.core.Coin;
|
import org.bitcoinj.core.Coin;
|
||||||
import org.bitcoinj.utils.Fiat;
|
import org.bitcoinj.utils.Fiat;
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We could remove that wrapper if it is not needed for additional UI only fields.
|
* We could remove that wrapper if it is not needed for additional UI only fields.
|
||||||
*/
|
*/
|
||||||
|
@ -31,39 +29,20 @@ public class PendingTradesListItem {
|
||||||
|
|
||||||
private final Trade trade;
|
private final Trade trade;
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Constructor
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
public PendingTradesListItem(Trade trade) {
|
public PendingTradesListItem(Trade trade) {
|
||||||
this.trade = trade;
|
this.trade = trade;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Getters
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
public Trade getTrade() {
|
public Trade getTrade() {
|
||||||
return trade;
|
return trade;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReadOnlyObjectProperty<Coin> tradeAmountProperty() {
|
public ReadOnlyObjectProperty<Coin> tradeAmountProperty() {
|
||||||
if (trade instanceof Trade)
|
return trade.tradeAmountProperty();
|
||||||
return trade.tradeAmountProperty();
|
|
||||||
else
|
|
||||||
return trade.tradeAmountProperty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReadOnlyObjectProperty<Fiat> tradeVolumeProperty() {
|
public ReadOnlyObjectProperty<Fiat> tradeVolumeProperty() {
|
||||||
if (trade instanceof Trade)
|
return trade.tradeVolumeProperty();
|
||||||
return trade.tradeVolumeProperty();
|
|
||||||
else
|
|
||||||
return trade.tradeVolumeProperty();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getDate() {
|
|
||||||
return trade.getDate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getId() {
|
public String getId() {
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<?import javafx.geometry.Insets?>
|
<?import javafx.geometry.Insets?>
|
||||||
<?import javafx.scene.control.cell.*?>
|
<?import javafx.scene.control.cell.PropertyValueFactory?>
|
||||||
<?import javafx.scene.control.*?>
|
<?import javafx.scene.control.*?>
|
||||||
<?import javafx.scene.layout.VBox?>
|
<?import javafx.scene.layout.VBox?>
|
||||||
<VBox fx:id="root" fx:controller="io.bitsquare.gui.main.portfolio.pendingtrades.PendingTradesView"
|
<VBox fx:id="root" fx:controller="io.bitsquare.gui.main.portfolio.pendingtrades.PendingTradesView"
|
||||||
|
@ -34,11 +34,7 @@
|
||||||
<PropertyValueFactory property="id"/>
|
<PropertyValueFactory property="id"/>
|
||||||
</cellValueFactory>
|
</cellValueFactory>
|
||||||
</TableColumn>
|
</TableColumn>
|
||||||
<TableColumn text="Date/Time" fx:id="dateColumn" minWidth="130">
|
<TableColumn text="Date/Time" fx:id="dateColumn" minWidth="130"/>
|
||||||
<cellValueFactory>
|
|
||||||
<PropertyValueFactory property="date"/>
|
|
||||||
</cellValueFactory>
|
|
||||||
</TableColumn>
|
|
||||||
<TableColumn text="Trade amount in BTC" fx:id="tradeAmountColumn" minWidth="130">
|
<TableColumn text="Trade amount in BTC" fx:id="tradeAmountColumn" minWidth="130">
|
||||||
<cellValueFactory>
|
<cellValueFactory>
|
||||||
<PropertyValueFactory property="tradeAmount"/>
|
<PropertyValueFactory property="tradeAmount"/>
|
||||||
|
|
|
@ -45,7 +45,6 @@ import org.bitcoinj.core.Coin;
|
||||||
import org.bitcoinj.utils.Fiat;
|
import org.bitcoinj.utils.Fiat;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
@FxmlView
|
@FxmlView
|
||||||
public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTradesViewModel> {
|
public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTradesViewModel> {
|
||||||
|
@ -54,13 +53,9 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
|
||||||
@FXML
|
@FXML
|
||||||
TableView<PendingTradesListItem> table;
|
TableView<PendingTradesListItem> table;
|
||||||
@FXML
|
@FXML
|
||||||
TableColumn<PendingTradesListItem, Fiat> priceColumn;
|
TableColumn<PendingTradesListItem, Fiat> priceColumn, tradeVolumeColumn;
|
||||||
@FXML
|
@FXML
|
||||||
TableColumn<PendingTradesListItem, Fiat> tradeVolumeColumn;
|
TableColumn<PendingTradesListItem, PendingTradesListItem> roleColumn, paymentMethodColumn, idColumn, dateColumn;
|
||||||
@FXML
|
|
||||||
TableColumn<PendingTradesListItem, PendingTradesListItem> roleColumn, paymentMethodColumn, idColumn;
|
|
||||||
@FXML
|
|
||||||
TableColumn<PendingTradesListItem, Date> dateColumn;
|
|
||||||
@FXML
|
@FXML
|
||||||
TableColumn<PendingTradesListItem, Coin> tradeAmountColumn;
|
TableColumn<PendingTradesListItem, Coin> tradeAmountColumn;
|
||||||
|
|
||||||
|
@ -119,31 +114,35 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
|
||||||
|
|
||||||
currentTradeChangeListener = (observable, oldValue, newValue) -> {
|
currentTradeChangeListener = (observable, oldValue, newValue) -> {
|
||||||
log.debug("currentTradeChangeListener {} ", newValue);
|
log.debug("currentTradeChangeListener {} ", newValue);
|
||||||
setNewSubView(newValue);
|
// setNewSubView(newValue);
|
||||||
};
|
};
|
||||||
|
|
||||||
// we use a hidden emergency shortcut to open support ticket
|
// we use a hidden emergency shortcut to open support ticket
|
||||||
keyEventEventHandler = event -> {
|
keyEventEventHandler = event -> {
|
||||||
if (new KeyCodeCombination(KeyCode.O, KeyCombination.SHORTCUT_DOWN).match(event))
|
if (new KeyCodeCombination(KeyCode.O, KeyCombination.SHORTCUT_DOWN).match(event))
|
||||||
new OpenEmergencyTicketPopup().onOpenTicket(() -> model.dataModel.onOpenSupportTicket()).show();
|
new OpenEmergencyTicketPopup().onOpenTicket(model.dataModel::onOpenSupportTicket).show();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void activate() {
|
protected void activate() {
|
||||||
scene = root.getScene();
|
scene = root.getScene();
|
||||||
appFocusProperty = scene.getWindow().focusedProperty();
|
if (scene != null) {
|
||||||
|
appFocusProperty = scene.getWindow().focusedProperty();
|
||||||
|
scene.addEventHandler(KeyEvent.KEY_RELEASED, keyEventEventHandler);
|
||||||
|
}
|
||||||
|
|
||||||
appFocusProperty.addListener(appFocusChangeListener);
|
appFocusProperty.addListener(appFocusChangeListener);
|
||||||
model.currentTrade().addListener(currentTradeChangeListener);
|
model.currentTrade().addListener(currentTradeChangeListener);
|
||||||
//setNewSubView(model.currentTrade().get());
|
//setNewSubView(model.currentTrade().get());
|
||||||
table.setItems(model.getList());
|
table.setItems(model.getList());
|
||||||
table.getSelectionModel().selectedItemProperty().addListener(selectedItemChangeListener);
|
table.getSelectionModel().selectedItemProperty().addListener(selectedItemChangeListener);
|
||||||
updateSelectedItem();
|
|
||||||
|
|
||||||
if (model.getSelectedItem() == null)
|
if (model.getSelectedItem() == null)
|
||||||
model.getList().addListener(listChangeListener);
|
model.getList().addListener(listChangeListener);
|
||||||
|
|
||||||
scene.addEventHandler(KeyEvent.KEY_RELEASED, keyEventEventHandler);
|
|
||||||
|
updateSelectedItem();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateSelectedItem() {
|
private void updateSelectedItem() {
|
||||||
|
@ -204,7 +203,7 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
|
||||||
else
|
else
|
||||||
currentSubView = new BuyerSubView(model);
|
currentSubView = new BuyerSubView(model);
|
||||||
}
|
}
|
||||||
currentSubView.setMinHeight(420);
|
currentSubView.setMinHeight(430);
|
||||||
VBox.setVgrow(currentSubView, Priority.ALWAYS);
|
VBox.setVgrow(currentSubView, Priority.ALWAYS);
|
||||||
root.getChildren().add(1, currentSubView);
|
root.getChildren().add(1, currentSubView);
|
||||||
|
|
||||||
|
@ -249,18 +248,33 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setDateColumnCellFactory() {
|
private void setDateColumnCellFactory() {
|
||||||
dateColumn.setCellFactory(TextFieldTableCell.<PendingTradesListItem, Date>forTableColumn(
|
dateColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue()));
|
||||||
new StringConverter<Date>() {
|
dateColumn.setCellFactory(
|
||||||
|
new Callback<TableColumn<PendingTradesListItem, PendingTradesListItem>, TableCell<PendingTradesListItem,
|
||||||
|
PendingTradesListItem>>() {
|
||||||
@Override
|
@Override
|
||||||
public String toString(Date value) {
|
public TableCell<PendingTradesListItem, PendingTradesListItem> call(
|
||||||
return model.formatDate(value);
|
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 && !empty) {
|
||||||
|
if (model.showDispute(item.getTrade())) {
|
||||||
|
setStyle("-fx-text-fill: -bs-error-red");
|
||||||
|
} else if (model.showWarning(item.getTrade())) {
|
||||||
|
setStyle("-fx-text-fill: -bs-orange");
|
||||||
|
} else {
|
||||||
|
setId("-fx-text-fill: black");
|
||||||
|
}
|
||||||
|
setText(model.getDate(item));
|
||||||
|
} else {
|
||||||
|
setText(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
});
|
||||||
@Override
|
|
||||||
public Date fromString(String string) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setAmountColumnCellFactory() {
|
private void setAmountColumnCellFactory() {
|
||||||
|
|
|
@ -167,7 +167,7 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
|
||||||
return sellerState;
|
return sellerState;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReadOnlyStringProperty getTxId() {
|
public ReadOnlyStringProperty txIdProperty() {
|
||||||
return txId;
|
return txId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,6 +244,32 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
|
||||||
return formatter.formatFiatWithCode(value);
|
return formatter.formatFiatWithCode(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getRemainingTime() {
|
||||||
|
return formatter.getPeriodBetweenBlockHeights(getBestChainHeight(),
|
||||||
|
dataModel.getTrade().getOpenDisputeTimeAsBlockHeight());
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getRemainingTimeAsPercentage() {
|
||||||
|
double remainingBlocks = dataModel.getTrade().getOpenDisputeTimeAsBlockHeight() - getBestChainHeight();
|
||||||
|
double maxPeriod = dataModel.getTrade().getOffer().getPaymentMethod().getMaxTradePeriod();
|
||||||
|
if (maxPeriod != 0)
|
||||||
|
return 1 - remainingBlocks / maxPeriod;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
String getDate(PendingTradesListItem item) {
|
||||||
|
return formatter.formatDateTime(item.getTrade().getDate());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean showWarning(Trade trade) {
|
||||||
|
return getBestChainHeight() >= trade.getCheckPaymentTimeAsBlockHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean showDispute(Trade trade) {
|
||||||
|
return getBestChainHeight() >= trade.getOpenDisputeTimeAsBlockHeight();
|
||||||
|
}
|
||||||
|
|
||||||
String getMyRole(PendingTradesListItem item) {
|
String getMyRole(PendingTradesListItem item) {
|
||||||
Trade trade = item.getTrade();
|
Trade trade = item.getTrade();
|
||||||
Contract contract = trade.getContract();
|
Contract contract = trade.getContract();
|
||||||
|
@ -288,7 +314,7 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
|
||||||
return dataModel.getCheckPaymentTimeAsBlockHeight();
|
return dataModel.getCheckPaymentTimeAsBlockHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getOpenDisputeTimeAsBlockHeight() {
|
private long getOpenDisputeTimeAsBlockHeight() {
|
||||||
return dataModel.getOpenDisputeTimeAsBlockHeight();
|
return dataModel.getOpenDisputeTimeAsBlockHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,8 +323,8 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
|
||||||
return dataModel.getBestChainHeight();
|
return dataModel.getBestChainHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDateFromBlocks(long missingBlocks) {
|
public String getOpenDisputeTimeAsFormattedDate() {
|
||||||
return formatter.getDateFromBlocks(missingBlocks);
|
return formatter.addBlocksToNowDateFormatted(getOpenDisputeTimeAsBlockHeight() - getBestChainHeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getReference() {
|
public String getReference() {
|
||||||
|
|
|
@ -17,16 +17,16 @@
|
||||||
|
|
||||||
package io.bitsquare.gui.main.portfolio.pendingtrades;
|
package io.bitsquare.gui.main.portfolio.pendingtrades;
|
||||||
|
|
||||||
import io.bitsquare.gui.main.portfolio.pendingtrades.steps.*;
|
import io.bitsquare.gui.main.portfolio.pendingtrades.steps.TradeWizardItem;
|
||||||
import io.bitsquare.locale.BSResources;
|
import io.bitsquare.gui.main.portfolio.pendingtrades.steps.seller.*;
|
||||||
import javafx.beans.value.ChangeListener;
|
import javafx.beans.value.ChangeListener;
|
||||||
|
|
||||||
public class SellerSubView extends TradeSubView {
|
public class SellerSubView extends TradeSubView {
|
||||||
private TradeWizardItem waitTxInBlockchain;
|
private TradeWizardItem step1;
|
||||||
private TradeWizardItem waitPaymentStarted;
|
private TradeWizardItem step2;
|
||||||
private TradeWizardItem confirmPaymentReceived;
|
private TradeWizardItem step3;
|
||||||
private TradeWizardItem waitPayoutUnlock;
|
private TradeWizardItem step4;
|
||||||
private TradeWizardItem completed;
|
private TradeWizardItem step5;
|
||||||
|
|
||||||
private final ChangeListener<PendingTradesViewModel.SellerState> stateChangeListener;
|
private final ChangeListener<PendingTradesViewModel.SellerState> stateChangeListener;
|
||||||
|
|
||||||
|
@ -55,16 +55,16 @@ public class SellerSubView extends TradeSubView {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void addWizards() {
|
protected void addWizards() {
|
||||||
waitTxInBlockchain = new TradeWizardItem(WaitTxInBlockchainView.class, "Wait for blockchain confirmation");
|
step1 = new TradeWizardItem(SellerStep1View.class, "Wait for blockchain confirmation");
|
||||||
waitPaymentStarted = new TradeWizardItem(WaitPaymentStartedView.class, "Wait until payment has started");
|
step2 = new TradeWizardItem(SellerStep2View.class, "Wait until payment has started");
|
||||||
confirmPaymentReceived = new TradeWizardItem(ConfirmPaymentReceivedView.class, "Confirm payment received");
|
step3 = new TradeWizardItem(SellerStep3View.class, "Confirm payment received");
|
||||||
waitPayoutUnlock = new TradeWizardItem(WaitPayoutLockTimeView.class, "Wait for payout unlock");
|
step4 = new TradeWizardItem(SellerStep4aView.class, "Wait for payout unlock");
|
||||||
completed = new TradeWizardItem(CompletedView.class, "Completed");
|
step5 = new TradeWizardItem(SellerStep5View.class, "Completed");
|
||||||
|
|
||||||
if (model.getLockTime() > 0)
|
if (model.getLockTime() > 0)
|
||||||
leftVBox.getChildren().setAll(waitTxInBlockchain, waitPaymentStarted, confirmPaymentReceived, waitPayoutUnlock, completed);
|
leftVBox.getChildren().setAll(step1, step2, step3, step4, step5);
|
||||||
else
|
else
|
||||||
leftVBox.getChildren().setAll(waitTxInBlockchain, waitPaymentStarted, confirmPaymentReceived, completed);
|
leftVBox.getChildren().setAll(step1, step2, step3, step5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -75,14 +75,14 @@ public class SellerSubView extends TradeSubView {
|
||||||
private void applyState(PendingTradesViewModel.SellerState viewState) {
|
private void applyState(PendingTradesViewModel.SellerState viewState) {
|
||||||
log.debug("applyState " + viewState);
|
log.debug("applyState " + viewState);
|
||||||
|
|
||||||
waitTxInBlockchain.setDisabled();
|
step1.setDisabled();
|
||||||
waitPaymentStarted.setDisabled();
|
step2.setDisabled();
|
||||||
confirmPaymentReceived.setDisabled();
|
step3.setDisabled();
|
||||||
waitPayoutUnlock.setDisabled();
|
step4.setDisabled();
|
||||||
completed.setDisabled();
|
step5.setDisabled();
|
||||||
|
|
||||||
if (tradeStepDetailsView != null)
|
if (tradeStepView != null)
|
||||||
tradeStepDetailsView.doDeactivate();
|
tradeStepView.doDeactivate();
|
||||||
|
|
||||||
switch (viewState) {
|
switch (viewState) {
|
||||||
case UNDEFINED:
|
case UNDEFINED:
|
||||||
|
@ -90,83 +90,57 @@ public class SellerSubView extends TradeSubView {
|
||||||
leftVBox.getChildren().clear();
|
leftVBox.getChildren().clear();
|
||||||
break;
|
break;
|
||||||
case WAIT_FOR_BLOCKCHAIN_CONFIRMATION:
|
case WAIT_FOR_BLOCKCHAIN_CONFIRMATION:
|
||||||
showItem(waitTxInBlockchain);
|
showItem(step1);
|
||||||
|
|
||||||
((WaitTxInBlockchainView) tradeStepDetailsView).setInfoLabelText("Deposit transaction has been published. " +
|
|
||||||
"The bitcoin buyer need to wait for at least one blockchain confirmation.");
|
|
||||||
break;
|
break;
|
||||||
case WAIT_FOR_FIAT_PAYMENT_STARTED:
|
case WAIT_FOR_FIAT_PAYMENT_STARTED:
|
||||||
waitTxInBlockchain.setCompleted();
|
step1.setCompleted();
|
||||||
showItem(waitPaymentStarted);
|
showItem(step2);
|
||||||
|
|
||||||
((WaitTxInBlockchainView) tradeStepDetailsView).setInfoLabelText(BSResources.get("Deposit transaction has at least one blockchain " +
|
|
||||||
"confirmation. " +
|
|
||||||
"Waiting that the bitcoin buyer starts the {0} payment.",
|
|
||||||
model.getCurrencyCode()));
|
|
||||||
break;
|
break;
|
||||||
case REQUEST_CONFIRM_FIAT_PAYMENT_RECEIVED:
|
case REQUEST_CONFIRM_FIAT_PAYMENT_RECEIVED:
|
||||||
waitTxInBlockchain.setCompleted();
|
step1.setCompleted();
|
||||||
waitPaymentStarted.setCompleted();
|
step2.setCompleted();
|
||||||
showItem(confirmPaymentReceived);
|
showItem(step3);
|
||||||
|
|
||||||
if (model.isBlockChainMethod()) {
|
|
||||||
((ConfirmPaymentReceivedView) tradeStepDetailsView).setInfoLabelText(BSResources.get("The bitcoin buyer has started the {0} payment. " +
|
|
||||||
"Check your Altcoin wallet or Block explorer and confirm when you have received the payment.",
|
|
||||||
model.getCurrencyCode()));
|
|
||||||
} else {
|
|
||||||
((ConfirmPaymentReceivedView) tradeStepDetailsView).setInfoLabelText(BSResources.get("The bitcoin buyer has started the {0} payment. " +
|
|
||||||
"Check your payment account and confirm when you have received the payment.",
|
|
||||||
model.getCurrencyCode()));
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case WAIT_FOR_PAYOUT_TX:
|
case WAIT_FOR_PAYOUT_TX:
|
||||||
waitTxInBlockchain.setCompleted();
|
step1.setCompleted();
|
||||||
waitPaymentStarted.setCompleted();
|
step2.setCompleted();
|
||||||
confirmPaymentReceived.setCompleted();
|
step3.setCompleted();
|
||||||
showItem(waitPayoutUnlock);
|
showItem(step4);
|
||||||
|
|
||||||
// We don't use a wizard for that step as it only gets displayed in case the other peer is offline
|
// We don't use a wizard for that step as it only gets displayed in case the other peer is offline
|
||||||
tradeStepDetailsView = new WaitPayoutFinalizedView(model);
|
tradeStepView = new SellerStep4bView(model);
|
||||||
contentPane.getChildren().setAll(tradeStepDetailsView);
|
contentPane.getChildren().setAll(tradeStepView);
|
||||||
|
|
||||||
((WaitPayoutFinalizedView) tradeStepDetailsView).setInfoLabelText("We requested the trading peer to sign and finalize the payout " +
|
|
||||||
"transaction.\n" +
|
|
||||||
"It might be that the other peer is offline, so we need to wait until he finalize the transaction when he goes online again.");
|
|
||||||
break;
|
break;
|
||||||
case WAIT_FOR_UNLOCK_PAYOUT:
|
case WAIT_FOR_UNLOCK_PAYOUT:
|
||||||
waitTxInBlockchain.setCompleted();
|
step1.setCompleted();
|
||||||
waitPaymentStarted.setCompleted();
|
step2.setCompleted();
|
||||||
confirmPaymentReceived.setCompleted();
|
step3.setCompleted();
|
||||||
showItem(waitPayoutUnlock);
|
showItem(step4);
|
||||||
|
|
||||||
((WaitPayoutLockTimeView) tradeStepDetailsView).setInfoLabelText("The payout transaction is signed and finalized by both parties." +
|
|
||||||
"\nFor reducing bank charge back risks you need to wait until the payout gets unlocked to transfer your bitcoin.");
|
|
||||||
break;
|
break;
|
||||||
case REQUEST_WITHDRAWAL:
|
case REQUEST_WITHDRAWAL:
|
||||||
waitTxInBlockchain.setCompleted();
|
step1.setCompleted();
|
||||||
waitPaymentStarted.setCompleted();
|
step2.setCompleted();
|
||||||
confirmPaymentReceived.setCompleted();
|
step3.setCompleted();
|
||||||
waitPayoutUnlock.setCompleted();
|
step4.setCompleted();
|
||||||
showItem(completed);
|
showItem(step5);
|
||||||
|
|
||||||
CompletedView completedView = (CompletedView) tradeStepDetailsView;
|
SellerStep5View sellerStep5View = (SellerStep5View) tradeStepView;
|
||||||
completedView.setBtcTradeAmountLabelText("You have sold:");
|
sellerStep5View.setBtcTradeAmountLabelText("You have sold:");
|
||||||
completedView.setFiatTradeAmountLabelText("You have received:");
|
sellerStep5View.setFiatTradeAmountLabelText("You have received:");
|
||||||
completedView.setBtcTradeAmountTextFieldText(model.getTradeVolume());
|
sellerStep5View.setBtcTradeAmountTextFieldText(model.getTradeVolume());
|
||||||
completedView.setFiatTradeAmountTextFieldText(model.getFiatVolume());
|
sellerStep5View.setFiatTradeAmountTextFieldText(model.getFiatVolume());
|
||||||
completedView.setFeesTextFieldText(model.getTotalFees());
|
sellerStep5View.setFeesTextFieldText(model.getTotalFees());
|
||||||
completedView.setSecurityDepositTextFieldText(model.getSecurityDeposit());
|
sellerStep5View.setSecurityDepositTextFieldText(model.getSecurityDeposit());
|
||||||
|
|
||||||
completedView.setWithdrawAmountTextFieldText(model.getPayoutAmount());
|
sellerStep5View.setWithdrawAmountTextFieldText(model.getPayoutAmount());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
log.warn("unhandled viewState " + viewState);
|
log.warn("unhandled viewState " + viewState);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tradeStepDetailsView != null)
|
if (tradeStepView != null)
|
||||||
tradeStepDetailsView.doActivate();
|
tradeStepView.doActivate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,23 +17,31 @@
|
||||||
|
|
||||||
package io.bitsquare.gui.main.portfolio.pendingtrades;
|
package io.bitsquare.gui.main.portfolio.pendingtrades;
|
||||||
|
|
||||||
import io.bitsquare.gui.main.portfolio.pendingtrades.steps.TradeStepDetailsView;
|
import io.bitsquare.common.util.Tuple3;
|
||||||
|
import io.bitsquare.gui.components.TitledGroupBg;
|
||||||
|
import io.bitsquare.gui.main.portfolio.pendingtrades.steps.TradeStepView;
|
||||||
import io.bitsquare.gui.main.portfolio.pendingtrades.steps.TradeWizardItem;
|
import io.bitsquare.gui.main.portfolio.pendingtrades.steps.TradeWizardItem;
|
||||||
import io.bitsquare.gui.util.Layout;
|
import io.bitsquare.gui.util.Layout;
|
||||||
import javafx.scene.layout.AnchorPane;
|
import javafx.geometry.Insets;
|
||||||
import javafx.scene.layout.HBox;
|
import javafx.geometry.Pos;
|
||||||
import javafx.scene.layout.Priority;
|
import javafx.scene.control.Button;
|
||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.control.Label;
|
||||||
|
import javafx.scene.layout.*;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import static io.bitsquare.gui.util.FormBuilder.addMultilineLabel;
|
||||||
|
import static io.bitsquare.gui.util.FormBuilder.addTitledGroupBg;
|
||||||
|
|
||||||
public abstract class TradeSubView extends HBox {
|
public abstract class TradeSubView extends HBox {
|
||||||
protected final Logger log = LoggerFactory.getLogger(this.getClass());
|
protected final Logger log = LoggerFactory.getLogger(this.getClass());
|
||||||
|
|
||||||
protected final PendingTradesViewModel model;
|
protected final PendingTradesViewModel model;
|
||||||
protected VBox leftVBox;
|
protected VBox leftVBox;
|
||||||
protected AnchorPane contentPane;
|
protected AnchorPane contentPane;
|
||||||
protected TradeStepDetailsView tradeStepDetailsView;
|
protected TradeStepView tradeStepView;
|
||||||
|
private Button openDisputeButton;
|
||||||
|
private Tuple3<GridPane, TitledGroupBg, Label> notificationTuple;
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -48,24 +56,48 @@ public abstract class TradeSubView extends HBox {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void activate() {
|
protected void activate() {
|
||||||
// don't call tradeStepDetailsView.activate() as that will be called when state is set
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void deactivate() {
|
protected void deactivate() {
|
||||||
if (tradeStepDetailsView != null)
|
if (tradeStepView != null)
|
||||||
tradeStepDetailsView.doDeactivate();
|
tradeStepView.doDeactivate();
|
||||||
|
|
||||||
|
if (openDisputeButton != null)
|
||||||
|
leftVBox.getChildren().remove(openDisputeButton);
|
||||||
|
if (notificationTuple != null)
|
||||||
|
leftVBox.getChildren().remove(notificationTuple.first);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Misc
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
private void buildViews() {
|
private void buildViews() {
|
||||||
addLeftBox();
|
addLeftBox();
|
||||||
addContentPane();
|
addContentPane();
|
||||||
addWizards();
|
addWizards();
|
||||||
|
|
||||||
|
openDisputeButton = new Button("Open Dispute");
|
||||||
|
openDisputeButton.setPrefHeight(40);
|
||||||
|
openDisputeButton.setPrefWidth(360);
|
||||||
|
openDisputeButton.setPadding(new Insets(0, 20, 0, 10));
|
||||||
|
openDisputeButton.setAlignment(Pos.CENTER);
|
||||||
|
openDisputeButton.setDefaultButton(true);
|
||||||
|
openDisputeButton.setId("open-dispute-button");
|
||||||
|
openDisputeButton.setVisible(false);
|
||||||
|
openDisputeButton.setManaged(false);
|
||||||
|
leftVBox.getChildren().add(openDisputeButton);
|
||||||
|
VBox.setMargin(openDisputeButton, new Insets(10, 0, 0, 0));
|
||||||
|
|
||||||
|
// notification fields
|
||||||
|
GridPane gridPane = new GridPane();
|
||||||
|
gridPane.setPrefWidth(340);
|
||||||
|
VBox.setMargin(gridPane, new Insets(10, 10, 10, 10));
|
||||||
|
gridPane.setHgap(Layout.GRID_GAP);
|
||||||
|
gridPane.setVgap(Layout.GRID_GAP);
|
||||||
|
gridPane.setVisible(false);
|
||||||
|
gridPane.setManaged(false);
|
||||||
|
leftVBox.getChildren().add(gridPane);
|
||||||
|
|
||||||
|
TitledGroupBg titledGroupBg = addTitledGroupBg(gridPane, 0, 4, "Important notice", 20);
|
||||||
|
Label label = addMultilineLabel(gridPane, 0, Layout.FIRST_ROW_DISTANCE + 20);
|
||||||
|
notificationTuple = new Tuple3<>(gridPane, titledGroupBg, label);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void showItem(TradeWizardItem item) {
|
protected void showItem(TradeWizardItem item) {
|
||||||
|
@ -75,10 +107,13 @@ public abstract class TradeSubView extends HBox {
|
||||||
|
|
||||||
abstract protected void addWizards();
|
abstract protected void addWizards();
|
||||||
|
|
||||||
private void createAndAddTradeStepView(Class<? extends TradeStepDetailsView> viewClass) {
|
private void createAndAddTradeStepView(Class<? extends TradeStepView> viewClass) {
|
||||||
try {
|
try {
|
||||||
tradeStepDetailsView = viewClass.getDeclaredConstructor(PendingTradesViewModel.class).newInstance(model);
|
tradeStepView = viewClass.getDeclaredConstructor(PendingTradesViewModel.class).newInstance(model);
|
||||||
contentPane.getChildren().setAll(tradeStepDetailsView);
|
contentPane.getChildren().setAll(tradeStepView);
|
||||||
|
|
||||||
|
tradeStepView.setNotificationFields(notificationTuple);
|
||||||
|
tradeStepView.setOpenDisputeButton(openDisputeButton);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,295 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Bitsquare.
|
|
||||||
*
|
|
||||||
* Bitsquare is free software: you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or (at
|
|
||||||
* your option) any later version.
|
|
||||||
*
|
|
||||||
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
|
||||||
* License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package io.bitsquare.gui.main.portfolio.pendingtrades.steps;
|
|
||||||
|
|
||||||
import io.bitsquare.arbitration.Dispute;
|
|
||||||
import io.bitsquare.gui.components.TitledGroupBg;
|
|
||||||
import io.bitsquare.gui.main.help.Help;
|
|
||||||
import io.bitsquare.gui.main.help.HelpId;
|
|
||||||
import io.bitsquare.gui.main.portfolio.pendingtrades.PendingTradesViewModel;
|
|
||||||
import io.bitsquare.gui.popups.Popup;
|
|
||||||
import io.bitsquare.gui.util.Layout;
|
|
||||||
import io.bitsquare.trade.Trade;
|
|
||||||
import javafx.geometry.HPos;
|
|
||||||
import javafx.scene.control.Button;
|
|
||||||
import javafx.scene.control.Label;
|
|
||||||
import javafx.scene.layout.AnchorPane;
|
|
||||||
import javafx.scene.layout.GridPane;
|
|
||||||
import org.bitcoinj.core.*;
|
|
||||||
import org.fxmisc.easybind.EasyBind;
|
|
||||||
import org.fxmisc.easybind.Subscription;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import static io.bitsquare.gui.util.FormBuilder.*;
|
|
||||||
|
|
||||||
public abstract class TradeStepDetailsView extends AnchorPane {
|
|
||||||
protected final Logger log = LoggerFactory.getLogger(this.getClass());
|
|
||||||
protected final PendingTradesViewModel model;
|
|
||||||
protected final GridPane gridPane;
|
|
||||||
protected int gridRow = 0;
|
|
||||||
private final BlockChainListener blockChainListener;
|
|
||||||
|
|
||||||
private long checkPaymentTimeInBlocks;
|
|
||||||
protected long openDisputeTimeInBlocks;
|
|
||||||
protected Label infoLabel;
|
|
||||||
protected TitledGroupBg infoTitledGroupBg;
|
|
||||||
protected Button openDisputeButton;
|
|
||||||
protected Button openSupportTicketButton;
|
|
||||||
|
|
||||||
private Trade trade;
|
|
||||||
private Subscription errorMessageSubscription;
|
|
||||||
private Subscription disputeStateSubscription;
|
|
||||||
private Subscription tradePeriodStateSubscription;
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Constructor, Initialisation
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
public TradeStepDetailsView(PendingTradesViewModel model) {
|
|
||||||
this.model = model;
|
|
||||||
|
|
||||||
AnchorPane.setLeftAnchor(this, 0d);
|
|
||||||
AnchorPane.setRightAnchor(this, 0d);
|
|
||||||
AnchorPane.setTopAnchor(this, -10d);
|
|
||||||
AnchorPane.setBottomAnchor(this, 0d);
|
|
||||||
|
|
||||||
gridPane = addGridPane(this);
|
|
||||||
|
|
||||||
buildGridEntries();
|
|
||||||
|
|
||||||
blockChainListener = new BlockChainListener() {
|
|
||||||
@Override
|
|
||||||
public void notifyNewBestBlock(StoredBlock block) throws VerificationException {
|
|
||||||
setDateFromBlocks(block.getHeight());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reorganize(StoredBlock splitPoint, List<StoredBlock> oldBlocks, List<StoredBlock> newBlocks) throws VerificationException {
|
|
||||||
setDateFromBlocks(model.getBestChainHeight());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isTransactionRelevant(Transaction tx) throws ScriptException {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void receiveFromBlock(Transaction tx, StoredBlock block, AbstractBlockChain.NewBlockType blockType, int relativityOffset) throws
|
|
||||||
VerificationException {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean notifyTransactionIsInBlock(Sha256Hash txHash, StoredBlock block, AbstractBlockChain.NewBlockType blockType, int relativityOffset)
|
|
||||||
throws VerificationException {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// That is called at every state change!
|
|
||||||
public void doActivate() {
|
|
||||||
trade = model.getTrade();
|
|
||||||
|
|
||||||
errorMessageSubscription = EasyBind.subscribe(trade.errorMessageProperty(), newValue -> {
|
|
||||||
if (newValue != null) {
|
|
||||||
addErrorLabel();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
disputeStateSubscription = EasyBind.subscribe(trade.disputeStateProperty(), newValue -> {
|
|
||||||
if (newValue != null) {
|
|
||||||
updateDisputeState(newValue);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
tradePeriodStateSubscription = EasyBind.subscribe(trade.getTradePeriodStateProperty(), newValue -> {
|
|
||||||
if (newValue != null) {
|
|
||||||
updateTradePeriodState(newValue);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
setDateFromBlocks(model.getBestChainHeight());
|
|
||||||
|
|
||||||
// first call updateTradePeriodState as there is the dispute button created in case we are in period over time
|
|
||||||
updateTradePeriodState(trade.getTradePeriodState());
|
|
||||||
updateDisputeState(trade.getDisputeState());
|
|
||||||
|
|
||||||
model.addBlockChainListener(blockChainListener);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doDeactivate() {
|
|
||||||
model.removeBlockChainListener(blockChainListener);
|
|
||||||
|
|
||||||
if (errorMessageSubscription != null)
|
|
||||||
errorMessageSubscription.unsubscribe();
|
|
||||||
if (disputeStateSubscription != null)
|
|
||||||
disputeStateSubscription.unsubscribe();
|
|
||||||
if (tradePeriodStateSubscription != null)
|
|
||||||
tradePeriodStateSubscription.unsubscribe();
|
|
||||||
|
|
||||||
if (openDisputeButton != null)
|
|
||||||
openDisputeButton.setOnAction(null);
|
|
||||||
if (openSupportTicketButton != null)
|
|
||||||
openSupportTicketButton.setOnAction(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void disputeInProgress() {
|
|
||||||
if (openDisputeButton != null)
|
|
||||||
openDisputeButton.setDisable(true);
|
|
||||||
|
|
||||||
addDisputeInfoLabel();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void addDisputeInfoLabel() {
|
|
||||||
if (infoLabel == null) {
|
|
||||||
infoTitledGroupBg = addTitledGroupBg(gridPane, ++gridRow, 1, "Information", Layout.GROUP_DISTANCE);
|
|
||||||
infoLabel = addMultilineLabel(gridPane, gridRow, Layout.FIRST_ROW_AND_GROUP_DISTANCE);
|
|
||||||
}
|
|
||||||
infoLabel.setStyle(" -fx-text-fill: -bs-error-red;");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void addOpenDisputeButton() {
|
|
||||||
if (openDisputeButton == null) {
|
|
||||||
openDisputeButton = addButtonAfterGroup(gridPane, ++gridRow, "Open a dispute with arbitrator");
|
|
||||||
GridPane.setColumnIndex(openDisputeButton, 0);
|
|
||||||
GridPane.setHalignment(openDisputeButton, HPos.LEFT);
|
|
||||||
openDisputeButton.setOnAction(e -> {
|
|
||||||
openDisputeButton.setDisable(true);
|
|
||||||
disputeInProgress();
|
|
||||||
model.dataModel.onOpenDispute();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addErrorLabel() {
|
|
||||||
new Popup().warning(trade.errorMessageProperty().getValue()
|
|
||||||
+ "\n\nPlease report the problem to your arbitrator. He will forward it to the developers to investigate the problem.\n" +
|
|
||||||
"After the problem has be analysed you will get back all the funds you paid in.\n" +
|
|
||||||
"There will be no arbitration fee charged if it was a technical error.").show();
|
|
||||||
|
|
||||||
/*if (infoLabel == null) {
|
|
||||||
infoTitledGroupBg = addTitledGroupBg(gridPane, ++gridRow, 1, "Error", Layout.GROUP_DISTANCE);
|
|
||||||
infoLabel = addMultilineLabel(gridPane, gridRow, Layout.FIRST_ROW_AND_GROUP_DISTANCE);
|
|
||||||
}
|
|
||||||
infoTitledGroupBg.setText("Error message");
|
|
||||||
infoLabel.setText(trade.errorMessageProperty().getValue()
|
|
||||||
+ "\n\nPlease report the problem to your arbitrator. He will forward it to the developers to investigate the problem.\n" +
|
|
||||||
"After the problem has be analysed you will get back all the funds you paid in.\n" +
|
|
||||||
"There will be no arbitration fee charged if it was a technical error.");
|
|
||||||
infoLabel.setStyle(" -fx-text-fill: -bs-error-red;");*/
|
|
||||||
|
|
||||||
if (openSupportTicketButton == null) {
|
|
||||||
openSupportTicketButton = addButton(gridPane, ++gridRow, "Request support");
|
|
||||||
GridPane.setHalignment(openSupportTicketButton, HPos.LEFT);
|
|
||||||
openSupportTicketButton.setOnAction(e -> model.dataModel.onOpenSupportTicket());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void updateDisputeState(Trade.DisputeState disputeState) {
|
|
||||||
Optional<Dispute> ownDispute = model.dataModel.getDisputeManager().findOwnDispute(trade.getId());
|
|
||||||
|
|
||||||
switch (disputeState) {
|
|
||||||
case NONE:
|
|
||||||
break;
|
|
||||||
case DISPUTE_REQUESTED:
|
|
||||||
disputeInProgress();
|
|
||||||
ownDispute.ifPresent(dispute -> {
|
|
||||||
String msg;
|
|
||||||
if (dispute.isSupportTicket())
|
|
||||||
msg = "You opened already a support ticket.\n" +
|
|
||||||
"Please communicate in the support section with the arbitrator.";
|
|
||||||
else
|
|
||||||
msg = "You opened already a dispute.\n" +
|
|
||||||
"Please communicate in the support section with the arbitrator.";
|
|
||||||
|
|
||||||
infoLabel.setText(msg);
|
|
||||||
});
|
|
||||||
|
|
||||||
break;
|
|
||||||
case DISPUTE_STARTED_BY_PEER:
|
|
||||||
disputeInProgress();
|
|
||||||
ownDispute.ifPresent(dispute -> {
|
|
||||||
String msg;
|
|
||||||
if (dispute.isSupportTicket())
|
|
||||||
msg = "Your trading peer opened a support ticket due technical problems.\n" +
|
|
||||||
"Please communicate in the support section with the arbitrator.";
|
|
||||||
else
|
|
||||||
msg = "Your trading peer opened a dispute.\n" +
|
|
||||||
"Please communicate in the support section with the arbitrator.";
|
|
||||||
|
|
||||||
infoLabel.setText(msg);
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case DISPUTE_CLOSED:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void updateTradePeriodState(Trade.TradePeriodState tradePeriodState) {
|
|
||||||
switch (tradePeriodState) {
|
|
||||||
case NORMAL:
|
|
||||||
break;
|
|
||||||
case HALF_REACHED:
|
|
||||||
displayRequestCheckPayment();
|
|
||||||
break;
|
|
||||||
case TRADE_PERIOD_OVER:
|
|
||||||
displayOpenForDisputeForm();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setDateFromBlocks(long bestBlocKHeight) {
|
|
||||||
checkPaymentTimeInBlocks = model.getCheckPaymentTimeAsBlockHeight() - bestBlocKHeight;
|
|
||||||
openDisputeTimeInBlocks = model.getOpenDisputeTimeAsBlockHeight() - bestBlocKHeight;
|
|
||||||
updateDateFromBlocks(bestBlocKHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void updateDateFromBlocks(long bestBlocKHeight) {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// UI Handlers
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
protected void onOpenHelp() {
|
|
||||||
Help.openWindow(model.isOfferer() ? HelpId.PENDING_TRADE_OFFERER : HelpId.PENDING_TRADE_TAKER);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Build view
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
abstract void buildGridEntries();
|
|
||||||
|
|
||||||
protected void displayRequestCheckPayment() {
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void displayOpenForDisputeForm() {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,402 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.gui.main.portfolio.pendingtrades.steps;
|
||||||
|
|
||||||
|
import io.bitsquare.arbitration.Dispute;
|
||||||
|
import io.bitsquare.common.util.Tuple3;
|
||||||
|
import io.bitsquare.gui.components.TitledGroupBg;
|
||||||
|
import io.bitsquare.gui.components.TxIdTextField;
|
||||||
|
import io.bitsquare.gui.components.paymentmethods.PaymentMethodForm;
|
||||||
|
import io.bitsquare.gui.main.portfolio.pendingtrades.PendingTradesViewModel;
|
||||||
|
import io.bitsquare.gui.popups.Popup;
|
||||||
|
import io.bitsquare.gui.util.Layout;
|
||||||
|
import io.bitsquare.trade.Trade;
|
||||||
|
import io.bitsquare.user.Preferences;
|
||||||
|
import javafx.beans.value.ChangeListener;
|
||||||
|
import javafx.scene.control.Button;
|
||||||
|
import javafx.scene.control.Label;
|
||||||
|
import javafx.scene.control.ProgressBar;
|
||||||
|
import javafx.scene.control.TextField;
|
||||||
|
import javafx.scene.layout.AnchorPane;
|
||||||
|
import javafx.scene.layout.GridPane;
|
||||||
|
import org.fxmisc.easybind.EasyBind;
|
||||||
|
import org.fxmisc.easybind.Subscription;
|
||||||
|
import org.reactfx.util.FxTimer;
|
||||||
|
import org.reactfx.util.Timer;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import static io.bitsquare.gui.util.FormBuilder.*;
|
||||||
|
|
||||||
|
public abstract class TradeStepView extends AnchorPane {
|
||||||
|
protected final Logger log = LoggerFactory.getLogger(this.getClass());
|
||||||
|
|
||||||
|
protected final PendingTradesViewModel model;
|
||||||
|
private final Trade trade;
|
||||||
|
protected final Preferences preferences;
|
||||||
|
protected final GridPane gridPane;
|
||||||
|
private final ChangeListener<String> txIdChangeListener;
|
||||||
|
|
||||||
|
private Subscription errorMessageSubscription;
|
||||||
|
private Subscription disputeStateSubscription;
|
||||||
|
private Subscription tradePeriodStateSubscription;
|
||||||
|
private Timer timer;
|
||||||
|
protected int gridRow = 0;
|
||||||
|
protected TitledGroupBg tradeInfoTitledGroupBg;
|
||||||
|
private TextField timeLeftTextField;
|
||||||
|
private ProgressBar timeLeftProgressBar;
|
||||||
|
private GridPane notificationGridPane;
|
||||||
|
private Label notificationLabel;
|
||||||
|
private TitledGroupBg notificationTitledGroupBg;
|
||||||
|
protected Button openDisputeButton;
|
||||||
|
private TxIdTextField txIdTextField;
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Constructor, Initialisation
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
protected TradeStepView(PendingTradesViewModel model) {
|
||||||
|
this.model = model;
|
||||||
|
preferences = model.dataModel.getPreferences();
|
||||||
|
trade = model.getTrade();
|
||||||
|
|
||||||
|
gridPane = addGridPane(this);
|
||||||
|
|
||||||
|
AnchorPane.setLeftAnchor(this, 0d);
|
||||||
|
AnchorPane.setRightAnchor(this, 0d);
|
||||||
|
AnchorPane.setTopAnchor(this, -10d);
|
||||||
|
AnchorPane.setBottomAnchor(this, 0d);
|
||||||
|
|
||||||
|
txIdChangeListener = (ov, oldValue, newValue) -> txIdTextField.setup(newValue);
|
||||||
|
|
||||||
|
addContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void doActivate() {
|
||||||
|
if (txIdTextField != null) {
|
||||||
|
txIdTextField.setup(model.txIdProperty().get());
|
||||||
|
|
||||||
|
model.txIdProperty().addListener(txIdChangeListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
errorMessageSubscription = EasyBind.subscribe(trade.errorMessageProperty(), newValue -> {
|
||||||
|
if (newValue != null) {
|
||||||
|
showSupportFields();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
disputeStateSubscription = EasyBind.subscribe(trade.disputeStateProperty(), newValue -> {
|
||||||
|
if (newValue != null) {
|
||||||
|
updateDisputeState(newValue);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
timer = FxTimer.runPeriodically(Duration.ofSeconds(1), this::updateTimeLeft);
|
||||||
|
|
||||||
|
tradePeriodStateSubscription = EasyBind.subscribe(trade.getTradePeriodStateProperty(), newValue -> {
|
||||||
|
if (newValue != null) {
|
||||||
|
updateTradePeriodState(newValue);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void doDeactivate() {
|
||||||
|
if (txIdTextField != null) {
|
||||||
|
txIdTextField.cleanup();
|
||||||
|
|
||||||
|
model.txIdProperty().removeListener(txIdChangeListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errorMessageSubscription != null)
|
||||||
|
errorMessageSubscription.unsubscribe();
|
||||||
|
|
||||||
|
if (disputeStateSubscription != null)
|
||||||
|
disputeStateSubscription.unsubscribe();
|
||||||
|
|
||||||
|
if (tradePeriodStateSubscription != null)
|
||||||
|
tradePeriodStateSubscription.unsubscribe();
|
||||||
|
|
||||||
|
if (openDisputeButton != null)
|
||||||
|
openDisputeButton.setOnAction(null);
|
||||||
|
|
||||||
|
if (timer != null)
|
||||||
|
timer.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Content
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
protected void addContent() {
|
||||||
|
addTradeInfoBlock();
|
||||||
|
addInfoBlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void addTradeInfoBlock() {
|
||||||
|
tradeInfoTitledGroupBg = addTitledGroupBg(gridPane, gridRow, 4, "Trade information");
|
||||||
|
txIdTextField = addLabelTxIdTextField(gridPane, gridRow, "Deposit transaction ID:", Layout.FIRST_ROW_DISTANCE).second;
|
||||||
|
|
||||||
|
//TODO
|
||||||
|
PaymentMethodForm.addAllowedPeriod(gridPane, ++gridRow, model.dataModel.getSellersPaymentAccountContractData(),
|
||||||
|
model.getOpenDisputeTimeAsFormattedDate());
|
||||||
|
|
||||||
|
timeLeftTextField = addLabelTextField(gridPane, ++gridRow, "Remaining time:").second;
|
||||||
|
|
||||||
|
timeLeftProgressBar = new ProgressBar(0);
|
||||||
|
timeLeftProgressBar.setOpacity(0.7);
|
||||||
|
timeLeftProgressBar.setMinHeight(9);
|
||||||
|
timeLeftProgressBar.setMaxHeight(9);
|
||||||
|
timeLeftProgressBar.setMaxWidth(Double.MAX_VALUE);
|
||||||
|
|
||||||
|
GridPane.setRowIndex(timeLeftProgressBar, ++gridRow);
|
||||||
|
GridPane.setColumnIndex(timeLeftProgressBar, 1);
|
||||||
|
GridPane.setFillWidth(timeLeftProgressBar, true);
|
||||||
|
gridPane.getChildren().add(timeLeftProgressBar);
|
||||||
|
|
||||||
|
updateTimeLeft();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void addInfoBlock() {
|
||||||
|
addTitledGroupBg(gridPane, ++gridRow, 1, getInfoBlockTitle(), Layout.GROUP_DISTANCE);
|
||||||
|
addMultilineLabel(gridPane, gridRow, getInfoText(), Layout.FIRST_ROW_AND_GROUP_DISTANCE);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getInfoText() {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getInfoBlockTitle() {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateTimeLeft() {
|
||||||
|
if (timeLeftTextField != null) {
|
||||||
|
String remainingTime = model.getRemainingTime();
|
||||||
|
timeLeftProgressBar.setProgress(model.getRemainingTimeAsPercentage());
|
||||||
|
if (remainingTime != null) {
|
||||||
|
timeLeftTextField.setText(remainingTime);
|
||||||
|
if (model.showWarning(model.getTrade()) || model.showDispute(model.getTrade())) {
|
||||||
|
timeLeftTextField.setStyle("-fx-text-fill: -bs-error-red");
|
||||||
|
timeLeftProgressBar.setStyle("-fx-accent: -bs-error-red;");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
timeLeftTextField.setText("Trade not completed in time (" + model.getOpenDisputeTimeAsFormattedDate() + ")");
|
||||||
|
timeLeftTextField.setStyle("-fx-text-fill: -bs-error-red");
|
||||||
|
timeLeftProgressBar.setStyle("-fx-accent: -bs-error-red;");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Dispute/warning label and button
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// We have the dispute button and text field on the left side, but we handle the content here as it
|
||||||
|
// is trade state specific
|
||||||
|
public void setNotificationFields(Tuple3<GridPane, TitledGroupBg, Label> notificationTuple) {
|
||||||
|
this.notificationGridPane = notificationTuple.first;
|
||||||
|
this.notificationTitledGroupBg = notificationTuple.second;
|
||||||
|
this.notificationLabel = notificationTuple.third;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOpenDisputeButton(Button openDisputeButton) {
|
||||||
|
this.openDisputeButton = openDisputeButton;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showDisputeInfoLabel() {
|
||||||
|
if (notificationGridPane != null) {
|
||||||
|
notificationGridPane.setVisible(true);
|
||||||
|
notificationGridPane.setManaged(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showOpenDisputeButton() {
|
||||||
|
if (openDisputeButton != null) {
|
||||||
|
openDisputeButton.setVisible(true);
|
||||||
|
openDisputeButton.setManaged(true);
|
||||||
|
openDisputeButton.setOnAction(e -> {
|
||||||
|
openDisputeButton.setDisable(true);
|
||||||
|
onDisputeOpened();
|
||||||
|
setDisputeState();
|
||||||
|
model.dataModel.onOpenDispute();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setWarningState() {
|
||||||
|
if (notificationGridPane != null) {
|
||||||
|
notificationTitledGroupBg.setText("Warning");
|
||||||
|
//notificationGridPane.setId("trade-notification-warning");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setInformationState() {
|
||||||
|
if (notificationGridPane != null) {
|
||||||
|
notificationTitledGroupBg.setText("Notification");
|
||||||
|
notificationTitledGroupBg.setId("titled-group-bg-warn");
|
||||||
|
notificationTitledGroupBg.getLabel().setId("titled-group-bg-label-warn");
|
||||||
|
//notificationLabel.setId("titled-group-bg-label-warn");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setDisputeState() {
|
||||||
|
if (notificationGridPane != null) {
|
||||||
|
notificationTitledGroupBg.setText("Dispute opened");
|
||||||
|
//notificationGridPane.setId("trade-notification-dispute");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setSupportState() {
|
||||||
|
if (notificationGridPane != null) {
|
||||||
|
notificationTitledGroupBg.setText("Support ticket opened");
|
||||||
|
//notificationGridPane.setId("trade-notification-support");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Support
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
private void showSupportFields() {
|
||||||
|
if (openDisputeButton != null) {
|
||||||
|
openDisputeButton.setText("Request support");
|
||||||
|
openDisputeButton.setId("open-support-button");
|
||||||
|
openDisputeButton.setOnAction(e -> model.dataModel.onOpenSupportTicket());
|
||||||
|
}
|
||||||
|
new Popup().warning(trade.errorMessageProperty().getValue()
|
||||||
|
+ "\n\nPlease report the problem to your arbitrator.\n\n" +
|
||||||
|
"He will forward teh information to the developers to investigate the problem.\n" +
|
||||||
|
"After the problem has be analyzed you will get back all the funds if they are locked.\n" +
|
||||||
|
"There will be no arbitration fee charged in case of a software bug.")
|
||||||
|
.show();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Warning
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
private void showWarning() {
|
||||||
|
showDisputeInfoLabel();
|
||||||
|
|
||||||
|
if (notificationLabel != null)
|
||||||
|
notificationLabel.setText(getWarningText());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getWarningText() {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Dispute
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
private void onOpenForDispute() {
|
||||||
|
showDisputeInfoLabel();
|
||||||
|
showOpenDisputeButton();
|
||||||
|
|
||||||
|
if (notificationLabel != null)
|
||||||
|
notificationLabel.setText(getOpenForDisputeText());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onDisputeOpened() {
|
||||||
|
showDisputeInfoLabel();
|
||||||
|
showOpenDisputeButton();
|
||||||
|
applyOnDisputeOpened();
|
||||||
|
|
||||||
|
|
||||||
|
if (openDisputeButton != null)
|
||||||
|
openDisputeButton.setDisable(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getOpenForDisputeText() {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void applyOnDisputeOpened() {
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateDisputeState(Trade.DisputeState disputeState) {
|
||||||
|
Optional<Dispute> ownDispute;
|
||||||
|
switch (disputeState) {
|
||||||
|
case NONE:
|
||||||
|
break;
|
||||||
|
case DISPUTE_REQUESTED:
|
||||||
|
onDisputeOpened();
|
||||||
|
ownDispute = model.dataModel.getDisputeManager().findOwnDispute(trade.getId());
|
||||||
|
ownDispute.ifPresent(dispute -> {
|
||||||
|
String msg;
|
||||||
|
if (dispute.isSupportTicket()) {
|
||||||
|
setSupportState();
|
||||||
|
msg = "You opened already a support ticket.\n" +
|
||||||
|
"Please communicate in the support section with the arbitrator.";
|
||||||
|
} else {
|
||||||
|
setDisputeState();
|
||||||
|
msg = "You opened already a dispute.\n" +
|
||||||
|
"Please communicate in the support section with the arbitrator.";
|
||||||
|
}
|
||||||
|
if (notificationLabel != null)
|
||||||
|
notificationLabel.setText(msg);
|
||||||
|
});
|
||||||
|
|
||||||
|
break;
|
||||||
|
case DISPUTE_STARTED_BY_PEER:
|
||||||
|
onDisputeOpened();
|
||||||
|
ownDispute = model.dataModel.getDisputeManager().findOwnDispute(trade.getId());
|
||||||
|
ownDispute.ifPresent(dispute -> {
|
||||||
|
String msg;
|
||||||
|
if (dispute.isSupportTicket()) {
|
||||||
|
setSupportState();
|
||||||
|
msg = "Your trading peer opened a support ticket due technical problems.\n" +
|
||||||
|
"Please communicate in the support section with the arbitrator.";
|
||||||
|
} else {
|
||||||
|
setDisputeState();
|
||||||
|
msg = "Your trading peer opened a dispute.\n" +
|
||||||
|
"Please communicate in the support section with the arbitrator.";
|
||||||
|
}
|
||||||
|
if (notificationLabel != null)
|
||||||
|
notificationLabel.setText(msg);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case DISPUTE_CLOSED:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateTradePeriodState(Trade.TradePeriodState tradePeriodState) {
|
||||||
|
if (trade.getDisputeState() != Trade.DisputeState.DISPUTE_REQUESTED &&
|
||||||
|
trade.getDisputeState() != Trade.DisputeState.DISPUTE_STARTED_BY_PEER) {
|
||||||
|
switch (tradePeriodState) {
|
||||||
|
case NORMAL:
|
||||||
|
break;
|
||||||
|
case HALF_REACHED:
|
||||||
|
showWarning();
|
||||||
|
break;
|
||||||
|
case TRADE_PERIOD_OVER:
|
||||||
|
onOpenForDispute();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -26,13 +26,13 @@ import javafx.scene.control.Button;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
|
|
||||||
public class TradeWizardItem extends Button {
|
public class TradeWizardItem extends Button {
|
||||||
public Class<? extends TradeStepDetailsView> getViewClass() {
|
public Class<? extends TradeStepView> getViewClass() {
|
||||||
return viewClass;
|
return viewClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Class<? extends TradeStepDetailsView> viewClass;
|
private final Class<? extends TradeStepView> viewClass;
|
||||||
|
|
||||||
public TradeWizardItem(Class<? extends TradeStepDetailsView> viewClass, String title) {
|
public TradeWizardItem(Class<? extends TradeStepView> viewClass, String title) {
|
||||||
this.viewClass = viewClass;
|
this.viewClass = viewClass;
|
||||||
|
|
||||||
setMouseTransparent(true);
|
setMouseTransparent(true);
|
||||||
|
|
|
@ -1,109 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Bitsquare.
|
|
||||||
*
|
|
||||||
* Bitsquare is free software: you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or (at
|
|
||||||
* your option) any later version.
|
|
||||||
*
|
|
||||||
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
|
||||||
* License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package io.bitsquare.gui.main.portfolio.pendingtrades.steps;
|
|
||||||
|
|
||||||
import io.bitsquare.gui.components.TxIdTextField;
|
|
||||||
import io.bitsquare.gui.main.portfolio.pendingtrades.PendingTradesViewModel;
|
|
||||||
import io.bitsquare.gui.util.Layout;
|
|
||||||
import javafx.beans.value.ChangeListener;
|
|
||||||
|
|
||||||
import static io.bitsquare.gui.util.FormBuilder.*;
|
|
||||||
|
|
||||||
public class WaitPaymentReceivedView extends TradeStepDetailsView {
|
|
||||||
private final ChangeListener<String> txIdChangeListener;
|
|
||||||
private TxIdTextField txIdTextField;
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Constructor, Initialisation
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
public WaitPaymentReceivedView(PendingTradesViewModel model) {
|
|
||||||
super(model);
|
|
||||||
|
|
||||||
txIdChangeListener = (ov, oldValue, newValue) -> txIdTextField.setup(newValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void doActivate() {
|
|
||||||
super.doActivate();
|
|
||||||
|
|
||||||
model.getTxId().addListener(txIdChangeListener);
|
|
||||||
txIdTextField.setup(model.getTxId().get());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void doDeactivate() {
|
|
||||||
super.doDeactivate();
|
|
||||||
|
|
||||||
model.getTxId().removeListener(txIdChangeListener);
|
|
||||||
txIdTextField.cleanup();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void displayRequestCheckPayment() {
|
|
||||||
infoLabel.setStyle(" -fx-text-fill: -bs-error-red;");
|
|
||||||
infoLabel.setText("The seller still has not confirmed your payment!\n" +
|
|
||||||
"Please check at your payment processor/bank/blockchain if the payment succeeded.\n" +
|
|
||||||
"If the seller has not confirmed the receipt of your payment until " +
|
|
||||||
model.getDateFromBlocks(openDisputeTimeInBlocks) +
|
|
||||||
" the trade will be investigated by the arbitrator.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void displayOpenForDisputeForm() {
|
|
||||||
infoLabel.setStyle(" -fx-text-fill: -bs-error-red;");
|
|
||||||
infoLabel.setText("The seller has not confirmed your payment!\n" +
|
|
||||||
"The max. period for the trade has elapsed (" +
|
|
||||||
model.getDateFromBlocks(openDisputeTimeInBlocks) +
|
|
||||||
") and you need to contact now the arbitrator to investigate the problem.");
|
|
||||||
|
|
||||||
addOpenDisputeButton();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void disputeInProgress() {
|
|
||||||
super.disputeInProgress();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Setters
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
public void setInfoLabelText(String text) {
|
|
||||||
if (infoLabel != null)
|
|
||||||
infoLabel.setText(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Build view
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void buildGridEntries() {
|
|
||||||
addTitledGroupBg(gridPane, gridRow, 1, "Blockchain confirmation");
|
|
||||||
txIdTextField = addLabelTxIdTextField(gridPane, gridRow, "Deposit transaction ID:", Layout.FIRST_ROW_DISTANCE).second;
|
|
||||||
|
|
||||||
infoTitledGroupBg = addTitledGroupBg(gridPane, ++gridRow, 1, "Information", Layout.GROUP_DISTANCE);
|
|
||||||
infoLabel = addMultilineLabel(gridPane, gridRow, Layout.FIRST_ROW_AND_GROUP_DISTANCE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,84 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Bitsquare.
|
|
||||||
*
|
|
||||||
* Bitsquare is free software: you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or (at
|
|
||||||
* your option) any later version.
|
|
||||||
*
|
|
||||||
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
|
||||||
* License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package io.bitsquare.gui.main.portfolio.pendingtrades.steps;
|
|
||||||
|
|
||||||
import io.bitsquare.gui.main.portfolio.pendingtrades.PendingTradesViewModel;
|
|
||||||
import io.bitsquare.gui.util.Layout;
|
|
||||||
|
|
||||||
import static io.bitsquare.gui.util.FormBuilder.addMultilineLabel;
|
|
||||||
import static io.bitsquare.gui.util.FormBuilder.addTitledGroupBg;
|
|
||||||
|
|
||||||
public class WaitPayoutFinalizedView extends TradeStepDetailsView {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Constructor, Initialisation
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
public WaitPayoutFinalizedView(PendingTradesViewModel model) {
|
|
||||||
super(model);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void doActivate() {
|
|
||||||
super.doActivate();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void doDeactivate() {
|
|
||||||
super.doDeactivate();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setInfoLabelText(String text) {
|
|
||||||
if (infoLabel != null)
|
|
||||||
infoLabel.setText(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void displayRequestCheckPayment() {
|
|
||||||
// we cannot do anything here, beside restart in case of software bugs
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void displayOpenForDisputeForm() {
|
|
||||||
infoLabel.setStyle(" -fx-text-fill: -bs-error-red;");
|
|
||||||
infoLabel.setText("The trading peer has not finalized the payout transaction!\n" +
|
|
||||||
"The max. period for the trade has elapsed (" +
|
|
||||||
model.getDateFromBlocks(openDisputeTimeInBlocks) + ")." +
|
|
||||||
"\nPlease contact now the arbitrator for opening a dispute.");
|
|
||||||
|
|
||||||
addOpenDisputeButton();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void disputeInProgress() {
|
|
||||||
super.disputeInProgress();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Build view
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void buildGridEntries() {
|
|
||||||
infoTitledGroupBg = addTitledGroupBg(gridPane, gridRow, 1, "Information");
|
|
||||||
infoLabel = addMultilineLabel(gridPane, gridRow, Layout.FIRST_ROW_DISTANCE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,82 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Bitsquare.
|
|
||||||
*
|
|
||||||
* Bitsquare is free software: you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or (at
|
|
||||||
* your option) any later version.
|
|
||||||
*
|
|
||||||
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
|
||||||
* License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package io.bitsquare.gui.main.portfolio.pendingtrades.steps;
|
|
||||||
|
|
||||||
import io.bitsquare.gui.main.portfolio.pendingtrades.PendingTradesViewModel;
|
|
||||||
import io.bitsquare.gui.util.Layout;
|
|
||||||
import javafx.scene.control.TextField;
|
|
||||||
|
|
||||||
import static io.bitsquare.gui.util.FormBuilder.*;
|
|
||||||
|
|
||||||
public class WaitPayoutLockTimeView extends TradeStepDetailsView {
|
|
||||||
private TextField blockTextField;
|
|
||||||
private TextField timeTextField;
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Constructor, Initialisation
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
public WaitPayoutLockTimeView(PendingTradesViewModel model) {
|
|
||||||
super(model);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void doActivate() {
|
|
||||||
super.doActivate();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void doDeactivate() {
|
|
||||||
super.doDeactivate();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void updateDateFromBlocks(long bestBlocKHeight) {
|
|
||||||
long missingBlocks = model.getLockTime() - bestBlocKHeight;
|
|
||||||
blockTextField.setText(String.valueOf(missingBlocks));
|
|
||||||
timeTextField.setText(model.getDateFromBlocks(missingBlocks));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Setters
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
public void setInfoLabelText(String text) {
|
|
||||||
if (infoLabel != null)
|
|
||||||
infoLabel.setText(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Build view
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void buildGridEntries() {
|
|
||||||
addTitledGroupBg(gridPane, gridRow, 2, "Payout transaction lock time");
|
|
||||||
blockTextField = addLabelTextField(gridPane, gridRow, "Block(s) to wait until unlock:", "", Layout.FIRST_ROW_DISTANCE).second;
|
|
||||||
timeTextField = addLabelTextField(gridPane, ++gridRow, "Approx. date when payout gets unlocked:").second;
|
|
||||||
|
|
||||||
infoTitledGroupBg = addTitledGroupBg(gridPane, ++gridRow, 1, "Information", Layout.GROUP_DISTANCE);
|
|
||||||
infoLabel = addMultilineLabel(gridPane, gridRow, Layout.FIRST_ROW_AND_GROUP_DISTANCE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,83 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Bitsquare.
|
|
||||||
*
|
|
||||||
* Bitsquare is free software: you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or (at
|
|
||||||
* your option) any later version.
|
|
||||||
*
|
|
||||||
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
|
||||||
* License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package io.bitsquare.gui.main.portfolio.pendingtrades.steps;
|
|
||||||
|
|
||||||
import io.bitsquare.gui.components.TxIdTextField;
|
|
||||||
import io.bitsquare.gui.main.portfolio.pendingtrades.PendingTradesViewModel;
|
|
||||||
import io.bitsquare.gui.util.Layout;
|
|
||||||
import javafx.beans.value.ChangeListener;
|
|
||||||
|
|
||||||
import static io.bitsquare.gui.util.FormBuilder.*;
|
|
||||||
|
|
||||||
public class WaitTxInBlockchainView extends TradeStepDetailsView {
|
|
||||||
private final ChangeListener<String> txIdChangeListener;
|
|
||||||
private TxIdTextField txIdTextField;
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Constructor, Initialisation
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
public WaitTxInBlockchainView(PendingTradesViewModel model) {
|
|
||||||
super(model);
|
|
||||||
|
|
||||||
txIdChangeListener = (ov, oldValue, newValue) -> txIdTextField.setup(newValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void doActivate() {
|
|
||||||
super.doActivate();
|
|
||||||
|
|
||||||
model.getTxId().addListener(txIdChangeListener);
|
|
||||||
txIdTextField.setup(model.getTxId().get());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void doDeactivate() {
|
|
||||||
super.doDeactivate();
|
|
||||||
|
|
||||||
model.getTxId().removeListener(txIdChangeListener);
|
|
||||||
txIdTextField.cleanup();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Setters
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
public void setInfoLabelText(String text) {
|
|
||||||
if (infoLabel != null)
|
|
||||||
infoLabel.setText(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Build view
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void buildGridEntries() {
|
|
||||||
addTitledGroupBg(gridPane, gridRow, 1, "Blockchain confirmation");
|
|
||||||
txIdTextField = addLabelTxIdTextField(gridPane, gridRow, "Deposit transaction ID:", Layout.FIRST_ROW_DISTANCE).second;
|
|
||||||
|
|
||||||
infoTitledGroupBg = addTitledGroupBg(gridPane, ++gridRow, 1, "Information", Layout.GROUP_DISTANCE);
|
|
||||||
infoLabel = addMultilineLabel(gridPane, gridRow, Layout.FIRST_ROW_AND_GROUP_DISTANCE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.gui.main.portfolio.pendingtrades.steps.buyer;
|
||||||
|
|
||||||
|
import io.bitsquare.gui.main.portfolio.pendingtrades.PendingTradesViewModel;
|
||||||
|
import io.bitsquare.gui.main.portfolio.pendingtrades.steps.TradeStepView;
|
||||||
|
|
||||||
|
public class BuyerStep1View extends TradeStepView {
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Constructor, Initialisation
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public BuyerStep1View(PendingTradesViewModel model) {
|
||||||
|
super(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Info
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getInfoBlockTitle() {
|
||||||
|
return "Wait for blockchain confirmation";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getInfoText() {
|
||||||
|
return "Deposit transaction has been published.\n" +
|
||||||
|
"You need to wait for at least one blockchain confirmation.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,24 +15,21 @@
|
||||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.bitsquare.gui.main.portfolio.pendingtrades.steps;
|
package io.bitsquare.gui.main.portfolio.pendingtrades.steps.buyer;
|
||||||
|
|
||||||
import io.bitsquare.app.BitsquareApp;
|
import io.bitsquare.app.BitsquareApp;
|
||||||
import io.bitsquare.common.util.Tuple3;
|
import io.bitsquare.common.util.Tuple3;
|
||||||
import io.bitsquare.gui.components.TextFieldWithCopyIcon;
|
import io.bitsquare.gui.components.TextFieldWithCopyIcon;
|
||||||
import io.bitsquare.gui.components.TitledGroupBg;
|
import io.bitsquare.gui.components.TitledGroupBg;
|
||||||
import io.bitsquare.gui.components.TxIdTextField;
|
|
||||||
import io.bitsquare.gui.components.paymentmethods.*;
|
import io.bitsquare.gui.components.paymentmethods.*;
|
||||||
import io.bitsquare.gui.main.portfolio.pendingtrades.PendingTradesViewModel;
|
import io.bitsquare.gui.main.portfolio.pendingtrades.PendingTradesViewModel;
|
||||||
|
import io.bitsquare.gui.main.portfolio.pendingtrades.steps.TradeStepView;
|
||||||
import io.bitsquare.gui.popups.Popup;
|
import io.bitsquare.gui.popups.Popup;
|
||||||
import io.bitsquare.gui.util.Layout;
|
import io.bitsquare.gui.util.Layout;
|
||||||
|
import io.bitsquare.locale.BSResources;
|
||||||
import io.bitsquare.payment.PaymentAccountContractData;
|
import io.bitsquare.payment.PaymentAccountContractData;
|
||||||
import io.bitsquare.payment.PaymentMethod;
|
import io.bitsquare.payment.PaymentMethod;
|
||||||
import io.bitsquare.user.PopupId;
|
import io.bitsquare.user.PopupId;
|
||||||
import io.bitsquare.user.Preferences;
|
|
||||||
import javafx.beans.value.ChangeListener;
|
|
||||||
import javafx.event.ActionEvent;
|
|
||||||
import javafx.geometry.Insets;
|
|
||||||
import javafx.scene.control.Button;
|
import javafx.scene.control.Button;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
import javafx.scene.control.ProgressIndicator;
|
import javafx.scene.control.ProgressIndicator;
|
||||||
|
@ -40,43 +37,33 @@ import javafx.scene.layout.GridPane;
|
||||||
|
|
||||||
import static io.bitsquare.gui.util.FormBuilder.*;
|
import static io.bitsquare.gui.util.FormBuilder.*;
|
||||||
|
|
||||||
public class StartPaymentView extends TradeStepDetailsView {
|
public class BuyerStep2View extends TradeStepView {
|
||||||
private final Preferences preferences;
|
|
||||||
private TxIdTextField txIdTextField;
|
|
||||||
|
|
||||||
private Button paymentStartedButton;
|
private Button paymentStartedButton;
|
||||||
private Label statusLabel;
|
private Label statusLabel;
|
||||||
|
|
||||||
private final ChangeListener<String> txIdChangeListener;
|
|
||||||
private ProgressIndicator statusProgressIndicator;
|
private ProgressIndicator statusProgressIndicator;
|
||||||
|
|
||||||
private TitledGroupBg txConfirmationGroup;
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Constructor, Initialisation
|
// Constructor, Initialisation
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
public StartPaymentView(PendingTradesViewModel model) {
|
public BuyerStep2View(PendingTradesViewModel model) {
|
||||||
super(model);
|
super(model);
|
||||||
txIdChangeListener = (ov, oldValue, newValue) -> txIdTextField.setup(newValue);
|
|
||||||
preferences = model.dataModel.getPreferences();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doActivate() {
|
public void doActivate() {
|
||||||
super.doActivate();
|
super.doActivate();
|
||||||
|
|
||||||
model.getTxId().addListener(txIdChangeListener);
|
String id = PopupId.SEND_PAYMENT_INFO;
|
||||||
txIdTextField.setup(model.getTxId().get());
|
if (preferences.showAgain(id) && !BitsquareApp.DEV_MODE) {
|
||||||
|
//TODO use payment method and trade values
|
||||||
String key = PopupId.SEND_PAYMENT_INFO;
|
|
||||||
if (preferences.showAgain(key) && !BitsquareApp.DEV_MODE) {
|
|
||||||
new Popup().information("You need to transfer now the agreed amount to your trading partner.\n" +
|
new Popup().information("You need to transfer now the agreed amount to your trading partner.\n" +
|
||||||
"Please take care that you use the exact data presented here, including the reference text\n" +
|
"Please take care that you use the exact data presented here, including the reference text\n" +
|
||||||
"Please do not click the \"Payment started\" button before you have completed the transfer.\n" +
|
"Please do not click the \"Payment started\" button before you have completed the transfer.\n" +
|
||||||
"Make sure that you make the transfer soon to not exceed the trading period.")
|
"Make sure that you make the transfer soon to not exceed the trading period.")
|
||||||
.onClose(() -> preferences.dontShowAgain(key))
|
.onClose(() -> preferences.dontShowAgain(id))
|
||||||
.show();
|
.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -85,62 +72,100 @@ public class StartPaymentView extends TradeStepDetailsView {
|
||||||
public void doDeactivate() {
|
public void doDeactivate() {
|
||||||
super.doDeactivate();
|
super.doDeactivate();
|
||||||
|
|
||||||
model.getTxId().removeListener(txIdChangeListener);
|
|
||||||
txIdTextField.cleanup();
|
|
||||||
removeStatusProgressIndicator();
|
removeStatusProgressIndicator();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
protected void displayRequestCheckPayment() {
|
// Content
|
||||||
addDisputeInfoLabel();
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
infoLabel.setText("You still have not done your payment!\n" +
|
|
||||||
"If the seller does not receive your payment until " +
|
|
||||||
model.getDateFromBlocks(openDisputeTimeInBlocks) +
|
|
||||||
" the trade will be investigated by the arbitrator."
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void displayOpenForDisputeForm() {
|
protected void addContent() {
|
||||||
addDisputeInfoLabel();
|
addTradeInfoBlock();
|
||||||
infoLabel.setText("You have not completed your payment!\n" +
|
|
||||||
|
PaymentAccountContractData paymentAccountContractData = model.dataModel.getSellersPaymentAccountContractData();
|
||||||
|
String paymentMethodName = paymentAccountContractData.getPaymentMethodName();
|
||||||
|
TitledGroupBg accountTitledGroupBg = addTitledGroupBg(gridPane, ++gridRow, 1,
|
||||||
|
"Start payment using " + BSResources.get(paymentAccountContractData.getPaymentMethodName()),
|
||||||
|
Layout.GROUP_DISTANCE);
|
||||||
|
TextFieldWithCopyIcon field = addLabelTextFieldWithCopyIcon(gridPane, gridRow, "Amount to transfer:",
|
||||||
|
model.getFiatAmount(),
|
||||||
|
Layout.FIRST_ROW_AND_GROUP_DISTANCE).second;
|
||||||
|
field.setCopyWithoutCurrencyPostFix(true);
|
||||||
|
|
||||||
|
switch (paymentMethodName) {
|
||||||
|
case PaymentMethod.OK_PAY_ID:
|
||||||
|
gridRow = OKPayForm.addFormForBuyer(gridPane, gridRow, paymentAccountContractData);
|
||||||
|
break;
|
||||||
|
case PaymentMethod.PERFECT_MONEY_ID:
|
||||||
|
gridRow = PerfectMoneyForm.addFormForBuyer(gridPane, gridRow, paymentAccountContractData);
|
||||||
|
break;
|
||||||
|
case PaymentMethod.SEPA_ID:
|
||||||
|
gridRow = SepaForm.addFormForBuyer(gridPane, gridRow, paymentAccountContractData);
|
||||||
|
break;
|
||||||
|
case PaymentMethod.SWISH_ID:
|
||||||
|
gridRow = SwishForm.addFormForBuyer(gridPane, gridRow, paymentAccountContractData);
|
||||||
|
break;
|
||||||
|
case PaymentMethod.ALI_PAY_ID:
|
||||||
|
gridRow = AliPayForm.addFormForBuyer(gridPane, gridRow, paymentAccountContractData);
|
||||||
|
break;
|
||||||
|
case PaymentMethod.BLOCK_CHAINS_ID:
|
||||||
|
gridRow = BlockChainForm.addFormForBuyer(gridPane, gridRow, paymentAccountContractData);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
log.error("Not supported PaymentMethod: " + paymentMethodName);
|
||||||
|
}
|
||||||
|
|
||||||
|
addLabelTextFieldWithCopyIcon(gridPane, ++gridRow, "Reference text:", model.getReference());
|
||||||
|
|
||||||
|
GridPane.setRowSpan(accountTitledGroupBg, gridRow - 3);
|
||||||
|
|
||||||
|
Tuple3<Button, ProgressIndicator, Label> tuple3 = addButtonWithStatus(gridPane, ++gridRow, "Payment started");
|
||||||
|
paymentStartedButton = tuple3.first;
|
||||||
|
paymentStartedButton.setOnAction(e -> onPaymentStarted());
|
||||||
|
statusProgressIndicator = tuple3.second;
|
||||||
|
statusLabel = tuple3.third;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Warning
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getWarningText() {
|
||||||
|
setWarningState();
|
||||||
|
return "You still have not done your " + model.getCurrencyCode() + " payment!\n" +
|
||||||
|
"Please not that the trade has to be completed until " +
|
||||||
|
model.getOpenDisputeTimeAsFormattedDate() +
|
||||||
|
" otherwise the trade will be investigated by the arbitrator.";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Dispute
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getOpenForDisputeText() {
|
||||||
|
return "You have not completed your payment!\n" +
|
||||||
"The max. period for the trade has elapsed (" +
|
"The max. period for the trade has elapsed (" +
|
||||||
model.getDateFromBlocks(openDisputeTimeInBlocks) + ")." +
|
model.getOpenDisputeTimeAsFormattedDate() + ")." +
|
||||||
"\nPlease contact now the arbitrator for opening a dispute.");
|
"\nPlease contact now the arbitrator for opening a dispute.";
|
||||||
|
|
||||||
addOpenDisputeButton();
|
|
||||||
GridPane.setMargin(openDisputeButton, new Insets(0, 0, 0, 0));
|
|
||||||
GridPane.setColumnIndex(openDisputeButton, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void disputeInProgress() {
|
protected void applyOnDisputeOpened() {
|
||||||
super.disputeInProgress();
|
|
||||||
|
|
||||||
paymentStartedButton.setDisable(true);
|
paymentStartedButton.setDisable(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void addDisputeInfoLabel() {
|
|
||||||
if (infoLabel == null) {
|
|
||||||
// we replace tx id field as there is not enough space
|
|
||||||
gridPane.getChildren().removeAll(txConfirmationGroup, txIdTextField);
|
|
||||||
|
|
||||||
infoTitledGroupBg = addTitledGroupBg(gridPane, 0, 1, "Information");
|
|
||||||
infoLabel = addMultilineLabel(gridPane, 0, Layout.FIRST_ROW_DISTANCE);
|
|
||||||
infoLabel.setStyle(" -fx-text-fill: -bs-error-red;");
|
|
||||||
// grid does not auto update layout correctly
|
|
||||||
infoLabel.setMinHeight(70);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// UI Handlers
|
// UI Handlers
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
private void onPaymentStarted(ActionEvent actionEvent) {
|
private void onPaymentStarted() {
|
||||||
log.debug("onPaymentStarted");
|
|
||||||
if (model.isBootstrapped()) {
|
if (model.isBootstrapped()) {
|
||||||
String key = PopupId.PAYMENT_SENT;
|
String key = PopupId.PAYMENT_SENT;
|
||||||
if (preferences.showAgain(key) && !BitsquareApp.DEV_MODE) {
|
if (preferences.showAgain(key) && !BitsquareApp.DEV_MODE) {
|
||||||
|
@ -149,7 +174,7 @@ public class StartPaymentView extends TradeStepDetailsView {
|
||||||
.dontShowAgainId(key, preferences)
|
.dontShowAgainId(key, preferences)
|
||||||
.actionButtonText("Yes I have started the payment")
|
.actionButtonText("Yes I have started the payment")
|
||||||
.closeButtonText("No")
|
.closeButtonText("No")
|
||||||
.onAction(() -> confirmPaymentStarted())
|
.onAction(this::confirmPaymentStarted)
|
||||||
.show();
|
.show();
|
||||||
} else {
|
} else {
|
||||||
confirmPaymentStarted();
|
confirmPaymentStarted();
|
||||||
|
@ -180,9 +205,9 @@ public class StartPaymentView extends TradeStepDetailsView {
|
||||||
|
|
||||||
// In case the first send failed we got the support button displayed.
|
// In case the first send failed we got the support button displayed.
|
||||||
// If it succeeds at a second try we remove the support button again.
|
// If it succeeds at a second try we remove the support button again.
|
||||||
if (openSupportTicketButton != null) {
|
if (openDisputeButton != null) {
|
||||||
gridPane.getChildren().remove(openSupportTicketButton);
|
openDisputeButton.setVisible(false);
|
||||||
openSupportTicketButton = null;
|
openDisputeButton.setManaged(false);
|
||||||
}
|
}
|
||||||
}, errorMessage -> {
|
}, errorMessage -> {
|
||||||
removeStatusProgressIndicator();
|
removeStatusProgressIndicator();
|
||||||
|
@ -198,55 +223,4 @@ public class StartPaymentView extends TradeStepDetailsView {
|
||||||
statusProgressIndicator.setManaged(false);
|
statusProgressIndicator.setManaged(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Build view
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void buildGridEntries() {
|
|
||||||
txConfirmationGroup = addTitledGroupBg(gridPane, gridRow, 1, "Blockchain confirmation");
|
|
||||||
txIdTextField = addLabelTxIdTextField(gridPane, gridRow, "Deposit transaction ID:", Layout.FIRST_ROW_DISTANCE).second;
|
|
||||||
|
|
||||||
TitledGroupBg accountTitledGroupBg = addTitledGroupBg(gridPane, ++gridRow, 1, "Payments details", Layout.GROUP_DISTANCE);
|
|
||||||
TextFieldWithCopyIcon field = addLabelTextFieldWithCopyIcon(gridPane, gridRow, "Amount to transfer:", model.getFiatAmount(),
|
|
||||||
Layout.FIRST_ROW_AND_GROUP_DISTANCE).second;
|
|
||||||
field.setCopyWithoutCurrencyPostFix(true);
|
|
||||||
PaymentAccountContractData paymentAccountContractData = model.dataModel.getSellersPaymentAccountContractData();
|
|
||||||
|
|
||||||
String paymentMethodName = paymentAccountContractData.getPaymentMethodName();
|
|
||||||
switch (paymentMethodName) {
|
|
||||||
case PaymentMethod.OK_PAY_ID:
|
|
||||||
gridRow = OKPayForm.addFormForBuyer(gridPane, gridRow, paymentAccountContractData);
|
|
||||||
break;
|
|
||||||
case PaymentMethod.PERFECT_MONEY_ID:
|
|
||||||
gridRow = PerfectMoneyForm.addFormForBuyer(gridPane, gridRow, paymentAccountContractData);
|
|
||||||
break;
|
|
||||||
case PaymentMethod.SEPA_ID:
|
|
||||||
gridRow = SepaForm.addFormForBuyer(gridPane, gridRow, paymentAccountContractData);
|
|
||||||
break;
|
|
||||||
case PaymentMethod.SWISH_ID:
|
|
||||||
gridRow = SwishForm.addFormForBuyer(gridPane, gridRow, paymentAccountContractData);
|
|
||||||
break;
|
|
||||||
case PaymentMethod.ALI_PAY_ID:
|
|
||||||
gridRow = AliPayForm.addFormForBuyer(gridPane, gridRow, paymentAccountContractData);
|
|
||||||
break;
|
|
||||||
case PaymentMethod.BLOCK_CHAINS_ID:
|
|
||||||
gridRow = BlockChainForm.addFormForBuyer(gridPane, gridRow, paymentAccountContractData);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
log.error("Not supported PaymentMethod: " + paymentMethodName);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
addLabelTextFieldWithCopyIcon(gridPane, ++gridRow, "Reference:", model.getReference());
|
|
||||||
|
|
||||||
Tuple3<Button, ProgressIndicator, Label> tuple3 = addButtonWithStatus(gridPane, ++gridRow, "Payment started");
|
|
||||||
paymentStartedButton = tuple3.first;
|
|
||||||
paymentStartedButton.setOnAction(this::onPaymentStarted);
|
|
||||||
statusProgressIndicator = tuple3.second;
|
|
||||||
statusLabel = tuple3.third;
|
|
||||||
|
|
||||||
GridPane.setRowSpan(accountTitledGroupBg, gridRow - 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -0,0 +1,87 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.gui.main.portfolio.pendingtrades.steps.buyer;
|
||||||
|
|
||||||
|
import io.bitsquare.gui.main.portfolio.pendingtrades.PendingTradesViewModel;
|
||||||
|
import io.bitsquare.gui.main.portfolio.pendingtrades.steps.TradeStepView;
|
||||||
|
import io.bitsquare.locale.BSResources;
|
||||||
|
|
||||||
|
public class BuyerStep3View extends TradeStepView {
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Constructor, Initialisation
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public BuyerStep3View(PendingTradesViewModel model) {
|
||||||
|
super(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Info
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getInfoBlockTitle() {
|
||||||
|
return "Wait for seller's payment confirmation";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getInfoText() {
|
||||||
|
return BSResources.get("Waiting for the bitcoin seller's confirmation " +
|
||||||
|
"for the receipt of the {0} payment.",
|
||||||
|
model.getCurrencyCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Warning
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getWarningText() {
|
||||||
|
setInformationState();
|
||||||
|
String substitute = model.isBlockChainMethod() ?
|
||||||
|
"on the " + model.getCurrencyCode() + "blockchain" :
|
||||||
|
"at your payment provider (e.g. bank)";
|
||||||
|
return "The seller still has not confirmed your payment!\n" +
|
||||||
|
"Please check " + substitute + " if the payment sending was successful.\n" +
|
||||||
|
"If the seller does not confirm the receipt of your payment until " +
|
||||||
|
model.getOpenDisputeTimeAsFormattedDate() +
|
||||||
|
" the trade will be investigated by the arbitrator.";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Dispute
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getOpenForDisputeText() {
|
||||||
|
return "The seller has not confirmed your payment!\n" +
|
||||||
|
"The max. period for the trade has elapsed (" +
|
||||||
|
model.getOpenDisputeTimeAsFormattedDate() +
|
||||||
|
") and you need to contact now the arbitrator to investigate the problem.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void applyOnDisputeOpened() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,148 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.gui.main.portfolio.pendingtrades.steps.buyer;
|
||||||
|
|
||||||
|
import io.bitsquare.gui.main.portfolio.pendingtrades.PendingTradesViewModel;
|
||||||
|
import io.bitsquare.gui.main.portfolio.pendingtrades.steps.TradeStepView;
|
||||||
|
import io.bitsquare.gui.util.Layout;
|
||||||
|
import javafx.scene.control.TextField;
|
||||||
|
import javafx.scene.layout.GridPane;
|
||||||
|
import org.bitcoinj.core.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static io.bitsquare.gui.util.FormBuilder.addLabelTextField;
|
||||||
|
|
||||||
|
public class BuyerStep4View extends TradeStepView {
|
||||||
|
|
||||||
|
private TextField blockTextField;
|
||||||
|
private TextField timeTextField;
|
||||||
|
private final BlockChainListener blockChainListener;
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Constructor, Initialisation
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public BuyerStep4View(PendingTradesViewModel model) {
|
||||||
|
super(model);
|
||||||
|
|
||||||
|
blockChainListener = new BlockChainListener() {
|
||||||
|
@Override
|
||||||
|
public void notifyNewBestBlock(StoredBlock block) throws VerificationException {
|
||||||
|
updateDateFromBlockHeight(block.getHeight());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reorganize(StoredBlock splitPoint, List<StoredBlock> oldBlocks, List<StoredBlock> newBlocks) throws VerificationException {
|
||||||
|
updateDateFromBlockHeight(model.getBestChainHeight());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isTransactionRelevant(Transaction tx) throws ScriptException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void receiveFromBlock(Transaction tx, StoredBlock block, AbstractBlockChain.NewBlockType blockType, int relativityOffset) throws
|
||||||
|
VerificationException {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean notifyTransactionIsInBlock(Sha256Hash txHash, StoredBlock block, AbstractBlockChain.NewBlockType blockType, int relativityOffset)
|
||||||
|
throws VerificationException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doActivate() {
|
||||||
|
super.doActivate();
|
||||||
|
|
||||||
|
model.addBlockChainListener(blockChainListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doDeactivate() {
|
||||||
|
super.doDeactivate();
|
||||||
|
|
||||||
|
model.removeBlockChainListener(blockChainListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Content
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void addContent() {
|
||||||
|
addTradeInfoBlock();
|
||||||
|
blockTextField = addLabelTextField(gridPane, gridRow, "Block(s) to wait until lock time elapsed:", "", Layout.FIRST_ROW_DISTANCE).second;
|
||||||
|
timeTextField = addLabelTextField(gridPane, ++gridRow, "Approx. date when payout gets unlocked:").second;
|
||||||
|
GridPane.setRowSpan(tradeInfoTitledGroupBg, 4);
|
||||||
|
|
||||||
|
addInfoBlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Info
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getInfoBlockTitle() {
|
||||||
|
return "Wait until payout lock time is over";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getInfoText() {
|
||||||
|
return "The payout transaction is signed and finalized by both parties.\n" +
|
||||||
|
"For reducing bank chargeback risks the payout transaction is blocked by a lock time.\n" +
|
||||||
|
"After that lock time is over the payout transaction gets published and you receive " +
|
||||||
|
"your bitcoin.";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Warning
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getWarningText() {
|
||||||
|
setInformationState();
|
||||||
|
return "The payout transaction is still blocked by the lock time!\n" +
|
||||||
|
"If the trade has not been completed on " +
|
||||||
|
model.getOpenDisputeTimeAsFormattedDate() +
|
||||||
|
" the arbitrator will investigate.";
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Private
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
private void updateDateFromBlockHeight(long bestBlocKHeight) {
|
||||||
|
long missingBlocks = model.getLockTime() - bestBlocKHeight;
|
||||||
|
blockTextField.setText(String.valueOf(missingBlocks));
|
||||||
|
timeTextField.setText(model.getOpenDisputeTimeAsFormattedDate());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,13 +15,14 @@
|
||||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.bitsquare.gui.main.portfolio.pendingtrades.steps;
|
package io.bitsquare.gui.main.portfolio.pendingtrades.steps.buyer;
|
||||||
|
|
||||||
import io.bitsquare.app.BitsquareApp;
|
import io.bitsquare.app.BitsquareApp;
|
||||||
import io.bitsquare.common.UserThread;
|
import io.bitsquare.common.UserThread;
|
||||||
import io.bitsquare.common.util.Tuple2;
|
import io.bitsquare.common.util.Tuple2;
|
||||||
import io.bitsquare.gui.components.InputTextField;
|
import io.bitsquare.gui.components.InputTextField;
|
||||||
import io.bitsquare.gui.main.portfolio.pendingtrades.PendingTradesViewModel;
|
import io.bitsquare.gui.main.portfolio.pendingtrades.PendingTradesViewModel;
|
||||||
|
import io.bitsquare.gui.main.portfolio.pendingtrades.steps.TradeStepView;
|
||||||
import io.bitsquare.gui.util.Layout;
|
import io.bitsquare.gui.util.Layout;
|
||||||
import javafx.beans.value.ChangeListener;
|
import javafx.beans.value.ChangeListener;
|
||||||
import javafx.scene.control.Button;
|
import javafx.scene.control.Button;
|
||||||
|
@ -30,7 +31,7 @@ import javafx.scene.control.TextField;
|
||||||
|
|
||||||
import static io.bitsquare.gui.util.FormBuilder.*;
|
import static io.bitsquare.gui.util.FormBuilder.*;
|
||||||
|
|
||||||
public class CompletedView extends TradeStepDetailsView {
|
public class BuyerStep5View extends TradeStepView {
|
||||||
private final ChangeListener<Boolean> focusedPropertyListener;
|
private final ChangeListener<Boolean> focusedPropertyListener;
|
||||||
|
|
||||||
private Label btcTradeAmountLabel;
|
private Label btcTradeAmountLabel;
|
||||||
|
@ -48,7 +49,7 @@ public class CompletedView extends TradeStepDetailsView {
|
||||||
// Constructor, Initialisation
|
// Constructor, Initialisation
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
public CompletedView(PendingTradesViewModel model) {
|
public BuyerStep5View(PendingTradesViewModel model) {
|
||||||
super(model);
|
super(model);
|
||||||
|
|
||||||
focusedPropertyListener = (ov, oldValue, newValue) -> {
|
focusedPropertyListener = (ov, oldValue, newValue) -> {
|
||||||
|
@ -87,12 +88,12 @@ public class CompletedView extends TradeStepDetailsView {
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Build view
|
// Content
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void buildGridEntries() {
|
protected void addContent() {
|
||||||
addTitledGroupBg(gridPane, gridRow, 4, "Summary", 0);
|
addTitledGroupBg(gridPane, gridRow, 4, "Summary of completed trade ", 0);
|
||||||
Tuple2<Label, TextField> btcTradeAmountPair = addLabelTextField(gridPane, gridRow, "You have bought:", "", Layout.FIRST_ROW_DISTANCE);
|
Tuple2<Label, TextField> btcTradeAmountPair = addLabelTextField(gridPane, gridRow, "You have bought:", "", Layout.FIRST_ROW_DISTANCE);
|
||||||
btcTradeAmountLabel = btcTradeAmountPair.first;
|
btcTradeAmountLabel = btcTradeAmountPair.first;
|
||||||
btcTradeAmountTextField = btcTradeAmountPair.second;
|
btcTradeAmountTextField = btcTradeAmountPair.second;
|
||||||
|
@ -120,6 +121,21 @@ public class CompletedView extends TradeStepDetailsView {
|
||||||
withdrawAddressTextField.setText("mxAkWWaQBqwqcYstKzqLku3kzR6pbu2zHq");
|
withdrawAddressTextField.setText("mxAkWWaQBqwqcYstKzqLku3kzR6pbu2zHq");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Warning
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getWarningText() {
|
||||||
|
setInformationState();
|
||||||
|
return "The trade took a bit longer as expected but has been completed successfully in the allowed trade period.";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Setters
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
public void setBtcTradeAmountLabelText(String text) {
|
public void setBtcTradeAmountLabelText(String text) {
|
||||||
btcTradeAmountLabel.setText(text);
|
btcTradeAmountLabel.setText(text);
|
||||||
}
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.gui.main.portfolio.pendingtrades.steps.seller;
|
||||||
|
|
||||||
|
import io.bitsquare.gui.main.portfolio.pendingtrades.PendingTradesViewModel;
|
||||||
|
import io.bitsquare.gui.main.portfolio.pendingtrades.steps.TradeStepView;
|
||||||
|
|
||||||
|
public class SellerStep1View extends TradeStepView {
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Constructor, Initialisation
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public SellerStep1View(PendingTradesViewModel model) {
|
||||||
|
super(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Info
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getInfoBlockTitle() {
|
||||||
|
return "Wait for blockchain confirmation";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getInfoText() {
|
||||||
|
return "Deposit transaction has been published.\n" +
|
||||||
|
"The bitcoin buyer need to wait for at least one blockchain confirmation before " +
|
||||||
|
"starting the payment.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.gui.main.portfolio.pendingtrades.steps.seller;
|
||||||
|
|
||||||
|
import io.bitsquare.gui.main.portfolio.pendingtrades.PendingTradesViewModel;
|
||||||
|
import io.bitsquare.gui.main.portfolio.pendingtrades.steps.TradeStepView;
|
||||||
|
import io.bitsquare.locale.BSResources;
|
||||||
|
|
||||||
|
public class SellerStep2View extends TradeStepView {
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Constructor, Initialisation
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public SellerStep2View(PendingTradesViewModel model) {
|
||||||
|
super(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Info
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getInfoBlockTitle() {
|
||||||
|
return "Wait for blockchain confirmation";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getInfoText() {
|
||||||
|
return BSResources.get(
|
||||||
|
"The deposit transaction has at least one blockchain confirmation.\n" +
|
||||||
|
"You need to wait until that the bitcoin buyer starts the {0} payment.",
|
||||||
|
model.getCurrencyCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Warning
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getWarningText() {
|
||||||
|
setInformationState();
|
||||||
|
return "The buyer still has not done the " + model.getCurrencyCode() + " payment!\n" +
|
||||||
|
"You need to wait until he starts the payment.\n" +
|
||||||
|
"If the trade has not been completed on " +
|
||||||
|
model.getOpenDisputeTimeAsFormattedDate() +
|
||||||
|
" the arbitrator will investigate.";
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Dispute
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getOpenForDisputeText() {
|
||||||
|
return "The buyer has not started his payment!\n" +
|
||||||
|
"The max. allowed period for the trade has elapsed.\n" +
|
||||||
|
"Please contact the arbitrator for opening a dispute.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void applyOnDisputeOpened() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,17 +15,15 @@
|
||||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.bitsquare.gui.main.portfolio.pendingtrades.steps;
|
package io.bitsquare.gui.main.portfolio.pendingtrades.steps.seller;
|
||||||
|
|
||||||
import io.bitsquare.app.BitsquareApp;
|
import io.bitsquare.app.BitsquareApp;
|
||||||
import io.bitsquare.gui.components.TxIdTextField;
|
|
||||||
import io.bitsquare.gui.main.portfolio.pendingtrades.PendingTradesViewModel;
|
import io.bitsquare.gui.main.portfolio.pendingtrades.PendingTradesViewModel;
|
||||||
|
import io.bitsquare.gui.main.portfolio.pendingtrades.steps.TradeStepView;
|
||||||
import io.bitsquare.gui.popups.Popup;
|
import io.bitsquare.gui.popups.Popup;
|
||||||
import io.bitsquare.gui.util.Layout;
|
import io.bitsquare.locale.BSResources;
|
||||||
import io.bitsquare.user.PopupId;
|
import io.bitsquare.user.PopupId;
|
||||||
import io.bitsquare.user.Preferences;
|
import io.bitsquare.user.Preferences;
|
||||||
import javafx.beans.value.ChangeListener;
|
|
||||||
import javafx.event.ActionEvent;
|
|
||||||
import javafx.geometry.HPos;
|
import javafx.geometry.HPos;
|
||||||
import javafx.geometry.Insets;
|
import javafx.geometry.Insets;
|
||||||
import javafx.scene.control.Button;
|
import javafx.scene.control.Button;
|
||||||
|
@ -34,12 +32,8 @@ import javafx.scene.control.ProgressIndicator;
|
||||||
import javafx.scene.layout.GridPane;
|
import javafx.scene.layout.GridPane;
|
||||||
import javafx.scene.layout.HBox;
|
import javafx.scene.layout.HBox;
|
||||||
|
|
||||||
import static io.bitsquare.gui.util.FormBuilder.*;
|
public class SellerStep3View extends TradeStepView {
|
||||||
|
|
||||||
public class ConfirmPaymentReceivedView extends TradeStepDetailsView {
|
|
||||||
private final ChangeListener<String> txIdChangeListener;
|
|
||||||
|
|
||||||
private TxIdTextField txIdTextField;
|
|
||||||
private Button confirmFiatReceivedButton;
|
private Button confirmFiatReceivedButton;
|
||||||
private Label statusLabel;
|
private Label statusLabel;
|
||||||
private ProgressIndicator statusProgressIndicator;
|
private ProgressIndicator statusProgressIndicator;
|
||||||
|
@ -49,63 +43,120 @@ public class ConfirmPaymentReceivedView extends TradeStepDetailsView {
|
||||||
// Constructor, Initialisation
|
// Constructor, Initialisation
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
public ConfirmPaymentReceivedView(PendingTradesViewModel model) {
|
public SellerStep3View(PendingTradesViewModel model) {
|
||||||
super(model);
|
super(model);
|
||||||
|
|
||||||
txIdChangeListener = (ov, oldValue, newValue) -> txIdTextField.setup(newValue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doActivate() {
|
public void doActivate() {
|
||||||
super.doActivate();
|
super.doActivate();
|
||||||
|
|
||||||
model.getTxId().addListener(txIdChangeListener);
|
|
||||||
txIdTextField.setup(model.getTxId().get());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doDeactivate() {
|
public void doDeactivate() {
|
||||||
super.doDeactivate();
|
super.doDeactivate();
|
||||||
|
|
||||||
model.getTxId().removeListener(txIdChangeListener);
|
|
||||||
txIdTextField.cleanup();
|
|
||||||
statusProgressIndicator.setProgress(0);
|
statusProgressIndicator.setProgress(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Content
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void displayRequestCheckPayment() {
|
protected void addContent() {
|
||||||
infoLabel.setStyle(" -fx-text-fill: -bs-error-red;");
|
super.addContent();
|
||||||
infoLabel.setText("You still have not confirmed the receipt of the payment!\n" +
|
|
||||||
"Please check you payment processor or bank account to see if the payment has arrived.\n" +
|
HBox hBox = new HBox();
|
||||||
|
hBox.setSpacing(10);
|
||||||
|
confirmFiatReceivedButton = new Button("Confirm payment receipt");
|
||||||
|
confirmFiatReceivedButton.setDefaultButton(true);
|
||||||
|
confirmFiatReceivedButton.setOnAction(e -> onPaymentReceived());
|
||||||
|
|
||||||
|
statusProgressIndicator = new ProgressIndicator(0);
|
||||||
|
statusProgressIndicator.setPrefHeight(24);
|
||||||
|
statusProgressIndicator.setPrefWidth(24);
|
||||||
|
statusProgressIndicator.setVisible(false);
|
||||||
|
|
||||||
|
statusLabel = new Label();
|
||||||
|
statusLabel.setPadding(new Insets(5, 0, 0, 0));
|
||||||
|
|
||||||
|
hBox.getChildren().addAll(confirmFiatReceivedButton, statusProgressIndicator, statusLabel);
|
||||||
|
GridPane.setRowIndex(hBox, ++gridRow);
|
||||||
|
GridPane.setColumnIndex(hBox, 0);
|
||||||
|
GridPane.setHalignment(hBox, HPos.LEFT);
|
||||||
|
GridPane.setMargin(hBox, new Insets(15, 0, 0, 0));
|
||||||
|
gridPane.getChildren().add(hBox);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Info
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getInfoBlockTitle() {
|
||||||
|
return "Confirm payment receipt";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getInfoText() {
|
||||||
|
if (model.isBlockChainMethod()) {
|
||||||
|
return BSResources.get("The bitcoin buyer has started the {0} payment.\n" +
|
||||||
|
"Check for blockchain confirmations at your Altcoin wallet or block explorer and " +
|
||||||
|
"confirm the payment when you have sufficient blockchain confirmations.",
|
||||||
|
model.getCurrencyCode());
|
||||||
|
} else {
|
||||||
|
return BSResources.get("The bitcoin buyer has started the {0} payment.\n" +
|
||||||
|
"Check at your payment account (e.g. bank account) and confirm when you have " +
|
||||||
|
"received the payment.",
|
||||||
|
model.getCurrencyCode());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Warning
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getWarningText() {
|
||||||
|
setWarningState();
|
||||||
|
String substitute = model.isBlockChainMethod() ?
|
||||||
|
"on the " + model.getCurrencyCode() + "blockchain" :
|
||||||
|
"at your payment provider (e.g. bank)";
|
||||||
|
return "You still have not confirmed the receipt of the payment!\n" +
|
||||||
|
"Please check " + substitute + " if you have received the payment.\n" +
|
||||||
"If you do not confirm receipt until " +
|
"If you do not confirm receipt until " +
|
||||||
model.getDateFromBlocks(openDisputeTimeInBlocks) +
|
model.getOpenDisputeTimeAsFormattedDate() +
|
||||||
" the trade will be investigated by the arbitrator.");
|
" the trade will be investigated by the arbitrator.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Dispute
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void displayOpenForDisputeForm() {
|
protected String getOpenForDisputeText() {
|
||||||
infoLabel.setStyle(" -fx-text-fill: -bs-error-red;");
|
return "You have not confirmed the receipt of the payment!\n" +
|
||||||
infoLabel.setText("You have not confirmed the receipt of the payment!\n" +
|
|
||||||
"The max. period for the trade has elapsed (" +
|
"The max. period for the trade has elapsed (" +
|
||||||
model.getDateFromBlocks(openDisputeTimeInBlocks) + ")." +
|
model.getOpenDisputeTimeAsFormattedDate() + ")." +
|
||||||
"\nPlease contact now the arbitrator for opening a dispute.");
|
"\nPlease contact now the arbitrator for opening a dispute.";
|
||||||
|
|
||||||
addOpenDisputeButton();
|
|
||||||
GridPane.setMargin(openDisputeButton, new Insets(0, 0, 0, 0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void disputeInProgress() {
|
protected void applyOnDisputeOpened() {
|
||||||
super.disputeInProgress();
|
|
||||||
|
|
||||||
confirmFiatReceivedButton.setDisable(true);
|
confirmFiatReceivedButton.setDisable(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// UI Handlers
|
// UI Handlers
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
private void onPaymentReceived(ActionEvent actionEvent) {
|
private void onPaymentReceived() {
|
||||||
log.debug("onPaymentReceived");
|
log.debug("onPaymentReceived");
|
||||||
if (model.isBootstrapped()) {
|
if (model.isBootstrapped()) {
|
||||||
Preferences preferences = model.dataModel.getPreferences();
|
Preferences preferences = model.dataModel.getPreferences();
|
||||||
|
@ -118,7 +169,7 @@ public class ConfirmPaymentReceivedView extends TradeStepDetailsView {
|
||||||
.dontShowAgainId(key, preferences)
|
.dontShowAgainId(key, preferences)
|
||||||
.actionButtonText("Yes I have received the payment")
|
.actionButtonText("Yes I have received the payment")
|
||||||
.closeButtonText("No")
|
.closeButtonText("No")
|
||||||
.onAction(() -> confirmPaymentReceived())
|
.onAction(this::confirmPaymentReceived)
|
||||||
.show();
|
.show();
|
||||||
} else {
|
} else {
|
||||||
confirmPaymentReceived();
|
confirmPaymentReceived();
|
||||||
|
@ -138,51 +189,6 @@ public class ConfirmPaymentReceivedView extends TradeStepDetailsView {
|
||||||
|
|
||||||
model.fiatPaymentReceived();
|
model.fiatPaymentReceived();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Setters
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
public void setInfoLabelText(String text) {
|
|
||||||
if (infoLabel != null)
|
|
||||||
infoLabel.setText(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Build view
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void buildGridEntries() {
|
|
||||||
addTitledGroupBg(gridPane, gridRow, 1, "Blockchain confirmation");
|
|
||||||
txIdTextField = addLabelTxIdTextField(gridPane, gridRow, "Deposit transaction ID:", Layout.FIRST_ROW_DISTANCE).second;
|
|
||||||
|
|
||||||
infoTitledGroupBg = addTitledGroupBg(gridPane, ++gridRow, 1, "Information", Layout.GROUP_DISTANCE);
|
|
||||||
infoLabel = addMultilineLabel(gridPane, gridRow, Layout.FIRST_ROW_AND_GROUP_DISTANCE);
|
|
||||||
|
|
||||||
HBox hBox = new HBox();
|
|
||||||
hBox.setSpacing(10);
|
|
||||||
confirmFiatReceivedButton = new Button("Confirm payment receipt");
|
|
||||||
confirmFiatReceivedButton.setDefaultButton(true);
|
|
||||||
confirmFiatReceivedButton.setOnAction(this::onPaymentReceived);
|
|
||||||
|
|
||||||
statusProgressIndicator = new ProgressIndicator(0);
|
|
||||||
statusProgressIndicator.setPrefHeight(24);
|
|
||||||
statusProgressIndicator.setPrefWidth(24);
|
|
||||||
statusProgressIndicator.setVisible(false);
|
|
||||||
|
|
||||||
statusLabel = new Label();
|
|
||||||
statusLabel.setPadding(new Insets(5, 0, 0, 0));
|
|
||||||
|
|
||||||
hBox.getChildren().addAll(confirmFiatReceivedButton, statusProgressIndicator, statusLabel);
|
|
||||||
GridPane.setRowIndex(hBox, ++gridRow);
|
|
||||||
GridPane.setColumnIndex(hBox, 0);
|
|
||||||
GridPane.setHalignment(hBox, HPos.LEFT);
|
|
||||||
GridPane.setMargin(hBox, new Insets(15, 0, 0, 0));
|
|
||||||
gridPane.getChildren().add(hBox);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,35 +15,20 @@
|
||||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.bitsquare.gui.main.portfolio.pendingtrades.steps;
|
package io.bitsquare.gui.main.portfolio.pendingtrades.steps.seller;
|
||||||
|
|
||||||
import io.bitsquare.gui.main.portfolio.pendingtrades.PendingTradesViewModel;
|
import io.bitsquare.gui.main.portfolio.pendingtrades.PendingTradesViewModel;
|
||||||
|
import io.bitsquare.gui.main.portfolio.pendingtrades.steps.buyer.BuyerStep4View;
|
||||||
|
|
||||||
public class WaitPaymentStartedView extends WaitTxInBlockchainView {
|
public class SellerStep4aView extends BuyerStep4View {
|
||||||
public WaitPaymentStartedView(PendingTradesViewModel model) {
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Constructor, Initialisation
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public SellerStep4aView(PendingTradesViewModel model) {
|
||||||
super(model);
|
super(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void doActivate() {
|
|
||||||
super.doActivate();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void displayRequestCheckPayment() {
|
|
||||||
// does not make sense to warn here
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void displayOpenForDisputeForm() {
|
|
||||||
addDisputeInfoLabel();
|
|
||||||
infoLabel.setText("The buyer has not started his payment!\n" +
|
|
||||||
"The max. period for the trade has elapsed (" +
|
|
||||||
model.getDateFromBlocks(openDisputeTimeInBlocks) + ")." +
|
|
||||||
"\nPlease contact the arbitrator for opening a dispute.");
|
|
||||||
|
|
||||||
addOpenDisputeButton();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.gui.main.portfolio.pendingtrades.steps.seller;
|
||||||
|
|
||||||
|
import io.bitsquare.gui.main.portfolio.pendingtrades.PendingTradesViewModel;
|
||||||
|
import io.bitsquare.gui.main.portfolio.pendingtrades.steps.TradeStepView;
|
||||||
|
|
||||||
|
public class SellerStep4bView extends TradeStepView {
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Constructor, Initialisation
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public SellerStep4bView(PendingTradesViewModel model) {
|
||||||
|
super(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Info
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getInfoBlockTitle() {
|
||||||
|
return "Wait until peer finalizes the payout transaction";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getInfoText() {
|
||||||
|
return "We requested from the trading peer to sign and finalize the payout transaction.\n" +
|
||||||
|
"It might be that the other peer is offline, so we need to wait until he finalize the " +
|
||||||
|
"transaction when he goes online again.";
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Warning
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getWarningText() {
|
||||||
|
setInformationState();
|
||||||
|
return "The trading peer has not finalized the payout transaction!\n" +
|
||||||
|
"He might be offline. You need to wait until he finalizes the payout transaction.\n" +
|
||||||
|
"If the trade has not been completed on " +
|
||||||
|
model.getOpenDisputeTimeAsFormattedDate() +
|
||||||
|
" the arbitrator will investigate.";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Dispute
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getOpenForDisputeText() {
|
||||||
|
return "The trading peer has not finalized the payout transaction!\n" +
|
||||||
|
"The max. period for the trade has elapsed (" +
|
||||||
|
model.getOpenDisputeTimeAsFormattedDate() + ").\n" +
|
||||||
|
"Please contact now the arbitrator for opening a dispute.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void applyOnDisputeOpened() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.gui.main.portfolio.pendingtrades.steps.seller;
|
||||||
|
|
||||||
|
import io.bitsquare.gui.main.portfolio.pendingtrades.PendingTradesViewModel;
|
||||||
|
import io.bitsquare.gui.main.portfolio.pendingtrades.steps.buyer.BuyerStep5View;
|
||||||
|
|
||||||
|
public class SellerStep5View extends BuyerStep5View {
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Constructor, Initialisation
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public SellerStep5View(PendingTradesViewModel model) {
|
||||||
|
super(model);
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,6 +23,11 @@ public abstract class TorNode<M extends OnionProxyManager, C extends OnionProxyC
|
||||||
private static final Logger log = LoggerFactory.getLogger(TorNode.class);
|
private static final Logger log = LoggerFactory.getLogger(TorNode.class);
|
||||||
|
|
||||||
private final OnionProxyManager tor;
|
private final OnionProxyManager tor;
|
||||||
|
|
||||||
|
public Socks5Proxy getProxy() {
|
||||||
|
return proxy;
|
||||||
|
}
|
||||||
|
|
||||||
private final Socks5Proxy proxy;
|
private final Socks5Proxy proxy;
|
||||||
|
|
||||||
public TorNode(M mgr) throws IOException {
|
public TorNode(M mgr) throws IOException {
|
||||||
|
|
|
@ -26,6 +26,10 @@
|
||||||
<root level="TRACE">
|
<root level="TRACE">
|
||||||
<appender-ref ref="CONSOLE_APPENDER"/>
|
<appender-ref ref="CONSOLE_APPENDER"/>
|
||||||
</root>
|
</root>
|
||||||
|
|
||||||
|
<logger name="io.bitsquare.storage.Storage" level="WARN"/>
|
||||||
|
<logger name="io.bitsquare.storage.FileManager" level="WARN"/>
|
||||||
|
|
||||||
<!-- <logger name="io.bitsquare.p2p.peers.PeerGroup" level="INFO"/>
|
<!-- <logger name="io.bitsquare.p2p.peers.PeerGroup" level="INFO"/>
|
||||||
<logger name="io.bitsquare.p2p.P2PService" level="INFO"/>
|
<logger name="io.bitsquare.p2p.P2PService" level="INFO"/>
|
||||||
<logger name="io.bitsquare.p2p.storage.ProtectedExpirableDataStorage" level="INFO"/>
|
<logger name="io.bitsquare.p2p.storage.ProtectedExpirableDataStorage" level="INFO"/>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue