offer creation screen, model updates, confirm comp.
21
README.md
@ -12,15 +12,15 @@ We use bitcoinj library as a submodule. To get the project with the submodule in
|
||||
git clone --recursive git://github.com/bitsquare/bitsquare
|
||||
|
||||
### Implemented (prototype level):
|
||||
* Screen for orderbook with filtering mock offers by amount, price and order type (buy, sell), other filters not impl. yet
|
||||
* Screen for creating an offer (needs update)
|
||||
* Screen for offer taking and payment process
|
||||
* Simple storage for some filter attributes
|
||||
* bitcoinj/wallet integration (basic)
|
||||
|
||||
* Screen for orderbook with filtering mock offers by amount, price and order type (buy, sell)
|
||||
* Screen for creating an offer
|
||||
* Screen for offer taking and payment process (needs update)
|
||||
* Simple persistence
|
||||
* bitcoinj integration
|
||||
* Setup with account registration and tx with OP_RETURN + embedded and blinded bank account data
|
||||
* Offer fee payment with a OP_RETURN tx and fees to miners
|
||||
|
||||
### Next steps:
|
||||
* Setup with account registration
|
||||
* Other trade variants (Buy BTC taker, Sell BTC offerer, Sell BTC offerer)
|
||||
* Arbitrator integration
|
||||
* Messaging system
|
||||
@ -28,7 +28,14 @@ git clone --recursive git://github.com/bitsquare/bitsquare
|
||||
|
||||
|
||||
### Screenshots of basic screens:
|
||||
* [Registration screen 1](https://github.com/bitsquare/bitsquare/tree/master/screenshots/reg1.png)
|
||||
* [Registration screen 2](https://github.com/bitsquare/bitsquare/tree/master/screenshots/reg2.png)
|
||||
* [Registration screen 3](https://github.com/bitsquare/bitsquare/tree/master/screenshots/reg3.png)
|
||||
* [Orderbook screen 1](https://github.com/bitsquare/bitsquare/tree/master/screenshots/orderbook1.png)
|
||||
* [Orderbook screen 2](https://github.com/bitsquare/bitsquare/tree/master/screenshots/orderbook2.png)
|
||||
* [Orderbook screen](https://github.com/bitsquare/bitsquare/tree/master/screenshots/orderbook.png)
|
||||
* [Create Offer screen 1](https://github.com/bitsquare/bitsquare/tree/master/screenshots/newOffer1.png)
|
||||
* [Create Offer screen 2](https://github.com/bitsquare/bitsquare/tree/master/screenshots/newOffer2.png)
|
||||
* [Trade screen](https://github.com/bitsquare/bitsquare/tree/master/screenshots/trade.png)
|
||||
* [Bank transfer screen](https://github.com/bitsquare/bitsquare/tree/master/screenshots/bank_transfer.png)
|
||||
* [Trade completed screen](https://github.com/bitsquare/bitsquare/tree/master/screenshots/completed.png)
|
||||
|
13
TODO.txt
Normal file
@ -0,0 +1,13 @@
|
||||
- payment process update with new models
|
||||
- btc payments in payment process
|
||||
- arbitration integration
|
||||
|
||||
Messaging!
|
||||
|
||||
low prio:
|
||||
- add settings after setup
|
||||
- settings screen
|
||||
- return to setup when unregistered, change/add bank accounts from settings
|
||||
|
||||
|
||||
|
BIN
screenshots/newOffer1.png
Normal file
After Width: | Height: | Size: 70 KiB |
BIN
screenshots/newOffer2.png
Normal file
After Width: | Height: | Size: 80 KiB |
Before Width: | Height: | Size: 152 KiB |
BIN
screenshots/orderbook1.png
Normal file
After Width: | Height: | Size: 147 KiB |
BIN
screenshots/orderbook2.png
Normal file
After Width: | Height: | Size: 92 KiB |
BIN
screenshots/reg1.png
Normal file
After Width: | Height: | Size: 72 KiB |
BIN
screenshots/reg2.png
Normal file
After Width: | Height: | Size: 73 KiB |
BIN
screenshots/reg3.png
Normal file
After Width: | Height: | Size: 73 KiB |
BIN
screenshots/reg4.png
Normal file
After Width: | Height: | Size: 65 KiB |
@ -6,7 +6,7 @@ import io.bitsquare.btc.WalletFacade;
|
||||
import io.bitsquare.di.BitSquareModule;
|
||||
import io.bitsquare.di.GuiceFXMLLoader;
|
||||
import io.bitsquare.gui.util.Localisation;
|
||||
import io.bitsquare.settings.Startup;
|
||||
import io.bitsquare.settings.Settings;
|
||||
import io.bitsquare.storage.Storage;
|
||||
import io.bitsquare.user.User;
|
||||
import javafx.application.Application;
|
||||
@ -16,6 +16,8 @@ import javafx.stage.Stage;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public class BitSquare extends Application
|
||||
{
|
||||
private static final Logger log = LoggerFactory.getLogger(BitSquare.class);
|
||||
@ -34,24 +36,30 @@ public class BitSquare extends Application
|
||||
|
||||
// apply stored data
|
||||
final User user = injector.getInstance(User.class);
|
||||
final Settings settings = injector.getInstance(Settings.class);
|
||||
final Storage storage = injector.getInstance(Storage.class);
|
||||
user.updateFromStorage((User) storage.read(user.getClass().getName()));
|
||||
|
||||
//TODO remove
|
||||
final Startup setup = injector.getInstance(Startup.class);
|
||||
setup.applyPersistedData();
|
||||
settings.updateFromStorage((Settings) storage.read(settings.getClass().getName()));
|
||||
initSettings(settings, storage);
|
||||
|
||||
stage.setTitle("BitSquare");
|
||||
|
||||
GuiceFXMLLoader.setInjector(injector);
|
||||
final GuiceFXMLLoader loader = new GuiceFXMLLoader(getClass().getResource("/io/bitsquare/gui/MainView.fxml"), Localisation.getResourceBundle());
|
||||
final Parent mainView = loader.load();
|
||||
|
||||
final Scene scene = new Scene(mainView, 800, 600);
|
||||
stage.setScene(scene);
|
||||
|
||||
final String global = getClass().getResource("/io/bitsquare/gui/global.css").toExternalForm();
|
||||
scene.getStylesheets().setAll(global);
|
||||
|
||||
stage.setMinWidth(740);
|
||||
stage.setMinHeight(400);
|
||||
stage.setWidth(800);
|
||||
stage.setHeight(600);
|
||||
|
||||
stage.show();
|
||||
}
|
||||
|
||||
@ -62,4 +70,31 @@ public class BitSquare extends Application
|
||||
|
||||
super.stop();
|
||||
}
|
||||
|
||||
private void initSettings(Settings settings, Storage storage)
|
||||
{
|
||||
Settings savedSettings = (Settings) storage.read(settings.getClass().getName());
|
||||
if (savedSettings == null)
|
||||
{
|
||||
settings.getAcceptedCountryLocales().clear();
|
||||
settings.getAcceptedLanguageLocales().clear();
|
||||
|
||||
settings.addAcceptedLanguageLocale(Locale.getDefault());
|
||||
settings.addAcceptedCountryLocale(Locale.getDefault());
|
||||
|
||||
//TODO mock
|
||||
settings.addAcceptedLanguageLocale(new Locale("en", "US"));
|
||||
settings.addAcceptedLanguageLocale(new Locale("es", "ES"));
|
||||
|
||||
settings.addAcceptedCountryLocale(new Locale("de", "AT"));
|
||||
settings.addAcceptedCountryLocale(new Locale("en", "US"));
|
||||
settings.addAcceptedCountryLocale(new Locale("es", "ES"));
|
||||
|
||||
storage.write(settings.getClass().getName(), settings);
|
||||
}
|
||||
else
|
||||
{
|
||||
settings.updateFromStorage(savedSettings);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,23 +18,26 @@ public class BankAccount implements Serializable
|
||||
private Currency currency;
|
||||
private String uid;
|
||||
|
||||
// TODO just for mock yet
|
||||
public BankAccount(BankAccountType bankAccountType)
|
||||
{
|
||||
this.bankAccountType = bankAccountType;
|
||||
|
||||
}
|
||||
|
||||
public BankAccount(BankAccountType bankAccountType, String accountPrimaryID, String accountSecondaryID, String accountHolderName, Locale countryLocale, Currency currency)
|
||||
|
||||
private String accountTitle;
|
||||
|
||||
public BankAccount(BankAccountType bankAccountType,
|
||||
Currency currency,
|
||||
Locale countryLocale,
|
||||
String accountTitle,
|
||||
String accountHolderName,
|
||||
String accountPrimaryID,
|
||||
String accountSecondaryID)
|
||||
{
|
||||
this.bankAccountType = bankAccountType;
|
||||
this.currency = currency;
|
||||
this.countryLocale = countryLocale;
|
||||
this.accountTitle = accountTitle;
|
||||
this.accountHolderName = accountHolderName;
|
||||
this.accountPrimaryID = accountPrimaryID;
|
||||
this.accountSecondaryID = accountSecondaryID;
|
||||
this.accountHolderName = accountHolderName;
|
||||
this.countryLocale = countryLocale;
|
||||
this.currency = currency;
|
||||
|
||||
uid = bankAccountType + "_" + accountPrimaryID + "_" + accountSecondaryID + "_" + accountHolderName + "_" + countryLocale.getISO3Country();
|
||||
uid = bankAccountType + "_" + accountPrimaryID + "_" + accountSecondaryID + "_" + accountHolderName + "_" + countryLocale.getCountry();
|
||||
}
|
||||
|
||||
public String getAccountPrimaryID()
|
||||
@ -72,6 +75,11 @@ public class BankAccount implements Serializable
|
||||
return uid;
|
||||
}
|
||||
|
||||
public String getAccountTitle()
|
||||
{
|
||||
return accountTitle;
|
||||
}
|
||||
|
||||
// Changes of that structure must be reflected in VERSION updates
|
||||
public String getStringifiedBankAccount()
|
||||
{
|
||||
@ -81,15 +89,9 @@ public class BankAccount implements Serializable
|
||||
", secondaryID='" + accountSecondaryID + '\'' +
|
||||
", holderName='" + accountHolderName + '\'' +
|
||||
", currency='" + currency.getCurrencyCode() + '\'' +
|
||||
", country='" + countryLocale.getISO3Country() + '\'' +
|
||||
", country='" + countryLocale.getCountry() + '\'' +
|
||||
", v='" + VERSION + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
public String getShortName()
|
||||
{
|
||||
return bankAccountType + " " + accountPrimaryID + " / " + accountSecondaryID + " / " + currency.getCurrencyCode();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -170,7 +170,7 @@ public class AccountRegistrationWallet extends Wallet implements WalletEventList
|
||||
public void onTransactionConfidenceChanged(Wallet wallet, Transaction tx)
|
||||
{
|
||||
for (WalletFacade.WalletListener walletListener : walletListeners)
|
||||
walletListener.onConfidenceChanged(tx.getConfidence().numBroadcastPeers(), WalletUtil.getConfirmationDepthInBlocks(this));
|
||||
walletListener.onConfidenceChanged(tx.getConfidence().numBroadcastPeers(), WalletUtil.getConfDepthInBlocks(this));
|
||||
|
||||
log.info("onTransactionConfidenceChanged " + tx.getConfidence().toString());
|
||||
}
|
||||
@ -205,7 +205,7 @@ public class AccountRegistrationWallet extends Wallet implements WalletEventList
|
||||
log.info("onScriptsAdded");
|
||||
}
|
||||
|
||||
int getConfirmationNumBroadcastPeers()
|
||||
int getConfNumBroadcastPeers()
|
||||
{
|
||||
Transaction transaction = WalletUtil.getTransaction(this);
|
||||
return (transaction == null || transaction.getConfidence() == null) ? 0 : transaction.getConfidence().numBroadcastPeers();
|
||||
|
@ -8,7 +8,6 @@ public class Fees
|
||||
{
|
||||
|
||||
public static BigInteger ACCOUNT_REGISTRATION_FEE = Transaction.MIN_NONDUST_OUTPUT;// Utils.toNanoCoins("0.001");
|
||||
public static BigInteger OFFER_CREATION_FEE = new BigInteger("500000");
|
||||
public static BigInteger OFFER_CREATION_FEE = Transaction.MIN_NONDUST_OUTPUT; // Utils.toNanoCoins("0.001");
|
||||
public static BigInteger OFFER_TAKER_FEE = OFFER_CREATION_FEE;
|
||||
public static BigInteger BTC_NETWORK_FEE = new BigInteger("10000");
|
||||
}
|
||||
|
@ -5,7 +5,10 @@ import com.google.bitcoin.kits.WalletAppKit;
|
||||
import com.google.bitcoin.params.MainNetParams;
|
||||
import com.google.bitcoin.params.RegTestParams;
|
||||
import com.google.bitcoin.script.Script;
|
||||
import com.google.bitcoin.script.ScriptBuilder;
|
||||
import com.google.bitcoin.utils.Threading;
|
||||
import com.google.common.util.concurrent.FutureCallback;
|
||||
import com.google.common.util.concurrent.Futures;
|
||||
import com.google.inject.Inject;
|
||||
import io.bitsquare.crypto.CryptoFacade;
|
||||
import javafx.application.Platform;
|
||||
@ -18,6 +21,8 @@ import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.google.bitcoin.script.ScriptOpCodes.OP_RETURN;
|
||||
|
||||
/**
|
||||
* That facade delivers wallet functionality from the bitcoinJ library
|
||||
* Code from BitcoinJ must not be used outside that facade.
|
||||
@ -79,12 +84,12 @@ public class WalletFacade implements WalletEventListener
|
||||
walletAppKit.startAsync();
|
||||
walletAppKit.awaitRunning();
|
||||
// Don't make the user wait for confirmations for now, as the intention is they're sending it their own money!
|
||||
walletAppKit.wallet().allowSpendingUnconfirmedTransactions();
|
||||
getWallet().allowSpendingUnconfirmedTransactions();
|
||||
walletAppKit.peerGroup().setMaxConnections(11);
|
||||
|
||||
walletAppKit.wallet().addEventListener(this);
|
||||
getWallet().addEventListener(this);
|
||||
|
||||
log.info(walletAppKit.wallet().toString());
|
||||
log.info(getWallet().toString());
|
||||
}
|
||||
|
||||
public void shutDown()
|
||||
@ -134,12 +139,12 @@ public class WalletFacade implements WalletEventListener
|
||||
|
||||
public BigInteger getBalance()
|
||||
{
|
||||
return walletAppKit.wallet().getBalance(Wallet.BalanceType.ESTIMATED);
|
||||
return getWallet().getBalance(Wallet.BalanceType.ESTIMATED);
|
||||
}
|
||||
|
||||
public String getAddress()
|
||||
{
|
||||
return walletAppKit.wallet().getKeys().get(0).toAddress(networkParameters).toString();
|
||||
return getWallet().getKeys().get(0).toAddress(networkParameters).toString();
|
||||
}
|
||||
|
||||
// account registration
|
||||
@ -171,14 +176,14 @@ public class WalletFacade implements WalletEventListener
|
||||
&& blockChainFacade.verifyAddressInBlockChain(hashAsHexStringToVerify, address);
|
||||
}
|
||||
|
||||
public int getRegistrationConfirmationNumBroadcastPeers()
|
||||
public int getRegConfNumBroadcastPeers()
|
||||
{
|
||||
return getAccountRegistrationWallet().getConfirmationNumBroadcastPeers();
|
||||
return getAccountRegistrationWallet().getConfNumBroadcastPeers();
|
||||
}
|
||||
|
||||
public int getRegistrationConfirmationDepthInBlocks()
|
||||
public int getRegConfDepthInBlocks()
|
||||
{
|
||||
return WalletUtil.getConfirmationDepthInBlocks(getAccountRegistrationWallet());
|
||||
return WalletUtil.getConfDepthInBlocks(getAccountRegistrationWallet());
|
||||
}
|
||||
|
||||
// WalletEventListener
|
||||
@ -195,7 +200,7 @@ public class WalletFacade implements WalletEventListener
|
||||
public void onTransactionConfidenceChanged(Wallet wallet, Transaction tx)
|
||||
{
|
||||
for (WalletListener walletListener : walletListeners)
|
||||
walletListener.onConfidenceChanged(tx.getConfidence().numBroadcastPeers(), WalletUtil.getConfirmationDepthInBlocks(walletAppKit.wallet()));
|
||||
walletListener.onConfidenceChanged(tx.getConfidence().numBroadcastPeers(), WalletUtil.getConfDepthInBlocks(getWallet()));
|
||||
|
||||
log.info("onTransactionConfidenceChanged " + tx.getConfidence().toString());
|
||||
}
|
||||
@ -239,6 +244,51 @@ public class WalletFacade implements WalletEventListener
|
||||
return accountRegistrationWallet;
|
||||
}
|
||||
|
||||
public String payOfferFee() throws InsufficientMoneyException
|
||||
{
|
||||
getWallet();
|
||||
|
||||
Script script = new ScriptBuilder()
|
||||
.op(OP_RETURN)
|
||||
.build();
|
||||
Transaction transaction = new Transaction(networkParameters);
|
||||
TransactionOutput dataOutput = new TransactionOutput(networkParameters,
|
||||
transaction,
|
||||
Transaction.MIN_NONDUST_OUTPUT,
|
||||
script.getProgram());
|
||||
transaction.addOutput(dataOutput);
|
||||
Wallet.SendRequest sendRequest = Wallet.SendRequest.forTx(transaction);
|
||||
|
||||
// give fee to miners yet. Later it could be spent to other traders via lottery...
|
||||
sendRequest.fee = Fees.OFFER_CREATION_FEE;
|
||||
|
||||
Wallet.SendResult sendResult = getWallet().sendCoins(sendRequest);
|
||||
|
||||
Futures.addCallback(sendResult.broadcastComplete, new FutureCallback<Transaction>()
|
||||
{
|
||||
@Override
|
||||
public void onSuccess(Transaction result)
|
||||
{
|
||||
log.info("sendResult onSuccess:" + result.toString());
|
||||
// Platform.runLater(overlayUi::done);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable t)
|
||||
{
|
||||
log.warn("sendResult onFailure:" + t.toString());
|
||||
// We died trying to empty the wallet.
|
||||
// crashAlert(t);
|
||||
}
|
||||
});
|
||||
|
||||
return transaction.getHashAsString();
|
||||
}
|
||||
|
||||
private Wallet getWallet()
|
||||
{
|
||||
return walletAppKit.wallet();
|
||||
}
|
||||
|
||||
// inner classes
|
||||
private class BlockChainDownloadListener extends com.google.bitcoin.core.DownloadListener
|
||||
|
@ -11,7 +11,7 @@ public class WalletUtil
|
||||
{
|
||||
|
||||
// TODO check if that is correct and safe
|
||||
public static int getConfirmationDepthInBlocks(Wallet wallet)
|
||||
public static int getConfDepthInBlocks(Wallet wallet)
|
||||
{
|
||||
Transaction transaction = WalletUtil.getTransaction(wallet);
|
||||
if (transaction != null && transaction.getConfidence() != null)
|
||||
|
@ -16,9 +16,9 @@ import io.bitsquare.crypto.CryptoFacade;
|
||||
import io.bitsquare.msg.MessageFacade;
|
||||
import io.bitsquare.settings.OrderBookFilterSettings;
|
||||
import io.bitsquare.settings.Settings;
|
||||
import io.bitsquare.settings.Startup;
|
||||
import io.bitsquare.storage.Storage;
|
||||
import io.bitsquare.trade.Trading;
|
||||
import io.bitsquare.trade.orderbook.MockOrderBook;
|
||||
import io.bitsquare.trade.orderbook.OrderBook;
|
||||
import io.bitsquare.trade.orderbook.OrderBookFilter;
|
||||
import io.bitsquare.user.User;
|
||||
@ -31,9 +31,8 @@ public class BitSquareModule extends AbstractModule
|
||||
@Override
|
||||
protected void configure()
|
||||
{
|
||||
bind(Startup.class).asEagerSingleton();
|
||||
bind(User.class).asEagerSingleton();
|
||||
bind(OrderBook.class).asEagerSingleton();
|
||||
bind(OrderBook.class).to(MockOrderBook.class).asEagerSingleton();
|
||||
bind(Storage.class).asEagerSingleton();
|
||||
bind(Settings.class).asEagerSingleton();
|
||||
bind(OrderBookFilter.class).asEagerSingleton();
|
||||
|
@ -3,4 +3,5 @@ package io.bitsquare.gui;
|
||||
public interface ChildController
|
||||
{
|
||||
void setNavigationController(NavigationController navigationController);
|
||||
|
||||
}
|
||||
|
@ -10,9 +10,7 @@ import io.bitsquare.gui.trade.TradeController;
|
||||
import io.bitsquare.gui.util.Formatter;
|
||||
import io.bitsquare.gui.util.Icons;
|
||||
import io.bitsquare.gui.util.Localisation;
|
||||
import io.bitsquare.settings.Settings;
|
||||
import io.bitsquare.trade.Direction;
|
||||
import io.bitsquare.trade.orderbook.OrderBookFilter;
|
||||
import io.bitsquare.user.User;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
@ -39,9 +37,7 @@ public class MainController implements Initializable, NavigationController, Wall
|
||||
{
|
||||
private static final Logger log = LoggerFactory.getLogger(MainController.class);
|
||||
|
||||
private Settings settings;
|
||||
private User user;
|
||||
private OrderBookFilter orderBookFilter;
|
||||
private WalletFacade walletFacade;
|
||||
private ChildController childController;
|
||||
private ToggleGroup toggleGroup;
|
||||
@ -61,11 +57,9 @@ public class MainController implements Initializable, NavigationController, Wall
|
||||
public AnchorPane anchorPane;
|
||||
|
||||
@Inject
|
||||
public MainController(Settings settings, User user, OrderBookFilter orderBookFilter, WalletFacade walletFacade)
|
||||
public MainController(User user, WalletFacade walletFacade)
|
||||
{
|
||||
this.settings = settings;
|
||||
this.user = user;
|
||||
this.orderBookFilter = orderBookFilter;
|
||||
this.walletFacade = walletFacade;
|
||||
}
|
||||
|
||||
@ -78,6 +72,7 @@ public class MainController implements Initializable, NavigationController, Wall
|
||||
|
||||
walletFacade.addDownloadListener(this);
|
||||
walletFacade.initWallet();
|
||||
|
||||
buildNavigation();
|
||||
if (user.getAccountID() == null)
|
||||
{
|
||||
@ -107,6 +102,11 @@ public class MainController implements Initializable, NavigationController, Wall
|
||||
return null;
|
||||
}
|
||||
|
||||
if (childController instanceof TradeController)
|
||||
{
|
||||
((TradeController) childController).cleanup();
|
||||
}
|
||||
|
||||
final GuiceFXMLLoader loader = new GuiceFXMLLoader(getClass().getResource(fxmlView), Localisation.getResourceBundle());
|
||||
try
|
||||
{
|
||||
@ -172,7 +172,7 @@ public class MainController implements Initializable, NavigationController, Wall
|
||||
addNavButton(leftNavPane, "Funds", Icons.FUNDS, Icons.FUNDS, NavigationController.FUNDS);
|
||||
addNavButton(leftNavPane, "Message", Icons.MSG, Icons.MSG, NavigationController.MSG);
|
||||
addBalanceInfo(rightNavPane);
|
||||
addAccountComboBox();
|
||||
addAccountComboBox(rightNavPane);
|
||||
|
||||
addNavButton(rightNavPane, "Settings", Icons.SETTINGS, Icons.SETTINGS, NavigationController.SETTINGS);
|
||||
|
||||
@ -226,15 +226,12 @@ public class MainController implements Initializable, NavigationController, Wall
|
||||
|
||||
private TextField addBalanceInfo(Pane parent)
|
||||
{
|
||||
Pane holder = new Pane();
|
||||
TextField balanceLabel = new TextField();
|
||||
balanceLabel.setEditable(false);
|
||||
balanceLabel.setMouseTransparent(true);
|
||||
balanceLabel.setPrefWidth(90);
|
||||
balanceLabel.setId("nav-balance-label");
|
||||
balanceLabel.setText(Formatter.formatSatoshis(walletFacade.getBalance(), false));
|
||||
holder.getChildren().add(balanceLabel);
|
||||
rightNavPane.getChildren().add(holder);
|
||||
|
||||
Label balanceCurrencyLabel = new Label("BTC");
|
||||
balanceCurrencyLabel.setPadding(new Insets(6, 0, 0, 0));
|
||||
@ -256,7 +253,7 @@ public class MainController implements Initializable, NavigationController, Wall
|
||||
return balanceLabel;
|
||||
}
|
||||
|
||||
private void addAccountComboBox()
|
||||
private void addAccountComboBox(Pane parent)
|
||||
{
|
||||
if (user.getBankAccounts().size() > 1)
|
||||
{
|
||||
@ -268,7 +265,7 @@ public class MainController implements Initializable, NavigationController, Wall
|
||||
@Override
|
||||
public String toString(BankAccount bankAccount)
|
||||
{
|
||||
return bankAccount.getShortName();
|
||||
return bankAccount.getAccountTitle();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -278,6 +275,16 @@ public class MainController implements Initializable, NavigationController, Wall
|
||||
}
|
||||
});
|
||||
|
||||
VBox vBox = new VBox();
|
||||
vBox.setPadding(new Insets(12, 0, 0, 0));
|
||||
vBox.setSpacing(2);
|
||||
Label titleLabel = new Label("Bank account");
|
||||
titleLabel.setMouseTransparent(true);
|
||||
titleLabel.setPrefWidth(90);
|
||||
titleLabel.setId("nav-button-label");
|
||||
|
||||
vBox.getChildren().setAll(accountComboBox, titleLabel);
|
||||
parent.getChildren().add(vBox);
|
||||
|
||||
accountComboBox.valueProperty().addListener(new ChangeListener<BankAccount>()
|
||||
{
|
||||
@ -285,16 +292,10 @@ public class MainController implements Initializable, NavigationController, Wall
|
||||
public void changed(ObservableValue ov, BankAccount oldValue, BankAccount newValue)
|
||||
{
|
||||
user.setCurrentBankAccount(newValue);
|
||||
orderBookFilter.setCurrency(newValue.getCurrency());
|
||||
orderBookFilter.setCountryLocale(newValue.getCountryLocale());
|
||||
}
|
||||
});
|
||||
|
||||
Pane holder = new Pane();
|
||||
holder.getChildren().add(accountComboBox);
|
||||
rightNavPane.getChildren().add(holder);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,10 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.layout.*?>
|
||||
<StackPane fx:id="rootContainer" minHeight="300" minWidth="400" prefHeight="600" prefWidth="800"
|
||||
stylesheets="/io/bitsquare/gui/global.css" xmlns:fx="http://javafx.com/fxml/1"
|
||||
<StackPane fx:id="rootContainer" stylesheets="/io/bitsquare/gui/global.css" xmlns:fx="http://javafx.com/fxml/1"
|
||||
xmlns="http://javafx.com/javafx/8" fx:controller="io.bitsquare.gui.MainController">
|
||||
<AnchorPane fx:id="anchorPane" id="root-pane" minHeight="300" minWidth="400" prefHeight="600" prefWidth="800">
|
||||
<AnchorPane fx:id="anchorPane" id="root-pane">
|
||||
<HBox fx:id="leftNavPane" spacing="10" AnchorPane.leftAnchor="0" AnchorPane.topAnchor="0"/>
|
||||
<HBox fx:id="rightNavPane" spacing="10" AnchorPane.rightAnchor="10" AnchorPane.topAnchor="0"/>
|
||||
<AnchorPane fx:id="contentPane" id="content-pane" AnchorPane.bottomAnchor="20" AnchorPane.leftAnchor="0"
|
||||
|
@ -0,0 +1,67 @@
|
||||
package io.bitsquare.gui.components;
|
||||
|
||||
import io.bitsquare.btc.WalletFacade;
|
||||
import io.bitsquare.gui.util.FormBuilder;
|
||||
import io.bitsquare.gui.util.Icons;
|
||||
import javafx.scene.control.ProgressIndicator;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
public class ConfirmationComponent implements WalletFacade.WalletListener
|
||||
{
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(ConfirmationComponent.class);
|
||||
private ImageView confirmIconImageView;
|
||||
private TextField confirmationsLabel;
|
||||
private ProgressIndicator confirmSpinner;
|
||||
|
||||
public ConfirmationComponent(WalletFacade walletFacade, GridPane gridPane, int row)
|
||||
{
|
||||
confirmationsLabel = FormBuilder.addConfirmationsLabel(gridPane, walletFacade, row);
|
||||
confirmIconImageView = FormBuilder.addConfirmationsIcon(gridPane, walletFacade, row);
|
||||
confirmSpinner = FormBuilder.addConfirmationsSpinner(gridPane, walletFacade, row);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfidenceChanged(int numBroadcastPeers, int depthInBlocks)
|
||||
{
|
||||
confirmIconImageView.setImage(getConfirmIconImage(numBroadcastPeers, depthInBlocks));
|
||||
confirmationsLabel.setText(getConfirmationsText(numBroadcastPeers, depthInBlocks));
|
||||
if (depthInBlocks == 0)
|
||||
confirmSpinner.setProgress(-1);
|
||||
else
|
||||
confirmSpinner.setOpacity(0);
|
||||
|
||||
log.info("onConfidenceChanged " + numBroadcastPeers + " / " + depthInBlocks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCoinsReceived(BigInteger newBalance)
|
||||
{
|
||||
log.info("onCoinsReceived " + newBalance);
|
||||
}
|
||||
|
||||
|
||||
private String getConfirmationsText(int numBroadcastPeers, int depthInBlocks)
|
||||
{
|
||||
depthInBlocks = 0;
|
||||
return depthInBlocks + " confirmation(s) / " + "Seen by " + numBroadcastPeers + " peer(s)";
|
||||
}
|
||||
|
||||
private Image getConfirmIconImage(int numBroadcastPeers, int depthInBlocks)
|
||||
{
|
||||
depthInBlocks = 0;
|
||||
if (depthInBlocks > 0)
|
||||
return Icons.getIconImage(Icons.getIconIDForConfirmations(depthInBlocks));
|
||||
else
|
||||
return Icons.getIconImage(Icons.getIconIDForPeersSeenTx(numBroadcastPeers));
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
package io.bitsquare.gui.components.processbar;
|
||||
|
||||
import io.bitsquare.gui.util.Utils;
|
||||
import io.bitsquare.gui.util.GUIUtils;
|
||||
import javafx.animation.AnimationTimer;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Control;
|
||||
@ -65,7 +65,7 @@ public class ProcessStepsBuilder
|
||||
|
||||
// TODO
|
||||
// mock simulate network delay
|
||||
Utils.setTimeout(100, (AnimationTimer animationTimer) -> {
|
||||
GUIUtils.setTimeout(100, (AnimationTimer animationTimer) -> {
|
||||
next();
|
||||
return null;
|
||||
});
|
||||
|
@ -1,7 +1,11 @@
|
||||
package io.bitsquare.gui.settings;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import io.bitsquare.gui.ChildController;
|
||||
import io.bitsquare.gui.NavigationController;
|
||||
import io.bitsquare.settings.Settings;
|
||||
import io.bitsquare.storage.Storage;
|
||||
import io.bitsquare.user.User;
|
||||
import javafx.fxml.Initializable;
|
||||
|
||||
import java.net.URL;
|
||||
@ -9,15 +13,24 @@ import java.util.ResourceBundle;
|
||||
|
||||
public class SettingsController implements Initializable, ChildController
|
||||
{
|
||||
|
||||
private User user;
|
||||
private Settings settings;
|
||||
private Storage storage;
|
||||
|
||||
private NavigationController navigationController;
|
||||
|
||||
@Inject
|
||||
public SettingsController(User user, Settings settings, Storage storage)
|
||||
{
|
||||
this.user = user;
|
||||
this.settings = settings;
|
||||
this.storage = storage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(URL url, ResourceBundle rb)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -10,6 +10,7 @@ import io.bitsquare.btc.WalletFacade;
|
||||
import io.bitsquare.crypto.CryptoFacade;
|
||||
import io.bitsquare.gui.ChildController;
|
||||
import io.bitsquare.gui.NavigationController;
|
||||
import io.bitsquare.gui.components.ConfirmationComponent;
|
||||
import io.bitsquare.gui.components.NetworkSyncPane;
|
||||
import io.bitsquare.gui.components.processbar.ProcessStepBar;
|
||||
import io.bitsquare.gui.components.processbar.ProcessStepItem;
|
||||
@ -18,11 +19,10 @@ import io.bitsquare.gui.util.Formatter;
|
||||
import io.bitsquare.settings.Settings;
|
||||
import io.bitsquare.storage.Storage;
|
||||
import io.bitsquare.user.User;
|
||||
import io.bitsquare.util.Utils;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.input.Clipboard;
|
||||
import javafx.scene.input.ClipboardContent;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
@ -48,8 +48,7 @@ public class SetupController implements Initializable, ChildController, WalletFa
|
||||
private List<ProcessStepItem> processStepItems = new ArrayList();
|
||||
|
||||
private NavigationController navigationController;
|
||||
private ImageView confirmIconImageView;
|
||||
private TextField balanceLabel, confirmationsLabel, accountHolderName, accountPrimaryID, accountSecondaryID;
|
||||
private TextField balanceLabel, accountTitle, accountHolderName, accountPrimaryID, accountSecondaryID;
|
||||
private ComboBox countryComboBox, bankTransferTypeComboBox, currencyComboBox;
|
||||
private Button addBankAccountButton;
|
||||
|
||||
@ -103,8 +102,7 @@ public class SetupController implements Initializable, ChildController, WalletFa
|
||||
public void onConfidenceChanged(int numBroadcastPeers, int depthInBlocks)
|
||||
{
|
||||
updateCreateAccountButton();
|
||||
confirmIconImageView.setImage(getConfirmIconImage(numBroadcastPeers, depthInBlocks));
|
||||
confirmationsLabel.setText(getConfirmationsText(numBroadcastPeers, depthInBlocks));
|
||||
|
||||
log.info("onConfidenceChanged " + numBroadcastPeers + " / " + depthInBlocks);
|
||||
}
|
||||
|
||||
@ -133,24 +131,18 @@ public class SetupController implements Initializable, ChildController, WalletFa
|
||||
return bankTransferTypeComboBox.getSelectionModel().getSelectedItem() != null
|
||||
&& countryComboBox.getSelectionModel().getSelectedItem() != null
|
||||
&& currencyComboBox.getSelectionModel().getSelectedItem() != null
|
||||
&& accountTitle.getText().length() > 0
|
||||
&& accountHolderName.getText().length() > 0
|
||||
&& accountPrimaryID.getText().length() > 0
|
||||
&& accountSecondaryID.getText().length() > 0
|
||||
&& accountHolderName.getText().length() > 0
|
||||
&& accountIDsByBankTransferTypeValid;
|
||||
}
|
||||
|
||||
private Image getConfirmIconImage(int numBroadcastPeers, int depthInBlocks)
|
||||
{
|
||||
if (depthInBlocks > 0)
|
||||
return Icons.getIconImage(Icons.getIconIDForConfirmations(depthInBlocks));
|
||||
else
|
||||
return Icons.getIconImage(Icons.getIconIDForPeersSeenTx(numBroadcastPeers));
|
||||
}
|
||||
|
||||
private void updateCreateAccountButton()
|
||||
{
|
||||
boolean funded = walletFacade.getAccountRegistrationBalance().compareTo(BigInteger.ZERO) > 0;
|
||||
nextButton.setDisable(!funded || walletFacade.getRegistrationConfirmationDepthInBlocks() == 0);
|
||||
nextButton.setDisable(!funded || walletFacade.getRegConfDepthInBlocks() == 0);
|
||||
}
|
||||
|
||||
|
||||
@ -158,11 +150,6 @@ public class SetupController implements Initializable, ChildController, WalletFa
|
||||
// GUI BUILDER
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private String getConfirmationsText(int registrationConfirmationNumBroadcastPeers, int registrationConfirmationDepthInBlocks)
|
||||
{
|
||||
return registrationConfirmationDepthInBlocks + " confirmation(s) / " + "Seen by " + registrationConfirmationNumBroadcastPeers + " peer(s)";
|
||||
}
|
||||
|
||||
private void buildStep0()
|
||||
{
|
||||
infoLabel.setText("You need to pay 0.01 BTC to the registration address.\n\n" +
|
||||
@ -174,8 +161,7 @@ public class SetupController implements Initializable, ChildController, WalletFa
|
||||
|
||||
int gridRow = -1;
|
||||
|
||||
TextField addressLabel = FormBuilder.addInputField(formGridPane, "Registration address:", walletFacade.getAccountRegistrationAddress().toString(), ++gridRow);
|
||||
addressLabel.setEditable(false);
|
||||
TextField addressLabel = FormBuilder.addTextField(formGridPane, "Registration address:", walletFacade.getAccountRegistrationAddress().toString(), ++gridRow, false, true);
|
||||
|
||||
Label copyIcon = new Label("");
|
||||
formGridPane.add(copyIcon, 2, gridRow);
|
||||
@ -183,14 +169,9 @@ public class SetupController implements Initializable, ChildController, WalletFa
|
||||
AwesomeDude.setIcon(copyIcon, AwesomeIcon.COPY);
|
||||
Tooltip.install(copyIcon, new Tooltip("Copy address to clipboard"));
|
||||
|
||||
balanceLabel = FormBuilder.addInputField(formGridPane, "Balance:", Formatter.formatSatoshis(walletFacade.getAccountRegistrationBalance(), true), ++gridRow);
|
||||
balanceLabel.setEditable(false);
|
||||
balanceLabel = FormBuilder.addTextField(formGridPane, "Balance:", Formatter.formatSatoshis(walletFacade.getAccountRegistrationBalance(), true), ++gridRow);
|
||||
|
||||
confirmationsLabel = FormBuilder.addInputField(formGridPane, "Confirmations:", getConfirmationsText(walletFacade.getRegistrationConfirmationNumBroadcastPeers(), walletFacade.getRegistrationConfirmationDepthInBlocks()), ++gridRow);
|
||||
confirmationsLabel.setEditable(false);
|
||||
|
||||
confirmIconImageView = new ImageView(getConfirmIconImage(walletFacade.getRegistrationConfirmationNumBroadcastPeers(), walletFacade.getRegistrationConfirmationDepthInBlocks()));
|
||||
formGridPane.add(confirmIconImageView, 2, gridRow);
|
||||
ConfirmationComponent confirmationComponent = new ConfirmationComponent(walletFacade, formGridPane, ++gridRow);
|
||||
|
||||
nextButton.setText("Payment done");
|
||||
updateCreateAccountButton();
|
||||
@ -221,13 +202,29 @@ public class SetupController implements Initializable, ChildController, WalletFa
|
||||
|
||||
formGridPane.getChildren().clear();
|
||||
int gridRow = -1;
|
||||
bankTransferTypeComboBox = FormBuilder.addComboBox(formGridPane, "Bank account type:", settings.getAllBankAccountTypes(), ++gridRow);
|
||||
bankTransferTypeComboBox = FormBuilder.addComboBox(formGridPane, "Bank account type:", Utils.getAllBankAccountTypes(), ++gridRow);
|
||||
bankTransferTypeComboBox.setConverter(new StringConverter<BankAccountType>()
|
||||
{
|
||||
@Override
|
||||
public String toString(BankAccountType bankAccountType)
|
||||
{
|
||||
return Localisation.get(bankAccountType.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public BankAccountType fromString(String s)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
bankTransferTypeComboBox.setPromptText("Select bank account type");
|
||||
accountTitle = FormBuilder.addInputField(formGridPane, "Bank account title:", "", ++gridRow);
|
||||
accountHolderName = FormBuilder.addInputField(formGridPane, "Bank account holder name:", "", ++gridRow);
|
||||
accountPrimaryID = FormBuilder.addInputField(formGridPane, "Bank account primary ID", "", ++gridRow);
|
||||
accountSecondaryID = FormBuilder.addInputField(formGridPane, "Bank account secondary ID:", "", ++gridRow);
|
||||
|
||||
currencyComboBox = FormBuilder.addComboBox(formGridPane, "Currency used for bank account:", settings.getAllCurrencies(), ++gridRow);
|
||||
currencyComboBox = FormBuilder.addComboBox(formGridPane, "Currency used for bank account:", Utils.getAllCurrencies(), ++gridRow);
|
||||
currencyComboBox.setPromptText("Select currency");
|
||||
currencyComboBox.setConverter(new StringConverter<Currency>()
|
||||
{
|
||||
@ -244,7 +241,7 @@ public class SetupController implements Initializable, ChildController, WalletFa
|
||||
}
|
||||
});
|
||||
|
||||
countryComboBox = FormBuilder.addComboBox(formGridPane, "Country of bank account:", settings.getAllLocales(), ++gridRow);
|
||||
countryComboBox = FormBuilder.addComboBox(formGridPane, "Country of bank account:", Utils.getAllLocales(), ++gridRow);
|
||||
countryComboBox.setPromptText("Select country");
|
||||
countryComboBox.setConverter(new StringConverter<Locale>()
|
||||
{
|
||||
@ -270,6 +267,7 @@ public class SetupController implements Initializable, ChildController, WalletFa
|
||||
skipButton.setText("Register later");
|
||||
|
||||
// handlers
|
||||
accountTitle.textProperty().addListener((ov, oldValue, newValue) -> checkCreateAccountButtonState());
|
||||
accountHolderName.textProperty().addListener((ov, oldValue, newValue) -> checkCreateAccountButtonState());
|
||||
accountPrimaryID.textProperty().addListener((ov, oldValue, newValue) -> checkCreateAccountButtonState());
|
||||
accountSecondaryID.textProperty().addListener((ov, oldValue, newValue) -> checkCreateAccountButtonState());
|
||||
@ -292,6 +290,8 @@ public class SetupController implements Initializable, ChildController, WalletFa
|
||||
|
||||
addBankAccountButton.setOnAction(e -> {
|
||||
addBankAccount();
|
||||
storage.write(user.getClass().getName(), user);
|
||||
|
||||
if (verifyBankAccountData())
|
||||
{
|
||||
bankTransferTypeComboBox.getSelectionModel().clearSelection();
|
||||
@ -313,13 +313,15 @@ public class SetupController implements Initializable, ChildController, WalletFa
|
||||
user.setAccountID(walletFacade.getAccountRegistrationAddress().toString());
|
||||
user.setMessageID(walletFacade.getAccountRegistrationPubKey().toString());
|
||||
|
||||
storage.saveUser(user);
|
||||
|
||||
storage.write(user.getClass().getName(), user);
|
||||
processStepBar.next();
|
||||
buildStep2();
|
||||
} catch (InsufficientMoneyException e1)
|
||||
{
|
||||
log.warn(e1.toString());
|
||||
// TODO
|
||||
processStepBar.next();
|
||||
buildStep2();
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -336,12 +338,14 @@ public class SetupController implements Initializable, ChildController, WalletFa
|
||||
{
|
||||
if (verifyBankAccountData())
|
||||
{
|
||||
BankAccount bankAccount = new BankAccount((BankAccountType) bankTransferTypeComboBox.getSelectionModel().getSelectedItem(),
|
||||
accountPrimaryID.getText(),
|
||||
accountSecondaryID.getText(),
|
||||
accountHolderName.getText(),
|
||||
BankAccount bankAccount = new BankAccount(
|
||||
(BankAccountType) bankTransferTypeComboBox.getSelectionModel().getSelectedItem(),
|
||||
(Currency) currencyComboBox.getSelectionModel().getSelectedItem(),
|
||||
(Locale) countryComboBox.getSelectionModel().getSelectedItem(),
|
||||
(Currency) currencyComboBox.getSelectionModel().getSelectedItem());
|
||||
accountTitle.getText(),
|
||||
accountHolderName.getText(),
|
||||
accountPrimaryID.getText(),
|
||||
accountSecondaryID.getText());
|
||||
user.addBankAccount(bankAccount);
|
||||
}
|
||||
}
|
||||
@ -360,20 +364,20 @@ public class SetupController implements Initializable, ChildController, WalletFa
|
||||
formGridPane.getChildren().clear();
|
||||
int gridRow = -1;
|
||||
List<BankAccount> bankAccounts = user.getBankAccounts();
|
||||
Iterator iterator = bankAccounts.iterator();
|
||||
Iterator<BankAccount> iterator = bankAccounts.iterator();
|
||||
int index = 0;
|
||||
while (iterator.hasNext())
|
||||
{
|
||||
FormBuilder.addHeaderLabel(formGridPane, "Bank account " + (index + 1), ++gridRow);
|
||||
Map.Entry<String, BankAccount> entry = (Map.Entry) iterator.next();
|
||||
BankAccount bankAccount = iterator.next();
|
||||
// need to get updated gridRow from subroutine
|
||||
gridRow = buildBankAccountDetails(entry.getValue(), ++gridRow);
|
||||
gridRow = buildBankAccountDetails(bankAccount, ++gridRow);
|
||||
FormBuilder.addVSpacer(formGridPane, ++gridRow);
|
||||
index++;
|
||||
}
|
||||
FormBuilder.addVSpacer(formGridPane, ++gridRow);
|
||||
FormBuilder.addInputField(formGridPane, "Registration address:", walletFacade.getAccountRegistrationAddress().toString(), ++gridRow).setMouseTransparent(true);
|
||||
FormBuilder.addInputField(formGridPane, "Balance:", Formatter.formatSatoshis(walletFacade.getAccountRegistrationBalance(), true), ++gridRow).setMouseTransparent(true);
|
||||
FormBuilder.addTextField(formGridPane, "Registration address:", walletFacade.getAccountRegistrationAddress().toString(), ++gridRow);
|
||||
FormBuilder.addTextField(formGridPane, "Balance:", Formatter.formatSatoshis(walletFacade.getAccountRegistrationBalance(), true), ++gridRow);
|
||||
|
||||
nextButton.setText("Done");
|
||||
skipButton.setOpacity(0);
|
||||
@ -385,11 +389,13 @@ public class SetupController implements Initializable, ChildController, WalletFa
|
||||
// util
|
||||
private int buildBankAccountDetails(BankAccount bankAccount, int row)
|
||||
{
|
||||
FormBuilder.addInputField(formGridPane, "Bank account holder name:", bankAccount.getAccountHolderName(), ++row).setMouseTransparent(true);
|
||||
FormBuilder.addInputField(formGridPane, "Bank account type", bankAccount.getBankAccountType().toString(), ++row).setMouseTransparent(true);
|
||||
FormBuilder.addInputField(formGridPane, "Bank account primary ID", bankAccount.getAccountPrimaryID(), ++row).setMouseTransparent(true);
|
||||
FormBuilder.addInputField(formGridPane, "Bank account secondary ID:", bankAccount.getAccountSecondaryID(), ++row).setMouseTransparent(true);
|
||||
FormBuilder.addTextField(formGridPane, "Bank account holder name:", bankAccount.getAccountHolderName(), ++row);
|
||||
FormBuilder.addTextField(formGridPane, "Bank account type", bankAccount.getBankAccountType().toString(), ++row);
|
||||
FormBuilder.addTextField(formGridPane, "Bank account primary ID", bankAccount.getAccountPrimaryID(), ++row);
|
||||
FormBuilder.addTextField(formGridPane, "Bank account secondary ID:", bankAccount.getAccountSecondaryID(), ++row);
|
||||
return row;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<AnchorPane fx:id="rootContainer" fx:controller="io.bitsquare.gui.setup.SetupController"
|
||||
xmlns:fx="http://javafx.com/fxml" minHeight="300" minWidth="400" prefHeight="600" prefWidth="800">
|
||||
xmlns:fx="http://javafx.com/fxml">
|
||||
<ScrollPane fitToWidth="true" AnchorPane.leftAnchor="10" AnchorPane.rightAnchor="10" AnchorPane.topAnchor="10"
|
||||
AnchorPane.bottomAnchor="30">
|
||||
<content>
|
||||
|
@ -84,5 +84,14 @@ public class TradeController implements Initializable, NavigationController, Chi
|
||||
orderBookController.setDirection(direction);
|
||||
}
|
||||
|
||||
public void cleanup()
|
||||
{
|
||||
if (orderBookController != null)
|
||||
{
|
||||
orderBookController.cleanup();
|
||||
orderBookController = null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,77 +1,65 @@
|
||||
package io.bitsquare.gui.trade.offer;
|
||||
|
||||
import com.google.bitcoin.core.InsufficientMoneyException;
|
||||
import com.google.inject.Inject;
|
||||
import io.bitsquare.btc.Fees;
|
||||
import io.bitsquare.btc.WalletFacade;
|
||||
import io.bitsquare.gui.ChildController;
|
||||
import io.bitsquare.gui.NavigationController;
|
||||
import io.bitsquare.gui.util.Converter;
|
||||
import io.bitsquare.gui.util.Formatter;
|
||||
import io.bitsquare.settings.OrderBookFilterSettings;
|
||||
import io.bitsquare.gui.components.ConfirmationComponent;
|
||||
import io.bitsquare.gui.util.*;
|
||||
import io.bitsquare.settings.Settings;
|
||||
import io.bitsquare.trade.Direction;
|
||||
import io.bitsquare.trade.Offer;
|
||||
import io.bitsquare.trade.OfferConstraints;
|
||||
import io.bitsquare.trade.Trading;
|
||||
import io.bitsquare.trade.orderbook.OrderBook;
|
||||
import io.bitsquare.trade.orderbook.OrderBookFilter;
|
||||
import io.bitsquare.user.User;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TabPane;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Currency;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.UUID;
|
||||
|
||||
public class CreateOfferController implements Initializable, ChildController
|
||||
public class CreateOfferController implements Initializable, ChildController, WalletFacade.WalletListener
|
||||
{
|
||||
private static final Logger log = LoggerFactory.getLogger(CreateOfferController.class);
|
||||
|
||||
private NavigationController navigationController;
|
||||
private Trading trading;
|
||||
private OrderBookFilterSettings orderBookFilterSettings;
|
||||
private WalletFacade walletFacade;
|
||||
private Settings settings;
|
||||
private User user;
|
||||
private double filterPaneItemOffset;
|
||||
private Direction direction;
|
||||
|
||||
@FXML
|
||||
public AnchorPane holderPane;
|
||||
@FXML
|
||||
public Pane detailsPane;
|
||||
private Button placeOfferButton;
|
||||
private int gridRow;
|
||||
|
||||
@FXML
|
||||
private AnchorPane holderPane;
|
||||
@FXML
|
||||
private GridPane formGridPane;
|
||||
@FXML
|
||||
public Label buyLabel;
|
||||
@FXML
|
||||
public TextField volume;
|
||||
@FXML
|
||||
public ImageView directionImageView;
|
||||
|
||||
@FXML
|
||||
public TextField amount;
|
||||
@FXML
|
||||
public TextField price;
|
||||
@FXML
|
||||
public TextField minAmount;
|
||||
@FXML
|
||||
public Button placeOfferButton;
|
||||
public TextField volume, amount, price, minAmount;
|
||||
|
||||
@Inject
|
||||
public CreateOfferController(Trading trading, OrderBookFilterSettings orderBookFilterSettings, Settings settings, User user)
|
||||
public CreateOfferController(Trading trading, WalletFacade walletFacade, Settings settings, User user)
|
||||
{
|
||||
this.trading = trading;
|
||||
this.orderBookFilterSettings = orderBookFilterSettings;
|
||||
this.walletFacade = walletFacade;
|
||||
this.settings = settings;
|
||||
this.user = user;
|
||||
}
|
||||
@ -79,14 +67,34 @@ public class CreateOfferController implements Initializable, ChildController
|
||||
@Override
|
||||
public void initialize(URL url, ResourceBundle rb)
|
||||
{
|
||||
createFilterPane();
|
||||
walletFacade.addRegistrationWalletListener(this);
|
||||
|
||||
gridRow = 2;
|
||||
FormBuilder.addVSpacer(formGridPane, ++gridRow);
|
||||
FormBuilder.addHeaderLabel(formGridPane, "Offer details:", ++gridRow);
|
||||
FormBuilder.addTextField(formGridPane, "Bank account type:", Localisation.get(user.getCurrentBankAccount().getBankAccountType().getType().toString()), ++gridRow);
|
||||
FormBuilder.addTextField(formGridPane, "Bank account currency:", user.getCurrentBankAccount().getCurrency().getCurrencyCode(), ++gridRow);
|
||||
FormBuilder.addTextField(formGridPane, "Bank account county:", user.getCurrentBankAccount().getCountryLocale().getDisplayCountry(), ++gridRow);
|
||||
FormBuilder.addTextField(formGridPane, "Accepted countries:", Formatter.countryLocalesToString(settings.getAcceptedCountryLocales()), ++gridRow);
|
||||
FormBuilder.addTextField(formGridPane, "Accepted languages:", Formatter.languageLocalesToString(settings.getAcceptedLanguageLocales()), ++gridRow);
|
||||
|
||||
FormBuilder.addVSpacer(formGridPane, ++gridRow);
|
||||
Label placeOfferTitle = FormBuilder.addHeaderLabel(formGridPane, "Place offer:", ++gridRow);
|
||||
|
||||
TextField feeLabel = FormBuilder.addTextField(formGridPane, "Offer fee:", Formatter.formatSatoshis(Fees.OFFER_CREATION_FEE, true), ++gridRow);
|
||||
feeLabel.setMouseTransparent(true);
|
||||
|
||||
placeOfferButton = new Button("Place offer");
|
||||
formGridPane.add(placeOfferButton, 1, ++gridRow);
|
||||
placeOfferButton.setDefaultButton(true);
|
||||
|
||||
// handlers
|
||||
amount.textProperty().addListener(new ChangeListener<String>()
|
||||
{
|
||||
@Override
|
||||
public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue)
|
||||
{
|
||||
setVolume();
|
||||
updateVolume();
|
||||
}
|
||||
});
|
||||
|
||||
@ -95,23 +103,66 @@ public class CreateOfferController implements Initializable, ChildController
|
||||
@Override
|
||||
public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue)
|
||||
{
|
||||
setVolume();
|
||||
updateVolume();
|
||||
}
|
||||
});
|
||||
|
||||
placeOfferButton.setOnAction(e -> {
|
||||
// TODO not impl yet. use mocks
|
||||
OfferConstraints offerConstraints = new OrderBook(settings).getRandomOfferConstraints();
|
||||
Offer offer = new Offer(UUID.randomUUID(),
|
||||
direction,
|
||||
Converter.convertToDouble(price.getText()),
|
||||
Converter.convertToDouble(amount.getText()),
|
||||
Converter.convertToDouble(minAmount.getText()),
|
||||
settings.getCurrency(),
|
||||
user,
|
||||
offerConstraints);
|
||||
trading.placeNewOffer(offer);
|
||||
|
||||
if (inputValid())
|
||||
{
|
||||
Offer offer = new Offer(user.getAccountID(),
|
||||
user.getMessageID(),
|
||||
direction,
|
||||
Converter.stringToDouble(price.getText()),
|
||||
Converter.stringToDouble(amount.getText()),
|
||||
Converter.stringToDouble(minAmount.getText()),
|
||||
user.getCurrentBankAccount().getBankAccountType().getType(),
|
||||
user.getCurrentBankAccount().getCurrency(),
|
||||
user.getCurrentBankAccount().getCountryLocale(),
|
||||
settings.getAcceptedCountryLocales(),
|
||||
settings.getAcceptedLanguageLocales());
|
||||
|
||||
try
|
||||
{
|
||||
String txID = trading.placeNewOffer(offer);
|
||||
formGridPane.getChildren().remove(placeOfferButton);
|
||||
placeOfferTitle.setText("Transaction sent:");
|
||||
buildConfirmationView(txID);
|
||||
} catch (InsufficientMoneyException e1)
|
||||
{
|
||||
//TODO popup
|
||||
log.error(e.toString());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onConfidenceChanged(int numBroadcastPeers, int depthInBlocks)
|
||||
{
|
||||
log.info("onConfidenceChanged " + numBroadcastPeers + " / " + depthInBlocks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCoinsReceived(BigInteger newBalance)
|
||||
{
|
||||
log.info("onCoinsReceived " + newBalance);
|
||||
}
|
||||
|
||||
private void buildConfirmationView(String txID)
|
||||
{
|
||||
FormBuilder.addTextField(formGridPane, "Transaction ID:", txID, ++gridRow, false, true);
|
||||
|
||||
ConfirmationComponent confirmationComponent = new ConfirmationComponent(walletFacade, formGridPane, ++gridRow);
|
||||
|
||||
Button closeButton = new Button("Close");
|
||||
formGridPane.add(closeButton, 1, ++gridRow);
|
||||
closeButton.setDefaultButton(true);
|
||||
|
||||
|
||||
closeButton.setOnAction(e -> {
|
||||
TabPane tabPane = ((TabPane) (holderPane.getParent().getParent()));
|
||||
tabPane.getTabs().remove(tabPane.getSelectionModel().getSelectedItem());
|
||||
|
||||
@ -119,6 +170,7 @@ public class CreateOfferController implements Initializable, ChildController
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setNavigationController(NavigationController navigationController)
|
||||
{
|
||||
@ -132,140 +184,36 @@ public class CreateOfferController implements Initializable, ChildController
|
||||
minAmount.setText(Formatter.formatPrice(orderBookFilter.getAmount()));
|
||||
price.setText(Formatter.formatPrice(orderBookFilter.getPrice()));
|
||||
|
||||
configDirection();
|
||||
String iconPath = (direction == Direction.BUY) ? Icons.BUY : Icons.SELL;
|
||||
buyLabel.setText(Formatter.formatDirection(direction, false) + ":");
|
||||
updateVolume();
|
||||
}
|
||||
|
||||
private void configDirection()
|
||||
//TODO
|
||||
private boolean inputValid()
|
||||
{
|
||||
String iconPath;
|
||||
String buyLabelText;
|
||||
if (direction == Direction.BUY)
|
||||
{
|
||||
iconPath = "/images/buy.png";
|
||||
buyLabelText = "BUY";
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void updateVolume()
|
||||
{
|
||||
double amountAsDouble = Converter.stringToDouble(amount.getText());
|
||||
double priceAsDouble = Converter.stringToDouble(price.getText());
|
||||
volume.setText(Formatter.formatPrice(amountAsDouble * priceAsDouble));
|
||||
}
|
||||
|
||||
private Image getConfirmIconImage(int numBroadcastPeers, int depthInBlocks)
|
||||
{
|
||||
if (depthInBlocks > 0)
|
||||
return Icons.getIconImage(Icons.getIconIDForConfirmations(depthInBlocks));
|
||||
else
|
||||
{
|
||||
iconPath = "/images/sell.png";
|
||||
buyLabelText = "SELL";
|
||||
}
|
||||
Image icon = new Image(getClass().getResourceAsStream(iconPath));
|
||||
directionImageView.setImage(icon);
|
||||
buyLabel.setText(buyLabelText);
|
||||
return Icons.getIconImage(Icons.getIconIDForPeersSeenTx(numBroadcastPeers));
|
||||
}
|
||||
|
||||
private void createFilterPane()
|
||||
private String getConfirmationsText(int registrationConfirmationNumBroadcastPeers, int registrationConfirmationDepthInBlocks)
|
||||
{
|
||||
filterPaneItemOffset = 30;
|
||||
|
||||
ArrayList<Currency> currencies = orderBookFilterSettings.getCurrencies();
|
||||
Currency currency = orderBookFilterSettings.getCurrency();
|
||||
ComboBox currencyComboBox = createCurrencyItem("Currency: ", currency, currencies);
|
||||
currencyComboBox.valueProperty().addListener(new ChangeListener<Currency>()
|
||||
{
|
||||
@Override
|
||||
public void changed(ObservableValue ov, Currency oldValue, Currency newValue)
|
||||
{
|
||||
orderBookFilterSettings.setCurrency(newValue);
|
||||
}
|
||||
});
|
||||
|
||||
Label bankLabel = createFilterItem("Bank transfer types: ", "SEPA, OKPAY");
|
||||
|
||||
Label countriesLabel = createFilterItem("Countries: ", "DE, GB, AT");
|
||||
Label languagesLabel = createFilterItem("Languages: ", "DE, EN");
|
||||
Label arbitratorsLabel = createFilterItem("Arbitrators: ", "Paysty, BitRated");
|
||||
Label identityLabel = createFilterItem("Identity verifications: ", "Passport, Google+, Facebook, Skype");
|
||||
TextField collateralLabel = createCollateralItem("Collateral (%): ", 10);
|
||||
return registrationConfirmationDepthInBlocks + " confirmation(s) / " + "Seen by " + registrationConfirmationNumBroadcastPeers + " peer(s)";
|
||||
}
|
||||
|
||||
private ComboBox createCurrencyItem(String labelText, Currency currency, ArrayList<Currency> currencies)
|
||||
{
|
||||
final Separator separator = new Separator();
|
||||
separator.setPrefWidth(380);
|
||||
separator.setLayoutY(0 + filterPaneItemOffset);
|
||||
separator.setLayoutX(0);
|
||||
final Label label = new Label(labelText);
|
||||
label.setLayoutY(10 + filterPaneItemOffset);
|
||||
ObservableList<Currency> options = FXCollections.observableArrayList(currencies);
|
||||
final ComboBox comboBox = new ComboBox(options);
|
||||
comboBox.setLayoutX(70);
|
||||
comboBox.setLayoutY(5 + filterPaneItemOffset);
|
||||
comboBox.setValue(currency);
|
||||
|
||||
|
||||
detailsPane.getChildren().addAll(separator, label, comboBox);
|
||||
filterPaneItemOffset += 40;
|
||||
return comboBox;
|
||||
}
|
||||
|
||||
private Label createFilterItem(String labelText, String valueText)
|
||||
{
|
||||
final Separator separator = new Separator();
|
||||
separator.setPrefWidth(380);
|
||||
separator.setLayoutY(0 + filterPaneItemOffset);
|
||||
separator.setLayoutX(0);
|
||||
final Label label = new Label(labelText + valueText);
|
||||
label.setLayoutY(10 + filterPaneItemOffset);
|
||||
label.setPrefWidth(310);
|
||||
Tooltip tooltip = new Tooltip(valueText);
|
||||
label.setTooltip(tooltip);
|
||||
|
||||
final Button edit = new Button("Edit");
|
||||
edit.setPrefWidth(50);
|
||||
edit.setLayoutX(330);
|
||||
edit.setLayoutY(5 + filterPaneItemOffset);
|
||||
|
||||
detailsPane.getChildren().addAll(separator, label, edit);
|
||||
filterPaneItemOffset += 40;
|
||||
return label;
|
||||
}
|
||||
|
||||
private TextField createCollateralItem(String labelText, double collateral)
|
||||
{
|
||||
final Separator separator = new Separator();
|
||||
separator.setPrefWidth(380);
|
||||
separator.setLayoutY(0 + filterPaneItemOffset);
|
||||
separator.setLayoutX(0);
|
||||
final Label label = new Label(labelText);
|
||||
label.setLayoutY(10 + filterPaneItemOffset);
|
||||
label.setPrefWidth(310);
|
||||
|
||||
final TextField collateralValue = new TextField(Double.toString(collateral));
|
||||
collateralValue.setLayoutX(90);
|
||||
collateralValue.setLayoutY(5 + filterPaneItemOffset);
|
||||
collateralValue.setPrefWidth(50);
|
||||
|
||||
detailsPane.getChildren().addAll(separator, label, collateralValue);
|
||||
filterPaneItemOffset += 40;
|
||||
|
||||
return collateralValue;
|
||||
}
|
||||
|
||||
|
||||
private double textInputToNumber(String oldValue, String newValue)
|
||||
{
|
||||
//TODO use regex.... or better custom textfield component
|
||||
double d = 0.0;
|
||||
if (!newValue.equals(""))
|
||||
{
|
||||
d = Converter.convertToDouble(newValue);
|
||||
if (d == Double.NEGATIVE_INFINITY)
|
||||
{
|
||||
amount.setText(oldValue);
|
||||
d = Converter.convertToDouble(oldValue);
|
||||
}
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
private void setVolume()
|
||||
{
|
||||
double a = textInputToNumber(amount.getText(), amount.getText());
|
||||
double p = textInputToNumber(price.getText(), price.getText());
|
||||
volume.setText(Formatter.formatPrice(a * p));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,78 +1,50 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.geometry.*?>
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.image.ImageView?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
<AnchorPane fx:id="holderPane" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0"
|
||||
AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" xmlns:fx="http://javafx.com/fxml/1"
|
||||
fx:controller="io.bitsquare.gui.trade.offer.CreateOfferController">
|
||||
<children>
|
||||
<HBox prefHeight="22.0" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="10.0">
|
||||
<children>
|
||||
<ImageView fx:id="directionImageView"/>
|
||||
<VBox spacing="10" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="5.0"
|
||||
AnchorPane.bottomAnchor="10.0">
|
||||
<GridPane fx:id="formGridPane" vgap="5" hgap="5">
|
||||
<children>
|
||||
<Label id="form-header-text" text="Create new offer:" GridPane.rowIndex="0"
|
||||
GridPane.columnIndex="0"/>
|
||||
|
||||
<Label fx:id="buyLabel" text="Buy">
|
||||
<padding>
|
||||
<Insets left="4.0" right="4.0" top="5.0"/>
|
||||
</padding>
|
||||
</Label>
|
||||
<Label fx:id="buyLabel" text="Buy" GridPane.rowIndex="1" GridPane.columnIndex="0"/>
|
||||
|
||||
<TextField fx:id="amount" prefHeight="26.0" prefWidth="70.0" alignment="CENTER_RIGHT">
|
||||
<HBox.margin>
|
||||
<Insets left="0.0"/>
|
||||
</HBox.margin>
|
||||
</TextField>
|
||||
<Label text="BTC for">
|
||||
<padding>
|
||||
<Insets left="4.0" right="4.0" top="5.0"/>
|
||||
</padding>
|
||||
</Label>
|
||||
<TextField fx:id="price" prefHeight="26.0" prefWidth="70.0" alignment="CENTER_RIGHT"/>
|
||||
<Label text="EUR =">
|
||||
<padding>
|
||||
<Insets left="4.0" right="4.0" top="5.0"/>
|
||||
</padding>
|
||||
</Label>
|
||||
<TextField fx:id="volume" prefHeight="26.0" prefWidth="70.0" alignment="CENTER_RIGHT" editable="false"/>
|
||||
<Label prefHeight="21.0" text="EUR in total (Min. Amount:">
|
||||
<padding>
|
||||
<Insets left="4.0" right="4.0" top="5.0"/>
|
||||
</padding>
|
||||
<HBox.margin>
|
||||
<Insets/>
|
||||
</HBox.margin>
|
||||
</Label>
|
||||
<TextField fx:id="minAmount" prefHeight="26.0" prefWidth="70.0" alignment="CENTER_RIGHT"/>
|
||||
<Label text="BTC)">
|
||||
<padding>
|
||||
<Insets left="4.0" right="4.0" top="5.0"/>
|
||||
</padding>
|
||||
</Label>
|
||||
<HBox GridPane.rowIndex="1" GridPane.columnIndex="1" GridPane.hgrow="NEVER" spacing="5"
|
||||
alignment="CENTER_RIGHT">
|
||||
<children>
|
||||
<TextField fx:id="amount" prefWidth="70.0" alignment="CENTER_RIGHT"/>
|
||||
<Label text="BTC for:"/>
|
||||
<TextField fx:id="price" prefWidth="70.0" alignment="CENTER_RIGHT"/>
|
||||
<Label text="EUR ="/>
|
||||
<TextField fx:id="volume" prefWidth="70.0" alignment="CENTER_RIGHT"
|
||||
mouseTransparent="true"/>
|
||||
<Label text="EUR in total"/>
|
||||
</children>
|
||||
</HBox>
|
||||
|
||||
</children>
|
||||
</HBox>
|
||||
<Label text="Min. Amount:" GridPane.rowIndex="2" GridPane.columnIndex="0"/>
|
||||
|
||||
<Pane fx:id="detailsPane" AnchorPane.topAnchor="50.0"
|
||||
AnchorPane.bottomAnchor="10.0" AnchorPane.leftAnchor="10.0">
|
||||
<TextField fx:id="minAmount" GridPane.rowIndex="2" GridPane.columnIndex="1"/>
|
||||
|
||||
<Label text="Offer details:">
|
||||
<font>
|
||||
<Font size="18.0"/>
|
||||
</font>
|
||||
</Label>
|
||||
</Pane>
|
||||
</children>
|
||||
|
||||
<Label text="Place offer" AnchorPane.leftAnchor="10.0" AnchorPane.topAnchor="380.0">
|
||||
<font>
|
||||
<Font size="18.0"/>
|
||||
</font>
|
||||
</Label>
|
||||
<Separator AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="405.0"/>
|
||||
|
||||
<Label text="Offer fee: 0.01 BTC" AnchorPane.leftAnchor="10.0" AnchorPane.topAnchor="415.0"/>
|
||||
<Button fx:id="placeOfferButton" text="Place offer" AnchorPane.leftAnchor="10.0" AnchorPane.topAnchor="440.0"/>
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/>
|
||||
</padding>
|
||||
|
||||
<columnConstraints>
|
||||
<ColumnConstraints halignment="RIGHT"/>
|
||||
<ColumnConstraints halignment="LEFT"/>
|
||||
<ColumnConstraints halignment="LEFT"/>
|
||||
</columnConstraints>
|
||||
</GridPane>
|
||||
</VBox>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
|
@ -10,14 +10,14 @@ import io.bitsquare.gui.util.Converter;
|
||||
import io.bitsquare.gui.util.Formatter;
|
||||
import io.bitsquare.gui.util.Icons;
|
||||
import io.bitsquare.gui.util.Localisation;
|
||||
import io.bitsquare.settings.Settings;
|
||||
import io.bitsquare.trade.Direction;
|
||||
import io.bitsquare.trade.orderbook.OrderBook;
|
||||
import io.bitsquare.trade.orderbook.OrderBookFilter;
|
||||
import io.bitsquare.user.User;
|
||||
import javafx.beans.property.ReadOnlyObjectWrapper;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.collections.transformation.SortedList;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.geometry.Pos;
|
||||
@ -33,7 +33,6 @@ import org.slf4j.LoggerFactory;
|
||||
import java.net.URL;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.ParseException;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
@ -43,10 +42,11 @@ public class OrderBookController implements Initializable, ChildController
|
||||
private NavigationController navigationController;
|
||||
private OrderBook orderBook;
|
||||
|
||||
private OrderBookListItem selectedOrderBookListItem;
|
||||
private SortedList<OrderBookListItem> offerList;
|
||||
private final OrderBookFilter orderBookFilter;
|
||||
private User user;
|
||||
|
||||
|
||||
private Button createOfferButton;
|
||||
private Image buyIcon = Icons.getIconImage(Icons.BUY);
|
||||
private Image sellIcon = Icons.getIconImage(Icons.SELL);
|
||||
|
||||
@ -61,22 +61,32 @@ public class OrderBookController implements Initializable, ChildController
|
||||
@FXML
|
||||
public TableColumn priceColumn, amountColumn, volumeColumn;
|
||||
@FXML
|
||||
private TableColumn<OrderBookListItem, OrderBookListItem> directionColumn, countryColumn, bankAccountTypeColumn;
|
||||
private TableColumn<String, OrderBookListItem> directionColumn, countryColumn, bankAccountTypeColumn;
|
||||
@FXML
|
||||
public Button createOfferButton;
|
||||
|
||||
@Inject
|
||||
public OrderBookController(OrderBook orderBook, OrderBookFilter orderBookFilter)
|
||||
public OrderBookController(OrderBook orderBook, OrderBookFilter orderBookFilter, User user)
|
||||
{
|
||||
this.orderBook = orderBook;
|
||||
this.orderBookFilter = orderBookFilter;
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(URL url, ResourceBundle rb)
|
||||
{
|
||||
// setup table
|
||||
setCountryColumnCellFactory();
|
||||
setBankAccountTypeColumnCellFactory();
|
||||
setDirectionColumnCellFactory();
|
||||
offerList = orderBook.getOfferList();
|
||||
offerList.comparatorProperty().bind(orderBookTable.comparatorProperty());
|
||||
orderBookTable.setItems(offerList);
|
||||
orderBookTable.getSortOrder().add(priceColumn);
|
||||
orderBookTable.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
|
||||
|
||||
// handlers
|
||||
amount.textProperty().addListener(new ChangeListener<String>()
|
||||
{
|
||||
@Override
|
||||
@ -97,10 +107,6 @@ public class OrderBookController implements Initializable, ChildController
|
||||
}
|
||||
});
|
||||
|
||||
orderBookTable.getSelectionModel().selectedItemProperty().addListener((observableValue, oldValue, newValue) -> {
|
||||
selectedOrderBookListItem = orderBookTable.getSelectionModel().getSelectedItem();
|
||||
});
|
||||
|
||||
orderBookFilter.getChangedProperty().addListener(new ChangeListener<Boolean>()
|
||||
{
|
||||
@Override
|
||||
@ -109,8 +115,19 @@ public class OrderBookController implements Initializable, ChildController
|
||||
updateOfferList();
|
||||
}
|
||||
});
|
||||
user.getChangedProperty().addListener(new ChangeListener<Boolean>()
|
||||
{
|
||||
@Override
|
||||
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue)
|
||||
{
|
||||
updateOfferList();
|
||||
}
|
||||
});
|
||||
|
||||
updateOfferList();
|
||||
createOfferButton.setOnAction(e -> {
|
||||
ChildController nextController = navigationController.navigateToView(NavigationController.TRADE__CREATE_OFFER, "Create offer");
|
||||
((CreateOfferController) nextController).setOrderBookFilter(orderBookFilter);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -126,6 +143,13 @@ public class OrderBookController implements Initializable, ChildController
|
||||
orderBookFilter.setDirection(direction);
|
||||
}
|
||||
|
||||
public void cleanup()
|
||||
{
|
||||
orderBookTable.setItems(null);
|
||||
orderBookTable.getSortOrder().clear();
|
||||
offerList.comparatorProperty().unbind();
|
||||
}
|
||||
|
||||
private void openTradeTab(OrderBookListItem orderBookListItem)
|
||||
{
|
||||
String title = orderBookListItem.getOffer().getDirection() == Direction.BUY ? "Trade: Sell Bitcoin" : "Trade: Buy Bitcoin";
|
||||
@ -133,57 +157,31 @@ public class OrderBookController implements Initializable, ChildController
|
||||
|
||||
double requestedAmount = orderBookListItem.getOffer().getAmount();
|
||||
if (!amount.getText().equals(""))
|
||||
requestedAmount = Converter.convertToDouble(amount.getText());
|
||||
requestedAmount = Converter.stringToDouble(amount.getText());
|
||||
|
||||
tradeProcessController.initView(orderBookListItem.getOffer(), requestedAmount);
|
||||
}
|
||||
|
||||
private void displayCreateOfferButton()
|
||||
{
|
||||
if (createOfferButton == null)
|
||||
{
|
||||
createOfferButton = new Button("Create new offer");
|
||||
holderPane.setBottomAnchor(createOfferButton, 360.0);
|
||||
holderPane.setLeftAnchor(createOfferButton, 10.0);
|
||||
holderPane.getChildren().add(createOfferButton);
|
||||
|
||||
createOfferButton.setOnAction(e -> {
|
||||
ChildController nextController = navigationController.navigateToView(NavigationController.TRADE__CREATE_OFFER, "Create offer");
|
||||
((CreateOfferController) nextController).setOrderBookFilter(orderBookFilter);
|
||||
});
|
||||
}
|
||||
createOfferButton.setVisible(true);
|
||||
|
||||
holderPane.setBottomAnchor(orderBookTable, 390.0);
|
||||
}
|
||||
|
||||
private void updateOfferList()
|
||||
{
|
||||
ObservableList offers = orderBook.getFilteredList(orderBookFilter);
|
||||
orderBookTable.setItems(offers);
|
||||
orderBookTable.getSortOrder().add(priceColumn);
|
||||
priceColumn.setSortType((orderBookFilter.getDirection() == Direction.BUY) ? TableColumn.SortType.ASCENDING : TableColumn.SortType.DESCENDING);
|
||||
orderBook.updateFilter(orderBookFilter);
|
||||
|
||||
if (offers.size() == 0)
|
||||
{
|
||||
displayCreateOfferButton();
|
||||
}
|
||||
else if (createOfferButton != null)
|
||||
{
|
||||
createOfferButton.setVisible(false);
|
||||
holderPane.setBottomAnchor(orderBookTable, 10.0);
|
||||
}
|
||||
priceColumn.setSortType((orderBookFilter.getDirection() == Direction.BUY) ? TableColumn.SortType.ASCENDING : TableColumn.SortType.DESCENDING);
|
||||
orderBookTable.sort();
|
||||
|
||||
if (orderBookTable.getItems() != null)
|
||||
createOfferButton.setDefaultButton(orderBookTable.getItems().size() == 0);
|
||||
}
|
||||
|
||||
private void setDirectionColumnCellFactory()
|
||||
{
|
||||
directionColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper(offer.getValue()));
|
||||
directionColumn.setCellFactory(new Callback<TableColumn<OrderBookListItem, OrderBookListItem>, TableCell<OrderBookListItem, OrderBookListItem>>()
|
||||
directionColumn.setCellFactory(new Callback<TableColumn<String, OrderBookListItem>, TableCell<String, OrderBookListItem>>()
|
||||
{
|
||||
@Override
|
||||
public TableCell<OrderBookListItem, OrderBookListItem> call(TableColumn<OrderBookListItem, OrderBookListItem> directionColumn)
|
||||
public TableCell<String, OrderBookListItem> call(TableColumn<String, OrderBookListItem> directionColumn)
|
||||
{
|
||||
return new TableCell<OrderBookListItem, OrderBookListItem>()
|
||||
return new TableCell<String, OrderBookListItem>()
|
||||
{
|
||||
final ImageView iconView = new ImageView();
|
||||
final Button button = new Button();
|
||||
@ -216,6 +214,7 @@ public class OrderBookController implements Initializable, ChildController
|
||||
button.setText(title);
|
||||
setGraphic(button);
|
||||
|
||||
button.setDefaultButton(getIndex() == 0);
|
||||
button.setOnAction(event -> openTradeTab(orderBookListItem));
|
||||
}
|
||||
else
|
||||
@ -231,12 +230,12 @@ public class OrderBookController implements Initializable, ChildController
|
||||
private void setCountryColumnCellFactory()
|
||||
{
|
||||
countryColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper(offer.getValue()));
|
||||
countryColumn.setCellFactory(new Callback<TableColumn<OrderBookListItem, OrderBookListItem>, TableCell<OrderBookListItem, OrderBookListItem>>()
|
||||
countryColumn.setCellFactory(new Callback<TableColumn<String, OrderBookListItem>, TableCell<String, OrderBookListItem>>()
|
||||
{
|
||||
@Override
|
||||
public TableCell<OrderBookListItem, OrderBookListItem> call(TableColumn<OrderBookListItem, OrderBookListItem> directionColumn)
|
||||
public TableCell<String, OrderBookListItem> call(TableColumn<String, OrderBookListItem> directionColumn)
|
||||
{
|
||||
return new TableCell<OrderBookListItem, OrderBookListItem>()
|
||||
return new TableCell<String, OrderBookListItem>()
|
||||
{
|
||||
final HBox hBox = new HBox();
|
||||
|
||||
@ -251,44 +250,19 @@ public class OrderBookController implements Initializable, ChildController
|
||||
{
|
||||
super.updateItem(orderBookListItem, empty);
|
||||
|
||||
hBox.getChildren().clear();
|
||||
if (orderBookListItem != null)
|
||||
{
|
||||
hBox.getChildren().clear();
|
||||
setText("");
|
||||
|
||||
List<Locale> countryLocales = orderBookListItem.getOffer().getOfferConstraints().getCountryLocales();
|
||||
int i = 0;
|
||||
String countries = "";
|
||||
for (Locale countryLocale : countryLocales)
|
||||
Locale countryLocale = orderBookListItem.getOffer().getBankAccountCountryLocale();
|
||||
try
|
||||
{
|
||||
countries += countryLocale.getDisplayCountry();
|
||||
if (i < countryLocales.size() - 1)
|
||||
countries += ", ";
|
||||
hBox.getChildren().add(Icons.getIconImageView("/images/countries/" + countryLocale.getCountry().toLowerCase() + ".png"));
|
||||
|
||||
if (i < 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
ImageView imageView = Icons.getIconImageView("/images/countries/" + countryLocale.getCountry().toLowerCase() + ".png");
|
||||
hBox.getChildren().add(imageView);
|
||||
|
||||
} catch (Exception e)
|
||||
{
|
||||
log.warn("Country icon not found: " + "/images/countries/" + countryLocale.getCountry().toLowerCase() + ".png country name: " + countryLocale.getDisplayCountry());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
setText("...");
|
||||
}
|
||||
i++;
|
||||
} catch (Exception e)
|
||||
{
|
||||
log.warn("Country icon not found: " + "/images/countries/" + countryLocale.getCountry().toLowerCase() + ".png country name: " + countryLocale.getDisplayCountry());
|
||||
}
|
||||
Tooltip.install(this, new Tooltip(countries));
|
||||
}
|
||||
else
|
||||
{
|
||||
setText("");
|
||||
hBox.getChildren().clear();
|
||||
Tooltip.install(this, new Tooltip(countryLocale.getDisplayCountry()));
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -299,12 +273,12 @@ public class OrderBookController implements Initializable, ChildController
|
||||
private void setBankAccountTypeColumnCellFactory()
|
||||
{
|
||||
bankAccountTypeColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper(offer.getValue()));
|
||||
bankAccountTypeColumn.setCellFactory(new Callback<TableColumn<OrderBookListItem, OrderBookListItem>, TableCell<OrderBookListItem, OrderBookListItem>>()
|
||||
bankAccountTypeColumn.setCellFactory(new Callback<TableColumn<String, OrderBookListItem>, TableCell<String, OrderBookListItem>>()
|
||||
{
|
||||
@Override
|
||||
public TableCell<OrderBookListItem, OrderBookListItem> call(TableColumn<OrderBookListItem, OrderBookListItem> directionColumn)
|
||||
public TableCell<String, OrderBookListItem> call(TableColumn<String, OrderBookListItem> directionColumn)
|
||||
{
|
||||
return new TableCell<OrderBookListItem, OrderBookListItem>()
|
||||
return new TableCell<String, OrderBookListItem>()
|
||||
{
|
||||
@Override
|
||||
public void updateItem(final OrderBookListItem orderBookListItem, boolean empty)
|
||||
@ -313,19 +287,8 @@ public class OrderBookController implements Initializable, ChildController
|
||||
|
||||
if (orderBookListItem != null)
|
||||
{
|
||||
List<BankAccountType.BankAccountTypeEnum> bankAccountTypeEnums = orderBookListItem.getOffer().getOfferConstraints().getBankAccountTypes();
|
||||
String text = "";
|
||||
int i = 0;
|
||||
for (BankAccountType.BankAccountTypeEnum bankAccountTypeEnum : bankAccountTypeEnums)
|
||||
{
|
||||
text += Localisation.get(bankAccountTypeEnum.toString());
|
||||
i++;
|
||||
if (i < bankAccountTypeEnums.size())
|
||||
text += ", ";
|
||||
}
|
||||
setText(text);
|
||||
if (text.length() > 20)
|
||||
Tooltip.install(this, new Tooltip(text));
|
||||
BankAccountType.BankAccountTypeEnum bankAccountTypeEnum = orderBookListItem.getOffer().getBankAccountTypeEnum();
|
||||
setText(Localisation.get(bankAccountTypeEnum.toString()));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -345,12 +308,12 @@ public class OrderBookController implements Initializable, ChildController
|
||||
{
|
||||
try
|
||||
{
|
||||
DecimalFormat decimalFormat = (DecimalFormat) DecimalFormat.getInstance(Settings.getLocale());
|
||||
DecimalFormat decimalFormat = (DecimalFormat) DecimalFormat.getInstance(Locale.getDefault());
|
||||
d = decimalFormat.parse(newValue).doubleValue();
|
||||
} catch (ParseException e)
|
||||
{
|
||||
amount.setText(oldValue);
|
||||
d = Converter.convertToDouble(oldValue);
|
||||
d = Converter.stringToDouble(oldValue);
|
||||
}
|
||||
}
|
||||
return d;
|
||||
@ -363,5 +326,23 @@ public class OrderBookController implements Initializable, ChildController
|
||||
volume.setText(Formatter.formatPrice(a * p));
|
||||
}
|
||||
|
||||
|
||||
// the scrollbar width is not handled correctly from the layout initially
|
||||
/* private void forceTableLayoutUpdate()
|
||||
{
|
||||
final List<OrderBookListItem> items = orderBookTable.getItems();
|
||||
if (items == null || items.size() == 0) return;
|
||||
|
||||
final OrderBookListItem item = orderBookTable.getItems().get(0);
|
||||
items.remove(0);
|
||||
Platform.runLater(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
items.add(0, item);
|
||||
}
|
||||
});
|
||||
} */
|
||||
}
|
||||
|
||||
|
@ -1,134 +0,0 @@
|
||||
package io.bitsquare.gui.trade.orderbook;
|
||||
|
||||
import io.bitsquare.gui.components.VSpacer;
|
||||
import io.bitsquare.gui.util.Icons;
|
||||
import io.bitsquare.settings.Settings;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ComboBox;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.Separator;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.FlowPane;
|
||||
import javafx.scene.layout.Pane;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class OrderBookFilterTextItemBuilder
|
||||
{
|
||||
|
||||
public static void build(Pane parent, String title, List<String> values, List<String> allValues)
|
||||
{
|
||||
final Pane pane = new Pane();
|
||||
pane.setPrefHeight(23);
|
||||
|
||||
final Label titleLabel = new Label(title);
|
||||
titleLabel.setLayoutY(4);
|
||||
titleLabel.setId("form-title");
|
||||
|
||||
FlowPane flowPane = new FlowPane();
|
||||
|
||||
double xPos = 170.0;
|
||||
double yPos = 5.0;
|
||||
|
||||
List<String> openValues = new ArrayList<>(allValues);
|
||||
openValues.removeAll(values);
|
||||
ObservableList<String> observableList = FXCollections.observableArrayList(openValues);
|
||||
Collections.sort(observableList);
|
||||
|
||||
ComboBox comboBox = new ComboBox(observableList);
|
||||
comboBox.setLayoutX(xPos);
|
||||
comboBox.setLayoutY(yPos);
|
||||
comboBox.setClip(Icons.getIconImageView(Icons.ADD));
|
||||
comboBox.setValue(Settings.getCurrency());
|
||||
|
||||
comboBox.valueProperty().addListener(new ChangeListener<Object>()
|
||||
{
|
||||
@Override
|
||||
public void changed(ObservableValue ov, Object oldValue, Object newValue)
|
||||
{
|
||||
if (newValue != null)
|
||||
{
|
||||
String value;
|
||||
if (newValue instanceof Currency)
|
||||
value = ((Currency) newValue).getCurrencyCode();
|
||||
else
|
||||
value = (String) newValue;
|
||||
|
||||
if (flowPane.getChildren().size() > 0)
|
||||
{
|
||||
Pane lastItem = (Pane) flowPane.getChildren().get(flowPane.getChildren().size() - 1);
|
||||
Button button = (Button) lastItem.getChildren().get(0);
|
||||
button.setText(button.getText().substring(0, button.getText().length() - 2) + ", ");
|
||||
}
|
||||
|
||||
addRemovableItem(flowPane, value + " ", observableList);
|
||||
comboBox.getSelectionModel().clearSelection();
|
||||
observableList.remove(newValue);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// combobox does not support icon (mask background with icon), so we need a graphic here
|
||||
ImageView addImageView = Icons.getIconImageView(Icons.ADD);
|
||||
addImageView.setLayoutX(xPos);
|
||||
addImageView.setLayoutY(yPos);
|
||||
addImageView.setMouseTransparent(true);
|
||||
|
||||
pane.getChildren().addAll(titleLabel, comboBox, addImageView);
|
||||
|
||||
Iterator<String> iterator = values.iterator();
|
||||
for (Iterator<String> stringIterator = iterator; stringIterator.hasNext(); )
|
||||
{
|
||||
String value = stringIterator.next();
|
||||
if (stringIterator.hasNext())
|
||||
addRemovableItem(flowPane, value + ", ", observableList);
|
||||
else
|
||||
addRemovableItem(flowPane, value + " ", observableList);
|
||||
}
|
||||
|
||||
parent.getChildren().addAll(pane, flowPane, new VSpacer(3), new Separator(), new VSpacer(10));
|
||||
}
|
||||
|
||||
private static void addRemovableItem(FlowPane flowPane, String text, ObservableList<String> observableList)
|
||||
{
|
||||
Pane pane = new Pane();
|
||||
|
||||
Button icon = new Button("", Icons.getIconImageView(Icons.REMOVE));
|
||||
icon.setStyle("-fx-background-color: transparent;");
|
||||
icon.setPadding(new Insets(-5.0, 0.0, 0.0, 0.0));
|
||||
icon.setVisible(false);
|
||||
|
||||
Button button = new Button(text);
|
||||
button.setStyle("-fx-background-color: transparent;");
|
||||
button.setPadding(new Insets(0.0, 0.0, 0.0, 0.0));
|
||||
|
||||
pane.setOnMouseEntered(e -> {
|
||||
icon.setVisible(true);
|
||||
icon.setLayoutX(button.getWidth() - 7);
|
||||
});
|
||||
pane.setOnMouseExited(e -> {
|
||||
icon.setVisible(false);
|
||||
icon.setLayoutX(0);
|
||||
});
|
||||
icon.setOnAction(e -> {
|
||||
flowPane.getChildren().remove(button.getParent());
|
||||
|
||||
observableList.add(text);
|
||||
Collections.sort(observableList);
|
||||
|
||||
if (flowPane.getChildren().size() > 0)
|
||||
{
|
||||
Pane lastItem = (Pane) flowPane.getChildren().get(flowPane.getChildren().size() - 1);
|
||||
Button lastButton = (Button) lastItem.getChildren().get(0);
|
||||
lastButton.setText(lastButton.getText().substring(0, lastButton.getText().length() - 2) + " ");
|
||||
}
|
||||
});
|
||||
pane.getChildren().addAll(button, icon);
|
||||
flowPane.getChildren().add(pane);
|
||||
}
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.geometry.*?>
|
||||
<?import javafx.scene.control.cell.PropertyValueFactory?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.control.cell.PropertyValueFactory?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<AnchorPane fx:id="holderPane" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0"
|
||||
AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" xmlns:fx="http://javafx.com/fxml/1"
|
||||
@ -40,27 +40,31 @@
|
||||
</children>
|
||||
</HBox>
|
||||
|
||||
<Button fx:id="createOfferButton" text="Create new offer" AnchorPane.topAnchor="10.0"
|
||||
AnchorPane.rightAnchor="10.0"/>
|
||||
|
||||
<TableView fx:id="orderBookTable" id="orderbook-table" AnchorPane.leftAnchor="10.0"
|
||||
AnchorPane.topAnchor="40.0" AnchorPane.bottomAnchor="10.0" AnchorPane.rightAnchor="10.0">
|
||||
AnchorPane.topAnchor="45.0" AnchorPane.bottomAnchor="10.0" AnchorPane.rightAnchor="10.0">
|
||||
<columns>
|
||||
<TableColumn text="Amount (Min.)" fx:id="amountColumn" prefWidth="120">
|
||||
<TableColumn text="Amount (Min.)" fx:id="amountColumn" minWidth="120">
|
||||
<cellValueFactory>
|
||||
<PropertyValueFactory property="amount"/>
|
||||
</cellValueFactory>
|
||||
</TableColumn>
|
||||
<TableColumn text="Price" fx:id="priceColumn" prefWidth="100">
|
||||
<TableColumn text="Price" fx:id="priceColumn" minWidth="70">
|
||||
<cellValueFactory>
|
||||
<PropertyValueFactory property="price"/>
|
||||
</cellValueFactory>
|
||||
</TableColumn>
|
||||
<TableColumn text="Volume (Min.)" fx:id="volumeColumn" prefWidth="160">
|
||||
<TableColumn text="Volume (Min.)" fx:id="volumeColumn" minWidth="130">
|
||||
<cellValueFactory>
|
||||
<PropertyValueFactory property="volume"/>
|
||||
</cellValueFactory>
|
||||
</TableColumn>
|
||||
<TableColumn text="Country" fx:id="countryColumn" prefWidth="100" sortable="false"/>
|
||||
<TableColumn text="Bank transfer type" fx:id="bankAccountTypeColumn" prefWidth="180"/>
|
||||
<TableColumn text="" fx:id="directionColumn" prefWidth="100" sortable="false"/>
|
||||
<TableColumn text="Country" fx:id="countryColumn" minWidth="60"/>
|
||||
<TableColumn text="Bank transfer type" fx:id="bankAccountTypeColumn" minWidth="140"/>
|
||||
<TableColumn text="" fx:id="directionColumn" minWidth="80" sortable="false"/>
|
||||
|
||||
</columns>
|
||||
</TableView>
|
||||
|
||||
|
@ -45,7 +45,7 @@ public class TradeProcessController implements Initializable, ChildController
|
||||
private TextField amountTextField;
|
||||
private Label offererPubKeyLabel, offererAccountPrimaryID, offererAccountSecondaryIDLabel,
|
||||
offererAccountHolderNameLabel, feedbackLabel, infoLabel, totalLabel, volumeLabel, totalToPayLabel,
|
||||
totalToReceiveLabel, collateralLabel1, collateralLabel2, amountLabel;
|
||||
/*totalToReceiveLabel,*/ amountLabel;
|
||||
private Pane progressPane;
|
||||
private ProgressBar progressBar;
|
||||
private ProgressIndicator progressIndicator;
|
||||
@ -90,7 +90,7 @@ public class TradeProcessController implements Initializable, ChildController
|
||||
|
||||
private void trade()
|
||||
{
|
||||
double requestedAmount = Converter.convertToDouble(amountTextField.getText());
|
||||
double requestedAmount = Converter.stringToDouble(amountTextField.getText());
|
||||
if (requestedAmount <= offer.getAmount() && requestedAmount >= offer.getMinAmount())
|
||||
{
|
||||
amountTextField.setEditable(false);
|
||||
@ -137,7 +137,7 @@ public class TradeProcessController implements Initializable, ChildController
|
||||
{
|
||||
trading.sendTakeOfferRequest(trade);
|
||||
feedbackLabel.setText("Request take offer confirmation from peer.");
|
||||
Utils.setTimeout(500, (AnimationTimer animationTimer) -> {
|
||||
GUIUtils.setTimeout(500, (AnimationTimer animationTimer) -> {
|
||||
onTakeOfferRequestConfirmed();
|
||||
progressBar.setProgress(1.0 / 3.0);
|
||||
return null;
|
||||
@ -149,7 +149,7 @@ public class TradeProcessController implements Initializable, ChildController
|
||||
trading.payOfferFee(trade);
|
||||
|
||||
feedbackLabel.setText("Request offer fee payment confirmation from peer.");
|
||||
Utils.setTimeout(500, (AnimationTimer animationTimer) -> {
|
||||
GUIUtils.setTimeout(500, (AnimationTimer animationTimer) -> {
|
||||
onOfferFeePaymentConfirmed();
|
||||
progressBar.setProgress(2.0 / 3.0);
|
||||
return null;
|
||||
@ -160,7 +160,7 @@ public class TradeProcessController implements Initializable, ChildController
|
||||
{
|
||||
trading.requestOffererDetailData();
|
||||
feedbackLabel.setText("Request detail data from peer.");
|
||||
Utils.setTimeout(500, (AnimationTimer animationTimer) -> {
|
||||
GUIUtils.setTimeout(500, (AnimationTimer animationTimer) -> {
|
||||
onUserDetailsReceived();
|
||||
progressBar.setProgress(1.0);
|
||||
return null;
|
||||
@ -187,7 +187,7 @@ public class TradeProcessController implements Initializable, ChildController
|
||||
infoLabel = new Label("Wait for Bank transfer.");
|
||||
vBox.getChildren().addAll(infoLabel);
|
||||
|
||||
Utils.setTimeout(2000, (AnimationTimer animationTimer) -> {
|
||||
GUIUtils.setTimeout(2000, (AnimationTimer animationTimer) -> {
|
||||
onBankTransferInited();
|
||||
return null;
|
||||
});
|
||||
@ -218,7 +218,7 @@ public class TradeProcessController implements Initializable, ChildController
|
||||
summaryGridPane.setPadding(new Insets(5, 5, 5, 5));
|
||||
|
||||
FormBuilder.addLabel(summaryGridPane, "You have payed:", getTotalToPay(), ++row);
|
||||
FormBuilder.addLabel(summaryGridPane, "You have received:\n ", getTotalToReceive(), ++row);
|
||||
// FormBuilder.addLabel(summaryGridPane, "You have received:\n ", getTotalToReceive(), ++row);
|
||||
|
||||
TitledPane summaryTitlePane = new TitledPane("Trade summary:", summaryGridPane);
|
||||
summaryTitlePane.setCollapsible(false);
|
||||
@ -235,7 +235,6 @@ public class TradeProcessController implements Initializable, ChildController
|
||||
|
||||
private void buildStep1()
|
||||
{
|
||||
OfferConstraints offerConstraints = offer.getOfferConstraints();
|
||||
User taker = contract.getTaker();
|
||||
User offerer = contract.getOfferer();
|
||||
|
||||
@ -245,13 +244,13 @@ public class TradeProcessController implements Initializable, ChildController
|
||||
offerDetailsGridPane.setHgap(5);
|
||||
offerDetailsGridPane.setPadding(new Insets(5, 5, 5, 5));
|
||||
|
||||
amountTextField = FormBuilder.addInputField(offerDetailsGridPane, "Amount (BTC):", Formatter.formatAmount(getAmount()), ++row);
|
||||
amountTextField = FormBuilder.addTextField(offerDetailsGridPane, "Amount (BTC):", Formatter.formatAmount(getAmount()), ++row);
|
||||
amountTextField.textProperty().addListener(e -> {
|
||||
setTotal();
|
||||
setVolume();
|
||||
setCollateral();
|
||||
//setCollateral();
|
||||
totalToPayLabel.setText(getTotalToPay());
|
||||
totalToReceiveLabel.setText(getTotalToReceive());
|
||||
// totalToReceiveLabel.setText(getTotalToReceive());
|
||||
amountLabel.setText(amountTextField.getText());
|
||||
|
||||
});
|
||||
@ -261,11 +260,10 @@ public class TradeProcessController implements Initializable, ChildController
|
||||
FormBuilder.addLabel(offerDetailsGridPane, "Price:", Formatter.formatPriceWithCurrencyPair(offer.getPrice(), offer.getCurrency()), ++row);
|
||||
totalLabel = FormBuilder.addLabel(offerDetailsGridPane, "Total:", "", ++row);
|
||||
setTotal();
|
||||
collateralLabel1 = FormBuilder.addLabel(offerDetailsGridPane, "Collateral:", Formatter.formatCollateral(offer.getOfferConstraints().getCollateral(), getAmount()), ++row);
|
||||
FormBuilder.addLabel(offerDetailsGridPane, "Offer fee:", Formatter.formatSatoshis(Fees.OFFER_CREATION_FEE, true), ++row);
|
||||
FormBuilder.addVSpacer(offerDetailsGridPane, ++row);
|
||||
totalToPayLabel = FormBuilder.addLabel(offerDetailsGridPane, "You pay:", getTotalToPay(), ++row);
|
||||
totalToReceiveLabel = FormBuilder.addLabel(offerDetailsGridPane, "You receive:\n ", getTotalToReceive(), ++row);
|
||||
// totalToReceiveLabel = FormBuilder.addLabel(offerDetailsGridPane, "You receive:\n ", getTotalToReceive(), ++row);
|
||||
|
||||
offerDetailsTitlePane = new TitledPane(takerIsSelling() ? "Sell Bitcoin" : "Buy Bitcoin", offerDetailsGridPane);
|
||||
offerDetailsTitlePane.setCollapsible(false);
|
||||
@ -286,10 +284,9 @@ public class TradeProcessController implements Initializable, ChildController
|
||||
volumeLabel = FormBuilder.addLabel(contractGridPane, "Volume:", "", ++row);
|
||||
setVolume();
|
||||
FormBuilder.addLabel(contractGridPane, "Price:", Formatter.formatPriceWithCurrencyPair(offer.getPrice(), offer.getCurrency()), ++row);
|
||||
collateralLabel2 = FormBuilder.addLabel(contractGridPane, "Collateral:", "", ++row);
|
||||
setCollateral();
|
||||
// FormBuilder.addLabel(contractGridPane, "Language:", Formatter.formatList(offerConstraints.getLanguageLocales()), ++row);
|
||||
FormBuilder.addLabel(contractGridPane, "Arbitrator:", offerConstraints.getArbitrator(), ++row);
|
||||
//setCollateral();
|
||||
// FormBuilder.addLabel(contractGridPane, "Language:", Formatter.formatList(offerConstraints.getAcceptedLanguageLocales()), ++row);
|
||||
// FormBuilder.addLabel(contractGridPane, "Arbitrator:", offerConstraints.getArbitrator(), ++row);
|
||||
// FormBuilder.addLabel(contractGridPane, "Identity verification:", Formatter.formatList(offerConstraints.getIdentityVerifications()), ++row);
|
||||
FormBuilder.addLabel(contractGridPane, "Bank transfer reference ID:", "Purchase xyz 01.04.2014", ++row);
|
||||
|
||||
@ -299,8 +296,8 @@ public class TradeProcessController implements Initializable, ChildController
|
||||
FormBuilder.addLabel(contractGridPane, "Messaging ID:", offerer.getMessageID(), ++row);
|
||||
//FormBuilder.addLabel(contractGridPane, "Country:", offerer.getCountry(), ++row);
|
||||
offererPubKeyLabel = FormBuilder.addLabel(contractGridPane, "Payment public key:", contract.getOffererPubKey(), ++row);
|
||||
FormBuilder.addLabel(contractGridPane, "Bank transfer type:", offerer.getCurrentBankAccount().getBankAccountType().toString(), ++row);
|
||||
offererAccountPrimaryID = FormBuilder.addLabel(contractGridPane, "Bank account IBAN:", offerer.getCurrentBankAccount().getAccountPrimaryID(), ++row);
|
||||
// FormBuilder.addLabel(contractGridPane, "Bank transfer type:", offerer.getCurrentBankAccount().getBankAccountType().toString(), ++row);
|
||||
// offererAccountPrimaryID = FormBuilder.addLabel(contractGridPane, "Bank account IBAN:", offerer.getCurrentBankAccount().getAccountPrimaryID(), ++row);
|
||||
offererAccountSecondaryIDLabel = FormBuilder.addLabel(contractGridPane, "Bank account BIC:", offerer.getCurrentBankAccount().getAccountSecondaryID(), ++row);
|
||||
offererAccountHolderNameLabel = FormBuilder.addLabel(contractGridPane, "Bank account holder:", offerer.getCurrentBankAccount().getAccountHolderName(), ++row);
|
||||
|
||||
@ -352,7 +349,7 @@ public class TradeProcessController implements Initializable, ChildController
|
||||
|
||||
private double getVolume()
|
||||
{
|
||||
return offer.getPrice() * Converter.convertToDouble(amountTextField.getText());
|
||||
return offer.getPrice() * Converter.stringToDouble(amountTextField.getText());
|
||||
}
|
||||
|
||||
private double getAmount()
|
||||
@ -365,40 +362,40 @@ public class TradeProcessController implements Initializable, ChildController
|
||||
String result = "";
|
||||
if (takerIsSelling())
|
||||
{
|
||||
double btcValue = Converter.convertToDouble(amountTextField.getText()) + BtcFormatter.satoshiToBTC(Fees.OFFER_CREATION_FEE) +
|
||||
offer.getOfferConstraints().getCollateral() * Converter.convertToDouble(amountTextField.getText());
|
||||
double btcValue = Converter.stringToDouble(amountTextField.getText()) + BtcFormatter.satoshiToBTC(Fees.OFFER_CREATION_FEE)/* +
|
||||
offer.getConstraints().getCollateral() * Converter.stringToDouble(amountTextField.getText())*/;
|
||||
result = Formatter.formatAmount(btcValue, true, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
double btcValue = BtcFormatter.satoshiToBTC(Fees.OFFER_CREATION_FEE) + offer.getOfferConstraints().getCollateral() * Converter.convertToDouble(amountTextField.getText());
|
||||
double btcValue = BtcFormatter.satoshiToBTC(Fees.OFFER_CREATION_FEE) /*+ offer.getConstraints().getCollateral() * Converter.stringToDouble(amountTextField.getText())*/;
|
||||
result = Formatter.formatAmount(btcValue, true, true) + "\n" + Formatter.formatVolume(getVolume(), offer.getCurrency());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private String getTotalToReceive()
|
||||
/*private String getTotalToReceive()
|
||||
{
|
||||
String result = "";
|
||||
if (takerIsSelling())
|
||||
{
|
||||
double btcValue = offer.getOfferConstraints().getCollateral() * Converter.convertToDouble(amountTextField.getText());
|
||||
double btcValue = offer.getConstraints().getCollateral() * Converter.stringToDouble(amountTextField.getText());
|
||||
result = Formatter.formatAmount(btcValue, true, true) + "\n" + Formatter.formatVolume(getVolume(), offer.getCurrency());
|
||||
}
|
||||
else
|
||||
{
|
||||
double btcValue = Converter.convertToDouble(amountTextField.getText()) +
|
||||
offer.getOfferConstraints().getCollateral() * Converter.convertToDouble(amountTextField.getText());
|
||||
double btcValue = Converter.stringToDouble(amountTextField.getText()) +
|
||||
offer.getConstraints().getCollateral() * Converter.stringToDouble(amountTextField.getText());
|
||||
result = Formatter.formatAmount(btcValue, true, true);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
} */
|
||||
|
||||
public void setCollateral()
|
||||
/*public void setCollateral()
|
||||
{
|
||||
String value = Formatter.formatCollateral(offer.getOfferConstraints().getCollateral(), Converter.convertToDouble(amountTextField.getText()));
|
||||
String value = Formatter.formatCollateral(offer.getConstraints().getCollateral(), Converter.stringToDouble(amountTextField.getText()));
|
||||
collateralLabel1.setText(value);
|
||||
collateralLabel2.setText(value);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
|
@ -1,23 +1,27 @@
|
||||
package io.bitsquare.gui.util;
|
||||
|
||||
import io.bitsquare.settings.Settings;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.ParseException;
|
||||
import java.util.Locale;
|
||||
|
||||
public class Converter
|
||||
{
|
||||
public static double convertToDouble(String input)
|
||||
private static final Logger log = LoggerFactory.getLogger(Converter.class);
|
||||
|
||||
public static double stringToDouble(String input)
|
||||
{
|
||||
try
|
||||
{
|
||||
DecimalFormat decimalFormat = (DecimalFormat) DecimalFormat.getInstance(Settings.getLocale());
|
||||
DecimalFormat decimalFormat = (DecimalFormat) DecimalFormat.getInstance(Locale.getDefault());
|
||||
return decimalFormat.parse(input).doubleValue();
|
||||
} catch (ParseException e)
|
||||
{
|
||||
//e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
|
||||
log.warn(e.toString());
|
||||
}
|
||||
return 0.0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
package io.bitsquare.gui.util;
|
||||
|
||||
import io.bitsquare.btc.WalletFacade;
|
||||
import io.bitsquare.gui.components.VSpacer;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ComboBox;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.GridPane;
|
||||
|
||||
import java.util.List;
|
||||
@ -20,18 +20,32 @@ public class FormBuilder
|
||||
return valueLabel;
|
||||
}
|
||||
|
||||
public static void addHeaderLabel(GridPane gridPane, String title, int row)
|
||||
public static Label addHeaderLabel(GridPane gridPane, String title, int row)
|
||||
{
|
||||
Label headerLabel = new Label(title);
|
||||
headerLabel.setId("form-header-text");
|
||||
gridPane.add(headerLabel, 0, row);
|
||||
return headerLabel;
|
||||
}
|
||||
|
||||
public static TextField addInputField(GridPane gridPane, String title, String value, int row)
|
||||
{
|
||||
return addTextField(gridPane, title, value, row, true, true);
|
||||
}
|
||||
|
||||
public static TextField addTextField(GridPane gridPane, String title, String value, int row)
|
||||
{
|
||||
return addTextField(gridPane, title, value, row, false, false);
|
||||
}
|
||||
|
||||
|
||||
public static TextField addTextField(GridPane gridPane, String title, String value, int row, boolean editable, boolean selectable)
|
||||
{
|
||||
gridPane.add(new Label(title), 0, row);
|
||||
TextField textField = new TextField(value);
|
||||
gridPane.add(textField, 1, row);
|
||||
textField.setMouseTransparent(!selectable && !editable);
|
||||
textField.setEditable(editable);
|
||||
return textField;
|
||||
}
|
||||
|
||||
@ -54,4 +68,49 @@ public class FormBuilder
|
||||
gridPane.add(comboBox, 1, row);
|
||||
return comboBox;
|
||||
}
|
||||
|
||||
|
||||
public static TextField addConfirmationsLabel(GridPane gridPane, WalletFacade walletFacade, int row)
|
||||
{
|
||||
return FormBuilder.addTextField(gridPane, "Confirmations:", getConfirmationText(walletFacade), row);
|
||||
}
|
||||
|
||||
public static ProgressIndicator addConfirmationsSpinner(GridPane gridPane, WalletFacade walletFacade, int row)
|
||||
{
|
||||
ProgressIndicator progressIndicator = new ProgressIndicator();
|
||||
gridPane.add(progressIndicator, 3, row);
|
||||
progressIndicator.setPrefSize(18, 18);
|
||||
if (walletFacade.getRegConfDepthInBlocks() == 0)
|
||||
progressIndicator.setProgress(-1);
|
||||
else
|
||||
progressIndicator.setOpacity(0);
|
||||
|
||||
return progressIndicator;
|
||||
}
|
||||
|
||||
public static ImageView addConfirmationsIcon(GridPane gridPane, WalletFacade walletFacade, int row)
|
||||
{
|
||||
int depthInBlocks = walletFacade.getRegConfNumBroadcastPeers();
|
||||
int numBroadcastPeers = walletFacade.getRegConfDepthInBlocks();
|
||||
|
||||
Image confirmIconImage;
|
||||
if (depthInBlocks > 0)
|
||||
confirmIconImage = Icons.getIconImage(Icons.getIconIDForConfirmations(depthInBlocks));
|
||||
else
|
||||
confirmIconImage = Icons.getIconImage(Icons.getIconIDForPeersSeenTx(numBroadcastPeers));
|
||||
|
||||
ImageView confirmIconImageView = new ImageView(confirmIconImage);
|
||||
gridPane.add(confirmIconImageView, 2, row);
|
||||
|
||||
return confirmIconImageView;
|
||||
}
|
||||
|
||||
public static String getConfirmationText(WalletFacade walletFacade)
|
||||
{
|
||||
int numBroadcastPeers = walletFacade.getRegConfNumBroadcastPeers();
|
||||
int depthInBlocks = walletFacade.getRegConfDepthInBlocks();
|
||||
return depthInBlocks + " confirmation(s) / " + "Seen by " + numBroadcastPeers + " peer(s)";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,13 +1,13 @@
|
||||
package io.bitsquare.gui.util;
|
||||
|
||||
import io.bitsquare.btc.BtcFormatter;
|
||||
import io.bitsquare.settings.Settings;
|
||||
import io.bitsquare.trade.Direction;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.Currency;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
public class Formatter
|
||||
{
|
||||
@ -111,7 +111,7 @@ public class Formatter
|
||||
|
||||
public static DecimalFormat getDecimalFormat(int fractionDigits)
|
||||
{
|
||||
DecimalFormat decimalFormat = (DecimalFormat) DecimalFormat.getInstance(Settings.getLocale());
|
||||
DecimalFormat decimalFormat = (DecimalFormat) DecimalFormat.getInstance(Locale.getDefault());
|
||||
decimalFormat.setMinimumFractionDigits(fractionDigits);
|
||||
decimalFormat.setMaximumFractionDigits(fractionDigits);
|
||||
decimalFormat.setGroupingUsed(false);
|
||||
@ -123,4 +123,32 @@ public class Formatter
|
||||
return value * 100 + "%";
|
||||
}
|
||||
|
||||
public static String countryLocalesToString(List<Locale> countryLocales)
|
||||
{
|
||||
String result = "";
|
||||
int i = 0;
|
||||
for (Locale locale : countryLocales)
|
||||
{
|
||||
result += locale.getCountry();
|
||||
i++;
|
||||
if (i < countryLocales.size())
|
||||
result += ", ";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static String languageLocalesToString(List<Locale> languageLocales)
|
||||
{
|
||||
String result = "";
|
||||
int i = 0;
|
||||
for (Locale locale : languageLocales)
|
||||
{
|
||||
result += locale.getDisplayLanguage();
|
||||
i++;
|
||||
if (i < languageLocales.size())
|
||||
result += ", ";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import javafx.animation.AnimationTimer;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
public class Utils
|
||||
public class GUIUtils
|
||||
{
|
||||
/**
|
||||
* @param delay in milliseconds
|
@ -1,194 +1,65 @@
|
||||
package io.bitsquare.settings;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import io.bitsquare.bank.BankAccountType;
|
||||
import io.bitsquare.storage.Storage;
|
||||
import io.bitsquare.trade.orderbook.OrderBookFilter;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Predicate;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
public class Settings
|
||||
public class Settings implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 7995048077355006861L;
|
||||
|
||||
public static Locale locale = Locale.ENGLISH;
|
||||
public static Currency currency = Currency.getInstance("USD");
|
||||
|
||||
|
||||
private Storage storage;
|
||||
private OrderBookFilter orderBookFilter;
|
||||
|
||||
public static Locale getLocale()
|
||||
{
|
||||
return Settings.locale;
|
||||
}
|
||||
|
||||
public static Currency getCurrency()
|
||||
{
|
||||
return Settings.currency;
|
||||
}
|
||||
private List<Locale> acceptedLanguageLocales = new ArrayList<>();
|
||||
private List<Locale> acceptedCountryLocales = new ArrayList<>();
|
||||
|
||||
@Inject
|
||||
public Settings(Storage storage, OrderBookFilter orderBookFilter)
|
||||
public Settings()
|
||||
{
|
||||
this.storage = storage;
|
||||
this.orderBookFilter = orderBookFilter;
|
||||
|
||||
|
||||
locale = Locale.ENGLISH;
|
||||
currency = Currency.getInstance("USD");
|
||||
|
||||
currency = (Currency) storage.read("Settings.currency");
|
||||
if (currency == null)
|
||||
currency = Currency.getInstance("USD");
|
||||
}
|
||||
|
||||
public ArrayList<Locale> getAllLocales()
|
||||
public void updateFromStorage(Settings savedSettings)
|
||||
{
|
||||
ArrayList<Locale> list = new ArrayList<Locale>(Arrays.asList(Locale.getAvailableLocales()));
|
||||
list.removeIf(new Predicate<Locale>()
|
||||
if (savedSettings != null)
|
||||
{
|
||||
@Override
|
||||
public boolean test(Locale locale)
|
||||
{
|
||||
return locale == null || locale.getCountry().equals("") || locale.getLanguage().equals("");
|
||||
}
|
||||
});
|
||||
acceptedLanguageLocales = savedSettings.getAcceptedLanguageLocales();
|
||||
|
||||
list.sort(new Comparator<Locale>()
|
||||
{
|
||||
@Override
|
||||
public int compare(Locale locale1, Locale locale2)
|
||||
{
|
||||
return locale1.getDisplayCountry().compareTo(locale2.getDisplayCountry());
|
||||
}
|
||||
});
|
||||
|
||||
Locale defaultLocale = Locale.getDefault();
|
||||
list.remove(defaultLocale);
|
||||
list.add(0, defaultLocale);
|
||||
|
||||
return list;
|
||||
acceptedCountryLocales = savedSettings.getAcceptedCountryLocales();
|
||||
}
|
||||
}
|
||||
|
||||
public List<Currency> getAllCurrencies()
|
||||
public void addAcceptedLanguageLocale(Locale locale)
|
||||
{
|
||||
ArrayList<Currency> mainCurrencies = new ArrayList<>();
|
||||
mainCurrencies.add(Currency.getInstance("USD"));
|
||||
mainCurrencies.add(Currency.getInstance("EUR"));
|
||||
mainCurrencies.add(Currency.getInstance("CNY"));
|
||||
mainCurrencies.add(Currency.getInstance("RUB"));
|
||||
mainCurrencies.add(Currency.getInstance("JPY"));
|
||||
mainCurrencies.add(Currency.getInstance("GBP"));
|
||||
mainCurrencies.add(Currency.getInstance("CAD"));
|
||||
mainCurrencies.add(Currency.getInstance("AUD"));
|
||||
mainCurrencies.add(Currency.getInstance("CHF"));
|
||||
mainCurrencies.add(Currency.getInstance("CNY"));
|
||||
|
||||
Set<Currency> allCurrenciesSet = Currency.getAvailableCurrencies();
|
||||
|
||||
allCurrenciesSet.removeAll(mainCurrencies);
|
||||
List<Currency> allCurrenciesList = new ArrayList<>(allCurrenciesSet);
|
||||
allCurrenciesList.sort(new Comparator<Currency>()
|
||||
{
|
||||
@Override
|
||||
public int compare(Currency a, Currency b)
|
||||
{
|
||||
return a.getCurrencyCode().compareTo(b.getCurrencyCode());
|
||||
}
|
||||
});
|
||||
|
||||
List<Currency> resultList = new ArrayList<>(mainCurrencies);
|
||||
resultList.addAll(allCurrenciesList);
|
||||
Currency defaultCurrency = Currency.getInstance(Locale.getDefault());
|
||||
resultList.remove(defaultCurrency);
|
||||
resultList.add(0, defaultCurrency);
|
||||
|
||||
return resultList;
|
||||
acceptedLanguageLocales.add(locale);
|
||||
}
|
||||
|
||||
public ArrayList<BankAccountType.BankAccountTypeEnum> getAllBankAccountTypeEnums()
|
||||
public void addAcceptedCountryLocale(Locale locale)
|
||||
{
|
||||
ArrayList<BankAccountType.BankAccountTypeEnum> bankAccountTypeEnums = new ArrayList<>();
|
||||
bankAccountTypeEnums.add(BankAccountType.BankAccountTypeEnum.SEPA);
|
||||
bankAccountTypeEnums.add(BankAccountType.BankAccountTypeEnum.WIRE);
|
||||
bankAccountTypeEnums.add(BankAccountType.BankAccountTypeEnum.INTERNATIONAL);
|
||||
bankAccountTypeEnums.add(BankAccountType.BankAccountTypeEnum.OK_PAY);
|
||||
bankAccountTypeEnums.add(BankAccountType.BankAccountTypeEnum.NET_TELLER);
|
||||
bankAccountTypeEnums.add(BankAccountType.BankAccountTypeEnum.PERFECT_MONEY);
|
||||
bankAccountTypeEnums.add(BankAccountType.BankAccountTypeEnum.OTHER);
|
||||
return bankAccountTypeEnums;
|
||||
acceptedCountryLocales.add(locale);
|
||||
}
|
||||
|
||||
public ArrayList<BankAccountType> getAllBankAccountTypes()
|
||||
//setters
|
||||
public void setAcceptedLanguageLocales(List<Locale> acceptedLanguageLocales)
|
||||
{
|
||||
ArrayList<BankAccountType> bankTransferTypes = new ArrayList<>();
|
||||
bankTransferTypes.add(new BankAccountType(BankAccountType.BankAccountTypeEnum.SEPA, "IBAN", "BIC"));
|
||||
bankTransferTypes.add(new BankAccountType(BankAccountType.BankAccountTypeEnum.WIRE, "Prim_todo", "Sec_todo"));
|
||||
bankTransferTypes.add(new BankAccountType(BankAccountType.BankAccountTypeEnum.INTERNATIONAL, "Prim_todo", "Sec_todo"));
|
||||
bankTransferTypes.add(new BankAccountType(BankAccountType.BankAccountTypeEnum.OK_PAY, "Prim_todo", "Sec_todo"));
|
||||
bankTransferTypes.add(new BankAccountType(BankAccountType.BankAccountTypeEnum.NET_TELLER, "Prim_todo", "Sec_todo"));
|
||||
bankTransferTypes.add(new BankAccountType(BankAccountType.BankAccountTypeEnum.PERFECT_MONEY, "Prim_todo", "Sec_todo"));
|
||||
bankTransferTypes.add(new BankAccountType(BankAccountType.BankAccountTypeEnum.OTHER, "Prim_todo", "Sec_todo"));
|
||||
return bankTransferTypes;
|
||||
this.acceptedLanguageLocales = acceptedLanguageLocales;
|
||||
}
|
||||
|
||||
public void setAcceptedCountryLocales(List<Locale> acceptedCountryLocales)
|
||||
{
|
||||
this.acceptedCountryLocales = acceptedCountryLocales;
|
||||
}
|
||||
|
||||
//getters
|
||||
public List<Locale> getAcceptedLanguageLocales()
|
||||
{
|
||||
return acceptedLanguageLocales;
|
||||
}
|
||||
|
||||
|
||||
public ArrayList<String> getAllArbitrators()
|
||||
public List<Locale> getAcceptedCountryLocales()
|
||||
{
|
||||
ArrayList<String> arbitrators = new ArrayList<>();
|
||||
arbitrators.add("Paysty pool 1");
|
||||
arbitrators.add("Paysty pool 2");
|
||||
arbitrators.add("Paysty pool 3");
|
||||
arbitrators.add("Paysty pool 4");
|
||||
return arbitrators;
|
||||
}
|
||||
|
||||
public ArrayList<String> getAllIdentityVerifications()
|
||||
{
|
||||
ArrayList<String> identityVerifications = new ArrayList<>();
|
||||
identityVerifications.add("Passport");
|
||||
identityVerifications.add("PGP");
|
||||
identityVerifications.add("BTC-OTC");
|
||||
identityVerifications.add("Bitcointalk");
|
||||
identityVerifications.add("Reddit");
|
||||
identityVerifications.add("Skype");
|
||||
identityVerifications.add("Google+");
|
||||
identityVerifications.add("Twitter");
|
||||
identityVerifications.add("Diaspora");
|
||||
identityVerifications.add("Facebook");
|
||||
identityVerifications.add("Jabber");
|
||||
identityVerifications.add("Other");
|
||||
identityVerifications.add("Any");
|
||||
identityVerifications.add("None");
|
||||
return identityVerifications;
|
||||
}
|
||||
|
||||
public ArrayList<String> getAllCollaterals()
|
||||
{
|
||||
ArrayList<String> list = new ArrayList<>();
|
||||
list.add("0.01");
|
||||
list.add("0.1");
|
||||
list.add("0.5");
|
||||
list.add("1.0");
|
||||
return list;
|
||||
}
|
||||
|
||||
public void setCurrency(Currency currency)
|
||||
{
|
||||
Settings.currency = currency;
|
||||
storage.write("Settings.currency", currency);
|
||||
}
|
||||
|
||||
|
||||
public void setLocale(Locale locale)
|
||||
{
|
||||
Settings.locale = locale;
|
||||
}
|
||||
|
||||
public OrderBookFilter getOrderBookFilter()
|
||||
{
|
||||
return orderBookFilter;
|
||||
return acceptedCountryLocales;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,32 +0,0 @@
|
||||
package io.bitsquare.settings;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import io.bitsquare.storage.Storage;
|
||||
import io.bitsquare.trade.Direction;
|
||||
import io.bitsquare.trade.orderbook.OrderBookFilter;
|
||||
import io.bitsquare.user.User;
|
||||
|
||||
public class Startup
|
||||
{
|
||||
private Storage storage;
|
||||
private User user;
|
||||
private OrderBookFilter orderBookFilter;
|
||||
|
||||
@Inject
|
||||
public Startup(Storage storage, OrderBookFilter orderBookFilter)
|
||||
{
|
||||
this.storage = storage;
|
||||
this.orderBookFilter = orderBookFilter;
|
||||
}
|
||||
|
||||
public void applyPersistedData()
|
||||
{
|
||||
|
||||
|
||||
// todo use persistence
|
||||
orderBookFilter.setAmount(0.0);
|
||||
orderBookFilter.setPrice(0.0);
|
||||
orderBookFilter.setDirection(Direction.BUY);
|
||||
orderBookFilter.setCurrency(Settings.getCurrency());
|
||||
}
|
||||
}
|
@ -33,10 +33,6 @@ public class Storage
|
||||
}
|
||||
}
|
||||
|
||||
public void saveUser(User user)
|
||||
{
|
||||
write(user.getClass().getName(), user);
|
||||
}
|
||||
|
||||
public void updateUserFromStorage(User user)
|
||||
{
|
||||
@ -47,7 +43,7 @@ public class Storage
|
||||
|
||||
public void write(String key, Object value)
|
||||
{
|
||||
log.info("Write object with key = " + key + " / value = " + value);
|
||||
//log.info("Write object with key = " + key + " / value = " + value);
|
||||
dataVO.dict.put(key, value);
|
||||
writeDataVO(dataVO);
|
||||
}
|
||||
@ -56,7 +52,7 @@ public class Storage
|
||||
{
|
||||
dataVO = readDataVO();
|
||||
Object result = dataVO.dict.get(key);
|
||||
log.info("Read object with key = " + key + " result = " + result);
|
||||
//log.info("Read object with key = " + key + " result = " + result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,10 @@
|
||||
package io.bitsquare.trade;
|
||||
|
||||
import io.bitsquare.user.User;
|
||||
import io.bitsquare.bank.BankAccountType;
|
||||
|
||||
import java.util.Currency;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.UUID;
|
||||
|
||||
public class Offer
|
||||
@ -11,28 +13,110 @@ public class Offer
|
||||
private double price;
|
||||
private double amount;
|
||||
private double minAmount;
|
||||
private Direction direction;
|
||||
private Currency currency;
|
||||
private User offerer;
|
||||
private OfferConstraints offerConstraints;
|
||||
|
||||
public Offer(UUID uid,
|
||||
|
||||
private String accountID;
|
||||
private String messageID;
|
||||
private Direction direction;
|
||||
private BankAccountType.BankAccountTypeEnum bankAccountTypeEnum;
|
||||
private Currency currency;
|
||||
private Locale bankAccountCountryLocale;
|
||||
private List<Locale> acceptedCountryLocales;
|
||||
private List<Locale> acceptedLanguageLocales;
|
||||
private String offerPaymentTxID;
|
||||
|
||||
public Offer(String accountID,
|
||||
String messageID,
|
||||
Direction direction,
|
||||
double price,
|
||||
double amount,
|
||||
double minAmount,
|
||||
BankAccountType.BankAccountTypeEnum bankAccountTypeEnum,
|
||||
Currency currency,
|
||||
User offerer,
|
||||
OfferConstraints offerConstraints)
|
||||
Locale bankAccountCountryLocale,
|
||||
List<Locale> acceptedCountryLocales,
|
||||
List<Locale> acceptedLanguageLocales)
|
||||
{
|
||||
this.uid = uid;
|
||||
this.accountID = accountID;
|
||||
this.messageID = messageID;
|
||||
this.direction = direction;
|
||||
this.price = price;
|
||||
this.amount = amount;
|
||||
this.minAmount = minAmount;
|
||||
this.bankAccountTypeEnum = bankAccountTypeEnum;
|
||||
this.currency = currency;
|
||||
this.offerer = offerer;
|
||||
this.offerConstraints = offerConstraints;
|
||||
this.bankAccountCountryLocale = bankAccountCountryLocale;
|
||||
this.acceptedCountryLocales = acceptedCountryLocales;
|
||||
this.acceptedLanguageLocales = acceptedLanguageLocales;
|
||||
|
||||
uid = UUID.randomUUID();
|
||||
}
|
||||
|
||||
// setter
|
||||
public void setOfferPaymentTxID(String offerPaymentTxID)
|
||||
{
|
||||
this.offerPaymentTxID = offerPaymentTxID;
|
||||
}
|
||||
|
||||
// getters
|
||||
public String getAccountID()
|
||||
{
|
||||
return accountID;
|
||||
}
|
||||
|
||||
public String getMessageID()
|
||||
{
|
||||
return messageID;
|
||||
}
|
||||
|
||||
public UUID getUid()
|
||||
{
|
||||
return uid;
|
||||
}
|
||||
|
||||
public double getPrice()
|
||||
{
|
||||
return price;
|
||||
}
|
||||
|
||||
public double getAmount()
|
||||
{
|
||||
return amount;
|
||||
}
|
||||
|
||||
public double getMinAmount()
|
||||
{
|
||||
return minAmount;
|
||||
}
|
||||
|
||||
public Direction getDirection()
|
||||
{
|
||||
return direction;
|
||||
}
|
||||
|
||||
public BankAccountType.BankAccountTypeEnum getBankAccountTypeEnum()
|
||||
{
|
||||
return bankAccountTypeEnum;
|
||||
}
|
||||
|
||||
public Currency getCurrency()
|
||||
{
|
||||
return currency;
|
||||
}
|
||||
|
||||
public Locale getBankAccountCountryLocale()
|
||||
{
|
||||
return bankAccountCountryLocale;
|
||||
}
|
||||
|
||||
public List<Locale> getAcceptedCountryLocales()
|
||||
{
|
||||
return acceptedCountryLocales;
|
||||
}
|
||||
|
||||
public List<Locale> getAcceptedLanguageLocales()
|
||||
{
|
||||
return acceptedLanguageLocales;
|
||||
}
|
||||
|
||||
public double getVolume()
|
||||
@ -45,85 +129,9 @@ public class Offer
|
||||
return price * minAmount;
|
||||
}
|
||||
|
||||
public UUID getUid()
|
||||
public String getOfferPaymentTxID()
|
||||
{
|
||||
return uid;
|
||||
return offerPaymentTxID;
|
||||
}
|
||||
|
||||
public void setUid(UUID uid)
|
||||
{
|
||||
this.uid = uid;
|
||||
}
|
||||
|
||||
public Direction getDirection()
|
||||
{
|
||||
return direction;
|
||||
}
|
||||
|
||||
public void setDirection(Direction direction)
|
||||
{
|
||||
this.direction = direction;
|
||||
}
|
||||
|
||||
public double getPrice()
|
||||
{
|
||||
return price;
|
||||
}
|
||||
|
||||
public void setPrice(double price)
|
||||
{
|
||||
this.price = price;
|
||||
}
|
||||
|
||||
public double getAmount()
|
||||
{
|
||||
return amount;
|
||||
}
|
||||
|
||||
public void setAmount(double amount)
|
||||
{
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public double getMinAmount()
|
||||
{
|
||||
return minAmount;
|
||||
}
|
||||
|
||||
public void setMinAmount(double minAmount)
|
||||
{
|
||||
this.minAmount = minAmount;
|
||||
}
|
||||
|
||||
public Currency getCurrency()
|
||||
{
|
||||
return currency;
|
||||
}
|
||||
|
||||
public void setCurrency(Currency currency)
|
||||
{
|
||||
this.currency = currency;
|
||||
}
|
||||
|
||||
|
||||
public OfferConstraints getOfferConstraints()
|
||||
{
|
||||
return offerConstraints;
|
||||
}
|
||||
|
||||
public void setOfferConstraints(OfferConstraints offerConstraints)
|
||||
{
|
||||
this.offerConstraints = offerConstraints;
|
||||
}
|
||||
|
||||
|
||||
public User getOfferer()
|
||||
{
|
||||
return offerer;
|
||||
}
|
||||
|
||||
public void setOfferer(User offerer)
|
||||
{
|
||||
this.offerer = offerer;
|
||||
}
|
||||
}
|
||||
|
29
src/main/java/io/bitsquare/trade/OfferConstraint.java
Normal file
@ -0,0 +1,29 @@
|
||||
package io.bitsquare.trade;
|
||||
|
||||
import io.bitsquare.bank.BankAccountType;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
public class OfferConstraint
|
||||
{
|
||||
private List<Locale> languageLocales;
|
||||
private List<BankAccountType.BankAccountTypeEnum> bankAccountTypes;
|
||||
|
||||
public OfferConstraint(List<Locale> languageLocales,
|
||||
List<BankAccountType.BankAccountTypeEnum> bankAccountTypes)
|
||||
{
|
||||
this.languageLocales = languageLocales;
|
||||
this.bankAccountTypes = bankAccountTypes;
|
||||
}
|
||||
|
||||
public List<Locale> getLanguageLocales()
|
||||
{
|
||||
return languageLocales;
|
||||
}
|
||||
|
||||
public List<BankAccountType.BankAccountTypeEnum> getBankAccountTypes()
|
||||
{
|
||||
return bankAccountTypes;
|
||||
}
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
package io.bitsquare.trade;
|
||||
|
||||
import io.bitsquare.bank.BankAccountType;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
public class OfferConstraints
|
||||
{
|
||||
//TODO remove
|
||||
private double collateral;
|
||||
private String arbitrator;
|
||||
private String identityVerification;
|
||||
|
||||
private List<Locale> countryLocales;
|
||||
private List<Locale> languageLocales;
|
||||
private List<BankAccountType.BankAccountTypeEnum> bankAccountTypes;
|
||||
|
||||
public OfferConstraints(List<Locale> countryLocales,
|
||||
List<Locale> languageLocales,
|
||||
double collateral,
|
||||
List<BankAccountType.BankAccountTypeEnum> bankAccountTypes,
|
||||
String arbitrator,
|
||||
String identityVerification)
|
||||
{
|
||||
this.countryLocales = countryLocales;
|
||||
this.languageLocales = languageLocales;
|
||||
this.bankAccountTypes = bankAccountTypes;
|
||||
|
||||
|
||||
this.collateral = collateral;
|
||||
this.arbitrator = arbitrator;
|
||||
this.identityVerification = identityVerification;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return List of ISO3 country codes
|
||||
*/
|
||||
public List<Locale> getCountryLocales()
|
||||
{
|
||||
return countryLocales;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return List of ISO3 language codes
|
||||
*/
|
||||
public List<Locale> getLanguageLocales()
|
||||
{
|
||||
return languageLocales;
|
||||
}
|
||||
|
||||
public List<BankAccountType.BankAccountTypeEnum> getBankAccountTypes()
|
||||
{
|
||||
return bankAccountTypes;
|
||||
}
|
||||
|
||||
|
||||
public String getArbitrator()
|
||||
{
|
||||
return arbitrator;
|
||||
}
|
||||
|
||||
public String getIdentityVerification()
|
||||
{
|
||||
return identityVerification;
|
||||
}
|
||||
|
||||
public double getCollateral()
|
||||
{
|
||||
return collateral;
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package io.bitsquare.trade;
|
||||
|
||||
import com.google.bitcoin.core.InsufficientMoneyException;
|
||||
import com.google.inject.Inject;
|
||||
import io.bitsquare.btc.BlockChainFacade;
|
||||
import io.bitsquare.btc.KeyPair;
|
||||
@ -52,11 +53,15 @@ public class Trading
|
||||
/**
|
||||
* @param offer
|
||||
*/
|
||||
public void placeNewOffer(Offer offer)
|
||||
public String placeNewOffer(Offer offer) throws InsufficientMoneyException
|
||||
{
|
||||
log.info("place New Offer");
|
||||
offers.put(offer.getUid().toString(), offer);
|
||||
String txID = walletFacade.payOfferFee();
|
||||
offer.setOfferPaymentTxID(txID);
|
||||
|
||||
messageFacade.broadcast(new Message(Message.BROADCAST_NEW_OFFER, offer));
|
||||
return txID;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -67,7 +72,7 @@ public class Trading
|
||||
public void sendTakeOfferRequest(Trade trade)
|
||||
{
|
||||
log.info("Taker asks offerer to take his offer");
|
||||
messageFacade.send(new Message(Message.REQUEST_TAKE_OFFER, trade), trade.getOffer().getOfferer().getMessageID());
|
||||
//messageFacade.send(new Message(Message.REQUEST_TAKE_OFFER, trade), trade.getOffer().getOfferer().getMessageID());
|
||||
}
|
||||
|
||||
|
||||
@ -81,7 +86,7 @@ public class Trading
|
||||
KeyPair address = walletFacade.createNewAddress();
|
||||
|
||||
Contract contract = new Contract(trade, address.getPubKey());
|
||||
contract.setOfferer(trade.getOffer().getOfferer());
|
||||
//contract.setOfferer(trade.getOffer().getOfferer());
|
||||
contract.setTaker(user);
|
||||
contracts.put(trade.getUid().toString(), contract);
|
||||
return contract;
|
||||
@ -132,7 +137,7 @@ public class Trading
|
||||
trade.setTakeOfferFeeTxID(txID);
|
||||
|
||||
log.info("Taker asks offerer for confirmation for his fee payment. txID=" + txID);
|
||||
messageFacade.send(new Message(Message.REQUEST_OFFER_FEE_PAYMENT_CONFIRM, trade), trade.getOffer().getOfferer().getMessageID());
|
||||
// messageFacade.send(new Message(Message.REQUEST_OFFER_FEE_PAYMENT_CONFIRM, trade), trade.getOffer().getOfferer().getMessageID());
|
||||
}
|
||||
|
||||
|
||||
@ -154,7 +159,7 @@ public class Trading
|
||||
log.info("Sign deposit tx");
|
||||
|
||||
log.info("Send deposit Tx");
|
||||
messageFacade.send(new Message(Message.REQUEST_OFFER_FEE_PAYMENT_CONFIRM, trade), trade.getOffer().getOfferer().getMessageID());
|
||||
// messageFacade.send(new Message(Message.REQUEST_OFFER_FEE_PAYMENT_CONFIRM, trade), trade.getOffer().getOfferer().getMessageID());
|
||||
}
|
||||
|
||||
|
||||
@ -168,7 +173,7 @@ public class Trading
|
||||
log.info("Broadcast payment tx");
|
||||
|
||||
log.info("Send message to peer that payment Tx has been broadcasted.");
|
||||
messageFacade.send(new Message(Message.REQUEST_OFFER_FEE_PAYMENT_CONFIRM, trade), trade.getOffer().getOfferer().getMessageID());
|
||||
// messageFacade.send(new Message(Message.REQUEST_OFFER_FEE_PAYMENT_CONFIRM, trade), trade.getOffer().getOfferer().getMessageID());
|
||||
}
|
||||
|
||||
|
||||
|
118
src/main/java/io/bitsquare/trade/orderbook/MockOrderBook.java
Normal file
@ -0,0 +1,118 @@
|
||||
package io.bitsquare.trade.orderbook;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import io.bitsquare.bank.BankAccountType;
|
||||
import io.bitsquare.gui.trade.orderbook.OrderBookListItem;
|
||||
import io.bitsquare.gui.util.Converter;
|
||||
import io.bitsquare.gui.util.Formatter;
|
||||
import io.bitsquare.settings.Settings;
|
||||
import io.bitsquare.trade.Direction;
|
||||
import io.bitsquare.trade.Offer;
|
||||
import io.bitsquare.user.User;
|
||||
import io.bitsquare.util.Utils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class MockOrderBook extends OrderBook
|
||||
{
|
||||
private static final Logger log = LoggerFactory.getLogger(MockOrderBook.class);
|
||||
|
||||
@Inject
|
||||
public MockOrderBook(Settings settings, User user)
|
||||
{
|
||||
super(settings, user);
|
||||
for (int i = 0; i < 1000; i++)
|
||||
{
|
||||
allOffers.add(new OrderBookListItem(getOffer()));
|
||||
}
|
||||
}
|
||||
|
||||
private Offer getOffer()
|
||||
{
|
||||
double amount = Math.random() * 10 + 0.1;
|
||||
amount = Converter.stringToDouble(Formatter.formatAmount(amount));
|
||||
double minAmount = Math.random() * amount;
|
||||
minAmount = Converter.stringToDouble(Formatter.formatAmount(minAmount));
|
||||
|
||||
Direction direction = Direction.BUY;
|
||||
double price = 500 + Math.random() * 50;
|
||||
if (Math.random() > 0.5)
|
||||
{
|
||||
direction = Direction.SELL;
|
||||
price = 500 - Math.random() * 50;
|
||||
}
|
||||
|
||||
Offer offer = new Offer(UUID.randomUUID().toString(),
|
||||
UUID.randomUUID().toString(),
|
||||
direction,
|
||||
price,
|
||||
amount,
|
||||
minAmount,
|
||||
getBankTransferTypeEnums().get(0),
|
||||
getCurrencies().get(0),
|
||||
getLocales().get(0),
|
||||
getLocales(),
|
||||
getLocales());
|
||||
|
||||
return offer;
|
||||
}
|
||||
|
||||
private List<Currency> getCurrencies()
|
||||
{
|
||||
List<Currency> list = new ArrayList<>();
|
||||
list.add(Currency.getInstance("EUR"));
|
||||
list.add(Currency.getInstance("USD"));
|
||||
list.add(Currency.getInstance("GBP"));
|
||||
list.add(Currency.getInstance("RUB"));
|
||||
list.add(Currency.getInstance("CAD"));
|
||||
list.add(Currency.getInstance("AUD"));
|
||||
list.add(Currency.getInstance("JPY"));
|
||||
list.add(Currency.getInstance("CNY"));
|
||||
list.add(Currency.getInstance("CHF"));
|
||||
return randomizeList(list);
|
||||
}
|
||||
|
||||
private List<Locale> getLocales()
|
||||
{
|
||||
List<Locale> list = new ArrayList<>();
|
||||
list.add(new Locale("de", "AT"));
|
||||
list.add(new Locale("de", "DE"));
|
||||
list.add(new Locale("en", "US"));
|
||||
list.add(new Locale("en", "UK"));
|
||||
list.add(new Locale("es", "ES"));
|
||||
list.add(new Locale("ru", "RU"));
|
||||
list.add(new Locale("zh", "CN"));
|
||||
list.add(new Locale("en", "AU"));
|
||||
list.add(new Locale("it", "IT"));
|
||||
list.add(new Locale("en", "CA"));
|
||||
return randomizeList(list);
|
||||
}
|
||||
|
||||
|
||||
private List<BankAccountType.BankAccountTypeEnum> getBankTransferTypeEnums()
|
||||
{
|
||||
return randomizeList(Utils.getAllBankAccountTypeEnums());
|
||||
}
|
||||
|
||||
private List randomizeList(List list)
|
||||
{
|
||||
int e = new Random().nextInt(list.size());
|
||||
if (list.size() > 0)
|
||||
e = Math.max(e, 1);
|
||||
int s = (e == 0) ? 0 : new Random().nextInt(e);
|
||||
list = list.subList(s, e);
|
||||
return list;
|
||||
}
|
||||
|
||||
private List reduce(List list, int count)
|
||||
{
|
||||
List result = new ArrayList();
|
||||
for (int i = 0; i < count && i < list.size(); i++)
|
||||
{
|
||||
result.add(list.get(i));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
@ -1,239 +1,167 @@
|
||||
package io.bitsquare.trade.orderbook;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import io.bitsquare.bank.BankAccount;
|
||||
import io.bitsquare.bank.BankAccountType;
|
||||
import io.bitsquare.gui.trade.orderbook.OrderBookListItem;
|
||||
import io.bitsquare.gui.util.Converter;
|
||||
import io.bitsquare.gui.util.Formatter;
|
||||
import io.bitsquare.settings.Settings;
|
||||
import io.bitsquare.trade.Direction;
|
||||
import io.bitsquare.trade.Offer;
|
||||
import io.bitsquare.trade.OfferConstraints;
|
||||
import io.bitsquare.user.User;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.collections.transformation.FilteredList;
|
||||
import javafx.collections.transformation.SortedList;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class OrderBook
|
||||
{
|
||||
private ObservableList<OrderBookListItem> orderBookListItems;
|
||||
private static final Logger log = LoggerFactory.getLogger(OrderBook.class);
|
||||
|
||||
private FilteredList<OrderBookListItem> filteredList;
|
||||
private SortedList<OrderBookListItem> offerList;
|
||||
|
||||
|
||||
protected ObservableList<OrderBookListItem> allOffers = FXCollections.observableArrayList();
|
||||
private Settings settings;
|
||||
private User user;
|
||||
|
||||
@Inject
|
||||
public OrderBook(Settings settings)
|
||||
public OrderBook(Settings settings, User user)
|
||||
{
|
||||
this.settings = settings;
|
||||
orderBookListItems = FXCollections.observableArrayList();
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
orderBookListItems.add(getOrderBookListItem());
|
||||
}
|
||||
this.user = user;
|
||||
|
||||
filteredList = new FilteredList<>(allOffers);
|
||||
// FilteredList does not support sorting, so we need to wrap it to a SortedList
|
||||
offerList = new SortedList<>(filteredList);
|
||||
}
|
||||
|
||||
public ObservableList<OrderBookListItem> getFilteredList(OrderBookFilter orderBookFilter)
|
||||
public SortedList<OrderBookListItem> getOfferList()
|
||||
{
|
||||
FilteredList filtered = orderBookListItems.filtered(new Predicate<OrderBookListItem>()
|
||||
return offerList;
|
||||
}
|
||||
|
||||
public void updateFilter(OrderBookFilter orderBookFilter)
|
||||
{
|
||||
filteredList.setPredicate(new Predicate<OrderBookListItem>()
|
||||
{
|
||||
@Override
|
||||
public boolean test(OrderBookListItem offerListVO)
|
||||
public boolean test(OrderBookListItem orderBookListItem)
|
||||
{
|
||||
boolean priceResult;
|
||||
boolean amountResult = offerListVO.getOffer().getAmount() >= orderBookFilter.getAmount();
|
||||
// swap direction. use who want to buy btc want to see sell offers...
|
||||
boolean directionResult = offerListVO.getOffer().getDirection() != orderBookFilter.getDirection();
|
||||
boolean currencyResult = offerListVO.getOffer().getCurrency().equals(orderBookFilter.getCurrency());
|
||||
Offer offer = orderBookListItem.getOffer();
|
||||
BankAccount currentBankAccount = user.getCurrentBankAccount();
|
||||
|
||||
if (offerListVO.getOffer().getDirection() == Direction.SELL && orderBookFilter.getPrice() > 0)
|
||||
priceResult = offerListVO.getOffer().getPrice() <= orderBookFilter.getPrice();
|
||||
else
|
||||
priceResult = offerListVO.getOffer().getPrice() >= orderBookFilter.getPrice();
|
||||
return priceResult && amountResult && directionResult && currencyResult;
|
||||
if (orderBookFilter == null
|
||||
|| offer == null
|
||||
|| currentBankAccount == null
|
||||
|| orderBookFilter.getDirection() == null)
|
||||
return false;
|
||||
|
||||
// The users current bank account currency must match the offer currency (1 to 1)
|
||||
boolean currencyResult = currentBankAccount.getCurrency().equals(offer.getCurrency());
|
||||
|
||||
// The offer bank account country must match one of the accepted countries defined in the settings (1 to n)
|
||||
boolean countryResult = countryInList(offer.getBankAccountCountryLocale(), settings.getAcceptedCountryLocales());
|
||||
|
||||
// One of the supported languages from the settings must match one of the offer languages (n to n)
|
||||
boolean languageResult = languagesInList(settings.getAcceptedLanguageLocales(), offer.getAcceptedLanguageLocales());
|
||||
|
||||
// Apply updateFilter only if there is a valid value set
|
||||
// The requested amount must be lower or equal then the offer amount
|
||||
boolean amountResult = true;
|
||||
if (orderBookFilter.getAmount() > 0)
|
||||
amountResult = orderBookFilter.getAmount() <= offer.getAmount();
|
||||
|
||||
// The requested trade direction must be opposite of the offerList trade direction
|
||||
boolean directionResult = !orderBookFilter.getDirection().equals(offer.getDirection());
|
||||
|
||||
// Apply updateFilter only if there is a valid value set
|
||||
boolean priceResult = true;
|
||||
if (orderBookFilter.getPrice() > 0)
|
||||
{
|
||||
if (offer.getDirection() == Direction.SELL)
|
||||
priceResult = orderBookFilter.getPrice() >= offer.getPrice();
|
||||
else
|
||||
priceResult = orderBookFilter.getPrice() <= offer.getPrice();
|
||||
}
|
||||
|
||||
boolean result = currencyResult
|
||||
&& countryResult
|
||||
&& languageResult
|
||||
&& amountResult
|
||||
&& directionResult
|
||||
&& priceResult;
|
||||
|
||||
/*
|
||||
log.debug("result = " + result +
|
||||
", currencyResult = " + currencyResult +
|
||||
", countryResult = " + countryResult +
|
||||
", languageResult = " + languageResult +
|
||||
", bankAccountTypeEnumResult = " + bankAccountTypeEnumResult +
|
||||
", amountResult = " + amountResult +
|
||||
", directionResult = " + directionResult +
|
||||
", priceResult = " + priceResult
|
||||
);
|
||||
|
||||
log.debug("currentBankAccount.getCurrency() = " + currentBankAccount.getCurrency() +
|
||||
", offer.getCurrency() = " + offer.getCurrency());
|
||||
log.debug("offer.getCountryLocale() = " + offer.getCountryLocale() +
|
||||
", settings.getAcceptedCountryLocales() = " + settings.getAcceptedCountryLocales().toString());
|
||||
log.debug("settings.getAcceptedLanguageLocales() = " + settings.getAcceptedLanguageLocales() +
|
||||
", constraints.getAcceptedLanguageLocales() = " + constraints.getLanguageLocales());
|
||||
log.debug("currentBankAccount.getBankAccountType().getType() = " + currentBankAccount.getBankAccountType().getType() +
|
||||
", constraints.getBankAccountTypes() = " + constraints.getBankAccountTypes());
|
||||
log.debug("orderBookFilter.getAmount() = " + orderBookFilter.getAmount() +
|
||||
", offer.getAmount() = " + offer.getAmount());
|
||||
log.debug("orderBookFilter.getDirection() = " + orderBookFilter.getDirection() +
|
||||
", offer.getDirection() = " + offer.getDirection());
|
||||
log.debug("orderBookFilter.getPrice() = " + orderBookFilter.getPrice() +
|
||||
", offer.getPrice() = " + offer.getPrice());
|
||||
*/
|
||||
|
||||
return result;
|
||||
}
|
||||
});
|
||||
|
||||
//TODO use FilteredList
|
||||
ObservableList<OrderBookListItem> result = FXCollections.observableArrayList();
|
||||
result.addAll(filtered);
|
||||
return result;
|
||||
}
|
||||
|
||||
private OrderBookListItem getOrderBookListItem()
|
||||
private boolean countryInList(Locale orderBookFilterLocale, List<Locale> offerConstraintsLocales)
|
||||
{
|
||||
return new OrderBookListItem(getOffer());
|
||||
}
|
||||
|
||||
public ArrayList<Currency> getCurrencies()
|
||||
{
|
||||
ArrayList<Currency> currencies = new ArrayList<>();
|
||||
currencies.add(Currency.getInstance("USD"));
|
||||
currencies.add(Currency.getInstance("EUR"));
|
||||
currencies.add(Currency.getInstance("CNY"));
|
||||
currencies.add(Currency.getInstance("RUB"));
|
||||
|
||||
currencies.add(Currency.getInstance("JPY"));
|
||||
currencies.add(Currency.getInstance("GBP"));
|
||||
currencies.add(Currency.getInstance("CAD"));
|
||||
currencies.add(Currency.getInstance("AUD"));
|
||||
currencies.add(Currency.getInstance("CHF"));
|
||||
currencies.add(Currency.getInstance("CNY"));
|
||||
|
||||
/* Set<Currency> otherCurrenciesSet = Currency.getAvailableCurrencies();
|
||||
ArrayList<Currency> otherCurrenciesList = new ArrayList<>();
|
||||
otherCurrenciesList.addAll(otherCurrenciesSet);
|
||||
Collections.sort(otherCurrenciesList, new CurrencyComparator());
|
||||
|
||||
currencies.addAll(otherCurrenciesList); */
|
||||
|
||||
return currencies;
|
||||
}
|
||||
|
||||
private Offer getOffer()
|
||||
{
|
||||
User offerer = new User();
|
||||
offerer.setAccountID(UUID.randomUUID().toString());
|
||||
offerer.setMessageID(UUID.randomUUID().toString());
|
||||
offerer.setOnline(Math.random() > 0.5 ? true : false);
|
||||
offerer.setLanguageLocales(getLanguageLocales());
|
||||
|
||||
double amount = Math.random() * 10 + 0.1;
|
||||
amount = Converter.convertToDouble(Formatter.formatAmount(amount));
|
||||
double minAmount = Math.random() * amount;
|
||||
minAmount = Converter.convertToDouble(Formatter.formatAmount(minAmount));
|
||||
|
||||
Direction direction = Direction.BUY;
|
||||
double price = 500 + Math.random() * 50;
|
||||
if (Math.random() > 0.5)
|
||||
for (Locale locale : offerConstraintsLocales)
|
||||
{
|
||||
direction = Direction.SELL;
|
||||
price = 500 - Math.random() * 50;
|
||||
if (locale.getCountry().equals(orderBookFilterLocale.getCountry()))
|
||||
return true;
|
||||
}
|
||||
Currency currency = (randomizeCurrencies(getCurrencies(), false)).get(0);
|
||||
return new Offer(UUID.randomUUID(),
|
||||
direction,
|
||||
price,
|
||||
amount,
|
||||
minAmount,
|
||||
currency,
|
||||
offerer,
|
||||
getRandomOfferConstraints()
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
public OfferConstraints getRandomOfferConstraints()
|
||||
private boolean languagesInList(List<Locale> orderBookFilterLocales, List<Locale> offerConstraintsLocales)
|
||||
{
|
||||
OfferConstraints offerConstraints = new OfferConstraints(getCountryLocales(),
|
||||
getLanguageLocales(),
|
||||
Double.valueOf(getCollaterals().get(0)),
|
||||
getBankTransferTypeEnums(),
|
||||
getArbitrators().get(0),
|
||||
randomizeStrings(settings.getAllIdentityVerifications(), false).get(0));
|
||||
|
||||
return offerConstraints;
|
||||
for (Locale offerConstraintsLocale : offerConstraintsLocales)
|
||||
{
|
||||
for (Locale orderBookFilterLocale : orderBookFilterLocales)
|
||||
{
|
||||
if (offerConstraintsLocale.getLanguage().equals(orderBookFilterLocale.getLanguage()))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private List<Locale> getCountryLocales()
|
||||
private boolean matchBankAccountTypeEnum(BankAccountType.BankAccountTypeEnum orderBookFilterBankAccountType, List<BankAccountType.BankAccountTypeEnum> offerConstraintsBankAccountTypes)
|
||||
{
|
||||
|
||||
return randomizeList(settings.getAllLocales(), false);
|
||||
}
|
||||
|
||||
private List<Locale> getLanguageLocales()
|
||||
{
|
||||
return randomizeList(settings.getAllLocales(), false);
|
||||
for (BankAccountType.BankAccountTypeEnum bankAccountType : offerConstraintsBankAccountTypes)
|
||||
{
|
||||
if (bankAccountType.equals(orderBookFilterBankAccountType))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private List<BankAccountType> getBankTransferTypes()
|
||||
{
|
||||
return randomizeBankAccountTypes(settings.getAllBankAccountTypes(), false);
|
||||
}
|
||||
|
||||
private List<BankAccountType.BankAccountTypeEnum> getBankTransferTypeEnums()
|
||||
{
|
||||
return randomizeBankAccountTypeEnums(settings.getAllBankAccountTypeEnums(), false);
|
||||
}
|
||||
|
||||
private List<String> getArbitrators()
|
||||
{
|
||||
return randomizeStrings(settings.getAllArbitrators(), false);
|
||||
}
|
||||
|
||||
private List<String> getCollaterals()
|
||||
{
|
||||
return randomizeStrings(settings.getAllCollaterals(), false);
|
||||
}
|
||||
|
||||
private List<BankAccountType.BankAccountTypeEnum> randomizeBankAccountTypeEnums(List<BankAccountType.BankAccountTypeEnum> list, boolean optional)
|
||||
{
|
||||
int e = new Random().nextInt(list.size());
|
||||
if (!optional && list.size() > 0)
|
||||
e = Math.max(e, 1);
|
||||
int s = (e == 0) ? 0 : new Random().nextInt(e);
|
||||
list = list.subList(s, e);
|
||||
return list;
|
||||
}
|
||||
|
||||
private List<BankAccountType> randomizeBankAccountTypes(List<BankAccountType> list, boolean optional)
|
||||
{
|
||||
int e = new Random().nextInt(list.size());
|
||||
if (!optional && list.size() > 0)
|
||||
e = Math.max(e, 1);
|
||||
int s = (e == 0) ? 0 : new Random().nextInt(e);
|
||||
list = list.subList(s, e);
|
||||
return list;
|
||||
}
|
||||
|
||||
private List<String> randomizeStrings(List<String> list, boolean optional)
|
||||
{
|
||||
int e = new Random().nextInt(list.size());
|
||||
if (!optional && list.size() > 0)
|
||||
e = Math.max(e, 1);
|
||||
int s = (e == 0) ? 0 : new Random().nextInt(e);
|
||||
list = list.subList(s, e);
|
||||
return list;
|
||||
}
|
||||
|
||||
private List randomizeList(List list, boolean optional)
|
||||
{
|
||||
int e = new Random().nextInt(list.size());
|
||||
if (!optional && list.size() > 0)
|
||||
e = Math.max(e, 1);
|
||||
int s = (e == 0) ? 0 : new Random().nextInt(e);
|
||||
list = list.subList(s, e);
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
private List<Double> randomizeDouble(List<Double> list, boolean optional)
|
||||
{
|
||||
int e = new Random().nextInt(list.size());
|
||||
if (!optional && list.size() > 0)
|
||||
e = Math.max(e, 1);
|
||||
int s = (e == 0) ? 0 : new Random().nextInt(e);
|
||||
list = list.subList(s, e);
|
||||
return list;
|
||||
}
|
||||
|
||||
private List<Currency> randomizeCurrencies(List<Currency> list, boolean optional)
|
||||
{
|
||||
int e = new Random().nextInt(list.size());
|
||||
if (!optional && list.size() > 0)
|
||||
e = Math.max(e, 1);
|
||||
int s = (e == 0) ? 0 : new Random().nextInt(e);
|
||||
list = list.subList(s, e);
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
class CurrencyComparator implements Comparator<Currency>
|
||||
{
|
||||
@Override
|
||||
public int compare(Currency a, Currency b)
|
||||
{
|
||||
return a.getCurrencyCode().compareTo(b.getCurrencyCode());
|
||||
}
|
||||
}
|
@ -1,36 +1,17 @@
|
||||
package io.bitsquare.trade.orderbook;
|
||||
|
||||
import io.bitsquare.trade.Direction;
|
||||
import io.bitsquare.trade.OfferConstraints;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
|
||||
import java.util.Currency;
|
||||
import java.util.Locale;
|
||||
|
||||
public class OrderBookFilter
|
||||
{
|
||||
transient private final SimpleBooleanProperty changedProperty = new SimpleBooleanProperty();
|
||||
|
||||
private double price;
|
||||
private double amount;
|
||||
private Direction direction;
|
||||
private Currency currency;
|
||||
private Locale countryLocale;
|
||||
private Locale languageLocale;
|
||||
private OfferConstraints offerConstraints;
|
||||
|
||||
|
||||
public SimpleBooleanProperty changedPropertyProperty()
|
||||
{
|
||||
return changedProperty;
|
||||
}
|
||||
|
||||
private final SimpleBooleanProperty changedProperty = new SimpleBooleanProperty();
|
||||
|
||||
// setters
|
||||
public void setCurrency(Currency currency)
|
||||
{
|
||||
this.currency = currency;
|
||||
triggerChange();
|
||||
}
|
||||
|
||||
public void setAmount(double amount)
|
||||
{
|
||||
@ -50,23 +31,6 @@ public class OrderBookFilter
|
||||
triggerChange();
|
||||
}
|
||||
|
||||
public void setOfferConstraints(OfferConstraints offerConstraints)
|
||||
{
|
||||
this.offerConstraints = offerConstraints;
|
||||
triggerChange();
|
||||
}
|
||||
|
||||
public void setCountryLocale(Locale countryLocale)
|
||||
{
|
||||
this.countryLocale = countryLocale;
|
||||
triggerChange();
|
||||
}
|
||||
|
||||
public void setLanguageLocale(Locale languageLocale)
|
||||
{
|
||||
this.languageLocale = languageLocale;
|
||||
triggerChange();
|
||||
}
|
||||
|
||||
// getters
|
||||
public double getAmount()
|
||||
@ -84,25 +48,6 @@ public class OrderBookFilter
|
||||
return price;
|
||||
}
|
||||
|
||||
public Currency getCurrency()
|
||||
{
|
||||
return currency;
|
||||
}
|
||||
|
||||
public OfferConstraints getOfferConstraints()
|
||||
{
|
||||
return offerConstraints;
|
||||
}
|
||||
|
||||
public Locale getCountryLocale()
|
||||
{
|
||||
return countryLocale;
|
||||
}
|
||||
|
||||
public Locale getLanguageLocale()
|
||||
{
|
||||
return languageLocale;
|
||||
}
|
||||
|
||||
public SimpleBooleanProperty getChangedProperty()
|
||||
{
|
||||
@ -113,4 +58,5 @@ public class OrderBookFilter
|
||||
{
|
||||
changedProperty.set(!changedProperty.get());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,28 +1,30 @@
|
||||
package io.bitsquare.user;
|
||||
|
||||
import io.bitsquare.bank.BankAccount;
|
||||
import io.bitsquare.trade.OfferConstraint;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
public class User implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 7409078808248518638L;
|
||||
|
||||
transient private final SimpleBooleanProperty changedProperty = new SimpleBooleanProperty();
|
||||
|
||||
private String accountID;
|
||||
private String messageID;
|
||||
private boolean online;
|
||||
private List<BankAccount> bankAccounts = new ArrayList<>();
|
||||
private BankAccount currentBankAccount = null;
|
||||
private List<Locale> languageLocales = new ArrayList<>();
|
||||
private Locale currentLanguageLocale = null;
|
||||
|
||||
private OfferConstraint offerConstraint;
|
||||
|
||||
public User()
|
||||
{
|
||||
addLanguageLocales(Locale.getDefault());
|
||||
}
|
||||
|
||||
public void updateFromStorage(User savedUser)
|
||||
@ -34,8 +36,6 @@ public class User implements Serializable
|
||||
online = savedUser.isOnline();
|
||||
currentBankAccount = savedUser.getCurrentBankAccount();
|
||||
bankAccounts = savedUser.getBankAccounts();
|
||||
languageLocales = savedUser.getLanguageLocales();
|
||||
currentLanguageLocale = savedUser.getCurrentLanguageLocale();
|
||||
}
|
||||
}
|
||||
|
||||
@ -53,15 +53,8 @@ public class User implements Serializable
|
||||
return bankAccountUIDs;
|
||||
}
|
||||
|
||||
public void addLanguageLocales(Locale locale)
|
||||
{
|
||||
languageLocales.add(locale);
|
||||
currentLanguageLocale = locale;
|
||||
}
|
||||
|
||||
public void addBankAccount(BankAccount bankAccount)
|
||||
{
|
||||
|
||||
bankAccounts.add(bankAccount);
|
||||
currentBankAccount = bankAccount;
|
||||
}
|
||||
@ -77,7 +70,6 @@ public class User implements Serializable
|
||||
this.accountID = accountID;
|
||||
}
|
||||
|
||||
|
||||
public void setBankAccounts(List<BankAccount> bankAccounts)
|
||||
{
|
||||
this.bankAccounts = bankAccounts;
|
||||
@ -86,23 +78,19 @@ public class User implements Serializable
|
||||
public void setCurrentBankAccount(BankAccount currentBankAccount)
|
||||
{
|
||||
this.currentBankAccount = currentBankAccount;
|
||||
triggerChange();
|
||||
}
|
||||
|
||||
public void setLanguageLocales(List<Locale> languageLocales)
|
||||
{
|
||||
this.languageLocales = languageLocales;
|
||||
}
|
||||
|
||||
public void setCurrentLanguageLocale(Locale currentLanguageLocale)
|
||||
{
|
||||
this.currentLanguageLocale = currentLanguageLocale;
|
||||
}
|
||||
|
||||
public void setOnline(boolean online)
|
||||
{
|
||||
this.online = online;
|
||||
}
|
||||
|
||||
public void setOfferConstraint(OfferConstraint offerConstraint)
|
||||
{
|
||||
this.offerConstraint = offerConstraint;
|
||||
}
|
||||
|
||||
// getter
|
||||
public String getMessageID()
|
||||
@ -125,20 +113,24 @@ public class User implements Serializable
|
||||
return currentBankAccount;
|
||||
}
|
||||
|
||||
public List<Locale> getLanguageLocales()
|
||||
{
|
||||
return languageLocales;
|
||||
}
|
||||
|
||||
public Locale getCurrentLanguageLocale()
|
||||
{
|
||||
return currentLanguageLocale;
|
||||
}
|
||||
|
||||
public boolean isOnline()
|
||||
{
|
||||
return online;
|
||||
}
|
||||
|
||||
public OfferConstraint getOfferConstraint()
|
||||
{
|
||||
return offerConstraint;
|
||||
}
|
||||
|
||||
public SimpleBooleanProperty getChangedProperty()
|
||||
{
|
||||
return changedProperty;
|
||||
}
|
||||
|
||||
private void triggerChange()
|
||||
{
|
||||
changedProperty.set(!changedProperty.get());
|
||||
}
|
||||
}
|
||||
|
@ -3,17 +3,40 @@ package io.bitsquare.util;
|
||||
import com.google.gson.FieldNamingPolicy;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import io.bitsquare.bank.BankAccountType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class Utils
|
||||
{
|
||||
private static final Logger log = LoggerFactory.getLogger(Utils.class);
|
||||
|
||||
public static String convertToJson(Object object)
|
||||
{
|
||||
Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE).create();
|
||||
return gson.toJson(object);
|
||||
}
|
||||
|
||||
private static long lastTimeStamp = System.currentTimeMillis();
|
||||
|
||||
public static void printElapsedTime(String msg)
|
||||
{
|
||||
if (msg.length() > 0)
|
||||
msg += " / ";
|
||||
long timeStamp = System.currentTimeMillis();
|
||||
log.debug(msg + "Elapsed: " + String.valueOf(timeStamp - lastTimeStamp));
|
||||
lastTimeStamp = timeStamp;
|
||||
}
|
||||
|
||||
public static void printElapsedTime()
|
||||
{
|
||||
printElapsedTime("");
|
||||
}
|
||||
|
||||
public static Object copy(Object orig)
|
||||
{
|
||||
Object obj = null;
|
||||
@ -40,4 +63,97 @@ public class Utils
|
||||
return obj;
|
||||
}
|
||||
|
||||
public static ArrayList<Locale> getAllLocales()
|
||||
{
|
||||
ArrayList<Locale> list = new ArrayList<Locale>(Arrays.asList(Locale.getAvailableLocales()));
|
||||
list.removeIf(new Predicate<Locale>()
|
||||
{
|
||||
@Override
|
||||
public boolean test(Locale locale)
|
||||
{
|
||||
return locale == null || locale.getCountry().equals("") || locale.getLanguage().equals("");
|
||||
}
|
||||
});
|
||||
|
||||
list.sort(new Comparator<Locale>()
|
||||
{
|
||||
@Override
|
||||
public int compare(Locale locale1, Locale locale2)
|
||||
{
|
||||
return locale1.getDisplayCountry().compareTo(locale2.getDisplayCountry());
|
||||
}
|
||||
});
|
||||
|
||||
Locale defaultLocale = Locale.getDefault();
|
||||
//Locale defaultLocale = new Locale("de", "AT");
|
||||
list.remove(defaultLocale);
|
||||
list.add(0, defaultLocale);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public static List<Currency> getAllCurrencies()
|
||||
{
|
||||
ArrayList<Currency> mainCurrencies = new ArrayList<>();
|
||||
mainCurrencies.add(Currency.getInstance("USD"));
|
||||
mainCurrencies.add(Currency.getInstance("EUR"));
|
||||
mainCurrencies.add(Currency.getInstance("CNY"));
|
||||
mainCurrencies.add(Currency.getInstance("RUB"));
|
||||
mainCurrencies.add(Currency.getInstance("JPY"));
|
||||
mainCurrencies.add(Currency.getInstance("GBP"));
|
||||
mainCurrencies.add(Currency.getInstance("CAD"));
|
||||
mainCurrencies.add(Currency.getInstance("AUD"));
|
||||
mainCurrencies.add(Currency.getInstance("CHF"));
|
||||
mainCurrencies.add(Currency.getInstance("CNY"));
|
||||
|
||||
Set<Currency> allCurrenciesSet = Currency.getAvailableCurrencies();
|
||||
|
||||
allCurrenciesSet.removeAll(mainCurrencies);
|
||||
List<Currency> allCurrenciesList = new ArrayList<>(allCurrenciesSet);
|
||||
allCurrenciesList.sort(new Comparator<Currency>()
|
||||
{
|
||||
@Override
|
||||
public int compare(Currency a, Currency b)
|
||||
{
|
||||
return a.getCurrencyCode().compareTo(b.getCurrencyCode());
|
||||
}
|
||||
});
|
||||
|
||||
List<Currency> resultList = new ArrayList<>(mainCurrencies);
|
||||
resultList.addAll(allCurrenciesList);
|
||||
|
||||
Currency defaultCurrency = Currency.getInstance(Locale.getDefault());
|
||||
resultList.remove(defaultCurrency);
|
||||
resultList.add(0, defaultCurrency);
|
||||
|
||||
return resultList;
|
||||
}
|
||||
|
||||
public static ArrayList<BankAccountType.BankAccountTypeEnum> getAllBankAccountTypeEnums()
|
||||
{
|
||||
ArrayList<BankAccountType.BankAccountTypeEnum> bankAccountTypeEnums = new ArrayList<>();
|
||||
bankAccountTypeEnums.add(BankAccountType.BankAccountTypeEnum.SEPA);
|
||||
bankAccountTypeEnums.add(BankAccountType.BankAccountTypeEnum.WIRE);
|
||||
bankAccountTypeEnums.add(BankAccountType.BankAccountTypeEnum.INTERNATIONAL);
|
||||
bankAccountTypeEnums.add(BankAccountType.BankAccountTypeEnum.OK_PAY);
|
||||
bankAccountTypeEnums.add(BankAccountType.BankAccountTypeEnum.NET_TELLER);
|
||||
bankAccountTypeEnums.add(BankAccountType.BankAccountTypeEnum.PERFECT_MONEY);
|
||||
bankAccountTypeEnums.add(BankAccountType.BankAccountTypeEnum.OTHER);
|
||||
return bankAccountTypeEnums;
|
||||
}
|
||||
|
||||
public static ArrayList<BankAccountType> getAllBankAccountTypes()
|
||||
{
|
||||
ArrayList<BankAccountType> bankTransferTypes = new ArrayList<>();
|
||||
bankTransferTypes.add(new BankAccountType(BankAccountType.BankAccountTypeEnum.SEPA, "IBAN", "BIC"));
|
||||
bankTransferTypes.add(new BankAccountType(BankAccountType.BankAccountTypeEnum.WIRE, "Prim_todo", "Sec_todo"));
|
||||
bankTransferTypes.add(new BankAccountType(BankAccountType.BankAccountTypeEnum.INTERNATIONAL, "Prim_todo", "Sec_todo"));
|
||||
bankTransferTypes.add(new BankAccountType(BankAccountType.BankAccountTypeEnum.OK_PAY, "Prim_todo", "Sec_todo"));
|
||||
bankTransferTypes.add(new BankAccountType(BankAccountType.BankAccountTypeEnum.NET_TELLER, "Prim_todo", "Sec_todo"));
|
||||
bankTransferTypes.add(new BankAccountType(BankAccountType.BankAccountTypeEnum.PERFECT_MONEY, "Prim_todo", "Sec_todo"));
|
||||
bankTransferTypes.add(new BankAccountType(BankAccountType.BankAccountTypeEnum.OTHER, "Prim_todo", "Sec_todo"));
|
||||
return bankTransferTypes;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
Before Width: | Height: | Size: 599 B After Width: | Height: | Size: 599 B |
Before Width: | Height: | Size: 157 B After Width: | Height: | Size: 157 B |
Before Width: | Height: | Size: 573 B After Width: | Height: | Size: 573 B |
Before Width: | Height: | Size: 205 B After Width: | Height: | Size: 205 B |