mirror of
https://github.com/bisq-network/bisq.git
synced 2025-03-13 11:09:10 +01:00
Update to new trade process UI
This commit is contained in:
parent
a650aef811
commit
f80758ca34
81 changed files with 2785 additions and 1418 deletions
|
@ -128,6 +128,9 @@ public class BitSquare extends Application {
|
|||
primaryStage.setMinWidth(750);
|
||||
primaryStage.setMinHeight(500);
|
||||
|
||||
Profiler.initScene(primaryStage.getScene());
|
||||
|
||||
|
||||
primaryStage.show();
|
||||
} catch (IOException e) {
|
||||
log.error(e.getMessage());
|
||||
|
|
|
@ -63,7 +63,7 @@ public class FeePolicy {
|
|||
try {
|
||||
return new Address(params, registrationFeeAddress);
|
||||
} catch (AddressFormatException e) {
|
||||
e.printStackTrace();
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}*/
|
||||
|
|
|
@ -18,8 +18,9 @@
|
|||
package io.bitsquare.btc;
|
||||
|
||||
import io.bitsquare.BitSquare;
|
||||
import io.bitsquare.btc.listeners.AddressConfidenceListener;
|
||||
import io.bitsquare.btc.listeners.BalanceListener;
|
||||
import io.bitsquare.btc.listeners.ConfidenceListener;
|
||||
import io.bitsquare.btc.listeners.TxConfidenceListener;
|
||||
import io.bitsquare.crypto.CryptoFacade;
|
||||
import io.bitsquare.persistence.Persistence;
|
||||
|
||||
|
@ -104,7 +105,8 @@ public class WalletFacade {
|
|||
private final CryptoFacade cryptoFacade;
|
||||
private final Persistence persistence;
|
||||
private final List<DownloadListener> downloadListeners = new ArrayList<>();
|
||||
private final List<ConfidenceListener> confidenceListeners = new ArrayList<>();
|
||||
private final List<AddressConfidenceListener> addressConfidenceListeners = new ArrayList<>();
|
||||
private final List<TxConfidenceListener> txConfidenceListeners = new ArrayList<>();
|
||||
private final List<BalanceListener> balanceListeners = new ArrayList<>();
|
||||
private Wallet wallet;
|
||||
private WalletEventListener walletEventListener;
|
||||
|
@ -268,13 +270,22 @@ public class WalletFacade {
|
|||
downloadListeners.remove(listener);
|
||||
}
|
||||
|
||||
public ConfidenceListener addConfidenceListener(ConfidenceListener listener) {
|
||||
confidenceListeners.add(listener);
|
||||
public AddressConfidenceListener addAddressConfidenceListener(AddressConfidenceListener listener) {
|
||||
addressConfidenceListeners.add(listener);
|
||||
return listener;
|
||||
}
|
||||
|
||||
public void removeConfidenceListener(ConfidenceListener listener) {
|
||||
confidenceListeners.remove(listener);
|
||||
public void removeAddressConfidenceListener(AddressConfidenceListener listener) {
|
||||
addressConfidenceListeners.remove(listener);
|
||||
}
|
||||
|
||||
public TxConfidenceListener addTxConfidenceListener(TxConfidenceListener listener) {
|
||||
txConfidenceListeners.add(listener);
|
||||
return listener;
|
||||
}
|
||||
|
||||
public void removeTxConfidenceListener(TxConfidenceListener listener) {
|
||||
txConfidenceListeners.remove(listener);
|
||||
}
|
||||
|
||||
public BalanceListener addBalanceListener(BalanceListener listener) {
|
||||
|
@ -354,16 +365,31 @@ public class WalletFacade {
|
|||
return getMostRecentConfidence(transactionConfidenceList);
|
||||
}
|
||||
|
||||
private void notifyConfidenceListeners(Transaction tx) {
|
||||
for (ConfidenceListener confidenceListener : confidenceListeners) {
|
||||
List<TransactionConfidence> transactionConfidenceList = new ArrayList<>();
|
||||
transactionConfidenceList.add(getTransactionConfidence(tx, confidenceListener.getAddress()));
|
||||
|
||||
TransactionConfidence transactionConfidence = getMostRecentConfidence(transactionConfidenceList);
|
||||
confidenceListener.onTransactionConfidenceChanged(transactionConfidence);
|
||||
public TransactionConfidence getConfidenceForTxId(String txId) {
|
||||
if (wallet != null) {
|
||||
Set<Transaction> transactions = wallet.getTransactions(true);
|
||||
for (Transaction tx : transactions) {
|
||||
if (tx.getHashAsString().equals(txId))
|
||||
return tx.getConfidence();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void notifyConfidenceListeners(Transaction tx) {
|
||||
for (AddressConfidenceListener addressConfidenceListener : addressConfidenceListeners) {
|
||||
List<TransactionConfidence> transactionConfidenceList = new ArrayList<>();
|
||||
transactionConfidenceList.add(getTransactionConfidence(tx, addressConfidenceListener.getAddress()));
|
||||
|
||||
TransactionConfidence transactionConfidence = getMostRecentConfidence(transactionConfidenceList);
|
||||
addressConfidenceListener.onTransactionConfidenceChanged(transactionConfidence);
|
||||
}
|
||||
|
||||
for (TxConfidenceListener txConfidenceListener : txConfidenceListeners) {
|
||||
if (tx.getHashAsString().equals(txConfidenceListener.getTxID()))
|
||||
txConfidenceListener.onTransactionConfidenceChanged(tx.getConfidence());
|
||||
}
|
||||
}
|
||||
|
||||
private TransactionConfidence getTransactionConfidence(Transaction tx, Address address) {
|
||||
List<TransactionOutput> mergedOutputs = getOutputsWithConnectedOutputs(tx);
|
||||
|
@ -924,7 +950,7 @@ public class WalletFacade {
|
|||
}
|
||||
|
||||
// 4 step deposit tx: Offerer send deposit tx to taker
|
||||
public String takerCommitDepositTx(String depositTxAsHex) {
|
||||
public Transaction takerCommitDepositTx(String depositTxAsHex) {
|
||||
log.trace("takerCommitDepositTx");
|
||||
log.trace("inputs: ");
|
||||
log.trace("depositTxID=" + depositTxAsHex);
|
||||
|
@ -941,7 +967,7 @@ public class WalletFacade {
|
|||
throw new RuntimeException(e); // Cannot happen, we already called multisigContract.verify()
|
||||
}
|
||||
|
||||
return depositTx.getHashAsString();
|
||||
return depositTx;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -20,10 +20,10 @@ package io.bitsquare.btc.listeners;
|
|||
import com.google.bitcoin.core.Address;
|
||||
import com.google.bitcoin.core.TransactionConfidence;
|
||||
|
||||
public class ConfidenceListener {
|
||||
public class AddressConfidenceListener {
|
||||
private final Address address;
|
||||
|
||||
public ConfidenceListener(Address address) {
|
||||
public AddressConfidenceListener(Address address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* 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.btc.listeners;
|
||||
|
||||
import com.google.bitcoin.core.TransactionConfidence;
|
||||
|
||||
public class TxConfidenceListener {
|
||||
private final String txID;
|
||||
|
||||
public TxConfidenceListener(String txID) {
|
||||
this.txID = txID;
|
||||
}
|
||||
|
||||
public String getTxID() {
|
||||
return txID;
|
||||
}
|
||||
|
||||
public void onTransactionConfidenceChanged(TransactionConfidence confidence) {
|
||||
}
|
||||
}
|
|
@ -178,9 +178,9 @@ public class Navigation {
|
|||
TAKE_OFFER("/io/bitsquare/gui/main/trade/takeoffer/TakeOfferView.fxml"),
|
||||
|
||||
// orders
|
||||
OFFER("/io/bitsquare/gui/main/orders/offer/OfferView.fxml"),
|
||||
PENDING_TRADE("/io/bitsquare/gui/main/orders/pending/PendingTradeView.fxml"),
|
||||
CLOSED_TRADE("/io/bitsquare/gui/main/orders/closed/ClosedTradeView.fxml"),
|
||||
OFFERS("/io/bitsquare/gui/main/orders/offer/OffersView.fxml"),
|
||||
PENDING_TRADES("/io/bitsquare/gui/main/orders/pending/PendingTradesView.fxml"),
|
||||
CLOSED_TRADES("/io/bitsquare/gui/main/orders/closed/ClosedTradesView.fxml"),
|
||||
|
||||
// funds
|
||||
DEPOSIT("/io/bitsquare/gui/main/funds/deposit/DepositView.fxml"),
|
||||
|
|
|
@ -29,13 +29,6 @@ lower gradient color on tab: dddddd
|
|||
-fx-focus-color: -fx-accent;
|
||||
-fx-faint-focus-color: #0f87c322;
|
||||
-fx-selection-bar: derive(-fx-accent,50%);
|
||||
|
||||
/*-fx-hover-base: ladder(
|
||||
-fx-base,
|
||||
derive(-fx-base,20%) 20%,
|
||||
derive(-fx-base,30%) 35%,
|
||||
derive(-fx-base,40%) 50%
|
||||
);*/
|
||||
}
|
||||
|
||||
/* Splash */
|
||||
|
@ -144,9 +137,9 @@ lower gradient color on tab: dddddd
|
|||
******************************************************************************/
|
||||
|
||||
.tooltip {
|
||||
-fx-background: rgba(30,30,30);
|
||||
-fx-background: white;
|
||||
-fx-text-fill: black;
|
||||
-fx-background-color: rgba(100,100,100,0.8);
|
||||
-fx-background-color: white;
|
||||
-fx-background-radius: 6px;
|
||||
-fx-background-insets: 0;
|
||||
-fx-padding: 0.667em 0.75em 0.667em 0.75em; /* 10px */
|
||||
|
|
|
@ -15,10 +15,9 @@
|
|||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.gui.components.btc;
|
||||
package io.bitsquare.gui.components;
|
||||
|
||||
import io.bitsquare.gui.OverlayManager;
|
||||
import io.bitsquare.gui.components.Popups;
|
||||
|
||||
import com.google.bitcoin.core.Coin;
|
||||
import com.google.bitcoin.uri.BitcoinURI;
|
||||
|
@ -77,14 +76,13 @@ public class AddressTextField extends AnchorPane {
|
|||
Desktop.getDesktop().browse(URI.create(getBitcoinURI()));
|
||||
} catch (IOException e) {
|
||||
log.warn(e.getMessage());
|
||||
Popups.openWarningPopup("Information", "Opening a system Bitcoin wallet application has failed. " +
|
||||
Popups.openWarningPopup("Warning", "Opening a system Bitcoin wallet application has failed. " +
|
||||
"Perhaps you don't have one installed?");
|
||||
}
|
||||
});
|
||||
addressLabel.focusTraversableProperty().set(focusTraversableProperty().get());
|
||||
focusedProperty().addListener((ov, oldValue, newValue) -> {
|
||||
addressLabel.requestFocus();
|
||||
log.debug("foc");
|
||||
});
|
||||
|
||||
Label copyIcon = new Label();
|
|
@ -15,11 +15,11 @@
|
|||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.gui.components.btc;
|
||||
package io.bitsquare.gui.components;
|
||||
|
||||
import io.bitsquare.btc.WalletFacade;
|
||||
import io.bitsquare.btc.listeners.AddressConfidenceListener;
|
||||
import io.bitsquare.btc.listeners.BalanceListener;
|
||||
import io.bitsquare.btc.listeners.ConfidenceListener;
|
||||
import io.bitsquare.gui.components.confidence.ConfidenceProgressIndicator;
|
||||
import io.bitsquare.gui.util.BSFormatter;
|
||||
|
||||
|
@ -74,7 +74,7 @@ public class BalanceTextField extends AnchorPane {
|
|||
}
|
||||
|
||||
public void setup(WalletFacade walletFacade, Address address) {
|
||||
walletFacade.addConfidenceListener(new ConfidenceListener(address) {
|
||||
walletFacade.addAddressConfidenceListener(new AddressConfidenceListener(address) {
|
||||
@Override
|
||||
public void onTransactionConfidenceChanged(TransactionConfidence confidence) {
|
||||
updateConfidence(confidence);
|
|
@ -134,12 +134,13 @@ public class InfoDisplay extends Parent {
|
|||
});
|
||||
|
||||
sceneProperty().addListener((ov, oldValue, newValue) -> {
|
||||
if (oldValue == null && newValue != null) {
|
||||
if (oldValue == null && newValue != null && newValue.getWindow() != null) {
|
||||
newValue.getWindow().widthProperty().addListener(listener);
|
||||
// localToScene does deliver 0 instead of the correct x position when scene propery gets set,
|
||||
// so we delay for 1 render cycle
|
||||
Platform.runLater(() -> {
|
||||
label.setVisible(true);
|
||||
label.prefWidthProperty().unbind();
|
||||
label.setPrefWidth(newValue.getWindow().getWidth() - localToScene(0, 0).getX() - 35);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -169,6 +169,8 @@ public class Popups {
|
|||
// Support handling of uncaught exception from any thread (also non gui thread)
|
||||
public static void handleUncaughtExceptions(Throwable throwable) {
|
||||
// while dev
|
||||
log.error(throwable.getMessage());
|
||||
log.error(throwable.toString());
|
||||
throwable.printStackTrace();
|
||||
|
||||
Runnable runnable = () -> {
|
||||
|
|
|
@ -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.components;
|
||||
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.input.*;
|
||||
import javafx.scene.layout.*;
|
||||
|
||||
import de.jensd.fx.fontawesome.AwesomeDude;
|
||||
import de.jensd.fx.fontawesome.AwesomeIcon;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class TextFieldWithCopyIcon extends AnchorPane {
|
||||
private static final Logger log = LoggerFactory.getLogger(TextFieldWithCopyIcon.class);
|
||||
|
||||
private final StringProperty text = new SimpleStringProperty();
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public TextFieldWithCopyIcon() {
|
||||
Label copyIcon = new Label();
|
||||
copyIcon.setLayoutY(3);
|
||||
copyIcon.getStyleClass().add("copy-icon");
|
||||
Tooltip.install(copyIcon, new Tooltip("Copy to clipboard"));
|
||||
AwesomeDude.setIcon(copyIcon, AwesomeIcon.COPY);
|
||||
AnchorPane.setRightAnchor(copyIcon, 0.0);
|
||||
copyIcon.setOnMouseClicked(e -> {
|
||||
if (getText() != null && getText().length() > 0) {
|
||||
Clipboard clipboard = Clipboard.getSystemClipboard();
|
||||
ClipboardContent content = new ClipboardContent();
|
||||
content.putString(getText());
|
||||
clipboard.setContent(content);
|
||||
}
|
||||
});
|
||||
TextField txIdLabel = new TextField();
|
||||
txIdLabel.setEditable(false);
|
||||
txIdLabel.textProperty().bindBidirectional(text);
|
||||
AnchorPane.setRightAnchor(txIdLabel, 30.0);
|
||||
AnchorPane.setLeftAnchor(txIdLabel, 0.0);
|
||||
txIdLabel.focusTraversableProperty().set(focusTraversableProperty().get());
|
||||
focusedProperty().addListener((ov, oldValue, newValue) -> {
|
||||
txIdLabel.requestFocus();
|
||||
});
|
||||
|
||||
getChildren().addAll(txIdLabel, copyIcon);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Getter/Setter
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public String getText() {
|
||||
return text.get();
|
||||
}
|
||||
|
||||
public StringProperty textProperty() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
this.text.set(text);
|
||||
}
|
||||
|
||||
}
|
157
src/main/java/io/bitsquare/gui/components/TxIdTextField.java
Normal file
157
src/main/java/io/bitsquare/gui/components/TxIdTextField.java
Normal file
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
* 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.components;
|
||||
|
||||
import io.bitsquare.btc.WalletFacade;
|
||||
import io.bitsquare.btc.listeners.TxConfidenceListener;
|
||||
import io.bitsquare.gui.components.confidence.ConfidenceProgressIndicator;
|
||||
|
||||
import com.google.bitcoin.core.TransactionConfidence;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.input.*;
|
||||
import javafx.scene.layout.*;
|
||||
|
||||
import de.jensd.fx.fontawesome.AwesomeDude;
|
||||
import de.jensd.fx.fontawesome.AwesomeIcon;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class TxIdTextField extends AnchorPane {
|
||||
private static final Logger log = LoggerFactory.getLogger(TxIdTextField.class);
|
||||
|
||||
private final TextField txIdLabel;
|
||||
private final Tooltip progressIndicatorTooltip;
|
||||
private final ConfidenceProgressIndicator progressIndicator;
|
||||
private final Label copyIcon;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public TxIdTextField() {
|
||||
progressIndicator = new ConfidenceProgressIndicator();
|
||||
progressIndicator.setFocusTraversable(false);
|
||||
progressIndicator.setPrefSize(24, 24);
|
||||
progressIndicator.setId("funds-confidence");
|
||||
progressIndicator.setLayoutY(1);
|
||||
progressIndicator.setProgress(0);
|
||||
progressIndicator.setVisible(false);
|
||||
AnchorPane.setRightAnchor(progressIndicator, 0.0);
|
||||
progressIndicatorTooltip = new Tooltip("-");
|
||||
Tooltip.install(progressIndicator, progressIndicatorTooltip);
|
||||
|
||||
copyIcon = new Label();
|
||||
copyIcon.setLayoutY(3);
|
||||
copyIcon.getStyleClass().add("copy-icon");
|
||||
Tooltip.install(copyIcon, new Tooltip("Copy transaction ID to clipboard"));
|
||||
AwesomeDude.setIcon(copyIcon, AwesomeIcon.COPY);
|
||||
AnchorPane.setRightAnchor(copyIcon, 30.0);
|
||||
|
||||
txIdLabel = new TextField();
|
||||
txIdLabel.setId("address-text-field");
|
||||
txIdLabel.setEditable(false);
|
||||
AnchorPane.setRightAnchor(txIdLabel, 55.0);
|
||||
AnchorPane.setLeftAnchor(txIdLabel, 0.0);
|
||||
txIdLabel.focusTraversableProperty().set(focusTraversableProperty().get());
|
||||
focusedProperty().addListener((ov, oldValue, newValue) -> {
|
||||
txIdLabel.requestFocus();
|
||||
});
|
||||
|
||||
getChildren().addAll(txIdLabel, copyIcon, progressIndicator);
|
||||
}
|
||||
|
||||
public void setup(WalletFacade walletFacade, String txID) {
|
||||
txIdLabel.setText(txID);
|
||||
txIdLabel.setOnMouseClicked(mouseEvent -> {
|
||||
try {
|
||||
Desktop.getDesktop().browse(URI.create("https://blockchain.info/address/" + txID));
|
||||
} catch (IOException e) {
|
||||
log.warn(e.getMessage());
|
||||
Popups.openWarningPopup("Warning", "Opening blockchain.info failed. Please check your internet " +
|
||||
"connection.");
|
||||
}
|
||||
});
|
||||
|
||||
copyIcon.setOnMouseClicked(e -> {
|
||||
if (txID != null && txID.length() > 0) {
|
||||
Clipboard clipboard = Clipboard.getSystemClipboard();
|
||||
ClipboardContent content = new ClipboardContent();
|
||||
content.putString(txID);
|
||||
clipboard.setContent(content);
|
||||
}
|
||||
});
|
||||
|
||||
walletFacade.addTxConfidenceListener(new TxConfidenceListener(txID) {
|
||||
@Override
|
||||
public void onTransactionConfidenceChanged(TransactionConfidence confidence) {
|
||||
updateConfidence(confidence);
|
||||
}
|
||||
});
|
||||
updateConfidence(walletFacade.getConfidenceForTxId(txID));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Getters/Setters
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Private
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
private void updateConfidence(TransactionConfidence confidence) {
|
||||
if (confidence != null) {
|
||||
switch (confidence.getConfidenceType()) {
|
||||
case UNKNOWN:
|
||||
progressIndicatorTooltip.setText("Unknown transaction status");
|
||||
progressIndicator.setProgress(0);
|
||||
break;
|
||||
case PENDING:
|
||||
progressIndicatorTooltip.setText(
|
||||
"Seen by " + confidence.numBroadcastPeers() + " peer(s) / 0 " + "confirmations");
|
||||
progressIndicator.setProgress(-1.0);
|
||||
break;
|
||||
case BUILDING:
|
||||
progressIndicatorTooltip.setText("Confirmed in " + confidence.getDepthInBlocks() + " block(s)");
|
||||
progressIndicator.setProgress(Math.min(1, (double) confidence.getDepthInBlocks() / 6.0));
|
||||
break;
|
||||
case DEAD:
|
||||
progressIndicatorTooltip.setText("Transaction is invalid.");
|
||||
progressIndicator.setProgress(0);
|
||||
break;
|
||||
}
|
||||
|
||||
if (progressIndicator.getProgress() != 0) {
|
||||
progressIndicator.setVisible(true);
|
||||
AnchorPane.setRightAnchor(progressIndicator, 0.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* 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.components.processbar;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javafx.beans.property.IntegerProperty;
|
||||
import javafx.beans.property.SimpleIntegerProperty;
|
||||
import javafx.scene.control.*;
|
||||
|
||||
public class ProcessStepBar<T> extends Control {
|
||||
|
||||
private List<ProcessStepItem> processStepItems;
|
||||
private IntegerProperty selectedIndex = new SimpleIntegerProperty(0);
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public ProcessStepBar() {
|
||||
}
|
||||
|
||||
public ProcessStepBar(List<ProcessStepItem> processStepItems) {
|
||||
this.processStepItems = processStepItems;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Methods
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void next() {
|
||||
setSelectedIndex(getSelectedIndex() + 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Skin<?> createDefaultSkin() {
|
||||
return new ProcessStepBarSkin<>(this);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Setters
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void setProcessStepItems(List<ProcessStepItem> processStepItems) {
|
||||
this.processStepItems = processStepItems;
|
||||
if (getSkin() != null)
|
||||
((ProcessStepBarSkin) getSkin()).setProcessStepItems(processStepItems);
|
||||
}
|
||||
|
||||
public void setSelectedIndex(int selectedIndex) {
|
||||
this.selectedIndex.set(selectedIndex);
|
||||
if (getSkin() != null)
|
||||
((ProcessStepBarSkin) getSkin()).setSelectedIndex(selectedIndex);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Getters
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
public List<ProcessStepItem> getProcessStepItems() {
|
||||
return processStepItems;
|
||||
}
|
||||
|
||||
public int getSelectedIndex() {
|
||||
return selectedIndex.get();
|
||||
}
|
||||
|
||||
public IntegerProperty selectedIndexProperty() {
|
||||
return selectedIndex;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,235 @@
|
|||
/*
|
||||
* 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.components.processbar;
|
||||
|
||||
import io.bitsquare.gui.util.Colors;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.*;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.layout.*;
|
||||
import javafx.scene.paint.*;
|
||||
import javafx.scene.shape.*;
|
||||
|
||||
import com.sun.javafx.scene.control.behavior.BehaviorBase;
|
||||
import com.sun.javafx.scene.control.behavior.KeyBinding;
|
||||
import com.sun.javafx.scene.control.skin.BehaviorSkinBase;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
class ProcessStepBarSkin<T> extends BehaviorSkinBase<ProcessStepBar<T>, BehaviorBase<ProcessStepBar<T>>> {
|
||||
private static final Logger log = LoggerFactory.getLogger(ProcessStepBarSkin.class);
|
||||
|
||||
private final ProcessStepBar<T> controller;
|
||||
private LabelWithBorder currentLabelWithBorder;
|
||||
private LabelWithBorder prevLabelWithBorder;
|
||||
private int index;
|
||||
private final List<LabelWithBorder> labelWithBorders = new ArrayList<>();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public ProcessStepBarSkin(final ProcessStepBar<T> control) {
|
||||
super(control, new BehaviorBase<>(control, Collections.<KeyBinding>emptyList()));
|
||||
|
||||
controller = getSkinnable();
|
||||
|
||||
setProcessStepItems(controller.getProcessStepItems());
|
||||
setSelectedIndex(controller.getSelectedIndex());
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Setters
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void setProcessStepItems(List<ProcessStepItem> processStepItems) {
|
||||
if (processStepItems != null) {
|
||||
int i = 0;
|
||||
int size = controller.getProcessStepItems().size();
|
||||
for (ProcessStepItem processStepItem : controller.getProcessStepItems()) {
|
||||
|
||||
LabelWithBorder labelWithBorder = new LabelWithBorder(processStepItem, i == 0, i == size - 1);
|
||||
getChildren().add(labelWithBorder);
|
||||
labelWithBorders.add(labelWithBorder);
|
||||
if (i == 0)
|
||||
currentLabelWithBorder = prevLabelWithBorder = labelWithBorder;
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
currentLabelWithBorder.select();
|
||||
}
|
||||
}
|
||||
|
||||
public void setSelectedIndex(int index) {
|
||||
|
||||
this.index = index;
|
||||
|
||||
if (index < labelWithBorders.size()) {
|
||||
for (int i = 0; i <= index; i++) {
|
||||
|
||||
if (prevLabelWithBorder != null)
|
||||
prevLabelWithBorder.deSelect();
|
||||
|
||||
currentLabelWithBorder = labelWithBorders.get(i);
|
||||
currentLabelWithBorder.select();
|
||||
|
||||
prevLabelWithBorder = currentLabelWithBorder;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void layoutChildren(double x, double y, double width, double height) {
|
||||
double distance = 10;
|
||||
double padding = 50;
|
||||
for (int i = 0; i < getChildren().size(); i++) {
|
||||
Node node = getChildren().get(i);
|
||||
|
||||
double newWidth = snapSize(node.prefWidth(height)) + padding;
|
||||
double newHeight = snapSize(node.prefHeight(-1) + 10);
|
||||
|
||||
if (i > 0)
|
||||
x = x - ((LabelWithBorder) node).getArrowWidth();
|
||||
|
||||
node.resize(newWidth, newHeight);
|
||||
// need to add 0.5 to make it sharp
|
||||
node.relocate(x + 0.5, 0.5);
|
||||
x += newWidth + distance;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class LabelWithBorder extends Label {
|
||||
final double borderWidth = 1;
|
||||
private final double arrowWidth = 10;
|
||||
private final double arrowHeight = 30;
|
||||
|
||||
private final ProcessStepItem processStepItem;
|
||||
private final boolean isFirst;
|
||||
private final boolean isLast;
|
||||
|
||||
public LabelWithBorder(ProcessStepItem processStepItem, boolean isFirst, boolean isLast) {
|
||||
super(processStepItem.getLabel());
|
||||
|
||||
this.processStepItem = processStepItem;
|
||||
|
||||
this.isFirst = isFirst;
|
||||
this.isLast = isLast;
|
||||
|
||||
setAlignment(Pos.CENTER);
|
||||
setStyle("-fx-font-size: 14");
|
||||
|
||||
this.setShape(createButtonShape());
|
||||
|
||||
BorderStroke borderStroke = new BorderStroke(Colors.LIGHT_GREY, BorderStrokeStyle.SOLID, null,
|
||||
new BorderWidths(borderWidth, borderWidth, borderWidth, borderWidth), Insets.EMPTY);
|
||||
this.setBorder(new Border(borderStroke));
|
||||
setTextFill(Colors.LIGHT_GREY);
|
||||
}
|
||||
|
||||
public void select() {
|
||||
log.debug("select " + processStepItem.getLabel());
|
||||
BorderStroke borderStroke = new BorderStroke(Colors.BLUE, BorderStrokeStyle.SOLID, null,
|
||||
new BorderWidths(borderWidth, borderWidth, borderWidth, borderWidth), Insets.EMPTY);
|
||||
this.setBorder(new Border(borderStroke));
|
||||
setTextFill(Colors.BLUE);
|
||||
}
|
||||
|
||||
public void deSelect() {
|
||||
log.debug("deSelect " + processStepItem.getLabel());
|
||||
BorderStroke borderStroke = new BorderStroke(Colors.GREEN, BorderStrokeStyle.SOLID, null,
|
||||
new BorderWidths(borderWidth, borderWidth, borderWidth, borderWidth), Insets.EMPTY);
|
||||
this.setBorder(new Border(borderStroke));
|
||||
setTextFill(Colors.GREEN);
|
||||
}
|
||||
|
||||
public double getArrowWidth() {
|
||||
return arrowWidth;
|
||||
}
|
||||
|
||||
|
||||
private Path createButtonShape() {
|
||||
// build the following shape (or home without left arrow)
|
||||
|
||||
// --------
|
||||
// \ \
|
||||
// / /
|
||||
// --------
|
||||
Path path = new Path();
|
||||
|
||||
// begin in the upper left corner
|
||||
MoveTo e1 = new MoveTo(0, 0);
|
||||
path.getElements().add(e1);
|
||||
|
||||
// draw a horizontal line that defines the width of the shape
|
||||
HLineTo e2 = new HLineTo();
|
||||
// bind the width of the shape to the width of the button
|
||||
e2.xProperty().bind(this.widthProperty().subtract(arrowWidth));
|
||||
path.getElements().add(e2);
|
||||
|
||||
if (!isLast) {
|
||||
// draw upper part of right arrow
|
||||
LineTo e3 = new LineTo();
|
||||
// the x endpoint of this line depends on the x property of line e2
|
||||
e3.xProperty().bind(e2.xProperty().add(arrowWidth));
|
||||
e3.setY(arrowHeight / 2.0);
|
||||
path.getElements().add(e3);
|
||||
}
|
||||
|
||||
|
||||
// draw lower part of right arrow
|
||||
LineTo e4 = new LineTo();
|
||||
// the x endpoint of this line depends on the x property of line e2
|
||||
e4.xProperty().bind(e2.xProperty());
|
||||
e4.setY(arrowHeight);
|
||||
path.getElements().add(e4);
|
||||
|
||||
// draw lower horizontal line
|
||||
HLineTo e5 = new HLineTo(0);
|
||||
path.getElements().add(e5);
|
||||
|
||||
if (!isFirst) {
|
||||
LineTo e6 = new LineTo(arrowWidth, arrowHeight / 2.0);
|
||||
path.getElements().add(e6);
|
||||
}
|
||||
|
||||
// close path
|
||||
ClosePath e7 = new ClosePath();
|
||||
path.getElements().add(e7);
|
||||
// this is a dummy color to fill the shape, it won't be visible
|
||||
path.setFill(Color.BLACK);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LabelWithBorder{" +
|
||||
", processStepItem=" + processStepItem +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* 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.components.processbar;
|
||||
|
||||
public class ProcessStepItem {
|
||||
private final String label;
|
||||
|
||||
public ProcessStepItem(String label) {
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
String getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
}
|
|
@ -141,7 +141,7 @@ public class MainViewCB extends ViewCB<MainPM> {
|
|||
|
||||
return childController;
|
||||
} catch (IOException e) {
|
||||
e.getStackTrace();
|
||||
e.printStackTrace();
|
||||
log.error("Loading view failed. FxmlUrl = " + navigationItem.getFxmlUrl());
|
||||
}
|
||||
return null;
|
||||
|
@ -191,7 +191,7 @@ public class MainViewCB extends ViewCB<MainPM> {
|
|||
alertButton.setOnAction((e) ->
|
||||
navigation.navigationTo(Navigation.Item.MAIN,
|
||||
Navigation.Item.ORDERS,
|
||||
Navigation.Item.PENDING_TRADE));
|
||||
Navigation.Item.PENDING_TRADES));
|
||||
Tooltip.install(alertButton, new Tooltip("Your offer has been accepted"));
|
||||
ordersButtonButtonPane.getChildren().add(alertButton);
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ import javafx.scene.layout.*;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
class AccountViewCB extends CachedViewCB<AccountPM> {
|
||||
public class AccountViewCB extends CachedViewCB<AccountPM> {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(AccountViewCB.class);
|
||||
|
||||
|
@ -125,7 +125,7 @@ class AccountViewCB extends CachedViewCB<AccountPM> {
|
|||
|
||||
} catch (IOException e) {
|
||||
log.error("Loading view failed. FxmlUrl = " + Navigation.Item.ACCOUNT_SETUP.getFxmlUrl());
|
||||
e.getStackTrace();
|
||||
e.printStackTrace();
|
||||
}
|
||||
return childController;
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
</GridPane.margin>
|
||||
</ComboBox>
|
||||
|
||||
<Label text="Title:" GridPane.rowIndex="1"/>
|
||||
<Label text="Account name:" GridPane.rowIndex="1"/>
|
||||
<InputTextField fx:id="titleTextField" GridPane.columnIndex="1" GridPane.rowIndex="1"/>
|
||||
|
||||
<Label text="Holder name:" GridPane.rowIndex="2"/>
|
||||
|
@ -72,7 +72,7 @@
|
|||
visible="false" prefWidth="150.0"/>
|
||||
</HBox>
|
||||
|
||||
<InfoDisplay gridPane="$root" onAction="#onOpenSetupHelp" rowIndex="7"
|
||||
<InfoDisplay gridPane="$root" onAction="#onOpenSetupHelp" rowIndex="7"
|
||||
text="The payments account data will be saved in a encrypted form to the Bitcoin block chain and will be used in the trade process for account verification."/>
|
||||
|
||||
<HBox fx:id="buttonsHBox" GridPane.columnIndex="1" GridPane.rowIndex="8" spacing="10">
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
~ along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<?import io.bitsquare.gui.components.btc.AddressTextField?>
|
||||
<?import io.bitsquare.gui.components.btc.BalanceTextField?>
|
||||
<?import io.bitsquare.gui.components.AddressTextField?>
|
||||
<?import io.bitsquare.gui.components.BalanceTextField?>
|
||||
<?import io.bitsquare.gui.components.InfoDisplay?>
|
||||
<?import io.bitsquare.gui.components.TitledGroupBg?>
|
||||
<?import javafx.geometry.Insets?>
|
||||
|
|
|
@ -19,9 +19,9 @@ package io.bitsquare.gui.main.account.content.registration;
|
|||
|
||||
import io.bitsquare.gui.CachedViewCB;
|
||||
import io.bitsquare.gui.OverlayManager;
|
||||
import io.bitsquare.gui.components.AddressTextField;
|
||||
import io.bitsquare.gui.components.BalanceTextField;
|
||||
import io.bitsquare.gui.components.Popups;
|
||||
import io.bitsquare.gui.components.btc.AddressTextField;
|
||||
import io.bitsquare.gui.components.btc.BalanceTextField;
|
||||
import io.bitsquare.gui.main.account.MultiStepNavigation;
|
||||
import io.bitsquare.gui.main.account.content.ContextAware;
|
||||
import io.bitsquare.gui.main.help.Help;
|
||||
|
|
|
@ -1,68 +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.account.settings;
|
||||
|
||||
import io.bitsquare.gui.UIModel;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
class AccountSettingsModel extends UIModel {
|
||||
private static final Logger log = LoggerFactory.getLogger(AccountSettingsModel.class);
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Inject
|
||||
private AccountSettingsModel() {
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Lifecycle
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@SuppressWarnings("EmptyMethod")
|
||||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void activate() {
|
||||
super.activate();
|
||||
}
|
||||
|
||||
@SuppressWarnings("EmptyMethod")
|
||||
@Override
|
||||
public void deactivate() {
|
||||
super.deactivate();
|
||||
}
|
||||
|
||||
@SuppressWarnings("EmptyMethod")
|
||||
@Override
|
||||
public void terminate() {
|
||||
super.terminate();
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,68 +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.account.settings;
|
||||
|
||||
import io.bitsquare.gui.PresentationModel;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
class AccountSettingsPM extends PresentationModel<AccountSettingsModel> {
|
||||
private static final Logger log = LoggerFactory.getLogger(AccountSettingsPM.class);
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Inject
|
||||
private AccountSettingsPM(AccountSettingsModel model) {
|
||||
super(model);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Lifecycle
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@SuppressWarnings("EmptyMethod")
|
||||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void activate() {
|
||||
super.activate();
|
||||
}
|
||||
|
||||
@SuppressWarnings("EmptyMethod")
|
||||
@Override
|
||||
public void deactivate() {
|
||||
super.deactivate();
|
||||
}
|
||||
|
||||
@SuppressWarnings("EmptyMethod")
|
||||
@Override
|
||||
public void terminate() {
|
||||
super.terminate();
|
||||
}
|
||||
|
||||
}
|
|
@ -46,7 +46,7 @@ import de.jensd.fx.fontawesome.AwesomeIcon;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class AccountSettingsViewCB extends CachedViewCB<AccountSettingsPM> {
|
||||
public class AccountSettingsViewCB extends CachedViewCB {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(AccountSettingsViewCB.class);
|
||||
|
||||
|
@ -63,8 +63,8 @@ public class AccountSettingsViewCB extends CachedViewCB<AccountSettingsPM> {
|
|||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Inject
|
||||
private AccountSettingsViewCB(AccountSettingsPM presentationModel, Navigation navigation) {
|
||||
super(presentationModel);
|
||||
private AccountSettingsViewCB(Navigation navigation) {
|
||||
super();
|
||||
|
||||
this.navigation = navigation;
|
||||
}
|
||||
|
@ -156,7 +156,7 @@ public class AccountSettingsViewCB extends CachedViewCB<AccountSettingsPM> {
|
|||
return childController;
|
||||
} catch (IOException e) {
|
||||
log.error("Loading view failed. FxmlUrl = " + navigationItem.getFxmlUrl());
|
||||
e.getStackTrace();
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -1,67 +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.account.setup;
|
||||
|
||||
import io.bitsquare.gui.UIModel;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
class AccountSetupModel extends UIModel {
|
||||
private static final Logger log = LoggerFactory.getLogger(AccountSetupModel.class);
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Inject
|
||||
private AccountSetupModel() {
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Lifecycle
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@SuppressWarnings("EmptyMethod")
|
||||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void activate() {
|
||||
super.activate();
|
||||
}
|
||||
|
||||
@SuppressWarnings("EmptyMethod")
|
||||
@Override
|
||||
public void deactivate() {
|
||||
super.deactivate();
|
||||
}
|
||||
|
||||
@SuppressWarnings("EmptyMethod")
|
||||
@Override
|
||||
public void terminate() {
|
||||
super.terminate();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,68 +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.account.setup;
|
||||
|
||||
import io.bitsquare.gui.PresentationModel;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
class AccountSetupPM extends PresentationModel<AccountSetupModel> {
|
||||
private static final Logger log = LoggerFactory.getLogger(AccountSetupPM.class);
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Inject
|
||||
private AccountSetupPM(AccountSetupModel model) {
|
||||
super(model);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Lifecycle
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@SuppressWarnings("EmptyMethod")
|
||||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void activate() {
|
||||
super.activate();
|
||||
}
|
||||
|
||||
@SuppressWarnings("EmptyMethod")
|
||||
@Override
|
||||
public void deactivate() {
|
||||
super.deactivate();
|
||||
}
|
||||
|
||||
@SuppressWarnings("EmptyMethod")
|
||||
@Override
|
||||
public void terminate() {
|
||||
super.terminate();
|
||||
}
|
||||
|
||||
}
|
|
@ -17,7 +17,6 @@
|
|||
|
||||
package io.bitsquare.gui.main.account.setup;
|
||||
|
||||
import io.bitsquare.gui.CachedViewCB;
|
||||
import io.bitsquare.gui.Navigation;
|
||||
import io.bitsquare.gui.PresentationModel;
|
||||
import io.bitsquare.gui.ViewCB;
|
||||
|
@ -48,7 +47,10 @@ import javafx.scene.layout.*;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class AccountSetupViewCB extends CachedViewCB<AccountSetupPM> implements MultiStepNavigation {
|
||||
/**
|
||||
* This UI is not cached as it is normally only needed once.
|
||||
*/
|
||||
public class AccountSetupViewCB extends ViewCB implements MultiStepNavigation {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(AccountSetupViewCB.class);
|
||||
|
||||
|
@ -65,8 +67,8 @@ public class AccountSetupViewCB extends CachedViewCB<AccountSetupPM> implements
|
|||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Inject
|
||||
private AccountSetupViewCB(AccountSetupPM presentationModel, Navigation navigation) {
|
||||
super(presentationModel);
|
||||
private AccountSetupViewCB(Navigation navigation) {
|
||||
super();
|
||||
this.navigation = navigation;
|
||||
}
|
||||
|
||||
|
@ -102,12 +104,6 @@ public class AccountSetupViewCB extends CachedViewCB<AccountSetupPM> implements
|
|||
leftVBox.getChildren().addAll(seedWords, password, restrictions, fiatAccount, registration);
|
||||
|
||||
super.initialize(url, rb);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void activate() {
|
||||
super.activate();
|
||||
|
||||
navigation.addListener(listener);
|
||||
|
||||
|
@ -115,17 +111,10 @@ public class AccountSetupViewCB extends CachedViewCB<AccountSetupPM> implements
|
|||
childController = seedWords.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deactivate() {
|
||||
super.deactivate();
|
||||
|
||||
navigation.removeListener(listener);
|
||||
}
|
||||
|
||||
@SuppressWarnings("EmptyMethod")
|
||||
@Override
|
||||
public void terminate() {
|
||||
super.terminate();
|
||||
navigation.removeListener(listener);
|
||||
}
|
||||
|
||||
|
||||
|
@ -176,7 +165,7 @@ public class AccountSetupViewCB extends CachedViewCB<AccountSetupPM> implements
|
|||
return childController;
|
||||
} catch (IOException e) {
|
||||
log.error("Loading view failed. FxmlUrl = " + navigationItem.getFxmlUrl());
|
||||
e.getStackTrace();
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -49,6 +49,9 @@ import javafx.stage.Stage;
|
|||
import net.tomp2p.peers.Number640;
|
||||
import net.tomp2p.storage.Data;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* TODO remove tomp2p dependencies
|
||||
* import net.tomp2p.peers.Number160;
|
||||
|
@ -57,6 +60,8 @@ import net.tomp2p.storage.Data;
|
|||
* Arbitration is not much developed yet
|
||||
*/
|
||||
public class ArbitratorBrowserController extends CachedViewController implements ArbitratorListener {
|
||||
private static final Logger log = LoggerFactory.getLogger(ArbitratorBrowserController.class);
|
||||
|
||||
private final Settings settings;
|
||||
private final Persistence persistence;
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
package io.bitsquare.gui.main.funds.transactions;
|
||||
|
||||
import io.bitsquare.btc.WalletFacade;
|
||||
import io.bitsquare.btc.listeners.ConfidenceListener;
|
||||
import io.bitsquare.btc.listeners.AddressConfidenceListener;
|
||||
import io.bitsquare.gui.components.confidence.ConfidenceProgressIndicator;
|
||||
import io.bitsquare.gui.util.BSFormatter;
|
||||
|
||||
|
@ -47,7 +47,7 @@ public class TransactionsListItem {
|
|||
|
||||
private final Tooltip tooltip;
|
||||
private String addressString;
|
||||
private ConfidenceListener confidenceListener;
|
||||
private AddressConfidenceListener confidenceListener;
|
||||
|
||||
public TransactionsListItem(Transaction transaction, WalletFacade walletFacade) {
|
||||
this.walletFacade = walletFacade;
|
||||
|
@ -135,7 +135,7 @@ public class TransactionsListItem {
|
|||
Tooltip.install(progressIndicator, tooltip);
|
||||
|
||||
if (address != null) {
|
||||
confidenceListener = walletFacade.addConfidenceListener(new ConfidenceListener(address) {
|
||||
confidenceListener = walletFacade.addAddressConfidenceListener(new AddressConfidenceListener(address) {
|
||||
@Override
|
||||
public void onTransactionConfidenceChanged(TransactionConfidence confidence) {
|
||||
updateConfidence(confidence);
|
||||
|
@ -148,7 +148,7 @@ public class TransactionsListItem {
|
|||
|
||||
|
||||
public void cleanup() {
|
||||
walletFacade.removeConfidenceListener(confidenceListener);
|
||||
walletFacade.removeAddressConfidenceListener(confidenceListener);
|
||||
}
|
||||
|
||||
private void updateConfidence(TransactionConfidence confidence) {
|
||||
|
|
|
@ -19,8 +19,8 @@ package io.bitsquare.gui.main.funds.withdrawal;
|
|||
|
||||
import io.bitsquare.btc.AddressEntry;
|
||||
import io.bitsquare.btc.WalletFacade;
|
||||
import io.bitsquare.btc.listeners.AddressConfidenceListener;
|
||||
import io.bitsquare.btc.listeners.BalanceListener;
|
||||
import io.bitsquare.btc.listeners.ConfidenceListener;
|
||||
import io.bitsquare.gui.components.confidence.ConfidenceProgressIndicator;
|
||||
|
||||
import com.google.bitcoin.core.Address;
|
||||
|
@ -42,7 +42,7 @@ public class WithdrawalListItem {
|
|||
private final AddressEntry addressEntry;
|
||||
|
||||
private final WalletFacade walletFacade;
|
||||
private final ConfidenceListener confidenceListener;
|
||||
private final AddressConfidenceListener confidenceListener;
|
||||
|
||||
private final ConfidenceProgressIndicator progressIndicator;
|
||||
|
||||
|
@ -63,7 +63,7 @@ public class WithdrawalListItem {
|
|||
progressIndicator.setPrefSize(24, 24);
|
||||
Tooltip.install(progressIndicator, tooltip);
|
||||
|
||||
confidenceListener = walletFacade.addConfidenceListener(new ConfidenceListener(getAddress()) {
|
||||
confidenceListener = walletFacade.addAddressConfidenceListener(new AddressConfidenceListener(getAddress()) {
|
||||
@Override
|
||||
public void onTransactionConfidenceChanged(TransactionConfidence confidence) {
|
||||
updateConfidence(confidence);
|
||||
|
@ -86,7 +86,7 @@ public class WithdrawalListItem {
|
|||
}
|
||||
|
||||
public void cleanup() {
|
||||
walletFacade.removeConfidenceListener(confidenceListener);
|
||||
walletFacade.removeAddressConfidenceListener(confidenceListener);
|
||||
walletFacade.removeBalanceListener(balanceListener);
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,10 @@ public enum HelpId {
|
|||
TAKE_OFFER_GENERAL,
|
||||
TAKE_OFFER_FUNDING,
|
||||
TAKE_OFFER_ADVANCED,
|
||||
PENDING_TRADE_OFFERER,
|
||||
PENDING_TRADE_PAYMENT,
|
||||
PENDING_TRADE_SUMMARY,
|
||||
PENDING_TRADE_TAKER,
|
||||
SETUP_SEED_WORDS,
|
||||
SETUP_PASSWORD,
|
||||
SETUP_RESTRICTION_LANGUAGES,
|
||||
|
|
|
@ -35,9 +35,14 @@ import javafx.scene.*;
|
|||
import javafx.stage.Modality;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
// home is just hosting the arbiters buttons yet, but that's just for dev, not clear yet what will be in home,
|
||||
// probably overview, event history, news, charts,... -> low prio
|
||||
public class HomeController extends CachedViewCB {
|
||||
private static final Logger log = LoggerFactory.getLogger(HomeController.class);
|
||||
|
||||
private ArbitratorRegistrationController arbitratorRegistrationController;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -17,16 +17,15 @@
|
|||
~ along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<?import io.bitsquare.gui.components.CachingTabPane?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<CachingTabPane fx:id="root" fx:controller="io.bitsquare.gui.main.orders.OrdersController"
|
||||
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0"
|
||||
AnchorPane.topAnchor="0.0"
|
||||
xmlns:fx="http://javafx.com/fxml">
|
||||
<TabPane fx:id="root" fx:controller="io.bitsquare.gui.main.orders.OrdersViewCB"
|
||||
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0"
|
||||
AnchorPane.topAnchor="0.0"
|
||||
xmlns:fx="http://javafx.com/fxml">
|
||||
|
||||
<Tab text="Open offers" closable="false"/>
|
||||
<Tab text="Pending trades" closable="false"/>
|
||||
<Tab text="Closed trades" closable="false"/>
|
||||
<Tab fx:id="offersTab" text="Open offers" closable="false"/>
|
||||
<Tab fx:id="pendingTradesTab" text="Pending trades" closable="false"/>
|
||||
<Tab fx:id="closedTradesTab" text="Closed trades" closable="false"/>
|
||||
|
||||
</CachingTabPane>
|
||||
</TabPane>
|
||||
|
|
137
src/main/java/io/bitsquare/gui/main/orders/OrdersViewCB.java
Normal file
137
src/main/java/io/bitsquare/gui/main/orders/OrdersViewCB.java
Normal file
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
* 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.orders;
|
||||
|
||||
import io.bitsquare.gui.CachedViewCB;
|
||||
import io.bitsquare.gui.Navigation;
|
||||
import io.bitsquare.gui.ViewCB;
|
||||
import io.bitsquare.util.ViewLoader;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.layout.*;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class OrdersViewCB extends CachedViewCB {
|
||||
private static final Logger log = LoggerFactory.getLogger(OrdersViewCB.class);
|
||||
|
||||
private Navigation navigation;
|
||||
private Navigation.Listener listener;
|
||||
|
||||
@FXML Tab offersTab, pendingTradesTab, closedTradesTab;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Inject
|
||||
OrdersViewCB(Navigation navigation) {
|
||||
super();
|
||||
|
||||
this.navigation = navigation;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Lifecycle
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void initialize(URL url, ResourceBundle rb) {
|
||||
listener = navigationItems -> {
|
||||
if (navigationItems != null && navigationItems.length == 3 && navigationItems[1] == Navigation.Item.ORDERS)
|
||||
loadView(navigationItems[2]);
|
||||
};
|
||||
|
||||
super.initialize(url, rb);
|
||||
}
|
||||
|
||||
@SuppressWarnings("EmptyMethod")
|
||||
@Override
|
||||
public void activate() {
|
||||
super.activate();
|
||||
|
||||
navigation.addListener(listener);
|
||||
navigation.navigationTo(Navigation.Item.MAIN, Navigation.Item.ORDERS, Navigation.Item.PENDING_TRADES);
|
||||
}
|
||||
|
||||
@SuppressWarnings("EmptyMethod")
|
||||
@Override
|
||||
public void deactivate() {
|
||||
super.deactivate();
|
||||
|
||||
navigation.removeListener(listener);
|
||||
}
|
||||
|
||||
@SuppressWarnings("EmptyMethod")
|
||||
@Override
|
||||
public void terminate() {
|
||||
super.terminate();
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Navigation
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
protected Initializable loadView(Navigation.Item navigationItem) {
|
||||
super.loadView(navigationItem);
|
||||
|
||||
final ViewLoader loader = new ViewLoader(getClass().getResource(navigationItem.getFxmlUrl()));
|
||||
try {
|
||||
GridPane view = loader.load();
|
||||
Tab tab = null;
|
||||
switch (navigationItem) {
|
||||
case OFFERS:
|
||||
tab = offersTab;
|
||||
break;
|
||||
case PENDING_TRADES:
|
||||
tab = pendingTradesTab;
|
||||
break;
|
||||
case CLOSED_TRADES:
|
||||
tab = closedTradesTab;
|
||||
break;
|
||||
}
|
||||
tab.setContent(view);
|
||||
((TabPane) root).getSelectionModel().select(tab);
|
||||
Initializable childController = loader.getController();
|
||||
((ViewCB) childController).setParent(this);
|
||||
|
||||
} catch (IOException e) {
|
||||
log.error("Loading view failed. FxmlUrl = " + Navigation.Item.ACCOUNT_SETUP.getFxmlUrl());
|
||||
e.printStackTrace();
|
||||
}
|
||||
return childController;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,473 +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.orders.pending;
|
||||
|
||||
import io.bitsquare.bank.BankAccount;
|
||||
import io.bitsquare.bank.BankAccountType;
|
||||
import io.bitsquare.btc.FeePolicy;
|
||||
import io.bitsquare.btc.WalletFacade;
|
||||
import io.bitsquare.gui.AWTSystemTray;
|
||||
import io.bitsquare.gui.CachedViewController;
|
||||
import io.bitsquare.gui.components.ConfidenceDisplay;
|
||||
import io.bitsquare.gui.components.confidence.ConfidenceProgressIndicator;
|
||||
import io.bitsquare.gui.util.BSFormatter;
|
||||
import io.bitsquare.gui.util.ImageUtil;
|
||||
import io.bitsquare.locale.BSResources;
|
||||
import io.bitsquare.locale.Country;
|
||||
import io.bitsquare.trade.Direction;
|
||||
import io.bitsquare.trade.Offer;
|
||||
import io.bitsquare.trade.Trade;
|
||||
import io.bitsquare.trade.TradeManager;
|
||||
|
||||
import com.google.bitcoin.core.Coin;
|
||||
import com.google.bitcoin.core.ECKey;
|
||||
import com.google.bitcoin.core.Transaction;
|
||||
import com.google.bitcoin.core.Wallet;
|
||||
import com.google.bitcoin.core.WalletEventListener;
|
||||
import com.google.bitcoin.script.Script;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import javafx.beans.property.ReadOnlyObjectWrapper;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ListChangeListener;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.image.*;
|
||||
import javafx.scene.input.*;
|
||||
import javafx.scene.layout.*;
|
||||
import javafx.util.Callback;
|
||||
|
||||
import de.jensd.fx.fontawesome.AwesomeDude;
|
||||
import de.jensd.fx.fontawesome.AwesomeIcon;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class PendingTradeController extends CachedViewController {
|
||||
private static final Logger log = LoggerFactory.getLogger(PendingTradeController.class);
|
||||
|
||||
private final TradeManager tradeManager;
|
||||
private final WalletFacade walletFacade;
|
||||
|
||||
private Trade currentTrade;
|
||||
|
||||
private ConfidenceDisplay confidenceDisplay;
|
||||
|
||||
@FXML TableView openTradesTable;
|
||||
@FXML TableColumn<String, PendingTradesListItem> directionColumn, countryColumn, bankAccountTypeColumn,
|
||||
priceColumn, amountColumn, volumeColumn, statusColumn, selectColumn;
|
||||
@FXML ConfidenceProgressIndicator progressIndicator;
|
||||
@FXML Label txTitleLabel, txHeaderLabel, confirmationLabel, txIDCopyIcon, holderNameCopyIcon,
|
||||
primaryBankAccountIDCopyIcon, secondaryBankAccountIDCopyIcon, bankAccountDetailsHeaderLabel,
|
||||
bankAccountTypeTitleLabel, holderNameTitleLabel, primaryBankAccountIDTitleLabel,
|
||||
secondaryBankAccountIDTitleLabel;
|
||||
@FXML TextField txTextField, bankAccountTypeTextField, holderNameTextField, primaryBankAccountIDTextField,
|
||||
secondaryBankAccountIDTextField;
|
||||
@FXML Button bankTransferInitedButton;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Inject
|
||||
public PendingTradeController(TradeManager tradeManager, WalletFacade walletFacade) {
|
||||
this.tradeManager = tradeManager;
|
||||
this.walletFacade = walletFacade;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Lifecycle
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void initialize(URL url, ResourceBundle rb) {
|
||||
super.initialize(url, rb);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deactivate() {
|
||||
super.deactivate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void activate() {
|
||||
super.activate();
|
||||
|
||||
Map<String, Trade> trades = tradeManager.getTrades();
|
||||
List<Trade> tradeList = new ArrayList<>(trades.values());
|
||||
ObservableList<PendingTradesListItem> tradeItems = FXCollections.observableArrayList();
|
||||
for (Iterator<Trade> iterator = tradeList.iterator(); iterator.hasNext(); ) {
|
||||
Trade trade = iterator.next();
|
||||
tradeItems.add(new PendingTradesListItem(trade));
|
||||
}
|
||||
|
||||
setCountryColumnCellFactory();
|
||||
setBankAccountTypeColumnCellFactory();
|
||||
setDirectionColumnCellFactory();
|
||||
setSelectColumnCellFactory();
|
||||
|
||||
openTradesTable.setItems(tradeItems);
|
||||
openTradesTable.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
|
||||
|
||||
openTradesTable.getSelectionModel().selectedItemProperty().addListener((obsValue, oldValue, newValue) -> {
|
||||
if (newValue instanceof PendingTradesListItem) {
|
||||
showTradeDetails((PendingTradesListItem) newValue);
|
||||
}
|
||||
});
|
||||
|
||||
tradeManager.getNewTradeProperty().addListener((observableValue, oldTradeId, newTradeId) -> {
|
||||
Trade newTrade = tradeManager.getTrade(newTradeId);
|
||||
if (newTrade != null) {
|
||||
tradeItems.add(new PendingTradesListItem(newTrade));
|
||||
}
|
||||
});
|
||||
|
||||
initCopyIcons();
|
||||
|
||||
// select
|
||||
Optional<PendingTradesListItem> currentTradeItemOptional = tradeItems.stream().filter((e) ->
|
||||
tradeManager.getPendingTrade() != null &&
|
||||
e.getTrade().getId().equals(tradeManager.getPendingTrade().getId())).findFirst();
|
||||
if (currentTradeItemOptional.isPresent()) {
|
||||
openTradesTable.getSelectionModel().select(currentTradeItemOptional.get());
|
||||
}
|
||||
|
||||
tradeItems.addListener((ListChangeListener<PendingTradesListItem>) change -> {
|
||||
if (openTradesTable.getSelectionModel().getSelectedItem() == null && tradeItems.size() > 0) {
|
||||
openTradesTable.getSelectionModel().select(0);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// GUI handlers
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void bankTransferInited() {
|
||||
tradeManager.bankTransferInited(currentTrade.getId());
|
||||
bankTransferInitedButton.setDisable(true);
|
||||
}
|
||||
|
||||
public void close() {
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Private methods
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private void showTradeDetails(PendingTradesListItem tradesTableItem) {
|
||||
fillData(tradesTableItem.getTrade());
|
||||
}
|
||||
|
||||
private void updateTx(Transaction transaction) {
|
||||
txTextField.setText(transaction.getHashAsString());
|
||||
|
||||
confidenceDisplay =
|
||||
new ConfidenceDisplay(walletFacade.getWallet(), confirmationLabel, transaction, progressIndicator);
|
||||
|
||||
int depthInBlocks = transaction.getConfidence().getDepthInBlocks();
|
||||
bankTransferInitedButton.setDisable(depthInBlocks == 0);
|
||||
|
||||
walletFacade.getWallet().addEventListener(new WalletEventListener() {
|
||||
@Override
|
||||
public void onTransactionConfidenceChanged(Wallet wallet, Transaction tx) {
|
||||
int depthInBlocks = tx.getConfidence().getDepthInBlocks();
|
||||
bankTransferInitedButton.setDisable(depthInBlocks == 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCoinsSent(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReorganize(Wallet wallet) {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onWalletChanged(Wallet wallet) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScriptsAdded(Wallet wallet, List<Script> scripts) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onKeysAdded(List<ECKey> keys) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void fillData(Trade trade) {
|
||||
currentTrade = trade;
|
||||
Transaction transaction = trade.getDepositTransaction();
|
||||
if (transaction == null) {
|
||||
trade.depositTxChangedProperty().addListener((observableValue, aBoolean, aBoolean2) ->
|
||||
updateTx(trade.getDepositTransaction()));
|
||||
}
|
||||
else {
|
||||
updateTx(trade.getDepositTransaction());
|
||||
}
|
||||
|
||||
// back details
|
||||
if (trade.getContract() != null) {
|
||||
setBankData(trade);
|
||||
}
|
||||
else {
|
||||
trade.contractChangedProperty().addListener((observableValue, aBoolean, aBoolean2) -> setBankData(trade));
|
||||
}
|
||||
|
||||
// state
|
||||
trade.stateChangedProperty().addListener((observableValue, aString, aString2) -> setState(trade));
|
||||
}
|
||||
|
||||
private void setState(Trade trade) {
|
||||
if (trade.getState() == Trade.State.COMPLETED) {
|
||||
Transaction transaction = trade.getPayoutTransaction();
|
||||
|
||||
confidenceDisplay.destroy();
|
||||
confidenceDisplay =
|
||||
new ConfidenceDisplay(walletFacade.getWallet(), confirmationLabel, transaction, progressIndicator);
|
||||
|
||||
txTextField.setText(transaction.getHashAsString());
|
||||
|
||||
txHeaderLabel.setText("Payout transaction");
|
||||
txTitleLabel.setText("Payout transaction ID:");
|
||||
|
||||
bankAccountDetailsHeaderLabel.setText("Summary");
|
||||
bankAccountTypeTitleLabel.setText("You have bought:");
|
||||
holderNameTitleLabel.setText("You have payed (" + trade.getOffer().getCurrency() + "):");
|
||||
primaryBankAccountIDTitleLabel.setText("Total fees (offer fee + tx fee):");
|
||||
secondaryBankAccountIDTitleLabel.setText("Refunded collateral:");
|
||||
|
||||
bankAccountTypeTextField.setText(BSFormatter.formatCoinWithCode(trade.getTradeAmount()));
|
||||
holderNameTextField.setText(BSFormatter.formatFiat(trade.getTradeVolume()));
|
||||
primaryBankAccountIDTextField.setText(
|
||||
BSFormatter.formatCoinWithCode(FeePolicy.CREATE_OFFER_FEE.add(FeePolicy.TX_FEE)));
|
||||
secondaryBankAccountIDTextField.setText(BSFormatter.formatCoinWithCode(trade.getCollateralAmount()));
|
||||
|
||||
holderNameCopyIcon.setVisible(false);
|
||||
primaryBankAccountIDCopyIcon.setVisible(false);
|
||||
secondaryBankAccountIDCopyIcon.setVisible(false);
|
||||
|
||||
bankTransferInitedButton.setVisible(false);
|
||||
|
||||
AWTSystemTray.setIcon();
|
||||
}
|
||||
}
|
||||
|
||||
private void setBankData(Trade trade) {
|
||||
BankAccount bankAccount = trade.getContract().getTakerBankAccount();
|
||||
bankAccountTypeTextField.setText(bankAccount.getBankAccountType().toString());
|
||||
holderNameTextField.setText(bankAccount.getAccountHolderName());
|
||||
primaryBankAccountIDTextField.setText(bankAccount.getAccountPrimaryID());
|
||||
secondaryBankAccountIDTextField.setText(bankAccount.getAccountSecondaryID());
|
||||
}
|
||||
|
||||
private void initCopyIcons() {
|
||||
AwesomeDude.setIcon(txIDCopyIcon, AwesomeIcon.COPY);
|
||||
txIDCopyIcon.setOnMouseClicked(e -> {
|
||||
Clipboard clipboard = Clipboard.getSystemClipboard();
|
||||
ClipboardContent content = new ClipboardContent();
|
||||
content.putString(txTextField.getText());
|
||||
clipboard.setContent(content);
|
||||
});
|
||||
|
||||
AwesomeDude.setIcon(holderNameCopyIcon, AwesomeIcon.COPY);
|
||||
holderNameCopyIcon.setOnMouseClicked(e -> {
|
||||
Clipboard clipboard = Clipboard.getSystemClipboard();
|
||||
ClipboardContent content = new ClipboardContent();
|
||||
content.putString(holderNameTextField.getText());
|
||||
clipboard.setContent(content);
|
||||
});
|
||||
|
||||
AwesomeDude.setIcon(primaryBankAccountIDCopyIcon, AwesomeIcon.COPY);
|
||||
primaryBankAccountIDCopyIcon.setOnMouseClicked(e -> {
|
||||
Clipboard clipboard = Clipboard.getSystemClipboard();
|
||||
ClipboardContent content = new ClipboardContent();
|
||||
content.putString(primaryBankAccountIDTextField.getText());
|
||||
clipboard.setContent(content);
|
||||
});
|
||||
|
||||
AwesomeDude.setIcon(secondaryBankAccountIDCopyIcon, AwesomeIcon.COPY);
|
||||
secondaryBankAccountIDCopyIcon.setOnMouseClicked(e -> {
|
||||
Clipboard clipboard = Clipboard.getSystemClipboard();
|
||||
ClipboardContent content = new ClipboardContent();
|
||||
content.putString(secondaryBankAccountIDTextField.getText());
|
||||
clipboard.setContent(content);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Table columns
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private void setCountryColumnCellFactory() {
|
||||
countryColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper(offer.getValue()));
|
||||
countryColumn.setCellFactory(
|
||||
new Callback<TableColumn<String, PendingTradesListItem>, TableCell<String, PendingTradesListItem>>() {
|
||||
@Override
|
||||
public TableCell<String, PendingTradesListItem> call(
|
||||
TableColumn<String, PendingTradesListItem> directionColumn) {
|
||||
return new TableCell<String, PendingTradesListItem>() {
|
||||
final HBox hBox = new HBox();
|
||||
|
||||
{
|
||||
hBox.setSpacing(3);
|
||||
hBox.setAlignment(Pos.CENTER);
|
||||
setGraphic(hBox);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateItem(final PendingTradesListItem tradesTableItem, boolean empty) {
|
||||
super.updateItem(tradesTableItem, empty);
|
||||
|
||||
hBox.getChildren().clear();
|
||||
if (tradesTableItem != null) {
|
||||
Country country = tradesTableItem.getTrade().getOffer().getBankAccountCountry();
|
||||
hBox.getChildren().add(ImageUtil.getCountryIconImageView(country));
|
||||
Tooltip.install(this, new Tooltip(country.getName()));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setBankAccountTypeColumnCellFactory() {
|
||||
bankAccountTypeColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper(offer.getValue()));
|
||||
bankAccountTypeColumn.setCellFactory(
|
||||
new Callback<TableColumn<String, PendingTradesListItem>, TableCell<String, PendingTradesListItem>>() {
|
||||
@Override
|
||||
public TableCell<String, PendingTradesListItem> call(
|
||||
TableColumn<String, PendingTradesListItem> directionColumn) {
|
||||
return new TableCell<String, PendingTradesListItem>() {
|
||||
@Override
|
||||
public void updateItem(final PendingTradesListItem tradesTableItem, boolean empty) {
|
||||
super.updateItem(tradesTableItem, empty);
|
||||
|
||||
if (tradesTableItem != null) {
|
||||
BankAccountType bankAccountType = tradesTableItem.getTrade().getOffer()
|
||||
.getBankAccountType();
|
||||
setText(BSResources.get(bankAccountType.toString()));
|
||||
}
|
||||
else {
|
||||
setText("");
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setDirectionColumnCellFactory() {
|
||||
directionColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper(offer.getValue()));
|
||||
directionColumn.setCellFactory(
|
||||
new Callback<TableColumn<String, PendingTradesListItem>, TableCell<String, PendingTradesListItem>>() {
|
||||
@Override
|
||||
public TableCell<String, PendingTradesListItem> call(
|
||||
TableColumn<String, PendingTradesListItem> directionColumn) {
|
||||
return new TableCell<String, PendingTradesListItem>() {
|
||||
final ImageView iconView = new ImageView();
|
||||
final Button button = new Button();
|
||||
|
||||
{
|
||||
button.setGraphic(iconView);
|
||||
button.setMinWidth(70);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateItem(final PendingTradesListItem tradesTableItem, boolean empty) {
|
||||
super.updateItem(tradesTableItem, empty);
|
||||
|
||||
if (tradesTableItem != null) {
|
||||
String title;
|
||||
Offer offer = tradesTableItem.getTrade().getOffer();
|
||||
|
||||
if (offer.getDirection() == Direction.SELL) {
|
||||
iconView.setId("image-buy");
|
||||
title = BSFormatter.formatDirection(Direction.BUY, true);
|
||||
}
|
||||
else {
|
||||
iconView.setId("image-sell");
|
||||
title = BSFormatter.formatDirection(Direction.SELL, true);
|
||||
}
|
||||
button.setDisable(true);
|
||||
button.setText(title);
|
||||
setGraphic(button);
|
||||
}
|
||||
else {
|
||||
setGraphic(null);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setSelectColumnCellFactory() {
|
||||
selectColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper(offer.getValue()));
|
||||
selectColumn.setCellFactory(
|
||||
new Callback<TableColumn<String, PendingTradesListItem>, TableCell<String, PendingTradesListItem>>() {
|
||||
@Override
|
||||
public TableCell<String, PendingTradesListItem> call(
|
||||
TableColumn<String, PendingTradesListItem> directionColumn) {
|
||||
return new TableCell<String, PendingTradesListItem>() {
|
||||
final Button button = new Button("Select");
|
||||
|
||||
@Override
|
||||
public void updateItem(final PendingTradesListItem tradesTableItem, boolean empty) {
|
||||
super.updateItem(tradesTableItem, empty);
|
||||
|
||||
if (tradesTableItem != null) {
|
||||
button.setOnAction(event -> showTradeDetails(tradesTableItem));
|
||||
setGraphic(button);
|
||||
}
|
||||
else {
|
||||
setGraphic(null);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,178 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!--
|
||||
~ 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/>.
|
||||
-->
|
||||
|
||||
<?import io.bitsquare.gui.components.confidence.ConfidenceProgressIndicator?>
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.control.cell.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<VBox fx:id="root" fx:controller="io.bitsquare.gui.main.orders.pending.PendingTradeController"
|
||||
spacing="10" AnchorPane.bottomAnchor="0"
|
||||
AnchorPane.leftAnchor="0" AnchorPane.rightAnchor="0" AnchorPane.topAnchor="0"
|
||||
xmlns:fx="http://javafx.com/fxml">
|
||||
<TableView id="orderbook-table" fx:id="openTradesTable" prefHeight="150.0">
|
||||
<columns>
|
||||
<TableColumn fx:id="amountColumn" minWidth="120" text="Amount in BTC (Min.)">
|
||||
<cellValueFactory>
|
||||
<PropertyValueFactory property="amount"/>
|
||||
</cellValueFactory>
|
||||
</TableColumn>
|
||||
<TableColumn fx:id="priceColumn" minWidth="70" text="Price">
|
||||
<cellValueFactory>
|
||||
<PropertyValueFactory property="price"/>
|
||||
</cellValueFactory>
|
||||
</TableColumn>
|
||||
<TableColumn fx:id="volumeColumn" minWidth="130" text="Amount in EUR (Min.)">
|
||||
<cellValueFactory>
|
||||
<PropertyValueFactory property="volume"/>
|
||||
</cellValueFactory>
|
||||
</TableColumn>
|
||||
<TableColumn fx:id="countryColumn" minWidth="60" text="Country"/>
|
||||
<TableColumn fx:id="bankAccountTypeColumn" minWidth="140" text="Bank transfer type"/>
|
||||
<TableColumn fx:id="directionColumn" minWidth="80" sortable="false" text="Offer type"/>
|
||||
<TableColumn fx:id="statusColumn" minWidth="80" text="Status">
|
||||
<cellValueFactory>
|
||||
<PropertyValueFactory property="status"/>
|
||||
</cellValueFactory>
|
||||
</TableColumn>
|
||||
|
||||
<TableColumn fx:id="selectColumn" minWidth="60" sortable="false" text=""/>
|
||||
</columns>
|
||||
<VBox.margin>
|
||||
<Insets left="10.0" right="10.0"/>
|
||||
</VBox.margin>
|
||||
</TableView>
|
||||
|
||||
|
||||
<Label text="After you received 1 blockchain confirmation you are safe to start the bank transfer.">
|
||||
<VBox.margin>
|
||||
<Insets bottom="10.0" left="10.0" top="10.0"/>
|
||||
</VBox.margin>
|
||||
</Label>
|
||||
|
||||
<GridPane hgap="5.0" vgap="5.0">
|
||||
|
||||
<!-- row 0 -->
|
||||
<Label fx:id="txHeaderLabel" id="form-header-text" text="Deposit transaction" GridPane.columnSpan="2"
|
||||
GridPane.halignment="LEFT"/>
|
||||
|
||||
<!-- row 1 -->
|
||||
<Label fx:id="txTitleLabel" text="Deposit transaction ID:" GridPane.rowIndex="1"/>
|
||||
<TextField fx:id="txTextField" editable="false" focusTraversable="false" GridPane.columnIndex="1"
|
||||
GridPane.rowIndex="1"/>
|
||||
<Label fx:id="txIDCopyIcon" id="copy-icon" minWidth="10" GridPane.columnIndex="2" GridPane.rowIndex="1">
|
||||
<padding>
|
||||
<Insets bottom="0.0" left="0.0" right="0.0" top="-1.0"/>
|
||||
</padding>
|
||||
<tooltip>
|
||||
<Tooltip text="Copy address to clipboard"/>
|
||||
</tooltip>
|
||||
</Label>
|
||||
<ConfidenceProgressIndicator fx:id="progressIndicator" visible="false" progress="0" GridPane.columnIndex="3"
|
||||
GridPane.halignment="LEFT" GridPane.rowIndex="1"
|
||||
GridPane.rowSpan="2" GridPane.valignment="TOP">
|
||||
<GridPane.margin>
|
||||
<Insets top="2.0"/>
|
||||
</GridPane.margin>
|
||||
</ConfidenceProgressIndicator>
|
||||
<Label fx:id="confirmationLabel" visible="false" GridPane.columnIndex="4" GridPane.rowIndex="1"/>
|
||||
|
||||
<!-- row 2 -->
|
||||
<Label fx:id="bankAccountDetailsHeaderLabel" id="form-header-text" text="Bank details" GridPane.columnIndex="0"
|
||||
GridPane.columnSpan="2" GridPane.halignment="LEFT"
|
||||
GridPane.rowIndex="2"/>
|
||||
|
||||
<!-- row 3 -->
|
||||
<Label fx:id="bankAccountTypeTitleLabel" text="Bank account type:" GridPane.columnIndex="0"
|
||||
GridPane.rowIndex="3"/>
|
||||
<TextField fx:id="bankAccountTypeTextField" editable="false" focusTraversable="false" GridPane.columnIndex="1"
|
||||
GridPane.rowIndex="3"/>
|
||||
|
||||
<!-- row 4 -->
|
||||
<Label fx:id="holderNameTitleLabel" text="Holder name:" GridPane.columnIndex="0" GridPane.rowIndex="4"/>
|
||||
<TextField fx:id="holderNameTextField" editable="false" focusTraversable="false" GridPane.columnIndex="1"
|
||||
GridPane.rowIndex="4"/>
|
||||
<Label fx:id="holderNameCopyIcon" id="copy-icon" minWidth="10" GridPane.columnIndex="2" GridPane.rowIndex="4">
|
||||
<padding>
|
||||
<Insets bottom="0.0" left="0.0" right="0.0" top="-1.0"/>
|
||||
</padding>
|
||||
<tooltip>
|
||||
<Tooltip text="Copy address to clipboard"/>
|
||||
</tooltip>
|
||||
</Label>
|
||||
|
||||
<!-- row 5 -->
|
||||
<Label fx:id="primaryBankAccountIDTitleLabel" text="Primary bank account ID:" GridPane.columnIndex="0"
|
||||
GridPane.rowIndex="5"/>
|
||||
<TextField fx:id="primaryBankAccountIDTextField" editable="false" focusTraversable="false"
|
||||
GridPane.columnIndex="1" GridPane.rowIndex="5"/>
|
||||
<Label fx:id="primaryBankAccountIDCopyIcon" id="copy-icon" minWidth="10" GridPane.columnIndex="2"
|
||||
GridPane.rowIndex="5">
|
||||
<padding>
|
||||
<Insets bottom="0.0" left="0.0" right="0.0" top="-1.0"/>
|
||||
</padding>
|
||||
<tooltip>
|
||||
<Tooltip text="Copy address to clipboard"/>
|
||||
</tooltip>
|
||||
</Label>
|
||||
|
||||
<!-- row 6 -->
|
||||
<Label fx:id="secondaryBankAccountIDTitleLabel" text="Secondary bank account ID:" GridPane.columnIndex="0"
|
||||
GridPane.rowIndex="6"/>
|
||||
<TextField fx:id="secondaryBankAccountIDTextField" editable="false" focusTraversable="false"
|
||||
GridPane.columnIndex="1" GridPane.rowIndex="6"/>
|
||||
<Label fx:id="secondaryBankAccountIDCopyIcon" id="copy-icon" minWidth="10" GridPane.columnIndex="2"
|
||||
GridPane.rowIndex="6">
|
||||
<padding>
|
||||
<Insets bottom="0.0" left="0.0" right="0.0" top="-1.0"/>
|
||||
</padding>
|
||||
<tooltip>
|
||||
<Tooltip text="Copy address to clipboard"/>
|
||||
</tooltip>
|
||||
</Label>
|
||||
|
||||
<!-- row 7 -->
|
||||
<Button fx:id="bankTransferInitedButton" defaultButton="true" onAction="#bankTransferInited" disable="true"
|
||||
text="Bank transfer initiated"
|
||||
GridPane.columnIndex="1"
|
||||
GridPane.rowIndex="7"/>
|
||||
|
||||
<columnConstraints>
|
||||
<ColumnConstraints halignment="RIGHT" hgrow="SOMETIMES"/>
|
||||
<ColumnConstraints hgrow="ALWAYS"/>
|
||||
<ColumnConstraints fillWidth="false" hgrow="SOMETIMES" minWidth="20"/>
|
||||
<ColumnConstraints fillWidth="false" hgrow="SOMETIMES" minWidth="20" prefWidth="20"/>
|
||||
<ColumnConstraints fillWidth="false" hgrow="SOMETIMES"/>
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints minHeight="10.0" vgrow="SOMETIMES"/>
|
||||
<RowConstraints minHeight="10.0" vgrow="SOMETIMES"/>
|
||||
<RowConstraints minHeight="10.0" vgrow="SOMETIMES"/>
|
||||
<RowConstraints minHeight="10.0" vgrow="SOMETIMES"/>
|
||||
<RowConstraints minHeight="10.0" vgrow="SOMETIMES"/>
|
||||
<RowConstraints minHeight="10.0" vgrow="SOMETIMES"/>
|
||||
<RowConstraints minHeight="10.0" vgrow="SOMETIMES"/>
|
||||
<RowConstraints minHeight="10.0" vgrow="SOMETIMES"/>
|
||||
<RowConstraints/>
|
||||
</rowConstraints>
|
||||
<VBox.margin>
|
||||
<Insets left="10.0" right="10.0"/>
|
||||
</VBox.margin>
|
||||
</GridPane>
|
||||
</VBox>
|
|
@ -0,0 +1,201 @@
|
|||
/*
|
||||
* 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.orders.pending;
|
||||
|
||||
import io.bitsquare.btc.FeePolicy;
|
||||
import io.bitsquare.btc.WalletFacade;
|
||||
import io.bitsquare.btc.listeners.TxConfidenceListener;
|
||||
import io.bitsquare.gui.UIModel;
|
||||
import io.bitsquare.trade.Trade;
|
||||
import io.bitsquare.trade.TradeManager;
|
||||
|
||||
import com.google.bitcoin.core.Coin;
|
||||
import com.google.bitcoin.core.TransactionConfidence;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import javafx.beans.property.IntegerProperty;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleIntegerProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.MapChangeListener;
|
||||
import javafx.collections.ObservableList;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class PendingTradesModel extends UIModel {
|
||||
private static final Logger log = LoggerFactory.getLogger(PendingTradesModel.class);
|
||||
|
||||
private final TradeManager tradeManager;
|
||||
private WalletFacade walletFacade;
|
||||
private final ObservableList<PendingTradesListItem> pendingTrades = FXCollections.observableArrayList();
|
||||
|
||||
private PendingTradesListItem currentItem;
|
||||
private boolean isOfferer;
|
||||
final IntegerProperty selectedIndex = new SimpleIntegerProperty(-1);
|
||||
|
||||
final ObjectProperty<Trade.State> tradeState = new SimpleObjectProperty<>();
|
||||
final ObjectProperty<Throwable> fault = new SimpleObjectProperty<>();
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Inject
|
||||
public PendingTradesModel(TradeManager tradeManager, WalletFacade walletFacade) {
|
||||
this.tradeManager = tradeManager;
|
||||
this.walletFacade = walletFacade;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Lifecycle
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
// transform trades to list of PendingTradesListItems and keep it updated
|
||||
tradeManager.getTrades().values().stream().forEach(e -> pendingTrades.add(new PendingTradesListItem(e)));
|
||||
tradeManager.getTrades().addListener((MapChangeListener<String, Trade>) change -> {
|
||||
if (change.wasAdded())
|
||||
pendingTrades.add(new PendingTradesListItem(change.getValueAdded()));
|
||||
else if (change.wasAdded())
|
||||
pendingTrades.remove(new PendingTradesListItem(change.getValueRemoved()));
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void activate() {
|
||||
super.activate();
|
||||
|
||||
// TODO Check if we can really use tradeManager.getPendingTrade()
|
||||
Optional<PendingTradesListItem> currentTradeItemOptional = pendingTrades.stream().filter((e) ->
|
||||
tradeManager.getCurrentPendingTrade() != null &&
|
||||
e.getTrade().getId().equals(tradeManager.getCurrentPendingTrade().getId())).findFirst();
|
||||
if (currentTradeItemOptional.isPresent())
|
||||
selectPendingTrade(currentTradeItemOptional.get());
|
||||
else if (pendingTrades.size() > 0)
|
||||
selectPendingTrade(pendingTrades.get(0));
|
||||
}
|
||||
|
||||
@SuppressWarnings("EmptyMethod")
|
||||
@Override
|
||||
public void deactivate() {
|
||||
super.deactivate();
|
||||
}
|
||||
|
||||
@SuppressWarnings("EmptyMethod")
|
||||
@Override
|
||||
public void terminate() {
|
||||
super.terminate();
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Methods
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void selectPendingTrade(PendingTradesListItem item) {
|
||||
if (item != null) {
|
||||
currentItem = item;
|
||||
isOfferer = tradeManager.isTradeMyOffer(currentItem.getTrade());
|
||||
|
||||
selectedIndex.set(pendingTrades.indexOf(item));
|
||||
Trade currentTrade = currentItem.getTrade();
|
||||
if (currentTrade.getDepositTx() != null) {
|
||||
walletFacade.addTxConfidenceListener(new TxConfidenceListener(currentItem.getTrade()
|
||||
.getDepositTx().getHashAsString()) {
|
||||
@Override
|
||||
public void onTransactionConfidenceChanged(TransactionConfidence confidence) {
|
||||
updateConfidence(confidence);
|
||||
}
|
||||
});
|
||||
updateConfidence(walletFacade.getConfidenceForTxId(currentItem.getTrade().getDepositTx()
|
||||
.getHashAsString()));
|
||||
}
|
||||
|
||||
currentTrade.stateProperty().addListener((ov, oldValue, newValue) -> tradeState.set(newValue));
|
||||
tradeState.set(currentTrade.stateProperty().get());
|
||||
|
||||
currentTrade.faultProperty().addListener((ov, oldValue, newValue) -> fault.set(newValue));
|
||||
fault.set(currentTrade.faultProperty().get());
|
||||
}
|
||||
}
|
||||
|
||||
public void paymentStarted() {
|
||||
tradeManager.bankTransferInited(currentItem.getTrade().getId());
|
||||
}
|
||||
|
||||
public void paymentReceived() {
|
||||
tradeManager.onFiatReceived(currentItem.getTrade().getId());
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Setters
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Getters
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ObservableList<PendingTradesListItem> getPendingTrades() {
|
||||
return pendingTrades;
|
||||
}
|
||||
|
||||
public boolean isOfferer() {
|
||||
return isOfferer;
|
||||
}
|
||||
|
||||
public Trade getTrade() {
|
||||
return currentItem.getTrade();
|
||||
}
|
||||
|
||||
public String getTxID() {
|
||||
if (currentItem.getTrade().getDepositTx() != null)
|
||||
return currentItem.getTrade().getDepositTx().getHashAsString();
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
public Coin getTotalFees() {
|
||||
Coin tradeFee = isOfferer() ? FeePolicy.CREATE_OFFER_FEE : FeePolicy.TAKE_OFFER_FEE;
|
||||
return tradeFee.add(FeePolicy.TX_FEE);
|
||||
}
|
||||
|
||||
public WalletFacade getWalletFacade() {
|
||||
return walletFacade;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Private
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private void updateConfidence(TransactionConfidence confidence) {
|
||||
if (confidence != null && confidence.getConfidenceType() == TransactionConfidence.ConfidenceType.BUILDING)
|
||||
currentItem.getTrade().setState(Trade.State.DEPOSIT_CONFIRMED);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,250 @@
|
|||
/*
|
||||
* 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.orders.pending;
|
||||
|
||||
import io.bitsquare.btc.WalletFacade;
|
||||
import io.bitsquare.gui.PresentationModel;
|
||||
import io.bitsquare.gui.util.BSFormatter;
|
||||
import io.bitsquare.locale.BSResources;
|
||||
import io.bitsquare.trade.Direction;
|
||||
import io.bitsquare.trade.Trade;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
import javafx.beans.property.IntegerProperty;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleIntegerProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import javafx.collections.ObservableList;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class PendingTradesPM extends PresentationModel<PendingTradesModel> {
|
||||
private static final Logger log = LoggerFactory.getLogger(PendingTradesPM.class);
|
||||
private BSFormatter formatter;
|
||||
private BSResources resources;
|
||||
|
||||
|
||||
enum State {
|
||||
TAKER_SELLER_WAIT_TX_CONF,
|
||||
TAKER_SELLER_WAIT_PAYMENT_STARTED,
|
||||
TAKER_SELLER_CONFIRM_RECEIVE_PAYMENT,
|
||||
TAKER_SELLER_COMPLETED,
|
||||
|
||||
OFFERER_BUYER_WAIT_TX_CONF,
|
||||
OFFERER_BUYER_START_PAYMENT,
|
||||
OFFERER_BUYER_WAIT_CONFIRM_PAYMENT_RECEIVED,
|
||||
OFFERER_BUYER_COMPLETED,
|
||||
}
|
||||
|
||||
|
||||
final StringProperty amount = new SimpleStringProperty();
|
||||
final StringProperty price = new SimpleStringProperty();
|
||||
final StringProperty volume = new SimpleStringProperty();
|
||||
final IntegerProperty selectedIndex = new SimpleIntegerProperty(-1);
|
||||
final ObjectProperty<State> state = new SimpleObjectProperty<>();
|
||||
final ObjectProperty<Trade.State> tradeState = new SimpleObjectProperty<>();
|
||||
final ObjectProperty<Throwable> fault = new SimpleObjectProperty<>();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Inject
|
||||
public PendingTradesPM(PendingTradesModel model, BSFormatter formatter, BSResources resources) {
|
||||
super(model);
|
||||
this.formatter = formatter;
|
||||
this.resources = resources;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Lifecycle
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
selectedIndex.bind(model.selectedIndex);
|
||||
tradeState.addListener((ov, oldValue, newValue) -> {
|
||||
updateState();
|
||||
});
|
||||
fault.bind(model.fault);
|
||||
|
||||
|
||||
super.initialize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void activate() {
|
||||
super.activate();
|
||||
|
||||
updateState();
|
||||
}
|
||||
|
||||
@SuppressWarnings("EmptyMethod")
|
||||
@Override
|
||||
public void deactivate() {
|
||||
super.deactivate();
|
||||
}
|
||||
|
||||
@SuppressWarnings("EmptyMethod")
|
||||
@Override
|
||||
public void terminate() {
|
||||
super.terminate();
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Methods
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
public void selectPendingTrade(PendingTradesListItem item) {
|
||||
model.selectPendingTrade(item);
|
||||
}
|
||||
|
||||
public void paymentStarted() {
|
||||
model.paymentStarted();
|
||||
}
|
||||
|
||||
public void paymentReceived() {
|
||||
model.paymentReceived();
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Getters
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ObservableList<PendingTradesListItem> getPendingTrades() {
|
||||
return model.getPendingTrades();
|
||||
}
|
||||
|
||||
|
||||
public boolean isOfferer() {
|
||||
return model.isOfferer();
|
||||
}
|
||||
|
||||
public String getTxID() {
|
||||
return model.getTxID();
|
||||
}
|
||||
|
||||
public WalletFacade getWalletFacade() {
|
||||
return model.getWalletFacade();
|
||||
}
|
||||
|
||||
String getAmount(PendingTradesListItem item) {
|
||||
return (item != null) ? BSFormatter.formatCoin(item.getOffer().getAmount()) +
|
||||
" (" + BSFormatter.formatCoin(item.getOffer().getMinAmount()) + ")" : "";
|
||||
}
|
||||
|
||||
String getPrice(PendingTradesListItem item) {
|
||||
return (item != null) ? BSFormatter.formatFiat(item.getOffer().getPrice()) : "";
|
||||
}
|
||||
|
||||
String getVolume(PendingTradesListItem item) {
|
||||
return (item != null) ? BSFormatter.formatFiat(item.getOffer().getOfferVolume()) +
|
||||
" (" + BSFormatter.formatFiat(item.getOffer().getMinOfferVolume()) + ")" : "";
|
||||
}
|
||||
|
||||
String getBankAccountType(PendingTradesListItem item) {
|
||||
return (item != null) ? BSResources.get(item.getOffer().getBankAccountType().toString()) : "";
|
||||
}
|
||||
|
||||
String getDirectionLabel(PendingTradesListItem item) {
|
||||
// mirror direction!
|
||||
if (item != null) {
|
||||
Direction direction = item.getOffer().getDirection() == Direction.BUY ? Direction.SELL : Direction.BUY;
|
||||
return BSFormatter.formatDirection(direction, true);
|
||||
}
|
||||
else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
String getPaymentMethod() {
|
||||
return BSResources.get(model.getTrade().getContract().getTakerBankAccount().getBankAccountType().toString());
|
||||
}
|
||||
|
||||
String getHolderName() {
|
||||
return model.getTrade().getContract().getTakerBankAccount().getAccountHolderName();
|
||||
}
|
||||
|
||||
String getPrimaryId() {
|
||||
return model.getTrade().getContract().getTakerBankAccount().getAccountPrimaryID();
|
||||
}
|
||||
|
||||
String getSecondaryId() {
|
||||
return model.getTrade().getContract().getTakerBankAccount().getAccountSecondaryID();
|
||||
}
|
||||
|
||||
|
||||
String getTradeVolume() {
|
||||
return formatter.formatCoinWithCode(model.getTrade().getTradeAmount());
|
||||
}
|
||||
|
||||
String getFiatVolume() {
|
||||
return formatter.formatFiatWithCode(model.getTrade().getTradeVolume());
|
||||
}
|
||||
|
||||
String getTotalFees() {
|
||||
return formatter.formatCoinWithCode(model.getTotalFees());
|
||||
}
|
||||
|
||||
String getCollateral() {
|
||||
return formatter.formatCoinWithCode(model.getTrade().getCollateralAmount());
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Private
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private void updateState() {
|
||||
log.debug("updateState " + model.tradeState.get());
|
||||
if (model.tradeState.get() != null) {
|
||||
switch (model.tradeState.get()) {
|
||||
case DEPOSIT_PUBLISHED:
|
||||
state.set(model.isOfferer() ? State.OFFERER_BUYER_WAIT_TX_CONF : State.TAKER_SELLER_WAIT_TX_CONF);
|
||||
break;
|
||||
case DEPOSIT_CONFIRMED:
|
||||
state.set(model.isOfferer() ? State.OFFERER_BUYER_START_PAYMENT : State
|
||||
.TAKER_SELLER_WAIT_PAYMENT_STARTED);
|
||||
break;
|
||||
case PAYMENT_STARTED:
|
||||
state.set(model.isOfferer() ? State.OFFERER_BUYER_WAIT_CONFIRM_PAYMENT_RECEIVED : State
|
||||
.TAKER_SELLER_CONFIRM_RECEIVE_PAYMENT);
|
||||
break;
|
||||
case PAYMENT_RECEIVED:
|
||||
case PAYOUT_PUBLISHED:
|
||||
state.set(model.isOfferer() ? State.OFFERER_BUYER_COMPLETED : State.TAKER_SELLER_COMPLETED);
|
||||
break;
|
||||
case FAULT:
|
||||
// TODO
|
||||
break;
|
||||
default:
|
||||
log.warn("unhandled state " + state);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,187 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!--
|
||||
~ 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/>.
|
||||
-->
|
||||
|
||||
|
||||
<?import io.bitsquare.gui.components.InfoDisplay?>
|
||||
<?import io.bitsquare.gui.components.processbar.ProcessStepBar?>
|
||||
<?import io.bitsquare.gui.components.TextFieldWithCopyIcon?>
|
||||
<?import io.bitsquare.gui.components.TitledGroupBg?>
|
||||
<?import io.bitsquare.gui.components.TitledSeparator?>
|
||||
<?import io.bitsquare.gui.components.TxIdTextField?>
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<GridPane fx:id="root" fx:controller="io.bitsquare.gui.main.orders.pending.PendingTradesViewCB"
|
||||
hgap="5.0" vgap="5"
|
||||
xmlns:fx="http://javafx.com/fxml">
|
||||
<padding>
|
||||
<Insets bottom="20.0" left="25.0" top="30.0" right="25"/>
|
||||
</padding>
|
||||
|
||||
<TitledSeparator text="Pending trades" GridPane.rowIndex="0" GridPane.columnIndex="0" GridPane.columnSpan="2"/>
|
||||
|
||||
<TableView fx:id="table" GridPane.rowIndex="0" GridPane.columnIndex="0" GridPane.columnSpan="2"
|
||||
minHeight="120" prefHeight="120">
|
||||
<GridPane.margin>
|
||||
<Insets top="10.0" left="-10" right="-10" bottom="-15"/>
|
||||
</GridPane.margin>
|
||||
<columns>
|
||||
<TableColumn text="Amount in BTC (Min.)" fx:id="amountColumn" minWidth="130"/>
|
||||
<TableColumn text="Price" fx:id="priceColumn" minWidth="130"/>
|
||||
<TableColumn text="Amount in EUR (Min.)" fx:id="volumeColumn" minWidth="130"/>
|
||||
<TableColumn text="Country" fx:id="countryColumn" minWidth="60"/>
|
||||
<TableColumn text="Bank transfer type" fx:id="bankAccountTypeColumn" minWidth="130"/>
|
||||
<TableColumn text="Trade tye" fx:id="directionColumn" minWidth="80" sortable="false"/>
|
||||
<TableColumn fx:id="selectColumn" minWidth="60" sortable="false" text=""/>
|
||||
</columns>
|
||||
</TableView>
|
||||
|
||||
<TitledGroupBg fx:id="titledGroupBg" text="Trade status" GridPane.rowIndex="1" GridPane.rowSpan="4"
|
||||
GridPane.columnSpan="2" visible="false">
|
||||
<GridPane.margin>
|
||||
<Insets top="40.0" bottom="-10" left="-10" right="-10"/>
|
||||
</GridPane.margin>
|
||||
</TitledGroupBg>
|
||||
|
||||
<ProcessStepBar fx:id="processBar" GridPane.rowIndex="1" GridPane.columnSpan="2" snapToPixel="true" visible="false">
|
||||
<GridPane.margin>
|
||||
<Insets top="60.0"/>
|
||||
</GridPane.margin>
|
||||
</ProcessStepBar>
|
||||
|
||||
|
||||
<Label fx:id="statusLabel" text="Status:" GridPane.rowIndex="2" visible="false">
|
||||
<GridPane.margin>
|
||||
<Insets top="20.0"/>
|
||||
</GridPane.margin>
|
||||
</Label>
|
||||
<TextField fx:id="statusTextField" GridPane.rowIndex="2" GridPane.columnIndex="1" editable="false" visible="false">
|
||||
<GridPane.margin>
|
||||
<Insets top="20.0"/>
|
||||
</GridPane.margin>
|
||||
</TextField>
|
||||
|
||||
<Label fx:id="txIdLabel" text="Deposit transaction ID:" GridPane.rowIndex="3" visible="false"/>
|
||||
<TxIdTextField fx:id="txIdTextField" GridPane.rowIndex="3" GridPane.columnIndex="1" visible="false"/>
|
||||
|
||||
<InfoDisplay fx:id="infoDisplay" onAction="#onOpenHelp" rowIndex="4" gridPane="$root" visible="false"/>
|
||||
|
||||
<Button fx:id="confirmPaymentReceiptButton" text="Confirm payment receipt" onAction="#onConfirmPaymentReceipt"
|
||||
GridPane.rowIndex="5" GridPane.columnIndex="1" defaultButton="true" visible="false">
|
||||
<GridPane.margin>
|
||||
<Insets top="-5"/>
|
||||
</GridPane.margin>
|
||||
</Button>
|
||||
|
||||
<!--
|
||||
Payments
|
||||
-->
|
||||
<TitledGroupBg fx:id="paymentsGroupBg" text="Payments details" GridPane.rowIndex="5" GridPane.rowSpan="5"
|
||||
GridPane.columnSpan="2" visible="false">
|
||||
<GridPane.margin>
|
||||
<Insets top="40.0" bottom="-10" left="-10" right="-10"/>
|
||||
</GridPane.margin>
|
||||
</TitledGroupBg>
|
||||
|
||||
<Label fx:id="paymentMethodLabel" text="Payments method:" GridPane.rowIndex="5" visible="false">
|
||||
<GridPane.margin>
|
||||
<Insets top="60.0"/>
|
||||
</GridPane.margin>
|
||||
</Label>
|
||||
<TextField fx:id="paymentMethodTextField" GridPane.rowIndex="5" GridPane.columnIndex="1" editable="false"
|
||||
visible="false">
|
||||
<GridPane.margin>
|
||||
<Insets top="60.0"/>
|
||||
</GridPane.margin>
|
||||
</TextField>
|
||||
|
||||
<Label fx:id="holderNameLabel" text="Holder name:" GridPane.rowIndex="6" visible="false"/>
|
||||
<TextFieldWithCopyIcon fx:id="holderNameTextField" GridPane.rowIndex="6" GridPane.columnIndex="1" visible="false"/>
|
||||
|
||||
<Label fx:id="primaryIdLabel" text="Primary ID:" GridPane.rowIndex="7" visible="false"/>
|
||||
<TextFieldWithCopyIcon fx:id="primaryIdTextField" GridPane.rowIndex="7" GridPane.columnIndex="1" visible="false"/>
|
||||
|
||||
<Label fx:id="secondaryIdLabel" text="Secondary ID:" GridPane.rowIndex="8" visible="false"/>
|
||||
<TextFieldWithCopyIcon fx:id="secondaryIdTextField" GridPane.rowIndex="8" GridPane.columnIndex="1" visible="false"/>
|
||||
|
||||
<InfoDisplay fx:id="paymentsInfoDisplay" onAction="#onOpenPaymentsHelp" rowIndex="9" gridPane="$root"
|
||||
visible="false"/>
|
||||
|
||||
<Button fx:id="paymentsButton" text="Payment started" onAction="#onPaymentStarted" GridPane.rowIndex="10"
|
||||
GridPane.columnIndex="1" defaultButton="true" visible="false">
|
||||
<GridPane.margin>
|
||||
<Insets top="15"/>
|
||||
</GridPane.margin>
|
||||
</Button>
|
||||
|
||||
<!--
|
||||
Summary
|
||||
-->
|
||||
<TitledGroupBg fx:id="summaryGroupBg" text="Summary" GridPane.rowIndex="5" GridPane.rowSpan="5"
|
||||
GridPane.columnSpan="2" visible="false">
|
||||
<GridPane.margin>
|
||||
<Insets top="40.0" bottom="-10" left="-10" right="-10"/>
|
||||
</GridPane.margin>
|
||||
</TitledGroupBg>
|
||||
|
||||
<Label fx:id="btcLabel" text="You have bought:" GridPane.rowIndex="5" visible="false">
|
||||
<GridPane.margin>
|
||||
<Insets top="60.0"/>
|
||||
</GridPane.margin>
|
||||
</Label>
|
||||
<TextField fx:id="btcTextField" GridPane.rowIndex="5" GridPane.columnIndex="1" editable="false"
|
||||
visible="false">
|
||||
<GridPane.margin>
|
||||
<Insets top="60.0"/>
|
||||
</GridPane.margin>
|
||||
</TextField>
|
||||
|
||||
<Label fx:id="fiatLabel" text="You have paid:" GridPane.rowIndex="6" visible="false"/>
|
||||
<TextField fx:id="fiatTextField" GridPane.rowIndex="6" GridPane.columnIndex="1" editable="false" visible="false"/>
|
||||
|
||||
<Label fx:id="feesLabel" text="Total fees paid:" GridPane.rowIndex="7" visible="false"/>
|
||||
<TextField fx:id="feesTextField" GridPane.rowIndex="7" GridPane.columnIndex="1" editable="false" visible="false"/>
|
||||
|
||||
<Label fx:id="collateralLabel" text="Refunded collateral:" GridPane.rowIndex="8" visible="false"/>
|
||||
<TextField fx:id="collateralTextField" GridPane.rowIndex="8" GridPane.columnIndex="1" editable="false"
|
||||
visible="false"/>
|
||||
|
||||
<InfoDisplay fx:id="summaryInfoDisplay" onAction="#onOpenSummaryHelp" rowIndex="9" gridPane="$root"
|
||||
visible="false"/>
|
||||
|
||||
<columnConstraints>
|
||||
<ColumnConstraints halignment="RIGHT" hgrow="SOMETIMES" minWidth="200"/>
|
||||
<ColumnConstraints hgrow="ALWAYS"/>
|
||||
</columnConstraints>
|
||||
|
||||
<rowConstraints>
|
||||
<RowConstraints/>
|
||||
<RowConstraints/>
|
||||
<RowConstraints/>
|
||||
<RowConstraints/>
|
||||
<RowConstraints/>
|
||||
<RowConstraints/>
|
||||
<RowConstraints/>
|
||||
<RowConstraints/>
|
||||
<RowConstraints/>
|
||||
<RowConstraints/>
|
||||
<RowConstraints/>
|
||||
</rowConstraints>
|
||||
|
||||
</GridPane>
|
|
@ -0,0 +1,576 @@
|
|||
/*
|
||||
* 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.orders.pending;
|
||||
|
||||
import io.bitsquare.gui.CachedViewCB;
|
||||
import io.bitsquare.gui.components.InfoDisplay;
|
||||
import io.bitsquare.gui.components.TextFieldWithCopyIcon;
|
||||
import io.bitsquare.gui.components.TitledGroupBg;
|
||||
import io.bitsquare.gui.components.TxIdTextField;
|
||||
import io.bitsquare.gui.components.processbar.ProcessStepBar;
|
||||
import io.bitsquare.gui.components.processbar.ProcessStepItem;
|
||||
import io.bitsquare.gui.main.help.Help;
|
||||
import io.bitsquare.gui.main.help.HelpId;
|
||||
import io.bitsquare.gui.util.ImageUtil;
|
||||
import io.bitsquare.locale.Country;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.ReadOnlyObjectWrapper;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.layout.*;
|
||||
import javafx.util.Callback;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class PendingTradesViewCB extends CachedViewCB<PendingTradesPM> {
|
||||
private static final Logger log = LoggerFactory.getLogger(PendingTradesViewCB.class);
|
||||
public TitledGroupBg summaryGroupBg;
|
||||
public Label btcLabel;
|
||||
public TextField btcTextField;
|
||||
public Label fiatLabel;
|
||||
public TextField fiatTextField;
|
||||
public Label feesLabel;
|
||||
public TextField feesTextField;
|
||||
|
||||
public Label collateralLabel;
|
||||
public TextField collateralTextField;
|
||||
public InfoDisplay summaryInfoDisplay;
|
||||
|
||||
@FXML TitledGroupBg titledGroupBg, paymentsGroupBg;
|
||||
@FXML ProcessStepBar processBar;
|
||||
@FXML Label statusLabel, txIdLabel, paymentMethodLabel, holderNameLabel, primaryIdLabel, secondaryIdLabel;
|
||||
@FXML TextField statusTextField, paymentMethodTextField;
|
||||
@FXML TxIdTextField txIdTextField;
|
||||
@FXML InfoDisplay infoDisplay, paymentsInfoDisplay;
|
||||
@FXML Button confirmPaymentReceiptButton, paymentsButton;
|
||||
@FXML TextFieldWithCopyIcon holderNameTextField, secondaryIdTextField, primaryIdTextField;
|
||||
@FXML TableView<PendingTradesListItem> table;
|
||||
@FXML TableColumn<PendingTradesListItem, PendingTradesListItem> priceColumn, amountColumn, volumeColumn,
|
||||
directionColumn, countryColumn, bankAccountTypeColumn, selectColumn;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Inject
|
||||
public PendingTradesViewCB(PendingTradesPM presentationModel) {
|
||||
super(presentationModel);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Lifecycle
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void initialize(URL url, ResourceBundle rb) {
|
||||
setAmountColumnCellFactory();
|
||||
setPriceColumnCellFactory();
|
||||
setVolumeColumnCellFactory();
|
||||
setCountryColumnCellFactory();
|
||||
setBankAccountTypeColumnCellFactory();
|
||||
setDirectionColumnCellFactory();
|
||||
setSelectColumnCellFactory();
|
||||
|
||||
table.setItems(presentationModel.getPendingTrades());
|
||||
table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
|
||||
|
||||
table.getSelectionModel().selectedItemProperty().
|
||||
addListener((obsValue, oldValue, newValue) -> {
|
||||
if (oldValue != newValue) {
|
||||
if (oldValue != null && newValue != null)
|
||||
presentationModel.selectPendingTrade(newValue);
|
||||
else if (newValue == null)
|
||||
table.getSelectionModel().clearSelection();
|
||||
}
|
||||
else {
|
||||
log.error("####### should not happen!");
|
||||
}
|
||||
});
|
||||
|
||||
// need runLater to avoid conflict with user initiated selection
|
||||
presentationModel.selectedIndex.addListener((ov, oldValue, newValue) ->
|
||||
Platform.runLater(() -> table.getSelectionModel().select((int) newValue)));
|
||||
|
||||
super.initialize(url, rb);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void activate() {
|
||||
super.activate();
|
||||
|
||||
if (!presentationModel.getPendingTrades().isEmpty()) {
|
||||
if (presentationModel.isOfferer())
|
||||
setupScreenForOfferer();
|
||||
else
|
||||
setupScreenForTaker();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("EmptyMethod")
|
||||
@Override
|
||||
public void deactivate() {
|
||||
super.deactivate();
|
||||
}
|
||||
|
||||
@SuppressWarnings("EmptyMethod")
|
||||
@Override
|
||||
public void terminate() {
|
||||
super.terminate();
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// GUI handlers
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@FXML
|
||||
void onPaymentStarted() {
|
||||
presentationModel.paymentStarted();
|
||||
}
|
||||
|
||||
@FXML
|
||||
void onConfirmPaymentReceipt() {
|
||||
presentationModel.paymentReceived();
|
||||
}
|
||||
|
||||
@FXML
|
||||
void onOpenHelp() {
|
||||
Help.openWindow(presentationModel.isOfferer() ? HelpId.PENDING_TRADE_OFFERER : HelpId.PENDING_TRADE_TAKER);
|
||||
}
|
||||
|
||||
@FXML
|
||||
void onOpenPaymentsHelp() {
|
||||
Help.openWindow(HelpId.PENDING_TRADE_PAYMENT);
|
||||
}
|
||||
|
||||
@FXML
|
||||
void onOpenSummaryHelp() {
|
||||
Help.openWindow(HelpId.PENDING_TRADE_SUMMARY);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Private methods
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
private void setupScreenForOfferer() {
|
||||
log.debug("setupScreenForOfferer");
|
||||
|
||||
titledGroupBg.setVisible(true);
|
||||
processBar.setVisible(true);
|
||||
statusLabel.setVisible(true);
|
||||
statusTextField.setVisible(true);
|
||||
txIdLabel.setVisible(true);
|
||||
txIdTextField.setVisible(true);
|
||||
infoDisplay.setVisible(true);
|
||||
|
||||
log.debug("setupScreenForTaker");
|
||||
if (processBar.getProcessStepItems() == null) {
|
||||
List<ProcessStepItem> items = new ArrayList<>();
|
||||
items.add(new ProcessStepItem("Wait for block chain confirmation"));
|
||||
items.add(new ProcessStepItem("Start payment"));
|
||||
items.add(new ProcessStepItem("Wait for payment confirmation"));
|
||||
items.add(new ProcessStepItem("Trade successful completed"));
|
||||
processBar.setProcessStepItems(items);
|
||||
}
|
||||
|
||||
txIdTextField.setup(presentationModel.getWalletFacade(), presentationModel.getTxID());
|
||||
|
||||
presentationModel.state.addListener((ov, oldValue, newValue) -> applyOffererState(newValue));
|
||||
applyOffererState(presentationModel.state.get());
|
||||
}
|
||||
|
||||
private void applyOffererState(PendingTradesPM.State state) {
|
||||
if (state != null) {
|
||||
paymentsGroupBg.setVisible(false);
|
||||
paymentMethodLabel.setVisible(false);
|
||||
holderNameLabel.setVisible(false);
|
||||
primaryIdLabel.setVisible(false);
|
||||
secondaryIdLabel.setVisible(false);
|
||||
paymentMethodTextField.setVisible(false);
|
||||
paymentsInfoDisplay.setVisible(false);
|
||||
paymentsButton.setVisible(false);
|
||||
holderNameTextField.setVisible(false);
|
||||
primaryIdTextField.setVisible(false);
|
||||
secondaryIdTextField.setVisible(false);
|
||||
|
||||
summaryGroupBg.setVisible(false);
|
||||
btcLabel.setVisible(false);
|
||||
btcTextField.setVisible(false);
|
||||
fiatLabel.setVisible(false);
|
||||
fiatTextField.setVisible(false);
|
||||
feesLabel.setVisible(false);
|
||||
feesTextField.setVisible(false);
|
||||
collateralLabel.setVisible(false);
|
||||
collateralTextField.setVisible(false);
|
||||
summaryInfoDisplay.setVisible(false);
|
||||
|
||||
|
||||
switch (state) {
|
||||
case OFFERER_BUYER_WAIT_TX_CONF:
|
||||
processBar.setSelectedIndex(0);
|
||||
statusTextField.setText("Deposit transaction is published. Waiting " +
|
||||
"for at least 1 confirmation");
|
||||
infoDisplay.setText("Deposit transaction has bee published. You need to wait for at least one " +
|
||||
"block " +
|
||||
"chain confirmation. After that you need to make the payments transfer.");
|
||||
break;
|
||||
case OFFERER_BUYER_START_PAYMENT:
|
||||
processBar.setSelectedIndex(1);
|
||||
|
||||
statusTextField.setText("Deposit transaction has at least 1 confirmation. Start payment.");
|
||||
infoDisplay.setText("Deposit transaction has at least one blockchain confirmation. You need to " +
|
||||
"start " +
|
||||
"the payment.");
|
||||
|
||||
paymentsGroupBg.setVisible(true);
|
||||
paymentMethodLabel.setVisible(true);
|
||||
holderNameLabel.setVisible(true);
|
||||
primaryIdLabel.setVisible(true);
|
||||
secondaryIdLabel.setVisible(true);
|
||||
paymentMethodTextField.setVisible(true);
|
||||
paymentsInfoDisplay.setVisible(true);
|
||||
holderNameTextField.setVisible(true);
|
||||
primaryIdTextField.setVisible(true);
|
||||
secondaryIdTextField.setVisible(true);
|
||||
paymentsButton.setVisible(true);
|
||||
|
||||
paymentMethodTextField.setText(presentationModel.getPaymentMethod());
|
||||
holderNameTextField.setText(presentationModel.getHolderName());
|
||||
primaryIdTextField.setText(presentationModel.getPrimaryId());
|
||||
secondaryIdTextField.setText(presentationModel.getSecondaryId());
|
||||
|
||||
|
||||
paymentsInfoDisplay.setText("Copy and paste the payments accounts data to your payments " +
|
||||
"accounts web page and transfer the payment to the other trader. When the transfer is " +
|
||||
"done confirm it with the 'Payment started' button.");
|
||||
|
||||
break;
|
||||
case OFFERER_BUYER_WAIT_CONFIRM_PAYMENT_RECEIVED:
|
||||
processBar.setSelectedIndex(2);
|
||||
|
||||
statusTextField.setText("Waiting until the other trader has received your payment.");
|
||||
infoDisplay.setText("Waiting until the other trader has confirmed that he has received your " +
|
||||
"payment.");
|
||||
break;
|
||||
case OFFERER_BUYER_COMPLETED:
|
||||
processBar.setSelectedIndex(3);
|
||||
|
||||
statusTextField.setText("Trade has successfully completed.");
|
||||
infoDisplay.setText("Trade has successfully completed. You can find the details to that trade" +
|
||||
" in the closed trades section.");
|
||||
|
||||
summaryGroupBg.setVisible(true);
|
||||
btcLabel.setVisible(true);
|
||||
btcTextField.setVisible(true);
|
||||
fiatLabel.setVisible(true);
|
||||
fiatTextField.setVisible(true);
|
||||
feesLabel.setVisible(true);
|
||||
feesTextField.setVisible(true);
|
||||
collateralLabel.setVisible(true);
|
||||
collateralTextField.setVisible(true);
|
||||
summaryInfoDisplay.setVisible(true);
|
||||
|
||||
btcTextField.setText(presentationModel.getTradeVolume());
|
||||
fiatTextField.setText(presentationModel.getFiatVolume());
|
||||
feesTextField.setText(presentationModel.getTotalFees());
|
||||
collateralTextField.setText(presentationModel.getCollateral());
|
||||
summaryInfoDisplay.setText("You can open that summary any time in the closed orders section.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setupScreenForTaker() {
|
||||
titledGroupBg.setVisible(true);
|
||||
processBar.setVisible(true);
|
||||
statusLabel.setVisible(true);
|
||||
statusTextField.setVisible(true);
|
||||
txIdLabel.setVisible(true);
|
||||
txIdTextField.setVisible(true);
|
||||
infoDisplay.setVisible(true);
|
||||
|
||||
summaryGroupBg.setVisible(false);
|
||||
btcLabel.setVisible(false);
|
||||
btcTextField.setVisible(false);
|
||||
fiatLabel.setVisible(false);
|
||||
fiatTextField.setVisible(false);
|
||||
feesLabel.setVisible(false);
|
||||
feesTextField.setVisible(false);
|
||||
collateralLabel.setVisible(false);
|
||||
collateralTextField.setVisible(false);
|
||||
summaryInfoDisplay.setVisible(false);
|
||||
|
||||
log.debug("setupScreenForTaker");
|
||||
if (processBar.getProcessStepItems() == null) {
|
||||
List<ProcessStepItem> items = new ArrayList<>();
|
||||
items.add(new ProcessStepItem("Wait for block chain confirmation"));
|
||||
items.add(new ProcessStepItem("Wait for payment started"));
|
||||
items.add(new ProcessStepItem("Confirm payment"));
|
||||
items.add(new ProcessStepItem("Trade successful completed"));
|
||||
processBar.setProcessStepItems(items);
|
||||
}
|
||||
|
||||
txIdTextField.setup(presentationModel.getWalletFacade(), presentationModel.getTxID());
|
||||
|
||||
presentationModel.state.addListener((ov, oldValue, newValue) -> applyTakerState(newValue));
|
||||
applyTakerState(presentationModel.state.get());
|
||||
}
|
||||
|
||||
private void applyTakerState(PendingTradesPM.State state) {
|
||||
log.debug("#### state " + state);
|
||||
if (state != null) {
|
||||
confirmPaymentReceiptButton.setVisible(false);
|
||||
switch (state) {
|
||||
case TAKER_SELLER_WAIT_TX_CONF:
|
||||
processBar.setSelectedIndex(0);
|
||||
statusTextField.setText("Deposit transaction is published. Waiting for at least 1 confirmation");
|
||||
infoDisplay.setText("Deposit transaction has bee published. He needs to wait for at least one " +
|
||||
"blockchain " +
|
||||
"confirmation.");
|
||||
break;
|
||||
case TAKER_SELLER_WAIT_PAYMENT_STARTED:
|
||||
processBar.setSelectedIndex(1);
|
||||
statusTextField.setText("Deposit transaction has at least 1 confirmation. Waiting that other " +
|
||||
"trader starts payment.");
|
||||
infoDisplay.setText("Deposit transaction has at least one blockchain " +
|
||||
"confirmation. The other trader need to start the payment. You will get informed when " +
|
||||
"that been done.");
|
||||
break;
|
||||
case TAKER_SELLER_CONFIRM_RECEIVE_PAYMENT:
|
||||
processBar.setSelectedIndex(2);
|
||||
statusTextField.setText("Payment is on the way. Check your payments account and confirm when you " +
|
||||
"have received the payment.");
|
||||
infoDisplay.setText("The other trader has started the payment. You need to check your payments " +
|
||||
"account and confirm the payment when the money has arrived there.");
|
||||
confirmPaymentReceiptButton.setVisible(true);
|
||||
break;
|
||||
case TAKER_SELLER_COMPLETED:
|
||||
processBar.setSelectedIndex(3);
|
||||
|
||||
statusTextField.setText("Trade has successfully completed.");
|
||||
infoDisplay.setText("Trade has successfully completed. You can find the details to that trade" +
|
||||
" in the closed trades section.");
|
||||
|
||||
summaryGroupBg.setVisible(true);
|
||||
btcLabel.setVisible(true);
|
||||
btcTextField.setVisible(true);
|
||||
fiatLabel.setVisible(true);
|
||||
fiatTextField.setVisible(true);
|
||||
feesLabel.setVisible(true);
|
||||
feesTextField.setVisible(true);
|
||||
collateralLabel.setVisible(true);
|
||||
collateralTextField.setVisible(true);
|
||||
summaryInfoDisplay.setVisible(true);
|
||||
|
||||
btcTextField.setText(presentationModel.getTradeVolume());
|
||||
fiatTextField.setText(presentationModel.getFiatVolume());
|
||||
feesTextField.setText(presentationModel.getTotalFees());
|
||||
collateralTextField.setText(presentationModel.getCollateral());
|
||||
summaryInfoDisplay.setText("You can open that summary any time in the closed orders section.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CellFactories
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private void setAmountColumnCellFactory() {
|
||||
amountColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue()));
|
||||
amountColumn.setCellFactory(
|
||||
new Callback<TableColumn<PendingTradesListItem, PendingTradesListItem>, TableCell<PendingTradesListItem,
|
||||
PendingTradesListItem>>() {
|
||||
@Override
|
||||
public TableCell<PendingTradesListItem, PendingTradesListItem> call(
|
||||
TableColumn<PendingTradesListItem, PendingTradesListItem> column) {
|
||||
return new TableCell<PendingTradesListItem, PendingTradesListItem>() {
|
||||
@Override
|
||||
public void updateItem(final PendingTradesListItem item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
setText(presentationModel.getAmount(item));
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setPriceColumnCellFactory() {
|
||||
priceColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue()));
|
||||
priceColumn.setCellFactory(
|
||||
new Callback<TableColumn<PendingTradesListItem, PendingTradesListItem>, TableCell<PendingTradesListItem,
|
||||
PendingTradesListItem>>() {
|
||||
@Override
|
||||
public TableCell<PendingTradesListItem, PendingTradesListItem> call(
|
||||
TableColumn<PendingTradesListItem, PendingTradesListItem> column) {
|
||||
return new TableCell<PendingTradesListItem, PendingTradesListItem>() {
|
||||
@Override
|
||||
public void updateItem(final PendingTradesListItem item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
setText(presentationModel.getPrice(item));
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setVolumeColumnCellFactory() {
|
||||
volumeColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue()));
|
||||
volumeColumn.setCellFactory(
|
||||
new Callback<TableColumn<PendingTradesListItem, PendingTradesListItem>, TableCell<PendingTradesListItem,
|
||||
PendingTradesListItem>>() {
|
||||
@Override
|
||||
public TableCell<PendingTradesListItem, PendingTradesListItem> call(
|
||||
TableColumn<PendingTradesListItem, PendingTradesListItem> column) {
|
||||
return new TableCell<PendingTradesListItem, PendingTradesListItem>() {
|
||||
@Override
|
||||
public void updateItem(final PendingTradesListItem item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
if (item != null)
|
||||
setText(presentationModel.getVolume(item));
|
||||
else
|
||||
setText("");
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setDirectionColumnCellFactory() {
|
||||
directionColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue()));
|
||||
directionColumn.setCellFactory(
|
||||
new Callback<TableColumn<PendingTradesListItem, PendingTradesListItem>, TableCell<PendingTradesListItem,
|
||||
PendingTradesListItem>>() {
|
||||
@Override
|
||||
public TableCell<PendingTradesListItem, PendingTradesListItem> call(
|
||||
TableColumn<PendingTradesListItem, PendingTradesListItem> column) {
|
||||
return new TableCell<PendingTradesListItem, PendingTradesListItem>() {
|
||||
@Override
|
||||
public void updateItem(final PendingTradesListItem item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
setText(presentationModel.getDirectionLabel(item));
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setCountryColumnCellFactory() {
|
||||
countryColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue()));
|
||||
countryColumn.setCellFactory(
|
||||
new Callback<TableColumn<PendingTradesListItem, PendingTradesListItem>, TableCell<PendingTradesListItem,
|
||||
PendingTradesListItem>>() {
|
||||
|
||||
@Override
|
||||
public TableCell<PendingTradesListItem, PendingTradesListItem> call(
|
||||
TableColumn<PendingTradesListItem, PendingTradesListItem> column) {
|
||||
return new TableCell<PendingTradesListItem, PendingTradesListItem>() {
|
||||
final HBox hBox = new HBox();
|
||||
|
||||
{
|
||||
hBox.setSpacing(3);
|
||||
hBox.setAlignment(Pos.CENTER);
|
||||
setGraphic(hBox);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateItem(final PendingTradesListItem item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
|
||||
hBox.getChildren().clear();
|
||||
if (item != null) {
|
||||
Country country = item.getOffer().getBankAccountCountry();
|
||||
hBox.getChildren().add(ImageUtil.getCountryIconImageView(item
|
||||
.getOffer().getBankAccountCountry()));
|
||||
Tooltip.install(this, new Tooltip(country.getName()));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setBankAccountTypeColumnCellFactory() {
|
||||
bankAccountTypeColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue()));
|
||||
bankAccountTypeColumn.setCellFactory(
|
||||
new Callback<TableColumn<PendingTradesListItem, PendingTradesListItem>, TableCell<PendingTradesListItem,
|
||||
PendingTradesListItem>>() {
|
||||
@Override
|
||||
public TableCell<PendingTradesListItem, PendingTradesListItem> call(
|
||||
TableColumn<PendingTradesListItem, PendingTradesListItem> column) {
|
||||
return new TableCell<PendingTradesListItem, PendingTradesListItem>() {
|
||||
@Override
|
||||
public void updateItem(final PendingTradesListItem item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
setText(presentationModel.getBankAccountType(item));
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setSelectColumnCellFactory() {
|
||||
selectColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper(offer.getValue()));
|
||||
selectColumn.setCellFactory(new Callback<TableColumn<PendingTradesListItem, PendingTradesListItem>,
|
||||
TableCell<PendingTradesListItem, PendingTradesListItem>>() {
|
||||
@Override
|
||||
public TableCell<PendingTradesListItem, PendingTradesListItem> call(
|
||||
TableColumn<PendingTradesListItem, PendingTradesListItem> column) {
|
||||
return new TableCell<PendingTradesListItem, PendingTradesListItem>() {
|
||||
final Button button = new Button("Select");
|
||||
|
||||
@Override
|
||||
public void updateItem(final PendingTradesListItem item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
|
||||
if (item != null) {
|
||||
button.setOnAction(event -> showTradeDetails(item));
|
||||
setGraphic(button);
|
||||
}
|
||||
else {
|
||||
setGraphic(null);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void showTradeDetails(PendingTradesListItem item) {
|
||||
presentationModel.selectPendingTrade(item);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -81,16 +81,15 @@ public class TradeViewCB extends CachedViewCB implements TradeNavigator {
|
|||
|
||||
@Override
|
||||
public void initialize(URL url, ResourceBundle rb) {
|
||||
direction = (this instanceof BuyViewCB) ? Direction.BUY : Direction.SELL;
|
||||
navigationItem = (direction == Direction.BUY) ? Navigation.Item.BUY : Navigation.Item.SELL;
|
||||
|
||||
listener = navigationItems -> {
|
||||
if (navigationItems != null && navigationItems.length == 3 && navigationItems[1] == navigationItem) {
|
||||
loadView(navigationItems[2]);
|
||||
}
|
||||
};
|
||||
|
||||
direction = (this instanceof BuyViewCB) ? Direction.BUY : Direction.SELL;
|
||||
// orderBookInfo.setDirection(direction);
|
||||
navigationItem = (direction == Direction.BUY) ? Navigation.Item.BUY : Navigation.Item.SELL;
|
||||
|
||||
super.initialize(url, rb);
|
||||
}
|
||||
|
||||
|
@ -126,6 +125,8 @@ public class TradeViewCB extends CachedViewCB implements TradeNavigator {
|
|||
@Override
|
||||
public void deactivate() {
|
||||
super.deactivate();
|
||||
|
||||
navigation.removeListener(listener);
|
||||
}
|
||||
|
||||
@SuppressWarnings("EmptyMethod")
|
||||
|
@ -225,9 +226,6 @@ public class TradeViewCB extends CachedViewCB implements TradeNavigator {
|
|||
log.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
else {
|
||||
log.error("navigationItem not supported: " + navigationItem);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
~ along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<?import io.bitsquare.gui.components.btc.AddressTextField?>
|
||||
<?import io.bitsquare.gui.components.btc.BalanceTextField?>
|
||||
<?import io.bitsquare.gui.components.AddressTextField?>
|
||||
<?import io.bitsquare.gui.components.BalanceTextField?>
|
||||
<?import io.bitsquare.gui.components.InfoDisplay?>
|
||||
<?import io.bitsquare.gui.components.InputTextField?>
|
||||
<?import io.bitsquare.gui.components.TitledGroupBg?>
|
||||
|
@ -77,7 +77,7 @@
|
|||
</VBox>
|
||||
<Label text="x">
|
||||
<font>
|
||||
<Font name="Helvetica" size="20.0"/>
|
||||
<Font name="Helvetica-Bold" size="20.0"/>
|
||||
</font>
|
||||
<padding>
|
||||
<Insets top="14.0" left="3" right="3"/>
|
||||
|
@ -96,7 +96,7 @@
|
|||
|
||||
<Label text="=">
|
||||
<font>
|
||||
<Font name="Helvetica" size="20.0"/>
|
||||
<Font name="Helvetica-Bold" size="20.0"/>
|
||||
</font>
|
||||
<padding>
|
||||
<Insets top="14.0" left="2" right="2"/>
|
||||
|
@ -127,7 +127,7 @@
|
|||
</HBox>
|
||||
</VBox>
|
||||
|
||||
<InfoDisplay gridPane="$gridPane" onAction="#onOpenGeneralHelp" rowIndex="2"
|
||||
<InfoDisplay gridPane="$gridPane" onAction="#onOpenGeneralHelp" rowIndex="2"
|
||||
text="%createOffer.amountPriceBox.info"/>
|
||||
|
||||
<Button fx:id="showPaymentInfoScreenButton" text="%createOffer.amountPriceBox.next" id="show-details-button"
|
||||
|
@ -245,7 +245,7 @@
|
|||
</TextField>
|
||||
|
||||
<InfoDisplay fx:id="advancedInfoDisplay" gridPane="$gridPane" onAction="#onOpenAdvancedSettingsHelp"
|
||||
rowIndex="15" visible="false"
|
||||
rowIndex="15" visible="false"
|
||||
text="%createOffer.advancedBox.info">
|
||||
</InfoDisplay>
|
||||
|
||||
|
|
|
@ -21,12 +21,12 @@ import io.bitsquare.gui.CachedViewCB;
|
|||
import io.bitsquare.gui.CloseListener;
|
||||
import io.bitsquare.gui.Navigation;
|
||||
import io.bitsquare.gui.OverlayManager;
|
||||
import io.bitsquare.gui.components.AddressTextField;
|
||||
import io.bitsquare.gui.components.BalanceTextField;
|
||||
import io.bitsquare.gui.components.InfoDisplay;
|
||||
import io.bitsquare.gui.components.InputTextField;
|
||||
import io.bitsquare.gui.components.Popups;
|
||||
import io.bitsquare.gui.components.TitledGroupBg;
|
||||
import io.bitsquare.gui.components.btc.AddressTextField;
|
||||
import io.bitsquare.gui.components.btc.BalanceTextField;
|
||||
import io.bitsquare.gui.main.help.Help;
|
||||
import io.bitsquare.gui.main.help.HelpId;
|
||||
import io.bitsquare.gui.util.ImageUtil;
|
||||
|
|
|
@ -31,7 +31,6 @@ import java.util.List;
|
|||
import javax.inject.Inject;
|
||||
|
||||
import javafx.animation.AnimationTimer;
|
||||
import javafx.beans.InvalidationListener;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
|
@ -58,7 +57,7 @@ public class OrderBook {
|
|||
private final ObservableList<OrderBookListItem> orderBookListItems = FXCollections.observableArrayList();
|
||||
private final OrderBookListener orderBookListener;
|
||||
private final ChangeListener<BankAccount> bankAccountChangeListener;
|
||||
private final InvalidationListener invalidationListener;
|
||||
private final ChangeListener<Number> invalidationListener;
|
||||
private String fiatCode;
|
||||
private AnimationTimer pollingTimer;
|
||||
private Country country;
|
||||
|
@ -75,7 +74,10 @@ public class OrderBook {
|
|||
this.user = user;
|
||||
|
||||
bankAccountChangeListener = (observableValue, oldValue, newValue) -> setBankAccount(newValue);
|
||||
invalidationListener = (ov) -> requestOffers();
|
||||
invalidationListener = (ov, oldValue, newValue) -> {
|
||||
log.debug("#### invalidationListener " + newValue);
|
||||
requestOffers();
|
||||
};
|
||||
|
||||
orderBookListener = new OrderBookListener() {
|
||||
@Override
|
||||
|
@ -142,12 +144,14 @@ public class OrderBook {
|
|||
}
|
||||
|
||||
private void addListeners() {
|
||||
log.debug("addListeners ");
|
||||
user.currentBankAccountProperty().addListener(bankAccountChangeListener);
|
||||
messageFacade.addOrderBookListener(orderBookListener);
|
||||
messageFacade.invalidationTimestampProperty().addListener(invalidationListener);
|
||||
}
|
||||
|
||||
private void removeListeners() {
|
||||
log.debug("removeListeners ");
|
||||
user.currentBankAccountProperty().removeListener(bankAccountChangeListener);
|
||||
messageFacade.removeOrderBookListener(orderBookListener);
|
||||
messageFacade.invalidationTimestampProperty().removeListener(invalidationListener);
|
||||
|
@ -160,6 +164,7 @@ public class OrderBook {
|
|||
}
|
||||
|
||||
private void requestOffers() {
|
||||
log.debug("#### requestOffers");
|
||||
messageFacade.getOffers(fiatCode);
|
||||
}
|
||||
|
||||
|
@ -173,7 +178,7 @@ public class OrderBook {
|
|||
addListeners();
|
||||
setBankAccount(user.getCurrentBankAccount());
|
||||
pollingTimer = Utilities.setInterval(1000, (animationTimer) -> {
|
||||
messageFacade.requestInvalidationTimeStamp(fiatCode);
|
||||
messageFacade.requestInvalidationTimeStampFromDHT(fiatCode);
|
||||
return null;
|
||||
});
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
</VBox>
|
||||
<Label text="x">
|
||||
<font>
|
||||
<Font name="Helvetica" size="20.0"/>
|
||||
<Font name="Helvetica-Bold" size="20.0"/>
|
||||
</font>
|
||||
<padding>
|
||||
<Insets top="14.0" left="3" right="3"/>
|
||||
|
@ -71,7 +71,7 @@
|
|||
|
||||
<Label text="=">
|
||||
<font>
|
||||
<Font name="Helvetica" size="20.0"/>
|
||||
<Font name="Helvetica-Bold" size="20.0"/>
|
||||
</font>
|
||||
<padding>
|
||||
<Insets top="14.0" left="2" right="2"/>
|
||||
|
|
|
@ -351,7 +351,7 @@ public class OrderBookViewCB extends CachedViewCB<OrderBookPM> {
|
|||
OrderBookListItem>>() {
|
||||
@Override
|
||||
public TableCell<OrderBookListItem, OrderBookListItem> call(
|
||||
TableColumn<OrderBookListItem, OrderBookListItem> directionColumn) {
|
||||
TableColumn<OrderBookListItem, OrderBookListItem> column) {
|
||||
return new TableCell<OrderBookListItem, OrderBookListItem>() {
|
||||
@Override
|
||||
public void updateItem(final OrderBookListItem item, boolean empty) {
|
||||
|
@ -370,7 +370,7 @@ public class OrderBookViewCB extends CachedViewCB<OrderBookPM> {
|
|||
OrderBookListItem>>() {
|
||||
@Override
|
||||
public TableCell<OrderBookListItem, OrderBookListItem> call(
|
||||
TableColumn<OrderBookListItem, OrderBookListItem> directionColumn) {
|
||||
TableColumn<OrderBookListItem, OrderBookListItem> column) {
|
||||
return new TableCell<OrderBookListItem, OrderBookListItem>() {
|
||||
@Override
|
||||
public void updateItem(final OrderBookListItem item, boolean empty) {
|
||||
|
@ -389,7 +389,7 @@ public class OrderBookViewCB extends CachedViewCB<OrderBookPM> {
|
|||
OrderBookListItem>>() {
|
||||
@Override
|
||||
public TableCell<OrderBookListItem, OrderBookListItem> call(
|
||||
TableColumn<OrderBookListItem, OrderBookListItem> directionColumn) {
|
||||
TableColumn<OrderBookListItem, OrderBookListItem> column) {
|
||||
return new TableCell<OrderBookListItem, OrderBookListItem>() {
|
||||
@Override
|
||||
public void updateItem(final OrderBookListItem item, boolean empty) {
|
||||
|
@ -409,7 +409,7 @@ public class OrderBookViewCB extends CachedViewCB<OrderBookPM> {
|
|||
|
||||
@Override
|
||||
public TableCell<OrderBookListItem, OrderBookListItem> call(
|
||||
TableColumn<OrderBookListItem, OrderBookListItem> directionColumn) {
|
||||
TableColumn<OrderBookListItem, OrderBookListItem> column) {
|
||||
return new TableCell<OrderBookListItem, OrderBookListItem>() {
|
||||
final ImageView iconView = new ImageView();
|
||||
final Button button = new Button();
|
||||
|
@ -493,7 +493,7 @@ public class OrderBookViewCB extends CachedViewCB<OrderBookPM> {
|
|||
|
||||
@Override
|
||||
public TableCell<OrderBookListItem, OrderBookListItem> call(
|
||||
TableColumn<OrderBookListItem, OrderBookListItem> directionColumn) {
|
||||
TableColumn<OrderBookListItem, OrderBookListItem> column) {
|
||||
return new TableCell<OrderBookListItem, OrderBookListItem>() {
|
||||
final HBox hBox = new HBox();
|
||||
|
||||
|
@ -527,7 +527,7 @@ public class OrderBookViewCB extends CachedViewCB<OrderBookPM> {
|
|||
OrderBookListItem>>() {
|
||||
@Override
|
||||
public TableCell<OrderBookListItem, OrderBookListItem> call(
|
||||
TableColumn<OrderBookListItem, OrderBookListItem> directionColumn) {
|
||||
TableColumn<OrderBookListItem, OrderBookListItem> column) {
|
||||
return new TableCell<OrderBookListItem, OrderBookListItem>() {
|
||||
@Override
|
||||
public void updateItem(final OrderBookListItem orderBookListItem, boolean empty) {
|
||||
|
|
|
@ -26,8 +26,6 @@ import io.bitsquare.settings.Settings;
|
|||
import io.bitsquare.trade.Offer;
|
||||
import io.bitsquare.trade.Trade;
|
||||
import io.bitsquare.trade.TradeManager;
|
||||
import io.bitsquare.trade.protocol.trade.taker.SellerTakesOfferProtocol;
|
||||
import io.bitsquare.trade.protocol.trade.taker.SellerTakesOfferProtocolListener;
|
||||
|
||||
import com.google.bitcoin.core.Coin;
|
||||
import com.google.bitcoin.utils.ExchangeRate;
|
||||
|
@ -155,116 +153,24 @@ class TakeOfferModel extends UIModel {
|
|||
}
|
||||
|
||||
void takeOffer() {
|
||||
// data validation is done in the trade domain
|
||||
/*tradeManager.requestPlaceOffer(orderBookInfo.getOffer().getId(),
|
||||
orderBookInfo.getOffer().getDirection(),
|
||||
priceAsFiat.get(),
|
||||
amountAsCoin.get(),
|
||||
minAmountAsCoin.get(),
|
||||
(transaction) -> {
|
||||
transactionId.set(transaction.getHashAsString());
|
||||
Trade trade = tradeManager.takeOffer(amountAsCoin.get(), offer);
|
||||
trade.stateProperty().addListener((ov, oldValue, newValue) -> {
|
||||
switch (newValue) {
|
||||
case DEPOSIT_PUBLISHED:
|
||||
transactionId.set(trade.getDepositTx().getHashAsString());
|
||||
requestTakeOfferSuccess.set(true);
|
||||
},
|
||||
requestTakeOfferErrorMessage::set
|
||||
);*/
|
||||
SellerTakesOfferProtocolListener listener = new SellerTakesOfferProtocolListener() {
|
||||
@Override
|
||||
public void onDepositTxPublished(String depositTxId) {
|
||||
transactionId.set(depositTxId);
|
||||
requestTakeOfferSuccess.set(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBankTransferInited(String tradeId) {
|
||||
break;
|
||||
case FAULT:
|
||||
requestTakeOfferErrorMessage.set("An error occurred. Error: " + trade.getFault().getMessage());
|
||||
break;
|
||||
case OFFERER_REJECTED:
|
||||
requestTakeOfferErrorMessage.set("Take offer request got rejected.");
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPayoutTxPublished(Trade trade, String hashAsString) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFault(Throwable throwable, SellerTakesOfferProtocol.State state) {
|
||||
requestTakeOfferErrorMessage.set("An error occurred. Error: " + throwable.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWaitingForPeerResponse(SellerTakesOfferProtocol.State state) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCompleted(SellerTakesOfferProtocol.State state) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTakeOfferRequestRejected(Trade trade) {
|
||||
requestTakeOfferErrorMessage.set("Take offer request got rejected.");
|
||||
}
|
||||
};
|
||||
|
||||
tradeManager.takeOffer(amountAsCoin.get(), offer, listener);
|
||||
/*new SellerTakesOfferProtocolListener() {
|
||||
@Override
|
||||
public void onDepositTxPublished(String depositTxId) {
|
||||
setDepositTxId(depositTxId);
|
||||
accordion.setExpandedPane(waitBankTxTitledPane);
|
||||
infoLabel.setText("Deposit transaction published by offerer.\n" +
|
||||
"As soon as the offerer starts the \n" +
|
||||
"Bank transfer, you will be informed.");
|
||||
depositTxIdTextField.setText(depositTxId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBankTransferInited(String tradeId) {
|
||||
setTradeId(tradeId);
|
||||
headLineLabel.setText("Bank transfer initiated");
|
||||
infoLabel.setText("Check your bank account and continue \n" + "when you have received the money.");
|
||||
receivedFiatButton.setDisable(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPayoutTxPublished(Trade trade, String payoutTxId) {
|
||||
accordion.setExpandedPane(summaryTitledPane);
|
||||
|
||||
summaryPaidTextField.setText(BSFormatter.formatCoinWithCode(trade.getTradeAmount()));
|
||||
summaryReceivedTextField.setText(BSFormatter.formatFiat(trade.getTradeVolume()));
|
||||
summaryFeesTextField.setText(BSFormatter.formatCoinWithCode(
|
||||
FeePolicy.TAKE_OFFER_FEE.add(FeePolicy.TX_FEE)));
|
||||
summaryCollateralTextField.setText(BSFormatter.formatCoinWithCode(
|
||||
trade.getCollateralAmount()));
|
||||
summaryDepositTxIdTextField.setText(depositTxId);
|
||||
summaryPayoutTxIdTextField.setText(payoutTxId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFault(Throwable throwable, SellerTakesOfferProtocol.State state) {
|
||||
log.error("Error while executing trade process at state: " + state + " / " + throwable);
|
||||
Popups.openErrorPopup("Error while executing trade process",
|
||||
"Error while executing trade process at state: " + state + " / " + throwable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWaitingForPeerResponse(SellerTakesOfferProtocol.State state) {
|
||||
log.debug("Waiting for peers response at state " + state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCompleted(SellerTakesOfferProtocol.State state) {
|
||||
log.debug("Trade protocol completed at state " + state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTakeOfferRequestRejected(Trade trade) {
|
||||
log.error("Take offer request rejected");
|
||||
Popups.openErrorPopup("Take offer request rejected",
|
||||
"Your take offer request has been rejected. It might be that the offerer got another " +
|
||||
"request shortly before your request arrived.");
|
||||
}
|
||||
});*/
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
void calculateVolume() {
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
~ along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<?import io.bitsquare.gui.components.btc.AddressTextField?>
|
||||
<?import io.bitsquare.gui.components.btc.BalanceTextField?>
|
||||
<?import io.bitsquare.gui.components.AddressTextField?>
|
||||
<?import io.bitsquare.gui.components.BalanceTextField?>
|
||||
<?import io.bitsquare.gui.components.InfoDisplay?>
|
||||
<?import io.bitsquare.gui.components.InputTextField?>
|
||||
<?import io.bitsquare.gui.components.TitledGroupBg?>
|
||||
|
@ -77,7 +77,7 @@
|
|||
</VBox>
|
||||
<Label text="x">
|
||||
<font>
|
||||
<Font name="Helvetica" size="20.0"/>
|
||||
<Font name="Helvetica-Bold" size="20.0"/>
|
||||
</font>
|
||||
<padding>
|
||||
<Insets top="14.0" left="3" right="3"/>
|
||||
|
@ -92,7 +92,7 @@
|
|||
|
||||
<Label text="=">
|
||||
<font>
|
||||
<Font name="Helvetica" size="20.0"/>
|
||||
<Font name="Helvetica-Bold" size="20.0"/>
|
||||
</font>
|
||||
<padding>
|
||||
<Insets top="14.0" left="2" right="2"/>
|
||||
|
|
|
@ -22,12 +22,12 @@ import io.bitsquare.gui.CachedViewCB;
|
|||
import io.bitsquare.gui.CloseListener;
|
||||
import io.bitsquare.gui.Navigation;
|
||||
import io.bitsquare.gui.OverlayManager;
|
||||
import io.bitsquare.gui.components.AddressTextField;
|
||||
import io.bitsquare.gui.components.BalanceTextField;
|
||||
import io.bitsquare.gui.components.InfoDisplay;
|
||||
import io.bitsquare.gui.components.InputTextField;
|
||||
import io.bitsquare.gui.components.Popups;
|
||||
import io.bitsquare.gui.components.TitledGroupBg;
|
||||
import io.bitsquare.gui.components.btc.AddressTextField;
|
||||
import io.bitsquare.gui.components.btc.BalanceTextField;
|
||||
import io.bitsquare.gui.main.help.Help;
|
||||
import io.bitsquare.gui.main.help.HelpId;
|
||||
import io.bitsquare.gui.util.ImageUtil;
|
||||
|
@ -318,6 +318,8 @@ public class TakeOfferViewCB extends CachedViewCB<TakeOfferPM> {
|
|||
public void handle(ActionEvent actionEvent) {
|
||||
try {
|
||||
close();
|
||||
navigation.navigationTo(Navigation.Item.MAIN, Navigation.Item.ORDERS,
|
||||
Navigation.Item.PENDING_TRADES);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
|
|
@ -20,8 +20,10 @@ package io.bitsquare.gui.util;
|
|||
import javafx.scene.paint.*;
|
||||
|
||||
public class Colors {
|
||||
public static final Paint BLUE = Color.valueOf("#0096c9");
|
||||
public static final Paint LIGHT_GREY = Color.valueOf("#f4f4f4");
|
||||
public static final Paint BLUE = Color.valueOf("#0f87c3");
|
||||
public static final Paint LIGHT_GREY = Color.valueOf("#AAAAAA");
|
||||
public static final Paint MID_GREY = Color.valueOf("#666666");
|
||||
public static final Paint DARK_GREY = Color.valueOf("#333333");
|
||||
public static final Paint GREEN = Color.valueOf("#00AA00");
|
||||
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ import com.google.common.base.Stopwatch;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javafx.animation.AnimationTimer;
|
||||
import javafx.scene.*;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -59,11 +60,21 @@ public class Profiler {
|
|||
counter++;
|
||||
long elapsed = (System.currentTimeMillis() - lastFPSTime);
|
||||
if (elapsed > 19)
|
||||
log.trace("FPS: elapsed: {}ms / FPS total counter: {}", elapsed, counter);
|
||||
log.trace("Profiler: last frame used {}ms", elapsed);
|
||||
|
||||
lastFPSTime = System.currentTimeMillis();
|
||||
}
|
||||
};
|
||||
fpsTimer.start();
|
||||
}
|
||||
|
||||
public static void initScene(Scene scene) {
|
||||
/* PerformanceTracker tracker = PerformanceTracker.getSceneTracker(scene);
|
||||
Timeline timeline = new Timeline(
|
||||
new KeyFrame(Duration.seconds(1), t -> {
|
||||
log.trace("FPS (tracker.getAverageFPS) = " + tracker.getAverageFPS());
|
||||
}));
|
||||
timeline.setCycleCount(Timeline.INDEFINITE);
|
||||
timeline.play();*/
|
||||
}
|
||||
}
|
||||
|
|
|
@ -191,7 +191,7 @@ public class MessageFacade implements MessageBroker {
|
|||
});
|
||||
|
||||
// TODO will be removed when we don't use polling anymore
|
||||
updateInvalidationTimestamp(locationKey);
|
||||
writeInvalidationTimestampToDHT(locationKey);
|
||||
log.trace("Add offer to DHT was successful. Added data: [locationKey: " + locationKey +
|
||||
", value: " + offerData + "]");
|
||||
});
|
||||
|
@ -246,7 +246,7 @@ public class MessageFacade implements MessageBroker {
|
|||
log.error("Remove offer from DHT failed. Error: " + e.getMessage());
|
||||
}
|
||||
});
|
||||
updateInvalidationTimestamp(locationKey);
|
||||
writeInvalidationTimestampToDHT(locationKey);
|
||||
});
|
||||
|
||||
log.trace("Remove offer from DHT was successful. Removed data: [key: " + locationKey + ", " +
|
||||
|
@ -448,7 +448,7 @@ public class MessageFacade implements MessageBroker {
|
|||
// Polling
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private void updateInvalidationTimestamp(Number160 locationKey) {
|
||||
private void writeInvalidationTimestampToDHT(Number160 locationKey) {
|
||||
invalidationTimestamp.set(System.currentTimeMillis());
|
||||
try {
|
||||
FuturePut putFuture = p2pNode.putData(getInvalidatedLocationKey(locationKey),
|
||||
|
@ -477,7 +477,7 @@ public class MessageFacade implements MessageBroker {
|
|||
return invalidationTimestamp;
|
||||
}
|
||||
|
||||
public void requestInvalidationTimeStamp(String currencyCode) {
|
||||
public void requestInvalidationTimeStampFromDHT(String currencyCode) {
|
||||
Number160 locationKey = Number160.createHash(currencyCode);
|
||||
try {
|
||||
FutureGet getFuture = p2pNode.getData(getInvalidatedLocationKey(locationKey));
|
||||
|
@ -490,8 +490,8 @@ public class MessageFacade implements MessageBroker {
|
|||
final Object object = data.object();
|
||||
Platform.runLater(() -> {
|
||||
Long timeStamp = (Long) object;
|
||||
// log.trace("Get invalidationTimestamp from DHT was successful. TimeStamp=" +
|
||||
// timeStamp);
|
||||
log.trace("Get invalidationTimestamp from DHT was successful. TimeStamp=" +
|
||||
timeStamp);
|
||||
invalidationTimestamp.set(timeStamp);
|
||||
});
|
||||
}
|
||||
|
@ -499,6 +499,10 @@ public class MessageFacade implements MessageBroker {
|
|||
log.error("Get invalidationTimestamp from DHT failed. Data = " + data);
|
||||
}
|
||||
}
|
||||
else if (getFuture.data() == null) {
|
||||
// OK as nothing is set at the moment
|
||||
log.trace("Get invalidationTimestamp from DHT returns null. That is ok for the startup.");
|
||||
}
|
||||
else {
|
||||
log.error("Get invalidationTimestamp from DHT failed with reason:" + getFuture.failedReason());
|
||||
}
|
||||
|
|
|
@ -23,44 +23,62 @@ import com.google.bitcoin.utils.Fiat;
|
|||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
|
||||
//TODO flatten down?
|
||||
|
||||
public class Trade implements Serializable {
|
||||
private static final long serialVersionUID = -8275323072940974077L;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Enum
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public static enum State {
|
||||
OPEN,
|
||||
OFFERER_ACCEPTED,
|
||||
OFFERER_REJECTED, /* For taker only*/
|
||||
DEPOSIT_PUBLISHED,
|
||||
DEPOSIT_CONFIRMED,
|
||||
PAYMENT_STARTED,
|
||||
PAYMENT_RECEIVED, /* For taker only*/
|
||||
PAYOUT_PUBLISHED,
|
||||
FAULT
|
||||
}
|
||||
|
||||
|
||||
private final Offer offer;
|
||||
private String takeOfferFeeTxID;
|
||||
private Coin tradeAmount;
|
||||
private Contract contract;
|
||||
private String contractAsJson;
|
||||
private String takerSignature;
|
||||
private Transaction depositTransaction;
|
||||
private Transaction payoutTransaction;
|
||||
private State state = State.OPEN;
|
||||
private Transaction depositTx;
|
||||
private Transaction payoutTx;
|
||||
private State state;
|
||||
private Throwable fault;
|
||||
|
||||
// The Property fields are not serialized and therefore not initialized when read from disc.
|
||||
// We need to access then with the getter to be sure it is not null.
|
||||
// Don't access them directly, use the getter method
|
||||
transient private SimpleBooleanProperty _depositTxChangedProperty;
|
||||
transient private SimpleBooleanProperty _payoutTxChangedProperty;
|
||||
transient private SimpleBooleanProperty _contractChangedProperty;
|
||||
transient private SimpleStringProperty _stateChangedProperty;
|
||||
// When serialized those transient properties are not instantiated, so we instantiate them in the getters at first
|
||||
// access. Only use the accessor not the private field.
|
||||
// TODO use ObjectPropertys instead of BooleanProperty
|
||||
transient private BooleanProperty _payoutTxChanged;
|
||||
transient private BooleanProperty _contractChanged;
|
||||
transient private ObjectProperty<Transaction> _depositTx;
|
||||
transient private ObjectProperty<State> _state;
|
||||
transient private ObjectProperty<Throwable> _fault;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public Trade(Offer offer) {
|
||||
this.offer = offer;
|
||||
|
||||
_depositTxChangedProperty = new SimpleBooleanProperty();
|
||||
_payoutTxChangedProperty = new SimpleBooleanProperty();
|
||||
_contractChangedProperty = new SimpleBooleanProperty();
|
||||
_stateChangedProperty = new SimpleStringProperty();
|
||||
state = State.OPEN;
|
||||
}
|
||||
|
||||
public Fiat getTradeVolume() {
|
||||
return offer.getVolumeByAmount(tradeAmount);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Setters
|
||||
|
@ -86,9 +104,65 @@ public class Trade implements Serializable {
|
|||
return contract;
|
||||
}
|
||||
|
||||
public void setContractAsJson(String contractAsJson) {
|
||||
this.contractAsJson = contractAsJson;
|
||||
}
|
||||
|
||||
public void setContract(Contract contract) {
|
||||
this.contract = contract;
|
||||
_contractChangedProperty.set(!_contractChangedProperty.get());
|
||||
contractChangedProperty().set(!contractChangedProperty().get());
|
||||
}
|
||||
|
||||
public void setDepositTx(Transaction tx) {
|
||||
this.depositTx = tx;
|
||||
depositTxProperty().set(tx);
|
||||
}
|
||||
|
||||
public void setPayoutTx(Transaction tx) {
|
||||
this.payoutTx = tx;
|
||||
payoutTxChangedProperty().set(!payoutTxChangedProperty().get());
|
||||
}
|
||||
|
||||
public void setState(State state) {
|
||||
this.state = state;
|
||||
stateProperty().set(state);
|
||||
}
|
||||
|
||||
public void setFault(Throwable fault) {
|
||||
this.fault = fault;
|
||||
faultProperty().set(fault);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Getters
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public Fiat getTradeVolume() {
|
||||
return offer.getVolumeByAmount(tradeAmount);
|
||||
}
|
||||
|
||||
public String getTakerSignature() {
|
||||
return takerSignature;
|
||||
}
|
||||
|
||||
public Transaction getDepositTx() {
|
||||
return depositTx;
|
||||
}
|
||||
|
||||
public Transaction getPayoutTx() {
|
||||
return payoutTx;
|
||||
}
|
||||
|
||||
public State getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public Throwable getFault() {
|
||||
return fault;
|
||||
}
|
||||
|
||||
public Coin getCollateralAmount() {
|
||||
return tradeAmount.multiply(offer.getCollateral()).divide(1000L);
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
|
@ -107,99 +181,40 @@ public class Trade implements Serializable {
|
|||
return contractAsJson;
|
||||
}
|
||||
|
||||
// When serialized those transient properties are not instantiated, so we need to instantiate them at first access
|
||||
public ObjectProperty<Transaction> depositTxProperty() {
|
||||
if (_depositTx == null)
|
||||
_depositTx = new SimpleObjectProperty<>(depositTx);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Getters
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void setContractAsJson(String contractAsJson) {
|
||||
this.contractAsJson = contractAsJson;
|
||||
return _depositTx;
|
||||
}
|
||||
|
||||
public String getTakerSignature() {
|
||||
return takerSignature;
|
||||
public BooleanProperty contractChangedProperty() {
|
||||
if (_contractChanged == null)
|
||||
_contractChanged = new SimpleBooleanProperty();
|
||||
|
||||
return _contractChanged;
|
||||
}
|
||||
|
||||
public Transaction getDepositTransaction() {
|
||||
return depositTransaction;
|
||||
public BooleanProperty payoutTxChangedProperty() {
|
||||
if (_payoutTxChanged == null)
|
||||
_payoutTxChanged = new SimpleBooleanProperty();
|
||||
|
||||
return _payoutTxChanged;
|
||||
}
|
||||
|
||||
public void setDepositTransaction(Transaction depositTransaction) {
|
||||
this.depositTransaction = depositTransaction;
|
||||
depositTxChangedProperty().set(!depositTxChangedProperty().get());
|
||||
public ObjectProperty<State> stateProperty() {
|
||||
if (_state == null)
|
||||
_state = new SimpleObjectProperty<>(state);
|
||||
|
||||
return _state;
|
||||
}
|
||||
|
||||
public Transaction getPayoutTransaction() {
|
||||
return payoutTransaction;
|
||||
}
|
||||
|
||||
public void setPayoutTransaction(Transaction payoutTransaction) {
|
||||
this.payoutTransaction = payoutTransaction;
|
||||
payoutTxChangedProperty().set(!payoutTxChangedProperty().get());
|
||||
}
|
||||
|
||||
public State getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public void setState(State state) {
|
||||
this.state = state;
|
||||
stateChangedProperty().set(state.toString());
|
||||
}
|
||||
|
||||
// The Property fields are not serialized and therefore not initialized when read from disc.
|
||||
// We need to access then with the getter to be sure it is not null.
|
||||
public SimpleBooleanProperty depositTxChangedProperty() {
|
||||
if (_depositTxChangedProperty == null) _depositTxChangedProperty = new SimpleBooleanProperty();
|
||||
|
||||
return _depositTxChangedProperty;
|
||||
public ObjectProperty<Throwable> faultProperty() {
|
||||
if (_fault == null)
|
||||
_fault = new SimpleObjectProperty<>(fault);
|
||||
return _fault;
|
||||
}
|
||||
|
||||
|
||||
public SimpleBooleanProperty contractChangedProperty() {
|
||||
if (_contractChangedProperty == null) _contractChangedProperty = new SimpleBooleanProperty();
|
||||
return _contractChangedProperty;
|
||||
}
|
||||
|
||||
|
||||
public SimpleBooleanProperty payoutTxChangedProperty() {
|
||||
if (_payoutTxChangedProperty == null) _payoutTxChangedProperty = new SimpleBooleanProperty();
|
||||
return _payoutTxChangedProperty;
|
||||
}
|
||||
|
||||
|
||||
public SimpleStringProperty stateChangedProperty() {
|
||||
if (_stateChangedProperty == null) _stateChangedProperty = new SimpleStringProperty();
|
||||
return _stateChangedProperty;
|
||||
}
|
||||
|
||||
public Coin getCollateralAmount() {
|
||||
return tradeAmount.multiply(offer.getCollateral()).divide(1000L);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Trade{" +
|
||||
"offer=" + offer +
|
||||
", takeOfferFeeTxID='" + takeOfferFeeTxID + '\'' +
|
||||
", tradeAmount=" + tradeAmount +
|
||||
", contract=" + contract +
|
||||
", contractAsJson='" + contractAsJson + '\'' +
|
||||
", takerSignature='" + takerSignature + '\'' +
|
||||
", depositTransaction=" + depositTransaction +
|
||||
", state=" + state +
|
||||
'}';
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// toString
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
public static enum State {
|
||||
OPEN,
|
||||
ACCEPTED,
|
||||
COMPLETED
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,8 +44,6 @@ import io.bitsquare.user.User;
|
|||
|
||||
import com.google.bitcoin.core.Coin;
|
||||
import com.google.bitcoin.core.Transaction;
|
||||
import com.google.bitcoin.core.TransactionConfidence;
|
||||
import com.google.bitcoin.core.Utils;
|
||||
import com.google.bitcoin.utils.Fiat;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -57,8 +55,8 @@ import java.util.Map;
|
|||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableMap;
|
||||
|
||||
import net.tomp2p.peers.PeerAddress;
|
||||
|
||||
|
@ -89,13 +87,11 @@ public class TradeManager {
|
|||
private final Map<String, BuyerAcceptsOfferProtocol> offererAsBuyerProtocolMap = new HashMap<>();
|
||||
private final Map<String, CreateOfferCoordinator> createOfferCoordinatorMap = new HashMap<>();
|
||||
|
||||
private final StringProperty newTradeProperty = new SimpleStringProperty();
|
||||
|
||||
private final Map<String, Offer> offers;
|
||||
private final Map<String, Trade> trades;
|
||||
private final ObservableMap<String, Offer> offers = FXCollections.observableHashMap();
|
||||
private final ObservableMap<String, Trade> trades = FXCollections.observableHashMap();
|
||||
|
||||
// TODO There might be multiple pending trades
|
||||
private Trade pendingTrade;
|
||||
private Trade currentPendingTrade;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -115,18 +111,12 @@ public class TradeManager {
|
|||
|
||||
Object offersObject = persistence.read(this, "offers");
|
||||
if (offersObject instanceof HashMap) {
|
||||
offers = (Map<String, Offer>) offersObject;
|
||||
}
|
||||
else {
|
||||
offers = new HashMap<>();
|
||||
offers.putAll((Map<String, Offer>) offersObject);
|
||||
}
|
||||
|
||||
Object tradesObject = persistence.read(this, "trades");
|
||||
if (tradesObject instanceof HashMap) {
|
||||
trades = (Map<String, Trade>) tradesObject;
|
||||
}
|
||||
else {
|
||||
trades = new HashMap<>();
|
||||
trades.putAll((Map<String, Trade>) tradesObject);
|
||||
}
|
||||
|
||||
messageFacade.addIncomingTradeMessageListener(this::onIncomingTradeMessage);
|
||||
|
@ -200,7 +190,8 @@ public class TradeManager {
|
|||
resultHandler.onResult(transactionId);
|
||||
} catch (Exception e) {
|
||||
//TODO retry policy
|
||||
errorMessageHandler.onFault("Could not save offer. Reason: " + e.getCause().getMessage());
|
||||
errorMessageHandler.onFault("Could not save offer. Reason: " +
|
||||
(e.getCause() != null ? e.getCause().getMessage() : e.toString()));
|
||||
createOfferCoordinatorMap.remove(offer.getId());
|
||||
}
|
||||
},
|
||||
|
@ -231,18 +222,6 @@ public class TradeManager {
|
|||
messageFacade.removeOffer(offer);
|
||||
}
|
||||
|
||||
public Trade takeOffer(Coin amount, Offer offer, SellerTakesOfferProtocolListener listener) {
|
||||
Trade trade = createTrade(offer);
|
||||
trade.setTradeAmount(amount);
|
||||
|
||||
SellerTakesOfferProtocol sellerTakesOfferProtocol = new SellerTakesOfferProtocol(
|
||||
trade, listener, messageFacade, walletFacade, blockChainFacade, cryptoFacade, user);
|
||||
takerAsSellerProtocolMap.put(trade.getId(), sellerTakesOfferProtocol);
|
||||
sellerTakesOfferProtocol.start();
|
||||
|
||||
return trade;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Manage trades
|
||||
|
@ -254,10 +233,7 @@ public class TradeManager {
|
|||
|
||||
Trade trade = new Trade(offer);
|
||||
trades.put(offer.getId(), trade);
|
||||
saveTrades();
|
||||
|
||||
// for updating UIs
|
||||
this.newTradeProperty.set(trade.getId());
|
||||
persistTrades();
|
||||
|
||||
return trade;
|
||||
}
|
||||
|
@ -267,10 +243,7 @@ public class TradeManager {
|
|||
log.error("trades does not contain the trade with the ID " + trade.getId());
|
||||
|
||||
trades.remove(trade.getId());
|
||||
saveTrades();
|
||||
|
||||
// for updating UIs
|
||||
this.newTradeProperty.set(null);
|
||||
persistTrades();
|
||||
}
|
||||
|
||||
|
||||
|
@ -284,7 +257,7 @@ public class TradeManager {
|
|||
Offer offer = offers.get(offerId);
|
||||
|
||||
Trade trade = createTrade(offer);
|
||||
pendingTrade = trade;
|
||||
currentPendingTrade = trade;
|
||||
|
||||
BuyerAcceptsOfferProtocol buyerAcceptsOfferProtocol = new BuyerAcceptsOfferProtocol(trade,
|
||||
sender,
|
||||
|
@ -296,57 +269,54 @@ public class TradeManager {
|
|||
new BuyerAcceptsOfferProtocolListener() {
|
||||
@Override
|
||||
public void onOfferAccepted(Offer offer) {
|
||||
trade.setState(Trade.State.OFFERER_ACCEPTED);
|
||||
persistTrades();
|
||||
removeOffer(offer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDepositTxPublished(String depositTxID) {
|
||||
log.trace("trading onDepositTxPublishedMessage " + depositTxID);
|
||||
public void onDepositTxPublished(Transaction depositTx) {
|
||||
trade.setDepositTx(depositTx);
|
||||
trade.setState(Trade.State.DEPOSIT_PUBLISHED);
|
||||
persistTrades();
|
||||
log.trace("trading onDepositTxPublishedMessage " + depositTx.getHashAsString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDepositTxConfirmedUpdate(TransactionConfidence confidence) {
|
||||
log.trace("trading onDepositTxConfirmedUpdate");
|
||||
public void onDepositTxConfirmedInBlockchain() {
|
||||
log.trace("trading onDepositTxConfirmedInBlockchain");
|
||||
trade.setState(Trade.State.DEPOSIT_CONFIRMED);
|
||||
persistTrades();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onPayoutTxPublished(String payoutTxAsHex) {
|
||||
Transaction payoutTx = new Transaction(walletFacade.getWallet().getParams(),
|
||||
Utils.parseAsHexOrBase58(payoutTxAsHex));
|
||||
trade.setPayoutTransaction(payoutTx);
|
||||
trade.setState(Trade.State.COMPLETED);
|
||||
public void onPayoutTxPublished(Transaction payoutTx) {
|
||||
trade.setPayoutTx(payoutTx);
|
||||
trade.setState(Trade.State.PAYOUT_PUBLISHED);
|
||||
persistTrades();
|
||||
log.debug("trading onPayoutTxPublishedMessage");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFault(Throwable throwable, BuyerAcceptsOfferProtocol.State state) {
|
||||
log.error("Error while executing trade process at state: " + state + " / " + throwable);
|
||||
/* Popups.openErrorPopup("Error while executing trade process",
|
||||
"Error while executing trade process at state: " + state + " / " +
|
||||
throwable);*/
|
||||
trade.setFault(throwable);
|
||||
trade.setState(Trade.State.FAULT);
|
||||
persistTrades();
|
||||
}
|
||||
|
||||
// probably not needed
|
||||
@Override
|
||||
public void onWaitingForPeerResponse(BuyerAcceptsOfferProtocol.State state) {
|
||||
log.debug("Waiting for peers response at state " + state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCompleted(BuyerAcceptsOfferProtocol.State state) {
|
||||
log.debug("Trade protocol completed at state " + state);
|
||||
}
|
||||
|
||||
// probably not needed
|
||||
@Override
|
||||
public void onWaitingForUserInteraction(BuyerAcceptsOfferProtocol.State state) {
|
||||
log.debug("Waiting for UI activity at state " + state);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onDepositTxConfirmedInBlockchain() {
|
||||
log.trace("trading onDepositTxConfirmedInBlockchain");
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
if (!offererAsBuyerProtocolMap.containsKey(trade.getId())) {
|
||||
|
@ -365,18 +335,91 @@ public class TradeManager {
|
|||
}
|
||||
}
|
||||
|
||||
public void bankTransferInited(String tradeUID) {
|
||||
offererAsBuyerProtocolMap.get(tradeUID).onUIEventBankTransferInited();
|
||||
public Trade takeOffer(Coin amount, Offer offer) {
|
||||
Trade trade = createTrade(offer);
|
||||
trade.setTradeAmount(amount);
|
||||
|
||||
currentPendingTrade = trade;
|
||||
SellerTakesOfferProtocolListener listener = new SellerTakesOfferProtocolListener() {
|
||||
@Override
|
||||
public void onTakeOfferRequestAccepted(Trade trade) {
|
||||
trade.setState(Trade.State.OFFERER_ACCEPTED);
|
||||
persistTrades();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTakeOfferRequestRejected(Trade trade) {
|
||||
trade.setState(Trade.State.OFFERER_REJECTED);
|
||||
persistTrades();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDepositTxPublished(Transaction depositTx) {
|
||||
trade.setDepositTx(depositTx);
|
||||
trade.setState(Trade.State.DEPOSIT_PUBLISHED);
|
||||
persistTrades();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBankTransferInited(String tradeId) {
|
||||
trade.setState(Trade.State.PAYMENT_STARTED);
|
||||
persistTrades();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPayoutTxPublished(Trade trade, Transaction payoutTx) {
|
||||
trade.setState(Trade.State.PAYOUT_PUBLISHED);
|
||||
trade.setPayoutTx(payoutTx);
|
||||
persistTrades();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFault(Throwable throwable, SellerTakesOfferProtocol.State state) {
|
||||
log.error("onFault: " + throwable.getMessage() + " / " + state);
|
||||
}
|
||||
|
||||
// probably not needed
|
||||
@Override
|
||||
public void onWaitingForPeerResponse(SellerTakesOfferProtocol.State state) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCompleted(SellerTakesOfferProtocol.State state) {
|
||||
trade.setState(Trade.State.PAYMENT_RECEIVED);
|
||||
persistTrades();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
SellerTakesOfferProtocol sellerTakesOfferProtocol = new SellerTakesOfferProtocol(
|
||||
trade, listener, messageFacade, walletFacade, blockChainFacade, cryptoFacade,
|
||||
user);
|
||||
takerAsSellerProtocolMap.put(trade.getId(), sellerTakesOfferProtocol);
|
||||
sellerTakesOfferProtocol.start();
|
||||
|
||||
return trade;
|
||||
}
|
||||
|
||||
public void onFiatReceived(String tradeUID) {
|
||||
takerAsSellerProtocolMap.get(tradeUID).onUIEventFiatReceived();
|
||||
//TODO we don't support interruptions yet.
|
||||
// If the user has shut down the app we lose the offererAsBuyerProtocolMap
|
||||
// Also we don't support yet offline messaging (mail box)
|
||||
public void bankTransferInited(String tradeId) {
|
||||
offererAsBuyerProtocolMap.get(tradeId).onUIEventBankTransferInited();
|
||||
trades.get(tradeId).setState(Trade.State.PAYMENT_STARTED);
|
||||
persistTrades();
|
||||
}
|
||||
|
||||
public void onFiatReceived(String tradeId) {
|
||||
takerAsSellerProtocolMap.get(tradeId).onUIEventFiatReceived();
|
||||
trades.get(tradeId).setState(Trade.State.PAYMENT_RECEIVED);
|
||||
persistTrades();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Process incoming tradeMessages
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Routes the incoming messages to the responsible protocol
|
||||
private void onIncomingTradeMessage(TradeMessage tradeMessage, PeerAddress sender) {
|
||||
// log.trace("processTradingMessage TradeId " + tradeMessage.getTradeId());
|
||||
log.trace("processTradingMessage instance " + tradeMessage.getClass().getSimpleName());
|
||||
|
@ -403,6 +446,7 @@ public class TradeManager {
|
|||
(RequestOffererPublishDepositTxMessage) tradeMessage);
|
||||
}
|
||||
else if (tradeMessage instanceof DepositTxPublishedMessage) {
|
||||
persistTrades();
|
||||
takerAsSellerProtocolMap.get(tradeId).onDepositTxPublishedMessage((DepositTxPublishedMessage) tradeMessage);
|
||||
}
|
||||
else if (tradeMessage instanceof BankTransferInitedMessage) {
|
||||
|
@ -422,12 +466,15 @@ public class TradeManager {
|
|||
return trades.containsKey(offer.getId());
|
||||
}
|
||||
|
||||
public boolean isTradeMyOffer(Trade trade) {
|
||||
return trade.getOffer().getMessagePublicKey().equals(user.getMessagePublicKey());
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Getters
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public Map<String, Trade> getTrades() {
|
||||
public ObservableMap<String, Trade> getTrades() {
|
||||
return trades;
|
||||
}
|
||||
|
||||
|
@ -439,12 +486,8 @@ public class TradeManager {
|
|||
return offers.get(offerId);
|
||||
}
|
||||
|
||||
public Trade getPendingTrade() {
|
||||
return pendingTrade;
|
||||
}
|
||||
|
||||
public final StringProperty getNewTradeProperty() {
|
||||
return this.newTradeProperty;
|
||||
public Trade getCurrentPendingTrade() {
|
||||
return currentPendingTrade;
|
||||
}
|
||||
|
||||
|
||||
|
@ -453,11 +496,11 @@ public class TradeManager {
|
|||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private void persistOffers() {
|
||||
persistence.write(this, "offers", offers);
|
||||
persistence.write(this, "offers", (Map<String, Offer>) new HashMap<>(offers));
|
||||
}
|
||||
|
||||
private void saveTrades() {
|
||||
persistence.write(this, "trades", trades);
|
||||
private void persistTrades() {
|
||||
persistence.write(this, "trades", (Map<String, Trade>) new HashMap<>(trades));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
|
|
@ -44,6 +44,7 @@ import io.bitsquare.user.User;
|
|||
import com.google.bitcoin.core.Coin;
|
||||
import com.google.bitcoin.core.ECKey;
|
||||
import com.google.bitcoin.core.Transaction;
|
||||
import com.google.bitcoin.core.Utils;
|
||||
|
||||
import java.security.PublicKey;
|
||||
|
||||
|
@ -169,7 +170,6 @@ public class BuyerAcceptsOfferProtocol {
|
|||
state = State.Init;
|
||||
}
|
||||
|
||||
|
||||
public void start() {
|
||||
log.debug("start called " + step++);
|
||||
state = State.HandleTakeOfferRequest;
|
||||
|
@ -180,7 +180,7 @@ public class BuyerAcceptsOfferProtocol {
|
|||
public void onResultHandleTakeOfferRequest(boolean takeOfferRequestAccepted) {
|
||||
log.debug("onResultHandleTakeOfferRequest called " + step++);
|
||||
if (takeOfferRequestAccepted) {
|
||||
trade.setState(Trade.State.ACCEPTED);
|
||||
trade.setState(Trade.State.OFFERER_ACCEPTED);
|
||||
messageFacade.removeOffer(offer);
|
||||
listener.onOfferAccepted(offer);
|
||||
listener.onWaitingForPeerResponse(state);
|
||||
|
@ -335,8 +335,7 @@ public class BuyerAcceptsOfferProtocol {
|
|||
public void onResultSignAndPublishDepositTx(Transaction depositTransaction) {
|
||||
log.debug("onResultSignAndPublishDepositTx called " + step++);
|
||||
|
||||
trade.setDepositTransaction(depositTransaction);
|
||||
listener.onDepositTxPublished(depositTransaction.getHashAsString());
|
||||
listener.onDepositTxPublished(depositTransaction);
|
||||
|
||||
state = State.SendDepositTxIdToTaker;
|
||||
SendDepositTxIdToTaker.run(this::onResultSendDepositTxIdToTaker, this::onFault, peerAddress, messageFacade,
|
||||
|
@ -348,7 +347,7 @@ public class BuyerAcceptsOfferProtocol {
|
|||
|
||||
state = State.SetupListenerForBlockChainConfirmation;
|
||||
SetupListenerForBlockChainConfirmation.run(this::onResultSetupListenerForBlockChainConfirmation,
|
||||
this::onFault, trade.getDepositTransaction(), listener);
|
||||
this::onFault, trade.getDepositTx(), listener);
|
||||
}
|
||||
|
||||
public void onResultSetupListenerForBlockChainConfirmation() {
|
||||
|
@ -375,7 +374,7 @@ public class BuyerAcceptsOfferProtocol {
|
|||
state = State.onUIEventBankTransferInited;
|
||||
|
||||
// next task
|
||||
String depositTransactionId = trade.getDepositTransaction().getHashAsString();
|
||||
String depositTransactionId = trade.getDepositTx().getHashAsString();
|
||||
Coin tradeAmount = trade.getTradeAmount();
|
||||
Coin collateral = trade.getCollateralAmount();
|
||||
state = State.SendSignedPayoutTx;
|
||||
|
@ -414,9 +413,9 @@ public class BuyerAcceptsOfferProtocol {
|
|||
|
||||
state = State.onPayoutTxPublishedMessage;
|
||||
|
||||
// next task
|
||||
listener.onPayoutTxPublished(payoutTxAsHex);
|
||||
listener.onCompleted(state);
|
||||
Transaction payoutTx = new Transaction(walletFacade.getWallet().getParams(),
|
||||
Utils.parseAsHexOrBase58(payoutTxAsHex));
|
||||
listener.onPayoutTxPublished(payoutTx);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -19,24 +19,20 @@ package io.bitsquare.trade.protocol.trade.offerer;
|
|||
|
||||
import io.bitsquare.trade.Offer;
|
||||
|
||||
import com.google.bitcoin.core.TransactionConfidence;
|
||||
import com.google.bitcoin.core.Transaction;
|
||||
|
||||
public interface BuyerAcceptsOfferProtocolListener {
|
||||
void onOfferAccepted(Offer offer);
|
||||
|
||||
void onDepositTxPublished(String depositTxID);
|
||||
void onDepositTxPublished(Transaction depositTx);
|
||||
|
||||
void onDepositTxConfirmedInBlockchain();
|
||||
|
||||
void onDepositTxConfirmedUpdate(TransactionConfidence confidence);
|
||||
|
||||
void onPayoutTxPublished(String payoutTxID);
|
||||
void onPayoutTxPublished(Transaction payoutTx);
|
||||
|
||||
void onFault(Throwable throwable, BuyerAcceptsOfferProtocol.State state);
|
||||
|
||||
void onWaitingForPeerResponse(BuyerAcceptsOfferProtocol.State state);
|
||||
|
||||
void onCompleted(BuyerAcceptsOfferProtocol.State state);
|
||||
|
||||
void onWaitingForUserInteraction(BuyerAcceptsOfferProtocol.State state);
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ public class HandleTakeOfferRequest {
|
|||
log.trace("Run task");
|
||||
boolean takeOfferRequestAccepted = tradeState == Trade.State.OPEN;
|
||||
if (!takeOfferRequestAccepted) {
|
||||
log.info("Received take offer request but the offer not marked as open anymore.");
|
||||
log.warn("Received take offer request but the offer not marked as open anymore.");
|
||||
}
|
||||
RespondToTakeOfferRequestMessage tradeMessage =
|
||||
new RespondToTakeOfferRequestMessage(tradeId, takeOfferRequestAccepted);
|
||||
|
|
|
@ -40,9 +40,6 @@ public class SetupListenerForBlockChainConfirmation {
|
|||
@Override
|
||||
public void onConfidenceChanged(Transaction tx, ChangeReason reason) {
|
||||
log.trace("onConfidenceChanged " + tx.getConfidence());
|
||||
if (reason == ChangeReason.SEEN_PEERS) {
|
||||
listener.onDepositTxConfirmedUpdate(tx.getConfidence());
|
||||
}
|
||||
if (reason == ChangeReason.TYPE &&
|
||||
tx.getConfidence().getConfidenceType() == TransactionConfidence.ConfidenceType.BUILDING) {
|
||||
listener.onDepositTxConfirmedInBlockchain();
|
||||
|
|
|
@ -197,6 +197,7 @@ public class SellerTakesOfferProtocol {
|
|||
|
||||
if (message.isTakeOfferRequestAccepted()) {
|
||||
state = State.PayTakeOfferFee;
|
||||
listener.onTakeOfferRequestAccepted(trade);
|
||||
PayTakeOfferFee.run(this::onResultPayTakeOfferFee, this::onFault, walletFacade, tradeId);
|
||||
}
|
||||
else {
|
||||
|
@ -319,7 +320,9 @@ public class SellerTakesOfferProtocol {
|
|||
log.debug("state " + state);
|
||||
checkState(state.ordinal() >= State.SendSignedTakerDepositTxAsHex.ordinal());
|
||||
checkArgument(tradeId.equals(message.getTradeId()));
|
||||
listener.onDepositTxPublished(walletFacade.takerCommitDepositTx(message.getDepositTxAsHex()));
|
||||
//TODO takerCommitDepositTx should be in task as well, but will be probably changed anyway when akka is used...
|
||||
Transaction tx = walletFacade.takerCommitDepositTx(message.getDepositTxAsHex());
|
||||
listener.onDepositTxPublished(tx);
|
||||
}
|
||||
|
||||
|
||||
|
@ -378,9 +381,9 @@ public class SellerTakesOfferProtocol {
|
|||
offererPayoutAddress);
|
||||
}
|
||||
|
||||
public void onResultSignAndPublishPayoutTx(String transactionId, String payoutTxAsHex) {
|
||||
public void onResultSignAndPublishPayoutTx(Transaction transaction, String payoutTxAsHex) {
|
||||
log.debug("onResultSignAndPublishPayoutTx called " + step++);
|
||||
listener.onPayoutTxPublished(trade, transactionId);
|
||||
listener.onPayoutTxPublished(trade, transaction);
|
||||
|
||||
state = State.SendPayoutTxToOfferer;
|
||||
SendPayoutTxToOfferer.run(this::onResultSendPayoutTxToOfferer, this::onFault, peerAddress, messageFacade,
|
||||
|
|
|
@ -19,12 +19,14 @@ package io.bitsquare.trade.protocol.trade.taker;
|
|||
|
||||
import io.bitsquare.trade.Trade;
|
||||
|
||||
import com.google.bitcoin.core.Transaction;
|
||||
|
||||
public interface SellerTakesOfferProtocolListener {
|
||||
void onDepositTxPublished(String depositTxId);
|
||||
void onDepositTxPublished(Transaction depositTx);
|
||||
|
||||
void onBankTransferInited(String tradeId);
|
||||
|
||||
void onPayoutTxPublished(Trade trade, String hashAsString);
|
||||
void onPayoutTxPublished(Trade trade, Transaction payoutTx);
|
||||
|
||||
void onFault(Throwable throwable, SellerTakesOfferProtocol.State state);
|
||||
|
||||
|
@ -32,5 +34,8 @@ public interface SellerTakesOfferProtocolListener {
|
|||
|
||||
void onCompleted(SellerTakesOfferProtocol.State state);
|
||||
|
||||
void onTakeOfferRequestAccepted(Trade trade);
|
||||
|
||||
void onTakeOfferRequestRejected(Trade trade);
|
||||
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ public class SignAndPublishPayoutTx {
|
|||
public void onSuccess(Transaction transaction) {
|
||||
log.debug("takerSignsAndSendsTx " + transaction);
|
||||
String payoutTxAsHex = Utils.HEX.encode(transaction.bitcoinSerialize());
|
||||
resultHandler.onResult(transaction.getHashAsString(), payoutTxAsHex);
|
||||
resultHandler.onResult(transaction, payoutTxAsHex);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -73,7 +73,7 @@ public class SignAndPublishPayoutTx {
|
|||
}
|
||||
|
||||
public interface ResultHandler {
|
||||
void onResult(String transactionId, String payoutTxAsHex);
|
||||
void onResult(Transaction transaction, String payoutTxAsHex);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ public class AccountSettingsUITestRunner extends Application {
|
|||
refreshStylesheets();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
log.error(e.getStackTrace().toString());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ public class AccountUITestRunner extends Application {
|
|||
refreshStylesheets();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
log.error(e.getStackTrace().toString());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ public class RegistrationUITestRunner extends Application {
|
|||
refreshStylesheets();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
log.error(e.getStackTrace().toString());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ public class SetupUITestRunner extends Application {
|
|||
refreshStylesheets();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
log.error(e.getStackTrace().toString());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* 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.orders.pending;
|
||||
|
||||
import io.bitsquare.di.BitSquareModule;
|
||||
import io.bitsquare.util.ViewLoader;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
import javafx.application.Application;
|
||||
import javafx.scene.*;
|
||||
import javafx.scene.input.*;
|
||||
import javafx.scene.layout.*;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* For testing single isolated UI screens
|
||||
*/
|
||||
public class PendingTradesUIRunner extends Application {
|
||||
private static final Logger log = LoggerFactory.getLogger(PendingTradesUIRunner.class);
|
||||
private Scene scene;
|
||||
private Parent view;
|
||||
private Pane pane;
|
||||
private boolean devTest = true;
|
||||
|
||||
public static void main(String[] args) {
|
||||
launch(args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws IOException {
|
||||
Injector injector = Guice.createInjector(new BitSquareModule());
|
||||
ViewLoader.setInjector(injector);
|
||||
|
||||
pane = new StackPane();
|
||||
scene = new Scene(pane, 1000, 630);
|
||||
scene.getAccelerators().put(KeyCombination.valueOf("Shortcut+S"), this::loadMainWindow);
|
||||
loadMainWindow();
|
||||
primaryStage.setScene(scene);
|
||||
primaryStage.show();
|
||||
}
|
||||
|
||||
public void loadMainWindow() {
|
||||
log.debug("re load");
|
||||
pane.getChildren().removeAll();
|
||||
ViewLoader loader = new ViewLoader(
|
||||
getUrl("/io/bitsquare/gui/main/orders/pending/PendingTradesView.fxml"), false);
|
||||
|
||||
try {
|
||||
view = loader.load();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
pane.getChildren().setAll(view);
|
||||
refreshStylesheets();
|
||||
}
|
||||
|
||||
private void refreshStylesheets() {
|
||||
scene.getStylesheets().clear();
|
||||
scene.getStylesheets().setAll(getUrl("/io/bitsquare/gui/bitsquare.css").toExternalForm());
|
||||
}
|
||||
|
||||
private URL getUrl(String subPath) {
|
||||
if (devTest) {
|
||||
try {
|
||||
// load from file system location to make a reload possible. makes dev process easier with hot reload
|
||||
return new URL("file:///Users/mk/Documents/_intellij/bitsquare/src/main/java" + subPath);
|
||||
} catch (MalformedURLException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return getClass().getResource(subPath);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -15,41 +15,33 @@
|
|||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.gui.main.orders;
|
||||
package io.bitsquare.gui.main.orders.pending.uimock;
|
||||
|
||||
import io.bitsquare.gui.CachedViewController;
|
||||
import io.bitsquare.gui.Navigation;
|
||||
import io.bitsquare.gui.components.CachingTabPane;
|
||||
import io.bitsquare.persistence.Persistence;
|
||||
import io.bitsquare.gui.components.processbar.ProcessStepBar;
|
||||
import io.bitsquare.gui.components.processbar.ProcessStepItem;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import javafx.fxml.Initializable;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class OrdersController extends CachedViewController {
|
||||
private static final Logger log = LoggerFactory.getLogger(OrdersController.class);
|
||||
private static OrdersController INSTANCE;
|
||||
private final Persistence persistence;
|
||||
|
||||
@Inject
|
||||
private OrdersController(Persistence persistence) {
|
||||
this.persistence = persistence;
|
||||
INSTANCE = this;
|
||||
}
|
||||
public class PendingTradesControllerUIMock extends CachedViewController {
|
||||
private static final Logger log = LoggerFactory.getLogger(PendingTradesControllerUIMock.class);
|
||||
public ProcessStepBar processBar;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public static OrdersController GET_INSTANCE() {
|
||||
return INSTANCE;
|
||||
@Inject
|
||||
public PendingTradesControllerUIMock() {
|
||||
}
|
||||
|
||||
|
||||
|
@ -61,8 +53,13 @@ public class OrdersController extends CachedViewController {
|
|||
public void initialize(URL url, ResourceBundle rb) {
|
||||
super.initialize(url, rb);
|
||||
|
||||
((CachingTabPane) root).initialize(this, persistence, Navigation.Item.OFFER.getFxmlUrl(),
|
||||
Navigation.Item.PENDING_TRADE.getFxmlUrl(), Navigation.Item.CLOSED_TRADE.getFxmlUrl());
|
||||
List<ProcessStepItem> items = new ArrayList<>();
|
||||
items.add(new ProcessStepItem("Deposit TX published"));
|
||||
items.add(new ProcessStepItem("Waiting for other trader"));
|
||||
items.add(new ProcessStepItem("Waiting for payment"));
|
||||
items.add(new ProcessStepItem("Payment received"));
|
||||
processBar.setProcessStepItems(items);
|
||||
// processBar.next();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -77,25 +74,14 @@ public class OrdersController extends CachedViewController {
|
|||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Navigation
|
||||
// GUI handlers
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public Initializable loadViewAndGetChildController(Navigation.Item item) {
|
||||
childController = ((CachingTabPane) root).loadViewAndGetChildController(item.getFxmlUrl());
|
||||
return childController;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Public Methods
|
||||
// Private methods
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void setSelectedTabIndex(int index) {
|
||||
log.trace("setSelectedTabIndex " + index);
|
||||
((CachingTabPane) root).setSelectedTabIndex(index);
|
||||
persistence.write(this, "selectedTabIndex", index);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* 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.orders.pending.uimock;
|
||||
|
||||
import io.bitsquare.di.BitSquareModule;
|
||||
import io.bitsquare.util.ViewLoader;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
import javafx.application.Application;
|
||||
import javafx.scene.*;
|
||||
import javafx.scene.input.*;
|
||||
import javafx.scene.layout.*;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* For testing single isolated UI screens
|
||||
*/
|
||||
public class PendingTradesUIMockRunner extends Application {
|
||||
private static final Logger log = LoggerFactory.getLogger(PendingTradesUIMockRunner.class);
|
||||
private Scene scene;
|
||||
private Parent view;
|
||||
private Pane pane;
|
||||
private boolean devTest = true;
|
||||
|
||||
public static void main(String[] args) {
|
||||
launch(args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws IOException {
|
||||
Injector injector = Guice.createInjector(new BitSquareModule());
|
||||
ViewLoader.setInjector(injector);
|
||||
|
||||
pane = new StackPane();
|
||||
scene = new Scene(pane, 1000, 630);
|
||||
scene.getAccelerators().put(KeyCombination.valueOf("Shortcut+S"), this::loadMainWindow);
|
||||
loadMainWindow();
|
||||
primaryStage.setScene(scene);
|
||||
primaryStage.show();
|
||||
}
|
||||
|
||||
public void loadMainWindow() {
|
||||
log.debug("re load");
|
||||
pane.getChildren().removeAll();
|
||||
ViewLoader loader = new ViewLoader(
|
||||
getUrl("/io/bitsquare/gui/main/orders/pending/uimock/PendingTradesViewUIMock.fxml"), false);
|
||||
|
||||
try {
|
||||
view = loader.load();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
pane.getChildren().setAll(view);
|
||||
refreshStylesheets();
|
||||
}
|
||||
|
||||
private void refreshStylesheets() {
|
||||
scene.getStylesheets().clear();
|
||||
scene.getStylesheets().setAll(getUrl("/io/bitsquare/gui/bitsquare.css").toExternalForm());
|
||||
}
|
||||
|
||||
private URL getUrl(String subPath) {
|
||||
if (devTest) {
|
||||
try {
|
||||
// load from file system location to make a reload possible. makes dev process easier with hot reload
|
||||
return new URL("file:///Users/mk/Documents/_intellij/bitsquare/src/test/java" + subPath);
|
||||
} catch (MalformedURLException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return getClass().getResource(subPath);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!--
|
||||
~ 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/>.
|
||||
-->
|
||||
|
||||
|
||||
<?import io.bitsquare.gui.components.processbar.ProcessStepBar?>
|
||||
<?import io.bitsquare.gui.components.TitledGroupBg?>
|
||||
<?import io.bitsquare.gui.components.TitledSeparator?>
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<GridPane fx:id="root" fx:controller="io.bitsquare.gui.main.orders.pending.uimock.PendingTradesControllerUIMock"
|
||||
hgap="5.0" vgap="5" stylesheets="@../../../../../../../../../main/java/io/bitsquare/gui/bitsquare.css"
|
||||
xmlns:fx="http://javafx.com/fxml">
|
||||
<padding>
|
||||
<Insets bottom="20.0" left="25.0" top="30.0" right="25"/>
|
||||
</padding>
|
||||
|
||||
<TitledSeparator text="Pending trades" GridPane.rowIndex="0" GridPane.columnIndex="0"
|
||||
GridPane.columnSpan="2"/>
|
||||
|
||||
<TableView fx:id="orderBookTable" GridPane.rowIndex="0" GridPane.columnIndex="0" GridPane.columnSpan="2"
|
||||
prefHeight="150">
|
||||
<GridPane.margin>
|
||||
<Insets top="10.0" left="-10" right="-10"/>
|
||||
</GridPane.margin>
|
||||
<columns>
|
||||
<TableColumn text="Amount in BTC (Min.)" fx:id="amountColumn" minWidth="130"/>
|
||||
<TableColumn text="Price" fx:id="priceColumn" minWidth="130"/>
|
||||
<TableColumn text="Amount in EUR (Min.)" fx:id="volumeColumn" minWidth="130"/>
|
||||
<TableColumn text="Country" fx:id="countryColumn" minWidth="60"/>
|
||||
<TableColumn text="Bank transfer type" fx:id="bankAccountTypeColumn" minWidth="130"/>
|
||||
<TableColumn text="" fx:id="directionColumn" minWidth="80" sortable="false"/>
|
||||
|
||||
</columns>
|
||||
</TableView>
|
||||
|
||||
|
||||
<ProcessStepBar fx:id="processBar" GridPane.columnSpan="2" GridPane.rowIndex="1" snapToPixel="true">
|
||||
<GridPane.margin>
|
||||
<Insets top="30.0" bottom="-10" left="-10" right="-10"/>
|
||||
</GridPane.margin>
|
||||
</ProcessStepBar>
|
||||
|
||||
<TitledGroupBg fx:id="priceAmountPane" text="Pending trade"
|
||||
GridPane.rowSpan="2" GridPane.columnSpan="2" GridPane.rowIndex="2">
|
||||
<GridPane.margin>
|
||||
<Insets top="40.0" bottom="-10" left="-10" right="-10"/>
|
||||
</GridPane.margin>
|
||||
</TitledGroupBg>
|
||||
|
||||
|
||||
<Label text="Status:" GridPane.rowIndex="2">
|
||||
<GridPane.margin>
|
||||
<Insets top="50.0"/>
|
||||
</GridPane.margin>
|
||||
</Label>
|
||||
<TextField disable="true" GridPane.rowIndex="2" GridPane.columnIndex="1" text="Blabal">
|
||||
<GridPane.margin>
|
||||
<Insets top="50.0"/>
|
||||
</GridPane.margin>
|
||||
</TextField>
|
||||
|
||||
<Label text="Deposit transaction ID:" GridPane.rowIndex="3"/>
|
||||
<TextField disable="true" GridPane.rowIndex="3" GridPane.columnIndex="1" text="324dsfsdffdafsdfasdf324"/>
|
||||
|
||||
<!--
|
||||
<InfoDisplay gridPane="root" rowIndex="3"
|
||||
text="%createOffer.amountPriceBox.info"/>
|
||||
-->
|
||||
|
||||
<columnConstraints>
|
||||
<ColumnConstraints halignment="RIGHT" hgrow="SOMETIMES" minWidth="200"/>
|
||||
<ColumnConstraints hgrow="ALWAYS"/>
|
||||
</columnConstraints>
|
||||
|
||||
<rowConstraints>
|
||||
<RowConstraints/>
|
||||
<RowConstraints/>
|
||||
<RowConstraints/>
|
||||
<RowConstraints/>
|
||||
</rowConstraints>
|
||||
|
||||
</GridPane>
|
|
@ -75,7 +75,7 @@ public class FiatAccountUITestRunner extends Application {
|
|||
refreshStylesheets();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
log.error(e.getStackTrace().toString());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ public class PasswordUITestRunner extends Application {
|
|||
refreshStylesheets();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
log.error(e.getStackTrace().toString());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ public class RegistrationUITestRunner extends Application {
|
|||
refreshStylesheets();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
log.error(e.getStackTrace().toString());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ public class RestrictionsUITestRunner extends Application {
|
|||
refreshStylesheets();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
log.error(e.getStackTrace().toString());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ public class SeedWordsUITestRunner extends Application {
|
|||
refreshStylesheets();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
log.error(e.getStackTrace().toString());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
<?import javafx.scene.layout.*?>
|
||||
<GridPane hgap="5.0" vgap="5.0" fx:id="root"
|
||||
fx:controller="io.bitsquare.gui.main.settings.uimock.BankAccountSettingsControllerUIMock"
|
||||
stylesheets="@../../../../../../../main/java/io/bitsquare/gui/bitsquare.css"
|
||||
stylesheets="@../../../../../../../../main/java/io/bitsquare/gui/bitsquare.css"
|
||||
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0"
|
||||
AnchorPane.topAnchor="0.0"
|
||||
xmlns:fx="http://javafx.com/fxml">
|
||||
|
|
|
@ -75,7 +75,7 @@ public class CreateOfferUITestRunner extends Application {
|
|||
refreshStylesheets();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
log.error(e.getStackTrace().toString());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ public class CreateOfferControllerUIMock implements Initializable {
|
|||
|
||||
@Override
|
||||
public void initialize(URL url, ResourceBundle rb) {
|
||||
|
||||
/*
|
||||
paymentInfoPane.setVisible(false);
|
||||
collateralLabel.setVisible(false);
|
||||
collateralTextField.setVisible(false);
|
||||
|
@ -114,7 +114,7 @@ public class CreateOfferControllerUIMock implements Initializable {
|
|||
bankAccountCountyLabel.setVisible(false);
|
||||
bankAccountCountyTextField.setVisible(false);
|
||||
showDetailsInfoIcon.setVisible(false);
|
||||
showDetailsInfoLabel.setVisible(false);
|
||||
showDetailsInfoLabel.setVisible(false);*/
|
||||
}
|
||||
|
||||
/* @FXML
|
||||
|
|
|
@ -68,7 +68,7 @@ public class CreateOfferUIMockRunner extends Application {
|
|||
log.debug("re load");
|
||||
pane.getChildren().removeAll();
|
||||
ViewLoader loader = new ViewLoader(
|
||||
getUrl("/io/bitsquare/gui/trade/createoffer/uimock/CreateOfferViewUIMock.fxml"), false);
|
||||
getUrl("/io/bitsquare/gui/main/trade/createoffer/uimock/CreateOfferViewUIMock.fxml"), false);
|
||||
|
||||
try {
|
||||
view = loader.load();
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
<?import javafx.scene.layout.*?>
|
||||
<?import javafx.scene.text.*?>
|
||||
<AnchorPane fx:id="root" prefHeight="630.0" prefWidth="1000.0" style="-fx-background-color: f4f4f4;"
|
||||
stylesheets="@../../../../../../../../main/java/io/bitsquare/gui/bitsquare.css"
|
||||
stylesheets="@../../../../../../../../../main/java/io/bitsquare/gui/bitsquare.css"
|
||||
AnchorPane.bottomAnchor="10.0" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0"
|
||||
AnchorPane.topAnchor="10.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"
|
||||
fx:controller="io.bitsquare.gui.main.trade.createoffer.uimock.CreateOfferControllerUIMock">
|
||||
|
@ -52,7 +52,8 @@
|
|||
<children>
|
||||
<ImageView fitHeight="54.0" fitWidth="62.0" pickOnBounds="true" preserveRatio="true">
|
||||
<image>
|
||||
<Image url="@../../../../../../../../main/resources/images/buy_black_62_54.png"/>
|
||||
<Image
|
||||
url="@../../../../../../../../../main/resources/images/buy_large.png"/>
|
||||
</image>
|
||||
</ImageView>
|
||||
<Label fx:id="buyLabel" alignment="CENTER"
|
||||
|
@ -87,7 +88,7 @@
|
|||
</VBox>
|
||||
<Label text="x">
|
||||
<font>
|
||||
<Font name="Helvetica" size="20.0"/>
|
||||
<Font name="Helvetica-Bold" size="20.0"/>
|
||||
</font>
|
||||
<padding>
|
||||
<Insets top="14.0"/>
|
||||
|
@ -111,7 +112,7 @@
|
|||
|
||||
<Label text="=">
|
||||
<font>
|
||||
<Font name="Helvetica" size="20.0"/>
|
||||
<Font name="Helvetica-Bold" size="20.0"/>
|
||||
</font>
|
||||
<padding>
|
||||
<Insets top="14.0"/>
|
||||
|
@ -161,7 +162,7 @@
|
|||
preserveRatio="true" GridPane.rowIndex="2" GridPane.valignment="TOP">
|
||||
<image>
|
||||
<Image fx:id="infoIcon"
|
||||
url="@../../../../../../../../main/resources/images/info.png"/>
|
||||
url="@../../../../../../../../../main/resources/images/info.png"/>
|
||||
</image>
|
||||
<GridPane.margin>
|
||||
<Insets right="2.0" top="4.0"/>
|
||||
|
|
Loading…
Add table
Reference in a new issue