mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-05-13 03:52:16 -04: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.setMinWidth(750);
|
||||||
primaryStage.setMinHeight(500);
|
primaryStage.setMinHeight(500);
|
||||||
|
|
||||||
|
Profiler.initScene(primaryStage.getScene());
|
||||||
|
|
||||||
|
|
||||||
primaryStage.show();
|
primaryStage.show();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.error(e.getMessage());
|
log.error(e.getMessage());
|
||||||
|
|
|
@ -18,8 +18,9 @@
|
||||||
package io.bitsquare.btc;
|
package io.bitsquare.btc;
|
||||||
|
|
||||||
import io.bitsquare.BitSquare;
|
import io.bitsquare.BitSquare;
|
||||||
|
import io.bitsquare.btc.listeners.AddressConfidenceListener;
|
||||||
import io.bitsquare.btc.listeners.BalanceListener;
|
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.crypto.CryptoFacade;
|
||||||
import io.bitsquare.persistence.Persistence;
|
import io.bitsquare.persistence.Persistence;
|
||||||
|
|
||||||
|
@ -104,7 +105,8 @@ public class WalletFacade {
|
||||||
private final CryptoFacade cryptoFacade;
|
private final CryptoFacade cryptoFacade;
|
||||||
private final Persistence persistence;
|
private final Persistence persistence;
|
||||||
private final List<DownloadListener> downloadListeners = new ArrayList<>();
|
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 final List<BalanceListener> balanceListeners = new ArrayList<>();
|
||||||
private Wallet wallet;
|
private Wallet wallet;
|
||||||
private WalletEventListener walletEventListener;
|
private WalletEventListener walletEventListener;
|
||||||
|
@ -268,13 +270,22 @@ public class WalletFacade {
|
||||||
downloadListeners.remove(listener);
|
downloadListeners.remove(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConfidenceListener addConfidenceListener(ConfidenceListener listener) {
|
public AddressConfidenceListener addAddressConfidenceListener(AddressConfidenceListener listener) {
|
||||||
confidenceListeners.add(listener);
|
addressConfidenceListeners.add(listener);
|
||||||
return listener;
|
return listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeConfidenceListener(ConfidenceListener listener) {
|
public void removeAddressConfidenceListener(AddressConfidenceListener listener) {
|
||||||
confidenceListeners.remove(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) {
|
public BalanceListener addBalanceListener(BalanceListener listener) {
|
||||||
|
@ -354,16 +365,31 @@ public class WalletFacade {
|
||||||
return getMostRecentConfidence(transactionConfidenceList);
|
return getMostRecentConfidence(transactionConfidenceList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
private void notifyConfidenceListeners(Transaction tx) {
|
||||||
for (ConfidenceListener confidenceListener : confidenceListeners) {
|
for (AddressConfidenceListener addressConfidenceListener : addressConfidenceListeners) {
|
||||||
List<TransactionConfidence> transactionConfidenceList = new ArrayList<>();
|
List<TransactionConfidence> transactionConfidenceList = new ArrayList<>();
|
||||||
transactionConfidenceList.add(getTransactionConfidence(tx, confidenceListener.getAddress()));
|
transactionConfidenceList.add(getTransactionConfidence(tx, addressConfidenceListener.getAddress()));
|
||||||
|
|
||||||
TransactionConfidence transactionConfidence = getMostRecentConfidence(transactionConfidenceList);
|
TransactionConfidence transactionConfidence = getMostRecentConfidence(transactionConfidenceList);
|
||||||
confidenceListener.onTransactionConfidenceChanged(transactionConfidence);
|
addressConfidenceListener.onTransactionConfidenceChanged(transactionConfidence);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (TxConfidenceListener txConfidenceListener : txConfidenceListeners) {
|
||||||
|
if (tx.getHashAsString().equals(txConfidenceListener.getTxID()))
|
||||||
|
txConfidenceListener.onTransactionConfidenceChanged(tx.getConfidence());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private TransactionConfidence getTransactionConfidence(Transaction tx, Address address) {
|
private TransactionConfidence getTransactionConfidence(Transaction tx, Address address) {
|
||||||
List<TransactionOutput> mergedOutputs = getOutputsWithConnectedOutputs(tx);
|
List<TransactionOutput> mergedOutputs = getOutputsWithConnectedOutputs(tx);
|
||||||
|
@ -924,7 +950,7 @@ public class WalletFacade {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4 step deposit tx: Offerer send deposit tx to taker
|
// 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("takerCommitDepositTx");
|
||||||
log.trace("inputs: ");
|
log.trace("inputs: ");
|
||||||
log.trace("depositTxID=" + depositTxAsHex);
|
log.trace("depositTxID=" + depositTxAsHex);
|
||||||
|
@ -941,7 +967,7 @@ public class WalletFacade {
|
||||||
throw new RuntimeException(e); // Cannot happen, we already called multisigContract.verify()
|
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.Address;
|
||||||
import com.google.bitcoin.core.TransactionConfidence;
|
import com.google.bitcoin.core.TransactionConfidence;
|
||||||
|
|
||||||
public class ConfidenceListener {
|
public class AddressConfidenceListener {
|
||||||
private final Address address;
|
private final Address address;
|
||||||
|
|
||||||
public ConfidenceListener(Address address) {
|
public AddressConfidenceListener(Address address) {
|
||||||
this.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"),
|
TAKE_OFFER("/io/bitsquare/gui/main/trade/takeoffer/TakeOfferView.fxml"),
|
||||||
|
|
||||||
// orders
|
// orders
|
||||||
OFFER("/io/bitsquare/gui/main/orders/offer/OfferView.fxml"),
|
OFFERS("/io/bitsquare/gui/main/orders/offer/OffersView.fxml"),
|
||||||
PENDING_TRADE("/io/bitsquare/gui/main/orders/pending/PendingTradeView.fxml"),
|
PENDING_TRADES("/io/bitsquare/gui/main/orders/pending/PendingTradesView.fxml"),
|
||||||
CLOSED_TRADE("/io/bitsquare/gui/main/orders/closed/ClosedTradeView.fxml"),
|
CLOSED_TRADES("/io/bitsquare/gui/main/orders/closed/ClosedTradesView.fxml"),
|
||||||
|
|
||||||
// funds
|
// funds
|
||||||
DEPOSIT("/io/bitsquare/gui/main/funds/deposit/DepositView.fxml"),
|
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-focus-color: -fx-accent;
|
||||||
-fx-faint-focus-color: #0f87c322;
|
-fx-faint-focus-color: #0f87c322;
|
||||||
-fx-selection-bar: derive(-fx-accent,50%);
|
-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 */
|
/* Splash */
|
||||||
|
@ -144,9 +137,9 @@ lower gradient color on tab: dddddd
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
.tooltip {
|
.tooltip {
|
||||||
-fx-background: rgba(30,30,30);
|
-fx-background: white;
|
||||||
-fx-text-fill: black;
|
-fx-text-fill: black;
|
||||||
-fx-background-color: rgba(100,100,100,0.8);
|
-fx-background-color: white;
|
||||||
-fx-background-radius: 6px;
|
-fx-background-radius: 6px;
|
||||||
-fx-background-insets: 0;
|
-fx-background-insets: 0;
|
||||||
-fx-padding: 0.667em 0.75em 0.667em 0.75em; /* 10px */
|
-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/>.
|
* 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.OverlayManager;
|
||||||
import io.bitsquare.gui.components.Popups;
|
|
||||||
|
|
||||||
import com.google.bitcoin.core.Coin;
|
import com.google.bitcoin.core.Coin;
|
||||||
import com.google.bitcoin.uri.BitcoinURI;
|
import com.google.bitcoin.uri.BitcoinURI;
|
||||||
|
@ -77,14 +76,13 @@ public class AddressTextField extends AnchorPane {
|
||||||
Desktop.getDesktop().browse(URI.create(getBitcoinURI()));
|
Desktop.getDesktop().browse(URI.create(getBitcoinURI()));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.warn(e.getMessage());
|
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?");
|
"Perhaps you don't have one installed?");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
addressLabel.focusTraversableProperty().set(focusTraversableProperty().get());
|
addressLabel.focusTraversableProperty().set(focusTraversableProperty().get());
|
||||||
focusedProperty().addListener((ov, oldValue, newValue) -> {
|
focusedProperty().addListener((ov, oldValue, newValue) -> {
|
||||||
addressLabel.requestFocus();
|
addressLabel.requestFocus();
|
||||||
log.debug("foc");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Label copyIcon = new Label();
|
Label copyIcon = new Label();
|
|
@ -15,11 +15,11 @@
|
||||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.bitsquare.gui.components.btc;
|
package io.bitsquare.gui.components;
|
||||||
|
|
||||||
import io.bitsquare.btc.WalletFacade;
|
import io.bitsquare.btc.WalletFacade;
|
||||||
|
import io.bitsquare.btc.listeners.AddressConfidenceListener;
|
||||||
import io.bitsquare.btc.listeners.BalanceListener;
|
import io.bitsquare.btc.listeners.BalanceListener;
|
||||||
import io.bitsquare.btc.listeners.ConfidenceListener;
|
|
||||||
import io.bitsquare.gui.components.confidence.ConfidenceProgressIndicator;
|
import io.bitsquare.gui.components.confidence.ConfidenceProgressIndicator;
|
||||||
import io.bitsquare.gui.util.BSFormatter;
|
import io.bitsquare.gui.util.BSFormatter;
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ public class BalanceTextField extends AnchorPane {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setup(WalletFacade walletFacade, Address address) {
|
public void setup(WalletFacade walletFacade, Address address) {
|
||||||
walletFacade.addConfidenceListener(new ConfidenceListener(address) {
|
walletFacade.addAddressConfidenceListener(new AddressConfidenceListener(address) {
|
||||||
@Override
|
@Override
|
||||||
public void onTransactionConfidenceChanged(TransactionConfidence confidence) {
|
public void onTransactionConfidenceChanged(TransactionConfidence confidence) {
|
||||||
updateConfidence(confidence);
|
updateConfidence(confidence);
|
|
@ -134,12 +134,13 @@ public class InfoDisplay extends Parent {
|
||||||
});
|
});
|
||||||
|
|
||||||
sceneProperty().addListener((ov, oldValue, newValue) -> {
|
sceneProperty().addListener((ov, oldValue, newValue) -> {
|
||||||
if (oldValue == null && newValue != null) {
|
if (oldValue == null && newValue != null && newValue.getWindow() != null) {
|
||||||
newValue.getWindow().widthProperty().addListener(listener);
|
newValue.getWindow().widthProperty().addListener(listener);
|
||||||
// localToScene does deliver 0 instead of the correct x position when scene propery gets set,
|
// localToScene does deliver 0 instead of the correct x position when scene propery gets set,
|
||||||
// so we delay for 1 render cycle
|
// so we delay for 1 render cycle
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
label.setVisible(true);
|
label.setVisible(true);
|
||||||
|
label.prefWidthProperty().unbind();
|
||||||
label.setPrefWidth(newValue.getWindow().getWidth() - localToScene(0, 0).getX() - 35);
|
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)
|
// Support handling of uncaught exception from any thread (also non gui thread)
|
||||||
public static void handleUncaughtExceptions(Throwable throwable) {
|
public static void handleUncaughtExceptions(Throwable throwable) {
|
||||||
// while dev
|
// while dev
|
||||||
|
log.error(throwable.getMessage());
|
||||||
|
log.error(throwable.toString());
|
||||||
throwable.printStackTrace();
|
throwable.printStackTrace();
|
||||||
|
|
||||||
Runnable runnable = () -> {
|
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;
|
return childController;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.getStackTrace();
|
e.printStackTrace();
|
||||||
log.error("Loading view failed. FxmlUrl = " + navigationItem.getFxmlUrl());
|
log.error("Loading view failed. FxmlUrl = " + navigationItem.getFxmlUrl());
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -191,7 +191,7 @@ public class MainViewCB extends ViewCB<MainPM> {
|
||||||
alertButton.setOnAction((e) ->
|
alertButton.setOnAction((e) ->
|
||||||
navigation.navigationTo(Navigation.Item.MAIN,
|
navigation.navigationTo(Navigation.Item.MAIN,
|
||||||
Navigation.Item.ORDERS,
|
Navigation.Item.ORDERS,
|
||||||
Navigation.Item.PENDING_TRADE));
|
Navigation.Item.PENDING_TRADES));
|
||||||
Tooltip.install(alertButton, new Tooltip("Your offer has been accepted"));
|
Tooltip.install(alertButton, new Tooltip("Your offer has been accepted"));
|
||||||
ordersButtonButtonPane.getChildren().add(alertButton);
|
ordersButtonButtonPane.getChildren().add(alertButton);
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ import javafx.scene.layout.*;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
class AccountViewCB extends CachedViewCB<AccountPM> {
|
public class AccountViewCB extends CachedViewCB<AccountPM> {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(AccountViewCB.class);
|
private static final Logger log = LoggerFactory.getLogger(AccountViewCB.class);
|
||||||
|
|
||||||
|
@ -125,7 +125,7 @@ class AccountViewCB extends CachedViewCB<AccountPM> {
|
||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.error("Loading view failed. FxmlUrl = " + Navigation.Item.ACCOUNT_SETUP.getFxmlUrl());
|
log.error("Loading view failed. FxmlUrl = " + Navigation.Item.ACCOUNT_SETUP.getFxmlUrl());
|
||||||
e.getStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
return childController;
|
return childController;
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
</GridPane.margin>
|
</GridPane.margin>
|
||||||
</ComboBox>
|
</ComboBox>
|
||||||
|
|
||||||
<Label text="Title:" GridPane.rowIndex="1"/>
|
<Label text="Account name:" GridPane.rowIndex="1"/>
|
||||||
<InputTextField fx:id="titleTextField" GridPane.columnIndex="1" GridPane.rowIndex="1"/>
|
<InputTextField fx:id="titleTextField" GridPane.columnIndex="1" GridPane.rowIndex="1"/>
|
||||||
|
|
||||||
<Label text="Holder name:" GridPane.rowIndex="2"/>
|
<Label text="Holder name:" GridPane.rowIndex="2"/>
|
||||||
|
|
|
@ -17,8 +17,8 @@
|
||||||
~ along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
~ along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<?import io.bitsquare.gui.components.btc.AddressTextField?>
|
<?import io.bitsquare.gui.components.AddressTextField?>
|
||||||
<?import io.bitsquare.gui.components.btc.BalanceTextField?>
|
<?import io.bitsquare.gui.components.BalanceTextField?>
|
||||||
<?import io.bitsquare.gui.components.InfoDisplay?>
|
<?import io.bitsquare.gui.components.InfoDisplay?>
|
||||||
<?import io.bitsquare.gui.components.TitledGroupBg?>
|
<?import io.bitsquare.gui.components.TitledGroupBg?>
|
||||||
<?import javafx.geometry.Insets?>
|
<?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.CachedViewCB;
|
||||||
import io.bitsquare.gui.OverlayManager;
|
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.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.MultiStepNavigation;
|
||||||
import io.bitsquare.gui.main.account.content.ContextAware;
|
import io.bitsquare.gui.main.account.content.ContextAware;
|
||||||
import io.bitsquare.gui.main.help.Help;
|
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.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class AccountSettingsViewCB extends CachedViewCB<AccountSettingsPM> {
|
public class AccountSettingsViewCB extends CachedViewCB {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(AccountSettingsViewCB.class);
|
private static final Logger log = LoggerFactory.getLogger(AccountSettingsViewCB.class);
|
||||||
|
|
||||||
|
@ -63,8 +63,8 @@ public class AccountSettingsViewCB extends CachedViewCB<AccountSettingsPM> {
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private AccountSettingsViewCB(AccountSettingsPM presentationModel, Navigation navigation) {
|
private AccountSettingsViewCB(Navigation navigation) {
|
||||||
super(presentationModel);
|
super();
|
||||||
|
|
||||||
this.navigation = navigation;
|
this.navigation = navigation;
|
||||||
}
|
}
|
||||||
|
@ -156,7 +156,7 @@ public class AccountSettingsViewCB extends CachedViewCB<AccountSettingsPM> {
|
||||||
return childController;
|
return childController;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.error("Loading view failed. FxmlUrl = " + navigationItem.getFxmlUrl());
|
log.error("Loading view failed. FxmlUrl = " + navigationItem.getFxmlUrl());
|
||||||
e.getStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
return null;
|
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;
|
package io.bitsquare.gui.main.account.setup;
|
||||||
|
|
||||||
import io.bitsquare.gui.CachedViewCB;
|
|
||||||
import io.bitsquare.gui.Navigation;
|
import io.bitsquare.gui.Navigation;
|
||||||
import io.bitsquare.gui.PresentationModel;
|
import io.bitsquare.gui.PresentationModel;
|
||||||
import io.bitsquare.gui.ViewCB;
|
import io.bitsquare.gui.ViewCB;
|
||||||
|
@ -48,7 +47,10 @@ import javafx.scene.layout.*;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
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);
|
private static final Logger log = LoggerFactory.getLogger(AccountSetupViewCB.class);
|
||||||
|
|
||||||
|
@ -65,8 +67,8 @@ public class AccountSetupViewCB extends CachedViewCB<AccountSetupPM> implements
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private AccountSetupViewCB(AccountSetupPM presentationModel, Navigation navigation) {
|
private AccountSetupViewCB(Navigation navigation) {
|
||||||
super(presentationModel);
|
super();
|
||||||
this.navigation = navigation;
|
this.navigation = navigation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,12 +104,6 @@ public class AccountSetupViewCB extends CachedViewCB<AccountSetupPM> implements
|
||||||
leftVBox.getChildren().addAll(seedWords, password, restrictions, fiatAccount, registration);
|
leftVBox.getChildren().addAll(seedWords, password, restrictions, fiatAccount, registration);
|
||||||
|
|
||||||
super.initialize(url, rb);
|
super.initialize(url, rb);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void activate() {
|
|
||||||
super.activate();
|
|
||||||
|
|
||||||
navigation.addListener(listener);
|
navigation.addListener(listener);
|
||||||
|
|
||||||
|
@ -115,17 +111,10 @@ public class AccountSetupViewCB extends CachedViewCB<AccountSetupPM> implements
|
||||||
childController = seedWords.show();
|
childController = seedWords.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void deactivate() {
|
|
||||||
super.deactivate();
|
|
||||||
|
|
||||||
navigation.removeListener(listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("EmptyMethod")
|
|
||||||
@Override
|
@Override
|
||||||
public void terminate() {
|
public void terminate() {
|
||||||
super.terminate();
|
super.terminate();
|
||||||
|
navigation.removeListener(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -176,7 +165,7 @@ public class AccountSetupViewCB extends CachedViewCB<AccountSetupPM> implements
|
||||||
return childController;
|
return childController;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.error("Loading view failed. FxmlUrl = " + navigationItem.getFxmlUrl());
|
log.error("Loading view failed. FxmlUrl = " + navigationItem.getFxmlUrl());
|
||||||
e.getStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,9 @@ import javafx.stage.Stage;
|
||||||
import net.tomp2p.peers.Number640;
|
import net.tomp2p.peers.Number640;
|
||||||
import net.tomp2p.storage.Data;
|
import net.tomp2p.storage.Data;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO remove tomp2p dependencies
|
* TODO remove tomp2p dependencies
|
||||||
* import net.tomp2p.peers.Number160;
|
* import net.tomp2p.peers.Number160;
|
||||||
|
@ -57,6 +60,8 @@ import net.tomp2p.storage.Data;
|
||||||
* Arbitration is not much developed yet
|
* Arbitration is not much developed yet
|
||||||
*/
|
*/
|
||||||
public class ArbitratorBrowserController extends CachedViewController implements ArbitratorListener {
|
public class ArbitratorBrowserController extends CachedViewController implements ArbitratorListener {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(ArbitratorBrowserController.class);
|
||||||
|
|
||||||
private final Settings settings;
|
private final Settings settings;
|
||||||
private final Persistence persistence;
|
private final Persistence persistence;
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
package io.bitsquare.gui.main.funds.transactions;
|
package io.bitsquare.gui.main.funds.transactions;
|
||||||
|
|
||||||
import io.bitsquare.btc.WalletFacade;
|
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.components.confidence.ConfidenceProgressIndicator;
|
||||||
import io.bitsquare.gui.util.BSFormatter;
|
import io.bitsquare.gui.util.BSFormatter;
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ public class TransactionsListItem {
|
||||||
|
|
||||||
private final Tooltip tooltip;
|
private final Tooltip tooltip;
|
||||||
private String addressString;
|
private String addressString;
|
||||||
private ConfidenceListener confidenceListener;
|
private AddressConfidenceListener confidenceListener;
|
||||||
|
|
||||||
public TransactionsListItem(Transaction transaction, WalletFacade walletFacade) {
|
public TransactionsListItem(Transaction transaction, WalletFacade walletFacade) {
|
||||||
this.walletFacade = walletFacade;
|
this.walletFacade = walletFacade;
|
||||||
|
@ -135,7 +135,7 @@ public class TransactionsListItem {
|
||||||
Tooltip.install(progressIndicator, tooltip);
|
Tooltip.install(progressIndicator, tooltip);
|
||||||
|
|
||||||
if (address != null) {
|
if (address != null) {
|
||||||
confidenceListener = walletFacade.addConfidenceListener(new ConfidenceListener(address) {
|
confidenceListener = walletFacade.addAddressConfidenceListener(new AddressConfidenceListener(address) {
|
||||||
@Override
|
@Override
|
||||||
public void onTransactionConfidenceChanged(TransactionConfidence confidence) {
|
public void onTransactionConfidenceChanged(TransactionConfidence confidence) {
|
||||||
updateConfidence(confidence);
|
updateConfidence(confidence);
|
||||||
|
@ -148,7 +148,7 @@ public class TransactionsListItem {
|
||||||
|
|
||||||
|
|
||||||
public void cleanup() {
|
public void cleanup() {
|
||||||
walletFacade.removeConfidenceListener(confidenceListener);
|
walletFacade.removeAddressConfidenceListener(confidenceListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateConfidence(TransactionConfidence confidence) {
|
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.AddressEntry;
|
||||||
import io.bitsquare.btc.WalletFacade;
|
import io.bitsquare.btc.WalletFacade;
|
||||||
|
import io.bitsquare.btc.listeners.AddressConfidenceListener;
|
||||||
import io.bitsquare.btc.listeners.BalanceListener;
|
import io.bitsquare.btc.listeners.BalanceListener;
|
||||||
import io.bitsquare.btc.listeners.ConfidenceListener;
|
|
||||||
import io.bitsquare.gui.components.confidence.ConfidenceProgressIndicator;
|
import io.bitsquare.gui.components.confidence.ConfidenceProgressIndicator;
|
||||||
|
|
||||||
import com.google.bitcoin.core.Address;
|
import com.google.bitcoin.core.Address;
|
||||||
|
@ -42,7 +42,7 @@ public class WithdrawalListItem {
|
||||||
private final AddressEntry addressEntry;
|
private final AddressEntry addressEntry;
|
||||||
|
|
||||||
private final WalletFacade walletFacade;
|
private final WalletFacade walletFacade;
|
||||||
private final ConfidenceListener confidenceListener;
|
private final AddressConfidenceListener confidenceListener;
|
||||||
|
|
||||||
private final ConfidenceProgressIndicator progressIndicator;
|
private final ConfidenceProgressIndicator progressIndicator;
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ public class WithdrawalListItem {
|
||||||
progressIndicator.setPrefSize(24, 24);
|
progressIndicator.setPrefSize(24, 24);
|
||||||
Tooltip.install(progressIndicator, tooltip);
|
Tooltip.install(progressIndicator, tooltip);
|
||||||
|
|
||||||
confidenceListener = walletFacade.addConfidenceListener(new ConfidenceListener(getAddress()) {
|
confidenceListener = walletFacade.addAddressConfidenceListener(new AddressConfidenceListener(getAddress()) {
|
||||||
@Override
|
@Override
|
||||||
public void onTransactionConfidenceChanged(TransactionConfidence confidence) {
|
public void onTransactionConfidenceChanged(TransactionConfidence confidence) {
|
||||||
updateConfidence(confidence);
|
updateConfidence(confidence);
|
||||||
|
@ -86,7 +86,7 @@ public class WithdrawalListItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cleanup() {
|
public void cleanup() {
|
||||||
walletFacade.removeConfidenceListener(confidenceListener);
|
walletFacade.removeAddressConfidenceListener(confidenceListener);
|
||||||
walletFacade.removeBalanceListener(balanceListener);
|
walletFacade.removeBalanceListener(balanceListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,10 @@ public enum HelpId {
|
||||||
TAKE_OFFER_GENERAL,
|
TAKE_OFFER_GENERAL,
|
||||||
TAKE_OFFER_FUNDING,
|
TAKE_OFFER_FUNDING,
|
||||||
TAKE_OFFER_ADVANCED,
|
TAKE_OFFER_ADVANCED,
|
||||||
|
PENDING_TRADE_OFFERER,
|
||||||
|
PENDING_TRADE_PAYMENT,
|
||||||
|
PENDING_TRADE_SUMMARY,
|
||||||
|
PENDING_TRADE_TAKER,
|
||||||
SETUP_SEED_WORDS,
|
SETUP_SEED_WORDS,
|
||||||
SETUP_PASSWORD,
|
SETUP_PASSWORD,
|
||||||
SETUP_RESTRICTION_LANGUAGES,
|
SETUP_RESTRICTION_LANGUAGES,
|
||||||
|
|
|
@ -35,9 +35,14 @@ import javafx.scene.*;
|
||||||
import javafx.stage.Modality;
|
import javafx.stage.Modality;
|
||||||
import javafx.stage.Stage;
|
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,
|
// 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
|
// probably overview, event history, news, charts,... -> low prio
|
||||||
public class HomeController extends CachedViewCB {
|
public class HomeController extends CachedViewCB {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(HomeController.class);
|
||||||
|
|
||||||
private ArbitratorRegistrationController arbitratorRegistrationController;
|
private ArbitratorRegistrationController arbitratorRegistrationController;
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -17,16 +17,15 @@
|
||||||
~ along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
~ along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<?import io.bitsquare.gui.components.CachingTabPane?>
|
|
||||||
<?import javafx.scene.control.*?>
|
<?import javafx.scene.control.*?>
|
||||||
<?import javafx.scene.layout.*?>
|
<?import javafx.scene.layout.*?>
|
||||||
<CachingTabPane fx:id="root" fx:controller="io.bitsquare.gui.main.orders.OrdersController"
|
<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.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0"
|
||||||
AnchorPane.topAnchor="0.0"
|
AnchorPane.topAnchor="0.0"
|
||||||
xmlns:fx="http://javafx.com/fxml">
|
xmlns:fx="http://javafx.com/fxml">
|
||||||
|
|
||||||
<Tab text="Open offers" closable="false"/>
|
<Tab fx:id="offersTab" text="Open offers" closable="false"/>
|
||||||
<Tab text="Pending trades" closable="false"/>
|
<Tab fx:id="pendingTradesTab" text="Pending trades" closable="false"/>
|
||||||
<Tab text="Closed 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
|
@Override
|
||||||
public void initialize(URL url, ResourceBundle rb) {
|
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 -> {
|
listener = navigationItems -> {
|
||||||
if (navigationItems != null && navigationItems.length == 3 && navigationItems[1] == navigationItem) {
|
if (navigationItems != null && navigationItems.length == 3 && navigationItems[1] == navigationItem) {
|
||||||
loadView(navigationItems[2]);
|
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);
|
super.initialize(url, rb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,6 +125,8 @@ public class TradeViewCB extends CachedViewCB implements TradeNavigator {
|
||||||
@Override
|
@Override
|
||||||
public void deactivate() {
|
public void deactivate() {
|
||||||
super.deactivate();
|
super.deactivate();
|
||||||
|
|
||||||
|
navigation.removeListener(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("EmptyMethod")
|
@SuppressWarnings("EmptyMethod")
|
||||||
|
@ -225,9 +226,6 @@ public class TradeViewCB extends CachedViewCB implements TradeNavigator {
|
||||||
log.error(e.getMessage());
|
log.error(e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
log.error("navigationItem not supported: " + navigationItem);
|
|
||||||
}
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,8 @@
|
||||||
~ along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
~ along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<?import io.bitsquare.gui.components.btc.AddressTextField?>
|
<?import io.bitsquare.gui.components.AddressTextField?>
|
||||||
<?import io.bitsquare.gui.components.btc.BalanceTextField?>
|
<?import io.bitsquare.gui.components.BalanceTextField?>
|
||||||
<?import io.bitsquare.gui.components.InfoDisplay?>
|
<?import io.bitsquare.gui.components.InfoDisplay?>
|
||||||
<?import io.bitsquare.gui.components.InputTextField?>
|
<?import io.bitsquare.gui.components.InputTextField?>
|
||||||
<?import io.bitsquare.gui.components.TitledGroupBg?>
|
<?import io.bitsquare.gui.components.TitledGroupBg?>
|
||||||
|
@ -77,7 +77,7 @@
|
||||||
</VBox>
|
</VBox>
|
||||||
<Label text="x">
|
<Label text="x">
|
||||||
<font>
|
<font>
|
||||||
<Font name="Helvetica" size="20.0"/>
|
<Font name="Helvetica-Bold" size="20.0"/>
|
||||||
</font>
|
</font>
|
||||||
<padding>
|
<padding>
|
||||||
<Insets top="14.0" left="3" right="3"/>
|
<Insets top="14.0" left="3" right="3"/>
|
||||||
|
@ -96,7 +96,7 @@
|
||||||
|
|
||||||
<Label text="=">
|
<Label text="=">
|
||||||
<font>
|
<font>
|
||||||
<Font name="Helvetica" size="20.0"/>
|
<Font name="Helvetica-Bold" size="20.0"/>
|
||||||
</font>
|
</font>
|
||||||
<padding>
|
<padding>
|
||||||
<Insets top="14.0" left="2" right="2"/>
|
<Insets top="14.0" left="2" right="2"/>
|
||||||
|
|
|
@ -21,12 +21,12 @@ import io.bitsquare.gui.CachedViewCB;
|
||||||
import io.bitsquare.gui.CloseListener;
|
import io.bitsquare.gui.CloseListener;
|
||||||
import io.bitsquare.gui.Navigation;
|
import io.bitsquare.gui.Navigation;
|
||||||
import io.bitsquare.gui.OverlayManager;
|
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.InfoDisplay;
|
||||||
import io.bitsquare.gui.components.InputTextField;
|
import io.bitsquare.gui.components.InputTextField;
|
||||||
import io.bitsquare.gui.components.Popups;
|
import io.bitsquare.gui.components.Popups;
|
||||||
import io.bitsquare.gui.components.TitledGroupBg;
|
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.Help;
|
||||||
import io.bitsquare.gui.main.help.HelpId;
|
import io.bitsquare.gui.main.help.HelpId;
|
||||||
import io.bitsquare.gui.util.ImageUtil;
|
import io.bitsquare.gui.util.ImageUtil;
|
||||||
|
|
|
@ -31,7 +31,6 @@ import java.util.List;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import javafx.animation.AnimationTimer;
|
import javafx.animation.AnimationTimer;
|
||||||
import javafx.beans.InvalidationListener;
|
|
||||||
import javafx.beans.value.ChangeListener;
|
import javafx.beans.value.ChangeListener;
|
||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
import javafx.collections.ObservableList;
|
import javafx.collections.ObservableList;
|
||||||
|
@ -58,7 +57,7 @@ public class OrderBook {
|
||||||
private final ObservableList<OrderBookListItem> orderBookListItems = FXCollections.observableArrayList();
|
private final ObservableList<OrderBookListItem> orderBookListItems = FXCollections.observableArrayList();
|
||||||
private final OrderBookListener orderBookListener;
|
private final OrderBookListener orderBookListener;
|
||||||
private final ChangeListener<BankAccount> bankAccountChangeListener;
|
private final ChangeListener<BankAccount> bankAccountChangeListener;
|
||||||
private final InvalidationListener invalidationListener;
|
private final ChangeListener<Number> invalidationListener;
|
||||||
private String fiatCode;
|
private String fiatCode;
|
||||||
private AnimationTimer pollingTimer;
|
private AnimationTimer pollingTimer;
|
||||||
private Country country;
|
private Country country;
|
||||||
|
@ -75,7 +74,10 @@ public class OrderBook {
|
||||||
this.user = user;
|
this.user = user;
|
||||||
|
|
||||||
bankAccountChangeListener = (observableValue, oldValue, newValue) -> setBankAccount(newValue);
|
bankAccountChangeListener = (observableValue, oldValue, newValue) -> setBankAccount(newValue);
|
||||||
invalidationListener = (ov) -> requestOffers();
|
invalidationListener = (ov, oldValue, newValue) -> {
|
||||||
|
log.debug("#### invalidationListener " + newValue);
|
||||||
|
requestOffers();
|
||||||
|
};
|
||||||
|
|
||||||
orderBookListener = new OrderBookListener() {
|
orderBookListener = new OrderBookListener() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -142,12 +144,14 @@ public class OrderBook {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addListeners() {
|
private void addListeners() {
|
||||||
|
log.debug("addListeners ");
|
||||||
user.currentBankAccountProperty().addListener(bankAccountChangeListener);
|
user.currentBankAccountProperty().addListener(bankAccountChangeListener);
|
||||||
messageFacade.addOrderBookListener(orderBookListener);
|
messageFacade.addOrderBookListener(orderBookListener);
|
||||||
messageFacade.invalidationTimestampProperty().addListener(invalidationListener);
|
messageFacade.invalidationTimestampProperty().addListener(invalidationListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeListeners() {
|
private void removeListeners() {
|
||||||
|
log.debug("removeListeners ");
|
||||||
user.currentBankAccountProperty().removeListener(bankAccountChangeListener);
|
user.currentBankAccountProperty().removeListener(bankAccountChangeListener);
|
||||||
messageFacade.removeOrderBookListener(orderBookListener);
|
messageFacade.removeOrderBookListener(orderBookListener);
|
||||||
messageFacade.invalidationTimestampProperty().removeListener(invalidationListener);
|
messageFacade.invalidationTimestampProperty().removeListener(invalidationListener);
|
||||||
|
@ -160,6 +164,7 @@ public class OrderBook {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void requestOffers() {
|
private void requestOffers() {
|
||||||
|
log.debug("#### requestOffers");
|
||||||
messageFacade.getOffers(fiatCode);
|
messageFacade.getOffers(fiatCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,7 +178,7 @@ public class OrderBook {
|
||||||
addListeners();
|
addListeners();
|
||||||
setBankAccount(user.getCurrentBankAccount());
|
setBankAccount(user.getCurrentBankAccount());
|
||||||
pollingTimer = Utilities.setInterval(1000, (animationTimer) -> {
|
pollingTimer = Utilities.setInterval(1000, (animationTimer) -> {
|
||||||
messageFacade.requestInvalidationTimeStamp(fiatCode);
|
messageFacade.requestInvalidationTimeStampFromDHT(fiatCode);
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@
|
||||||
</VBox>
|
</VBox>
|
||||||
<Label text="x">
|
<Label text="x">
|
||||||
<font>
|
<font>
|
||||||
<Font name="Helvetica" size="20.0"/>
|
<Font name="Helvetica-Bold" size="20.0"/>
|
||||||
</font>
|
</font>
|
||||||
<padding>
|
<padding>
|
||||||
<Insets top="14.0" left="3" right="3"/>
|
<Insets top="14.0" left="3" right="3"/>
|
||||||
|
@ -71,7 +71,7 @@
|
||||||
|
|
||||||
<Label text="=">
|
<Label text="=">
|
||||||
<font>
|
<font>
|
||||||
<Font name="Helvetica" size="20.0"/>
|
<Font name="Helvetica-Bold" size="20.0"/>
|
||||||
</font>
|
</font>
|
||||||
<padding>
|
<padding>
|
||||||
<Insets top="14.0" left="2" right="2"/>
|
<Insets top="14.0" left="2" right="2"/>
|
||||||
|
|
|
@ -351,7 +351,7 @@ public class OrderBookViewCB extends CachedViewCB<OrderBookPM> {
|
||||||
OrderBookListItem>>() {
|
OrderBookListItem>>() {
|
||||||
@Override
|
@Override
|
||||||
public TableCell<OrderBookListItem, OrderBookListItem> call(
|
public TableCell<OrderBookListItem, OrderBookListItem> call(
|
||||||
TableColumn<OrderBookListItem, OrderBookListItem> directionColumn) {
|
TableColumn<OrderBookListItem, OrderBookListItem> column) {
|
||||||
return new TableCell<OrderBookListItem, OrderBookListItem>() {
|
return new TableCell<OrderBookListItem, OrderBookListItem>() {
|
||||||
@Override
|
@Override
|
||||||
public void updateItem(final OrderBookListItem item, boolean empty) {
|
public void updateItem(final OrderBookListItem item, boolean empty) {
|
||||||
|
@ -370,7 +370,7 @@ public class OrderBookViewCB extends CachedViewCB<OrderBookPM> {
|
||||||
OrderBookListItem>>() {
|
OrderBookListItem>>() {
|
||||||
@Override
|
@Override
|
||||||
public TableCell<OrderBookListItem, OrderBookListItem> call(
|
public TableCell<OrderBookListItem, OrderBookListItem> call(
|
||||||
TableColumn<OrderBookListItem, OrderBookListItem> directionColumn) {
|
TableColumn<OrderBookListItem, OrderBookListItem> column) {
|
||||||
return new TableCell<OrderBookListItem, OrderBookListItem>() {
|
return new TableCell<OrderBookListItem, OrderBookListItem>() {
|
||||||
@Override
|
@Override
|
||||||
public void updateItem(final OrderBookListItem item, boolean empty) {
|
public void updateItem(final OrderBookListItem item, boolean empty) {
|
||||||
|
@ -389,7 +389,7 @@ public class OrderBookViewCB extends CachedViewCB<OrderBookPM> {
|
||||||
OrderBookListItem>>() {
|
OrderBookListItem>>() {
|
||||||
@Override
|
@Override
|
||||||
public TableCell<OrderBookListItem, OrderBookListItem> call(
|
public TableCell<OrderBookListItem, OrderBookListItem> call(
|
||||||
TableColumn<OrderBookListItem, OrderBookListItem> directionColumn) {
|
TableColumn<OrderBookListItem, OrderBookListItem> column) {
|
||||||
return new TableCell<OrderBookListItem, OrderBookListItem>() {
|
return new TableCell<OrderBookListItem, OrderBookListItem>() {
|
||||||
@Override
|
@Override
|
||||||
public void updateItem(final OrderBookListItem item, boolean empty) {
|
public void updateItem(final OrderBookListItem item, boolean empty) {
|
||||||
|
@ -409,7 +409,7 @@ public class OrderBookViewCB extends CachedViewCB<OrderBookPM> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TableCell<OrderBookListItem, OrderBookListItem> call(
|
public TableCell<OrderBookListItem, OrderBookListItem> call(
|
||||||
TableColumn<OrderBookListItem, OrderBookListItem> directionColumn) {
|
TableColumn<OrderBookListItem, OrderBookListItem> column) {
|
||||||
return new TableCell<OrderBookListItem, OrderBookListItem>() {
|
return new TableCell<OrderBookListItem, OrderBookListItem>() {
|
||||||
final ImageView iconView = new ImageView();
|
final ImageView iconView = new ImageView();
|
||||||
final Button button = new Button();
|
final Button button = new Button();
|
||||||
|
@ -493,7 +493,7 @@ public class OrderBookViewCB extends CachedViewCB<OrderBookPM> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TableCell<OrderBookListItem, OrderBookListItem> call(
|
public TableCell<OrderBookListItem, OrderBookListItem> call(
|
||||||
TableColumn<OrderBookListItem, OrderBookListItem> directionColumn) {
|
TableColumn<OrderBookListItem, OrderBookListItem> column) {
|
||||||
return new TableCell<OrderBookListItem, OrderBookListItem>() {
|
return new TableCell<OrderBookListItem, OrderBookListItem>() {
|
||||||
final HBox hBox = new HBox();
|
final HBox hBox = new HBox();
|
||||||
|
|
||||||
|
@ -527,7 +527,7 @@ public class OrderBookViewCB extends CachedViewCB<OrderBookPM> {
|
||||||
OrderBookListItem>>() {
|
OrderBookListItem>>() {
|
||||||
@Override
|
@Override
|
||||||
public TableCell<OrderBookListItem, OrderBookListItem> call(
|
public TableCell<OrderBookListItem, OrderBookListItem> call(
|
||||||
TableColumn<OrderBookListItem, OrderBookListItem> directionColumn) {
|
TableColumn<OrderBookListItem, OrderBookListItem> column) {
|
||||||
return new TableCell<OrderBookListItem, OrderBookListItem>() {
|
return new TableCell<OrderBookListItem, OrderBookListItem>() {
|
||||||
@Override
|
@Override
|
||||||
public void updateItem(final OrderBookListItem orderBookListItem, boolean empty) {
|
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.Offer;
|
||||||
import io.bitsquare.trade.Trade;
|
import io.bitsquare.trade.Trade;
|
||||||
import io.bitsquare.trade.TradeManager;
|
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.core.Coin;
|
||||||
import com.google.bitcoin.utils.ExchangeRate;
|
import com.google.bitcoin.utils.ExchangeRate;
|
||||||
|
@ -155,116 +153,24 @@ class TakeOfferModel extends UIModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
void takeOffer() {
|
void takeOffer() {
|
||||||
// data validation is done in the trade domain
|
Trade trade = tradeManager.takeOffer(amountAsCoin.get(), offer);
|
||||||
/*tradeManager.requestPlaceOffer(orderBookInfo.getOffer().getId(),
|
trade.stateProperty().addListener((ov, oldValue, newValue) -> {
|
||||||
orderBookInfo.getOffer().getDirection(),
|
switch (newValue) {
|
||||||
priceAsFiat.get(),
|
case DEPOSIT_PUBLISHED:
|
||||||
amountAsCoin.get(),
|
transactionId.set(trade.getDepositTx().getHashAsString());
|
||||||
minAmountAsCoin.get(),
|
|
||||||
(transaction) -> {
|
|
||||||
transactionId.set(transaction.getHashAsString());
|
|
||||||
requestTakeOfferSuccess.set(true);
|
requestTakeOfferSuccess.set(true);
|
||||||
},
|
break;
|
||||||
requestTakeOfferErrorMessage::set
|
case FAULT:
|
||||||
);*/
|
requestTakeOfferErrorMessage.set("An error occurred. Error: " + trade.getFault().getMessage());
|
||||||
SellerTakesOfferProtocolListener listener = new SellerTakesOfferProtocolListener() {
|
break;
|
||||||
@Override
|
case OFFERER_REJECTED:
|
||||||
public void onDepositTxPublished(String depositTxId) {
|
|
||||||
transactionId.set(depositTxId);
|
|
||||||
requestTakeOfferSuccess.set(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBankTransferInited(String tradeId) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@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.");
|
requestTakeOfferErrorMessage.set("Take offer request got rejected.");
|
||||||
}
|
break;
|
||||||
};
|
|
||||||
|
|
||||||
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() {
|
void calculateVolume() {
|
||||||
|
|
|
@ -17,8 +17,8 @@
|
||||||
~ along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
~ along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<?import io.bitsquare.gui.components.btc.AddressTextField?>
|
<?import io.bitsquare.gui.components.AddressTextField?>
|
||||||
<?import io.bitsquare.gui.components.btc.BalanceTextField?>
|
<?import io.bitsquare.gui.components.BalanceTextField?>
|
||||||
<?import io.bitsquare.gui.components.InfoDisplay?>
|
<?import io.bitsquare.gui.components.InfoDisplay?>
|
||||||
<?import io.bitsquare.gui.components.InputTextField?>
|
<?import io.bitsquare.gui.components.InputTextField?>
|
||||||
<?import io.bitsquare.gui.components.TitledGroupBg?>
|
<?import io.bitsquare.gui.components.TitledGroupBg?>
|
||||||
|
@ -77,7 +77,7 @@
|
||||||
</VBox>
|
</VBox>
|
||||||
<Label text="x">
|
<Label text="x">
|
||||||
<font>
|
<font>
|
||||||
<Font name="Helvetica" size="20.0"/>
|
<Font name="Helvetica-Bold" size="20.0"/>
|
||||||
</font>
|
</font>
|
||||||
<padding>
|
<padding>
|
||||||
<Insets top="14.0" left="3" right="3"/>
|
<Insets top="14.0" left="3" right="3"/>
|
||||||
|
@ -92,7 +92,7 @@
|
||||||
|
|
||||||
<Label text="=">
|
<Label text="=">
|
||||||
<font>
|
<font>
|
||||||
<Font name="Helvetica" size="20.0"/>
|
<Font name="Helvetica-Bold" size="20.0"/>
|
||||||
</font>
|
</font>
|
||||||
<padding>
|
<padding>
|
||||||
<Insets top="14.0" left="2" right="2"/>
|
<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.CloseListener;
|
||||||
import io.bitsquare.gui.Navigation;
|
import io.bitsquare.gui.Navigation;
|
||||||
import io.bitsquare.gui.OverlayManager;
|
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.InfoDisplay;
|
||||||
import io.bitsquare.gui.components.InputTextField;
|
import io.bitsquare.gui.components.InputTextField;
|
||||||
import io.bitsquare.gui.components.Popups;
|
import io.bitsquare.gui.components.Popups;
|
||||||
import io.bitsquare.gui.components.TitledGroupBg;
|
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.Help;
|
||||||
import io.bitsquare.gui.main.help.HelpId;
|
import io.bitsquare.gui.main.help.HelpId;
|
||||||
import io.bitsquare.gui.util.ImageUtil;
|
import io.bitsquare.gui.util.ImageUtil;
|
||||||
|
@ -318,6 +318,8 @@ public class TakeOfferViewCB extends CachedViewCB<TakeOfferPM> {
|
||||||
public void handle(ActionEvent actionEvent) {
|
public void handle(ActionEvent actionEvent) {
|
||||||
try {
|
try {
|
||||||
close();
|
close();
|
||||||
|
navigation.navigationTo(Navigation.Item.MAIN, Navigation.Item.ORDERS,
|
||||||
|
Navigation.Item.PENDING_TRADES);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,8 +20,10 @@ package io.bitsquare.gui.util;
|
||||||
import javafx.scene.paint.*;
|
import javafx.scene.paint.*;
|
||||||
|
|
||||||
public class Colors {
|
public class Colors {
|
||||||
public static final Paint BLUE = Color.valueOf("#0096c9");
|
public static final Paint BLUE = Color.valueOf("#0f87c3");
|
||||||
public static final Paint LIGHT_GREY = Color.valueOf("#f4f4f4");
|
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 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 java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import javafx.animation.AnimationTimer;
|
import javafx.animation.AnimationTimer;
|
||||||
|
import javafx.scene.*;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
@ -59,11 +60,21 @@ public class Profiler {
|
||||||
counter++;
|
counter++;
|
||||||
long elapsed = (System.currentTimeMillis() - lastFPSTime);
|
long elapsed = (System.currentTimeMillis() - lastFPSTime);
|
||||||
if (elapsed > 19)
|
if (elapsed > 19)
|
||||||
log.trace("FPS: elapsed: {}ms / FPS total counter: {}", elapsed, counter);
|
log.trace("Profiler: last frame used {}ms", elapsed);
|
||||||
|
|
||||||
lastFPSTime = System.currentTimeMillis();
|
lastFPSTime = System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
fpsTimer.start();
|
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
|
// 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 +
|
log.trace("Add offer to DHT was successful. Added data: [locationKey: " + locationKey +
|
||||||
", value: " + offerData + "]");
|
", value: " + offerData + "]");
|
||||||
});
|
});
|
||||||
|
@ -246,7 +246,7 @@ public class MessageFacade implements MessageBroker {
|
||||||
log.error("Remove offer from DHT failed. Error: " + e.getMessage());
|
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 + ", " +
|
log.trace("Remove offer from DHT was successful. Removed data: [key: " + locationKey + ", " +
|
||||||
|
@ -448,7 +448,7 @@ public class MessageFacade implements MessageBroker {
|
||||||
// Polling
|
// Polling
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
private void updateInvalidationTimestamp(Number160 locationKey) {
|
private void writeInvalidationTimestampToDHT(Number160 locationKey) {
|
||||||
invalidationTimestamp.set(System.currentTimeMillis());
|
invalidationTimestamp.set(System.currentTimeMillis());
|
||||||
try {
|
try {
|
||||||
FuturePut putFuture = p2pNode.putData(getInvalidatedLocationKey(locationKey),
|
FuturePut putFuture = p2pNode.putData(getInvalidatedLocationKey(locationKey),
|
||||||
|
@ -477,7 +477,7 @@ public class MessageFacade implements MessageBroker {
|
||||||
return invalidationTimestamp;
|
return invalidationTimestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void requestInvalidationTimeStamp(String currencyCode) {
|
public void requestInvalidationTimeStampFromDHT(String currencyCode) {
|
||||||
Number160 locationKey = Number160.createHash(currencyCode);
|
Number160 locationKey = Number160.createHash(currencyCode);
|
||||||
try {
|
try {
|
||||||
FutureGet getFuture = p2pNode.getData(getInvalidatedLocationKey(locationKey));
|
FutureGet getFuture = p2pNode.getData(getInvalidatedLocationKey(locationKey));
|
||||||
|
@ -490,8 +490,8 @@ public class MessageFacade implements MessageBroker {
|
||||||
final Object object = data.object();
|
final Object object = data.object();
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
Long timeStamp = (Long) object;
|
Long timeStamp = (Long) object;
|
||||||
// log.trace("Get invalidationTimestamp from DHT was successful. TimeStamp=" +
|
log.trace("Get invalidationTimestamp from DHT was successful. TimeStamp=" +
|
||||||
// timeStamp);
|
timeStamp);
|
||||||
invalidationTimestamp.set(timeStamp);
|
invalidationTimestamp.set(timeStamp);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -499,6 +499,10 @@ public class MessageFacade implements MessageBroker {
|
||||||
log.error("Get invalidationTimestamp from DHT failed. Data = " + data);
|
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 {
|
else {
|
||||||
log.error("Get invalidationTimestamp from DHT failed with reason:" + getFuture.failedReason());
|
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 java.io.Serializable;
|
||||||
|
|
||||||
|
import javafx.beans.property.BooleanProperty;
|
||||||
|
import javafx.beans.property.ObjectProperty;
|
||||||
import javafx.beans.property.SimpleBooleanProperty;
|
import javafx.beans.property.SimpleBooleanProperty;
|
||||||
import javafx.beans.property.SimpleStringProperty;
|
import javafx.beans.property.SimpleObjectProperty;
|
||||||
|
|
||||||
//TODO flatten down?
|
//TODO flatten down?
|
||||||
|
|
||||||
public class Trade implements Serializable {
|
public class Trade implements Serializable {
|
||||||
private static final long serialVersionUID = -8275323072940974077L;
|
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 final Offer offer;
|
||||||
private String takeOfferFeeTxID;
|
private String takeOfferFeeTxID;
|
||||||
private Coin tradeAmount;
|
private Coin tradeAmount;
|
||||||
private Contract contract;
|
private Contract contract;
|
||||||
private String contractAsJson;
|
private String contractAsJson;
|
||||||
private String takerSignature;
|
private String takerSignature;
|
||||||
private Transaction depositTransaction;
|
private Transaction depositTx;
|
||||||
private Transaction payoutTransaction;
|
private Transaction payoutTx;
|
||||||
private State state = State.OPEN;
|
private State state;
|
||||||
|
private Throwable fault;
|
||||||
|
|
||||||
// The Property fields are not serialized and therefore not initialized when read from disc.
|
// When serialized those transient properties are not instantiated, so we instantiate them in the getters at first
|
||||||
// We need to access then with the getter to be sure it is not null.
|
// access. Only use the accessor not the private field.
|
||||||
// Don't access them directly, use the getter method
|
// TODO use ObjectPropertys instead of BooleanProperty
|
||||||
transient private SimpleBooleanProperty _depositTxChangedProperty;
|
transient private BooleanProperty _payoutTxChanged;
|
||||||
transient private SimpleBooleanProperty _payoutTxChangedProperty;
|
transient private BooleanProperty _contractChanged;
|
||||||
transient private SimpleBooleanProperty _contractChangedProperty;
|
transient private ObjectProperty<Transaction> _depositTx;
|
||||||
transient private SimpleStringProperty _stateChangedProperty;
|
transient private ObjectProperty<State> _state;
|
||||||
|
transient private ObjectProperty<Throwable> _fault;
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Constructor
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
public Trade(Offer offer) {
|
public Trade(Offer offer) {
|
||||||
this.offer = offer;
|
this.offer = offer;
|
||||||
|
state = State.OPEN;
|
||||||
_depositTxChangedProperty = new SimpleBooleanProperty();
|
|
||||||
_payoutTxChangedProperty = new SimpleBooleanProperty();
|
|
||||||
_contractChangedProperty = new SimpleBooleanProperty();
|
|
||||||
_stateChangedProperty = new SimpleStringProperty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Fiat getTradeVolume() {
|
|
||||||
return offer.getVolumeByAmount(tradeAmount);
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Setters
|
// Setters
|
||||||
|
@ -86,9 +104,65 @@ public class Trade implements Serializable {
|
||||||
return contract;
|
return contract;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setContractAsJson(String contractAsJson) {
|
||||||
|
this.contractAsJson = contractAsJson;
|
||||||
|
}
|
||||||
|
|
||||||
public void setContract(Contract contract) {
|
public void setContract(Contract contract) {
|
||||||
this.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() {
|
public String getId() {
|
||||||
|
@ -107,99 +181,40 @@ public class Trade implements Serializable {
|
||||||
return contractAsJson;
|
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);
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
return _depositTx;
|
||||||
// Getters
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
public void setContractAsJson(String contractAsJson) {
|
|
||||||
this.contractAsJson = contractAsJson;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTakerSignature() {
|
public BooleanProperty contractChangedProperty() {
|
||||||
return takerSignature;
|
if (_contractChanged == null)
|
||||||
|
_contractChanged = new SimpleBooleanProperty();
|
||||||
|
|
||||||
|
return _contractChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Transaction getDepositTransaction() {
|
public BooleanProperty payoutTxChangedProperty() {
|
||||||
return depositTransaction;
|
if (_payoutTxChanged == null)
|
||||||
|
_payoutTxChanged = new SimpleBooleanProperty();
|
||||||
|
|
||||||
|
return _payoutTxChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDepositTransaction(Transaction depositTransaction) {
|
public ObjectProperty<State> stateProperty() {
|
||||||
this.depositTransaction = depositTransaction;
|
if (_state == null)
|
||||||
depositTxChangedProperty().set(!depositTxChangedProperty().get());
|
_state = new SimpleObjectProperty<>(state);
|
||||||
|
|
||||||
|
return _state;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Transaction getPayoutTransaction() {
|
public ObjectProperty<Throwable> faultProperty() {
|
||||||
return payoutTransaction;
|
if (_fault == null)
|
||||||
}
|
_fault = new SimpleObjectProperty<>(fault);
|
||||||
|
return _fault;
|
||||||
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 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.Coin;
|
||||||
import com.google.bitcoin.core.Transaction;
|
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 com.google.bitcoin.utils.Fiat;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -57,8 +55,8 @@ import java.util.Map;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import javafx.beans.property.SimpleStringProperty;
|
import javafx.collections.FXCollections;
|
||||||
import javafx.beans.property.StringProperty;
|
import javafx.collections.ObservableMap;
|
||||||
|
|
||||||
import net.tomp2p.peers.PeerAddress;
|
import net.tomp2p.peers.PeerAddress;
|
||||||
|
|
||||||
|
@ -89,13 +87,11 @@ public class TradeManager {
|
||||||
private final Map<String, BuyerAcceptsOfferProtocol> offererAsBuyerProtocolMap = new HashMap<>();
|
private final Map<String, BuyerAcceptsOfferProtocol> offererAsBuyerProtocolMap = new HashMap<>();
|
||||||
private final Map<String, CreateOfferCoordinator> createOfferCoordinatorMap = new HashMap<>();
|
private final Map<String, CreateOfferCoordinator> createOfferCoordinatorMap = new HashMap<>();
|
||||||
|
|
||||||
private final StringProperty newTradeProperty = new SimpleStringProperty();
|
private final ObservableMap<String, Offer> offers = FXCollections.observableHashMap();
|
||||||
|
private final ObservableMap<String, Trade> trades = FXCollections.observableHashMap();
|
||||||
private final Map<String, Offer> offers;
|
|
||||||
private final Map<String, Trade> trades;
|
|
||||||
|
|
||||||
// TODO There might be multiple pending trades
|
// 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");
|
Object offersObject = persistence.read(this, "offers");
|
||||||
if (offersObject instanceof HashMap) {
|
if (offersObject instanceof HashMap) {
|
||||||
offers = (Map<String, Offer>) offersObject;
|
offers.putAll((Map<String, Offer>) offersObject);
|
||||||
}
|
|
||||||
else {
|
|
||||||
offers = new HashMap<>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Object tradesObject = persistence.read(this, "trades");
|
Object tradesObject = persistence.read(this, "trades");
|
||||||
if (tradesObject instanceof HashMap) {
|
if (tradesObject instanceof HashMap) {
|
||||||
trades = (Map<String, Trade>) tradesObject;
|
trades.putAll((Map<String, Trade>) tradesObject);
|
||||||
}
|
|
||||||
else {
|
|
||||||
trades = new HashMap<>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
messageFacade.addIncomingTradeMessageListener(this::onIncomingTradeMessage);
|
messageFacade.addIncomingTradeMessageListener(this::onIncomingTradeMessage);
|
||||||
|
@ -200,7 +190,8 @@ public class TradeManager {
|
||||||
resultHandler.onResult(transactionId);
|
resultHandler.onResult(transactionId);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
//TODO retry policy
|
//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());
|
createOfferCoordinatorMap.remove(offer.getId());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -231,18 +222,6 @@ public class TradeManager {
|
||||||
messageFacade.removeOffer(offer);
|
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
|
// Manage trades
|
||||||
|
@ -254,10 +233,7 @@ public class TradeManager {
|
||||||
|
|
||||||
Trade trade = new Trade(offer);
|
Trade trade = new Trade(offer);
|
||||||
trades.put(offer.getId(), trade);
|
trades.put(offer.getId(), trade);
|
||||||
saveTrades();
|
persistTrades();
|
||||||
|
|
||||||
// for updating UIs
|
|
||||||
this.newTradeProperty.set(trade.getId());
|
|
||||||
|
|
||||||
return trade;
|
return trade;
|
||||||
}
|
}
|
||||||
|
@ -267,10 +243,7 @@ public class TradeManager {
|
||||||
log.error("trades does not contain the trade with the ID " + trade.getId());
|
log.error("trades does not contain the trade with the ID " + trade.getId());
|
||||||
|
|
||||||
trades.remove(trade.getId());
|
trades.remove(trade.getId());
|
||||||
saveTrades();
|
persistTrades();
|
||||||
|
|
||||||
// for updating UIs
|
|
||||||
this.newTradeProperty.set(null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -284,7 +257,7 @@ public class TradeManager {
|
||||||
Offer offer = offers.get(offerId);
|
Offer offer = offers.get(offerId);
|
||||||
|
|
||||||
Trade trade = createTrade(offer);
|
Trade trade = createTrade(offer);
|
||||||
pendingTrade = trade;
|
currentPendingTrade = trade;
|
||||||
|
|
||||||
BuyerAcceptsOfferProtocol buyerAcceptsOfferProtocol = new BuyerAcceptsOfferProtocol(trade,
|
BuyerAcceptsOfferProtocol buyerAcceptsOfferProtocol = new BuyerAcceptsOfferProtocol(trade,
|
||||||
sender,
|
sender,
|
||||||
|
@ -296,57 +269,54 @@ public class TradeManager {
|
||||||
new BuyerAcceptsOfferProtocolListener() {
|
new BuyerAcceptsOfferProtocolListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onOfferAccepted(Offer offer) {
|
public void onOfferAccepted(Offer offer) {
|
||||||
|
trade.setState(Trade.State.OFFERER_ACCEPTED);
|
||||||
|
persistTrades();
|
||||||
removeOffer(offer);
|
removeOffer(offer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDepositTxPublished(String depositTxID) {
|
public void onDepositTxPublished(Transaction depositTx) {
|
||||||
log.trace("trading onDepositTxPublishedMessage " + depositTxID);
|
trade.setDepositTx(depositTx);
|
||||||
|
trade.setState(Trade.State.DEPOSIT_PUBLISHED);
|
||||||
|
persistTrades();
|
||||||
|
log.trace("trading onDepositTxPublishedMessage " + depositTx.getHashAsString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDepositTxConfirmedUpdate(TransactionConfidence confidence) {
|
public void onDepositTxConfirmedInBlockchain() {
|
||||||
log.trace("trading onDepositTxConfirmedUpdate");
|
log.trace("trading onDepositTxConfirmedInBlockchain");
|
||||||
|
trade.setState(Trade.State.DEPOSIT_CONFIRMED);
|
||||||
|
persistTrades();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPayoutTxPublished(String payoutTxAsHex) {
|
public void onPayoutTxPublished(Transaction payoutTx) {
|
||||||
Transaction payoutTx = new Transaction(walletFacade.getWallet().getParams(),
|
trade.setPayoutTx(payoutTx);
|
||||||
Utils.parseAsHexOrBase58(payoutTxAsHex));
|
trade.setState(Trade.State.PAYOUT_PUBLISHED);
|
||||||
trade.setPayoutTransaction(payoutTx);
|
persistTrades();
|
||||||
trade.setState(Trade.State.COMPLETED);
|
|
||||||
log.debug("trading onPayoutTxPublishedMessage");
|
log.debug("trading onPayoutTxPublishedMessage");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFault(Throwable throwable, BuyerAcceptsOfferProtocol.State state) {
|
public void onFault(Throwable throwable, BuyerAcceptsOfferProtocol.State state) {
|
||||||
log.error("Error while executing trade process at state: " + state + " / " + throwable);
|
log.error("Error while executing trade process at state: " + state + " / " + throwable);
|
||||||
/* Popups.openErrorPopup("Error while executing trade process",
|
trade.setFault(throwable);
|
||||||
"Error while executing trade process at state: " + state + " / " +
|
trade.setState(Trade.State.FAULT);
|
||||||
throwable);*/
|
persistTrades();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// probably not needed
|
||||||
@Override
|
@Override
|
||||||
public void onWaitingForPeerResponse(BuyerAcceptsOfferProtocol.State state) {
|
public void onWaitingForPeerResponse(BuyerAcceptsOfferProtocol.State state) {
|
||||||
log.debug("Waiting for peers response at state " + state);
|
log.debug("Waiting for peers response at state " + state);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// probably not needed
|
||||||
public void onCompleted(BuyerAcceptsOfferProtocol.State state) {
|
|
||||||
log.debug("Trade protocol completed at state " + state);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onWaitingForUserInteraction(BuyerAcceptsOfferProtocol.State state) {
|
public void onWaitingForUserInteraction(BuyerAcceptsOfferProtocol.State state) {
|
||||||
log.debug("Waiting for UI activity at state " + state);
|
log.debug("Waiting for UI activity at state " + state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDepositTxConfirmedInBlockchain() {
|
|
||||||
log.trace("trading onDepositTxConfirmedInBlockchain");
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!offererAsBuyerProtocolMap.containsKey(trade.getId())) {
|
if (!offererAsBuyerProtocolMap.containsKey(trade.getId())) {
|
||||||
|
@ -365,18 +335,91 @@ public class TradeManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bankTransferInited(String tradeUID) {
|
public Trade takeOffer(Coin amount, Offer offer) {
|
||||||
offererAsBuyerProtocolMap.get(tradeUID).onUIEventBankTransferInited();
|
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onFiatReceived(String tradeUID) {
|
@Override
|
||||||
takerAsSellerProtocolMap.get(tradeUID).onUIEventFiatReceived();
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
//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
|
// Process incoming tradeMessages
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Routes the incoming messages to the responsible protocol
|
||||||
private void onIncomingTradeMessage(TradeMessage tradeMessage, PeerAddress sender) {
|
private void onIncomingTradeMessage(TradeMessage tradeMessage, PeerAddress sender) {
|
||||||
// log.trace("processTradingMessage TradeId " + tradeMessage.getTradeId());
|
// log.trace("processTradingMessage TradeId " + tradeMessage.getTradeId());
|
||||||
log.trace("processTradingMessage instance " + tradeMessage.getClass().getSimpleName());
|
log.trace("processTradingMessage instance " + tradeMessage.getClass().getSimpleName());
|
||||||
|
@ -403,6 +446,7 @@ public class TradeManager {
|
||||||
(RequestOffererPublishDepositTxMessage) tradeMessage);
|
(RequestOffererPublishDepositTxMessage) tradeMessage);
|
||||||
}
|
}
|
||||||
else if (tradeMessage instanceof DepositTxPublishedMessage) {
|
else if (tradeMessage instanceof DepositTxPublishedMessage) {
|
||||||
|
persistTrades();
|
||||||
takerAsSellerProtocolMap.get(tradeId).onDepositTxPublishedMessage((DepositTxPublishedMessage) tradeMessage);
|
takerAsSellerProtocolMap.get(tradeId).onDepositTxPublishedMessage((DepositTxPublishedMessage) tradeMessage);
|
||||||
}
|
}
|
||||||
else if (tradeMessage instanceof BankTransferInitedMessage) {
|
else if (tradeMessage instanceof BankTransferInitedMessage) {
|
||||||
|
@ -422,12 +466,15 @@ public class TradeManager {
|
||||||
return trades.containsKey(offer.getId());
|
return trades.containsKey(offer.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isTradeMyOffer(Trade trade) {
|
||||||
|
return trade.getOffer().getMessagePublicKey().equals(user.getMessagePublicKey());
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Getters
|
// Getters
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
public Map<String, Trade> getTrades() {
|
public ObservableMap<String, Trade> getTrades() {
|
||||||
return trades;
|
return trades;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -439,12 +486,8 @@ public class TradeManager {
|
||||||
return offers.get(offerId);
|
return offers.get(offerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Trade getPendingTrade() {
|
public Trade getCurrentPendingTrade() {
|
||||||
return pendingTrade;
|
return currentPendingTrade;
|
||||||
}
|
|
||||||
|
|
||||||
public final StringProperty getNewTradeProperty() {
|
|
||||||
return this.newTradeProperty;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -453,11 +496,11 @@ public class TradeManager {
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
private void persistOffers() {
|
private void persistOffers() {
|
||||||
persistence.write(this, "offers", offers);
|
persistence.write(this, "offers", (Map<String, Offer>) new HashMap<>(offers));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void saveTrades() {
|
private void persistTrades() {
|
||||||
persistence.write(this, "trades", trades);
|
persistence.write(this, "trades", (Map<String, Trade>) new HashMap<>(trades));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|
|
@ -44,6 +44,7 @@ import io.bitsquare.user.User;
|
||||||
import com.google.bitcoin.core.Coin;
|
import com.google.bitcoin.core.Coin;
|
||||||
import com.google.bitcoin.core.ECKey;
|
import com.google.bitcoin.core.ECKey;
|
||||||
import com.google.bitcoin.core.Transaction;
|
import com.google.bitcoin.core.Transaction;
|
||||||
|
import com.google.bitcoin.core.Utils;
|
||||||
|
|
||||||
import java.security.PublicKey;
|
import java.security.PublicKey;
|
||||||
|
|
||||||
|
@ -169,7 +170,6 @@ public class BuyerAcceptsOfferProtocol {
|
||||||
state = State.Init;
|
state = State.Init;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void start() {
|
public void start() {
|
||||||
log.debug("start called " + step++);
|
log.debug("start called " + step++);
|
||||||
state = State.HandleTakeOfferRequest;
|
state = State.HandleTakeOfferRequest;
|
||||||
|
@ -180,7 +180,7 @@ public class BuyerAcceptsOfferProtocol {
|
||||||
public void onResultHandleTakeOfferRequest(boolean takeOfferRequestAccepted) {
|
public void onResultHandleTakeOfferRequest(boolean takeOfferRequestAccepted) {
|
||||||
log.debug("onResultHandleTakeOfferRequest called " + step++);
|
log.debug("onResultHandleTakeOfferRequest called " + step++);
|
||||||
if (takeOfferRequestAccepted) {
|
if (takeOfferRequestAccepted) {
|
||||||
trade.setState(Trade.State.ACCEPTED);
|
trade.setState(Trade.State.OFFERER_ACCEPTED);
|
||||||
messageFacade.removeOffer(offer);
|
messageFacade.removeOffer(offer);
|
||||||
listener.onOfferAccepted(offer);
|
listener.onOfferAccepted(offer);
|
||||||
listener.onWaitingForPeerResponse(state);
|
listener.onWaitingForPeerResponse(state);
|
||||||
|
@ -335,8 +335,7 @@ public class BuyerAcceptsOfferProtocol {
|
||||||
public void onResultSignAndPublishDepositTx(Transaction depositTransaction) {
|
public void onResultSignAndPublishDepositTx(Transaction depositTransaction) {
|
||||||
log.debug("onResultSignAndPublishDepositTx called " + step++);
|
log.debug("onResultSignAndPublishDepositTx called " + step++);
|
||||||
|
|
||||||
trade.setDepositTransaction(depositTransaction);
|
listener.onDepositTxPublished(depositTransaction);
|
||||||
listener.onDepositTxPublished(depositTransaction.getHashAsString());
|
|
||||||
|
|
||||||
state = State.SendDepositTxIdToTaker;
|
state = State.SendDepositTxIdToTaker;
|
||||||
SendDepositTxIdToTaker.run(this::onResultSendDepositTxIdToTaker, this::onFault, peerAddress, messageFacade,
|
SendDepositTxIdToTaker.run(this::onResultSendDepositTxIdToTaker, this::onFault, peerAddress, messageFacade,
|
||||||
|
@ -348,7 +347,7 @@ public class BuyerAcceptsOfferProtocol {
|
||||||
|
|
||||||
state = State.SetupListenerForBlockChainConfirmation;
|
state = State.SetupListenerForBlockChainConfirmation;
|
||||||
SetupListenerForBlockChainConfirmation.run(this::onResultSetupListenerForBlockChainConfirmation,
|
SetupListenerForBlockChainConfirmation.run(this::onResultSetupListenerForBlockChainConfirmation,
|
||||||
this::onFault, trade.getDepositTransaction(), listener);
|
this::onFault, trade.getDepositTx(), listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onResultSetupListenerForBlockChainConfirmation() {
|
public void onResultSetupListenerForBlockChainConfirmation() {
|
||||||
|
@ -375,7 +374,7 @@ public class BuyerAcceptsOfferProtocol {
|
||||||
state = State.onUIEventBankTransferInited;
|
state = State.onUIEventBankTransferInited;
|
||||||
|
|
||||||
// next task
|
// next task
|
||||||
String depositTransactionId = trade.getDepositTransaction().getHashAsString();
|
String depositTransactionId = trade.getDepositTx().getHashAsString();
|
||||||
Coin tradeAmount = trade.getTradeAmount();
|
Coin tradeAmount = trade.getTradeAmount();
|
||||||
Coin collateral = trade.getCollateralAmount();
|
Coin collateral = trade.getCollateralAmount();
|
||||||
state = State.SendSignedPayoutTx;
|
state = State.SendSignedPayoutTx;
|
||||||
|
@ -414,9 +413,9 @@ public class BuyerAcceptsOfferProtocol {
|
||||||
|
|
||||||
state = State.onPayoutTxPublishedMessage;
|
state = State.onPayoutTxPublishedMessage;
|
||||||
|
|
||||||
// next task
|
Transaction payoutTx = new Transaction(walletFacade.getWallet().getParams(),
|
||||||
listener.onPayoutTxPublished(payoutTxAsHex);
|
Utils.parseAsHexOrBase58(payoutTxAsHex));
|
||||||
listener.onCompleted(state);
|
listener.onPayoutTxPublished(payoutTx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -19,24 +19,20 @@ package io.bitsquare.trade.protocol.trade.offerer;
|
||||||
|
|
||||||
import io.bitsquare.trade.Offer;
|
import io.bitsquare.trade.Offer;
|
||||||
|
|
||||||
import com.google.bitcoin.core.TransactionConfidence;
|
import com.google.bitcoin.core.Transaction;
|
||||||
|
|
||||||
public interface BuyerAcceptsOfferProtocolListener {
|
public interface BuyerAcceptsOfferProtocolListener {
|
||||||
void onOfferAccepted(Offer offer);
|
void onOfferAccepted(Offer offer);
|
||||||
|
|
||||||
void onDepositTxPublished(String depositTxID);
|
void onDepositTxPublished(Transaction depositTx);
|
||||||
|
|
||||||
void onDepositTxConfirmedInBlockchain();
|
void onDepositTxConfirmedInBlockchain();
|
||||||
|
|
||||||
void onDepositTxConfirmedUpdate(TransactionConfidence confidence);
|
void onPayoutTxPublished(Transaction payoutTx);
|
||||||
|
|
||||||
void onPayoutTxPublished(String payoutTxID);
|
|
||||||
|
|
||||||
void onFault(Throwable throwable, BuyerAcceptsOfferProtocol.State state);
|
void onFault(Throwable throwable, BuyerAcceptsOfferProtocol.State state);
|
||||||
|
|
||||||
void onWaitingForPeerResponse(BuyerAcceptsOfferProtocol.State state);
|
void onWaitingForPeerResponse(BuyerAcceptsOfferProtocol.State state);
|
||||||
|
|
||||||
void onCompleted(BuyerAcceptsOfferProtocol.State state);
|
|
||||||
|
|
||||||
void onWaitingForUserInteraction(BuyerAcceptsOfferProtocol.State state);
|
void onWaitingForUserInteraction(BuyerAcceptsOfferProtocol.State state);
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ public class HandleTakeOfferRequest {
|
||||||
log.trace("Run task");
|
log.trace("Run task");
|
||||||
boolean takeOfferRequestAccepted = tradeState == Trade.State.OPEN;
|
boolean takeOfferRequestAccepted = tradeState == Trade.State.OPEN;
|
||||||
if (!takeOfferRequestAccepted) {
|
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 =
|
RespondToTakeOfferRequestMessage tradeMessage =
|
||||||
new RespondToTakeOfferRequestMessage(tradeId, takeOfferRequestAccepted);
|
new RespondToTakeOfferRequestMessage(tradeId, takeOfferRequestAccepted);
|
||||||
|
|
|
@ -40,9 +40,6 @@ public class SetupListenerForBlockChainConfirmation {
|
||||||
@Override
|
@Override
|
||||||
public void onConfidenceChanged(Transaction tx, ChangeReason reason) {
|
public void onConfidenceChanged(Transaction tx, ChangeReason reason) {
|
||||||
log.trace("onConfidenceChanged " + tx.getConfidence());
|
log.trace("onConfidenceChanged " + tx.getConfidence());
|
||||||
if (reason == ChangeReason.SEEN_PEERS) {
|
|
||||||
listener.onDepositTxConfirmedUpdate(tx.getConfidence());
|
|
||||||
}
|
|
||||||
if (reason == ChangeReason.TYPE &&
|
if (reason == ChangeReason.TYPE &&
|
||||||
tx.getConfidence().getConfidenceType() == TransactionConfidence.ConfidenceType.BUILDING) {
|
tx.getConfidence().getConfidenceType() == TransactionConfidence.ConfidenceType.BUILDING) {
|
||||||
listener.onDepositTxConfirmedInBlockchain();
|
listener.onDepositTxConfirmedInBlockchain();
|
||||||
|
|
|
@ -197,6 +197,7 @@ public class SellerTakesOfferProtocol {
|
||||||
|
|
||||||
if (message.isTakeOfferRequestAccepted()) {
|
if (message.isTakeOfferRequestAccepted()) {
|
||||||
state = State.PayTakeOfferFee;
|
state = State.PayTakeOfferFee;
|
||||||
|
listener.onTakeOfferRequestAccepted(trade);
|
||||||
PayTakeOfferFee.run(this::onResultPayTakeOfferFee, this::onFault, walletFacade, tradeId);
|
PayTakeOfferFee.run(this::onResultPayTakeOfferFee, this::onFault, walletFacade, tradeId);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -319,7 +320,9 @@ public class SellerTakesOfferProtocol {
|
||||||
log.debug("state " + state);
|
log.debug("state " + state);
|
||||||
checkState(state.ordinal() >= State.SendSignedTakerDepositTxAsHex.ordinal());
|
checkState(state.ordinal() >= State.SendSignedTakerDepositTxAsHex.ordinal());
|
||||||
checkArgument(tradeId.equals(message.getTradeId()));
|
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);
|
offererPayoutAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onResultSignAndPublishPayoutTx(String transactionId, String payoutTxAsHex) {
|
public void onResultSignAndPublishPayoutTx(Transaction transaction, String payoutTxAsHex) {
|
||||||
log.debug("onResultSignAndPublishPayoutTx called " + step++);
|
log.debug("onResultSignAndPublishPayoutTx called " + step++);
|
||||||
listener.onPayoutTxPublished(trade, transactionId);
|
listener.onPayoutTxPublished(trade, transaction);
|
||||||
|
|
||||||
state = State.SendPayoutTxToOfferer;
|
state = State.SendPayoutTxToOfferer;
|
||||||
SendPayoutTxToOfferer.run(this::onResultSendPayoutTxToOfferer, this::onFault, peerAddress, messageFacade,
|
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 io.bitsquare.trade.Trade;
|
||||||
|
|
||||||
|
import com.google.bitcoin.core.Transaction;
|
||||||
|
|
||||||
public interface SellerTakesOfferProtocolListener {
|
public interface SellerTakesOfferProtocolListener {
|
||||||
void onDepositTxPublished(String depositTxId);
|
void onDepositTxPublished(Transaction depositTx);
|
||||||
|
|
||||||
void onBankTransferInited(String tradeId);
|
void onBankTransferInited(String tradeId);
|
||||||
|
|
||||||
void onPayoutTxPublished(Trade trade, String hashAsString);
|
void onPayoutTxPublished(Trade trade, Transaction payoutTx);
|
||||||
|
|
||||||
void onFault(Throwable throwable, SellerTakesOfferProtocol.State state);
|
void onFault(Throwable throwable, SellerTakesOfferProtocol.State state);
|
||||||
|
|
||||||
|
@ -32,5 +34,8 @@ public interface SellerTakesOfferProtocolListener {
|
||||||
|
|
||||||
void onCompleted(SellerTakesOfferProtocol.State state);
|
void onCompleted(SellerTakesOfferProtocol.State state);
|
||||||
|
|
||||||
|
void onTakeOfferRequestAccepted(Trade trade);
|
||||||
|
|
||||||
void onTakeOfferRequestRejected(Trade trade);
|
void onTakeOfferRequestRejected(Trade trade);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ public class SignAndPublishPayoutTx {
|
||||||
public void onSuccess(Transaction transaction) {
|
public void onSuccess(Transaction transaction) {
|
||||||
log.debug("takerSignsAndSendsTx " + transaction);
|
log.debug("takerSignsAndSendsTx " + transaction);
|
||||||
String payoutTxAsHex = Utils.HEX.encode(transaction.bitcoinSerialize());
|
String payoutTxAsHex = Utils.HEX.encode(transaction.bitcoinSerialize());
|
||||||
resultHandler.onResult(transaction.getHashAsString(), payoutTxAsHex);
|
resultHandler.onResult(transaction, payoutTxAsHex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -73,7 +73,7 @@ public class SignAndPublishPayoutTx {
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface ResultHandler {
|
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();
|
refreshStylesheets();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
log.error(e.getStackTrace().toString());
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@ public class AccountUITestRunner extends Application {
|
||||||
refreshStylesheets();
|
refreshStylesheets();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
log.error(e.getStackTrace().toString());
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@ public class RegistrationUITestRunner extends Application {
|
||||||
refreshStylesheets();
|
refreshStylesheets();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
log.error(e.getStackTrace().toString());
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@ public class SetupUITestRunner extends Application {
|
||||||
refreshStylesheets();
|
refreshStylesheets();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
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/>.
|
* 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.CachedViewController;
|
||||||
import io.bitsquare.gui.Navigation;
|
import io.bitsquare.gui.components.processbar.ProcessStepBar;
|
||||||
import io.bitsquare.gui.components.CachingTabPane;
|
import io.bitsquare.gui.components.processbar.ProcessStepItem;
|
||||||
import io.bitsquare.persistence.Persistence;
|
|
||||||
|
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.ResourceBundle;
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import javafx.fxml.Initializable;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class OrdersController extends CachedViewController {
|
public class PendingTradesControllerUIMock extends CachedViewController {
|
||||||
private static final Logger log = LoggerFactory.getLogger(OrdersController.class);
|
private static final Logger log = LoggerFactory.getLogger(PendingTradesControllerUIMock.class);
|
||||||
private static OrdersController INSTANCE;
|
public ProcessStepBar processBar;
|
||||||
private final Persistence persistence;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
private OrdersController(Persistence persistence) {
|
|
||||||
this.persistence = persistence;
|
|
||||||
INSTANCE = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Constructor
|
// Constructor
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
public static OrdersController GET_INSTANCE() {
|
@Inject
|
||||||
return INSTANCE;
|
public PendingTradesControllerUIMock() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -61,8 +53,13 @@ public class OrdersController extends CachedViewController {
|
||||||
public void initialize(URL url, ResourceBundle rb) {
|
public void initialize(URL url, ResourceBundle rb) {
|
||||||
super.initialize(url, rb);
|
super.initialize(url, rb);
|
||||||
|
|
||||||
((CachingTabPane) root).initialize(this, persistence, Navigation.Item.OFFER.getFxmlUrl(),
|
List<ProcessStepItem> items = new ArrayList<>();
|
||||||
Navigation.Item.PENDING_TRADE.getFxmlUrl(), Navigation.Item.CLOSED_TRADE.getFxmlUrl());
|
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
|
@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();
|
refreshStylesheets();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
log.error(e.getStackTrace().toString());
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@ public class PasswordUITestRunner extends Application {
|
||||||
refreshStylesheets();
|
refreshStylesheets();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
log.error(e.getStackTrace().toString());
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@ public class RegistrationUITestRunner extends Application {
|
||||||
refreshStylesheets();
|
refreshStylesheets();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
log.error(e.getStackTrace().toString());
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@ public class RestrictionsUITestRunner extends Application {
|
||||||
refreshStylesheets();
|
refreshStylesheets();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
log.error(e.getStackTrace().toString());
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@ public class SeedWordsUITestRunner extends Application {
|
||||||
refreshStylesheets();
|
refreshStylesheets();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
log.error(e.getStackTrace().toString());
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
<?import javafx.scene.layout.*?>
|
<?import javafx.scene.layout.*?>
|
||||||
<GridPane hgap="5.0" vgap="5.0" fx:id="root"
|
<GridPane hgap="5.0" vgap="5.0" fx:id="root"
|
||||||
fx:controller="io.bitsquare.gui.main.settings.uimock.BankAccountSettingsControllerUIMock"
|
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.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0"
|
||||||
AnchorPane.topAnchor="0.0"
|
AnchorPane.topAnchor="0.0"
|
||||||
xmlns:fx="http://javafx.com/fxml">
|
xmlns:fx="http://javafx.com/fxml">
|
||||||
|
|
|
@ -75,7 +75,7 @@ public class CreateOfferUITestRunner extends Application {
|
||||||
refreshStylesheets();
|
refreshStylesheets();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
log.error(e.getStackTrace().toString());
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ public class CreateOfferControllerUIMock implements Initializable {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize(URL url, ResourceBundle rb) {
|
public void initialize(URL url, ResourceBundle rb) {
|
||||||
|
/*
|
||||||
paymentInfoPane.setVisible(false);
|
paymentInfoPane.setVisible(false);
|
||||||
collateralLabel.setVisible(false);
|
collateralLabel.setVisible(false);
|
||||||
collateralTextField.setVisible(false);
|
collateralTextField.setVisible(false);
|
||||||
|
@ -114,7 +114,7 @@ public class CreateOfferControllerUIMock implements Initializable {
|
||||||
bankAccountCountyLabel.setVisible(false);
|
bankAccountCountyLabel.setVisible(false);
|
||||||
bankAccountCountyTextField.setVisible(false);
|
bankAccountCountyTextField.setVisible(false);
|
||||||
showDetailsInfoIcon.setVisible(false);
|
showDetailsInfoIcon.setVisible(false);
|
||||||
showDetailsInfoLabel.setVisible(false);
|
showDetailsInfoLabel.setVisible(false);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/* @FXML
|
/* @FXML
|
||||||
|
|
|
@ -68,7 +68,7 @@ public class CreateOfferUIMockRunner extends Application {
|
||||||
log.debug("re load");
|
log.debug("re load");
|
||||||
pane.getChildren().removeAll();
|
pane.getChildren().removeAll();
|
||||||
ViewLoader loader = new ViewLoader(
|
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 {
|
try {
|
||||||
view = loader.load();
|
view = loader.load();
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
<?import javafx.scene.layout.*?>
|
<?import javafx.scene.layout.*?>
|
||||||
<?import javafx.scene.text.*?>
|
<?import javafx.scene.text.*?>
|
||||||
<AnchorPane fx:id="root" prefHeight="630.0" prefWidth="1000.0" style="-fx-background-color: f4f4f4;"
|
<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.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"
|
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">
|
fx:controller="io.bitsquare.gui.main.trade.createoffer.uimock.CreateOfferControllerUIMock">
|
||||||
|
@ -52,7 +52,8 @@
|
||||||
<children>
|
<children>
|
||||||
<ImageView fitHeight="54.0" fitWidth="62.0" pickOnBounds="true" preserveRatio="true">
|
<ImageView fitHeight="54.0" fitWidth="62.0" pickOnBounds="true" preserveRatio="true">
|
||||||
<image>
|
<image>
|
||||||
<Image url="@../../../../../../../../main/resources/images/buy_black_62_54.png"/>
|
<Image
|
||||||
|
url="@../../../../../../../../../main/resources/images/buy_large.png"/>
|
||||||
</image>
|
</image>
|
||||||
</ImageView>
|
</ImageView>
|
||||||
<Label fx:id="buyLabel" alignment="CENTER"
|
<Label fx:id="buyLabel" alignment="CENTER"
|
||||||
|
@ -87,7 +88,7 @@
|
||||||
</VBox>
|
</VBox>
|
||||||
<Label text="x">
|
<Label text="x">
|
||||||
<font>
|
<font>
|
||||||
<Font name="Helvetica" size="20.0"/>
|
<Font name="Helvetica-Bold" size="20.0"/>
|
||||||
</font>
|
</font>
|
||||||
<padding>
|
<padding>
|
||||||
<Insets top="14.0"/>
|
<Insets top="14.0"/>
|
||||||
|
@ -111,7 +112,7 @@
|
||||||
|
|
||||||
<Label text="=">
|
<Label text="=">
|
||||||
<font>
|
<font>
|
||||||
<Font name="Helvetica" size="20.0"/>
|
<Font name="Helvetica-Bold" size="20.0"/>
|
||||||
</font>
|
</font>
|
||||||
<padding>
|
<padding>
|
||||||
<Insets top="14.0"/>
|
<Insets top="14.0"/>
|
||||||
|
@ -161,7 +162,7 @@
|
||||||
preserveRatio="true" GridPane.rowIndex="2" GridPane.valignment="TOP">
|
preserveRatio="true" GridPane.rowIndex="2" GridPane.valignment="TOP">
|
||||||
<image>
|
<image>
|
||||||
<Image fx:id="infoIcon"
|
<Image fx:id="infoIcon"
|
||||||
url="@../../../../../../../../main/resources/images/info.png"/>
|
url="@../../../../../../../../../main/resources/images/info.png"/>
|
||||||
</image>
|
</image>
|
||||||
<GridPane.margin>
|
<GridPane.margin>
|
||||||
<Insets right="2.0" top="4.0"/>
|
<Insets right="2.0" top="4.0"/>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue