mirror of
https://github.com/bisq-network/bisq.git
synced 2025-02-25 07:27:18 +01:00
Merge branch 'Development'
This commit is contained in:
commit
ef46e50798
136 changed files with 1089 additions and 758 deletions
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>parent</artifactId>
|
<artifactId>parent</artifactId>
|
||||||
<groupId>io.bitsquare</groupId>
|
<groupId>io.bitsquare</groupId>
|
||||||
<version>0.4.9.1</version>
|
<version>0.4.9.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ public class Version {
|
||||||
private static final Logger log = LoggerFactory.getLogger(Version.class);
|
private static final Logger log = LoggerFactory.getLogger(Version.class);
|
||||||
|
|
||||||
// The application versions
|
// The application versions
|
||||||
public static final String VERSION = "0.4.9.1";
|
public static final String VERSION = "0.4.9.2";
|
||||||
|
|
||||||
// The version nr. for the objects sent over the network. A change will break the serialization of old objects.
|
// The version nr. for the objects sent over the network. A change will break the serialization of old objects.
|
||||||
// If objects are used for both network and database the network version is applied.
|
// If objects are used for both network and database the network version is applied.
|
||||||
|
|
|
@ -34,6 +34,7 @@ import java.security.interfaces.DSAParams;
|
||||||
import java.security.interfaces.DSAPrivateKey;
|
import java.security.interfaces.DSAPrivateKey;
|
||||||
import java.security.interfaces.RSAPrivateCrtKey;
|
import java.security.interfaces.RSAPrivateCrtKey;
|
||||||
import java.security.spec.*;
|
import java.security.spec.*;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
// TODO: use a password protection for key storage
|
// TODO: use a password protection for key storage
|
||||||
public class KeyStorage {
|
public class KeyStorage {
|
||||||
|
@ -124,7 +125,7 @@ public class KeyStorage {
|
||||||
throw new RuntimeException("Unsupported key algo" + keyEntry.getAlgorithm());
|
throw new RuntimeException("Unsupported key algo" + keyEntry.getAlgorithm());
|
||||||
}
|
}
|
||||||
|
|
||||||
//log.info("load completed in {} msec", System.currentTimeMillis() - now);
|
log.debug("load completed in {} msec", System.currentTimeMillis() - new Date().getTime());
|
||||||
return new KeyPair(publicKey, privateKey);
|
return new KeyPair(publicKey, privateKey);
|
||||||
} catch (NoSuchAlgorithmException | InvalidKeySpecException | NoSuchProviderException e) {
|
} catch (NoSuchAlgorithmException | InvalidKeySpecException | NoSuchProviderException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|
|
@ -24,12 +24,11 @@ public class Profiler {
|
||||||
private static final Logger log = LoggerFactory.getLogger(Profiler.class);
|
private static final Logger log = LoggerFactory.getLogger(Profiler.class);
|
||||||
|
|
||||||
public static void printSystemLoad(Logger log) {
|
public static void printSystemLoad(Logger log) {
|
||||||
log.warn(printSystemLoadString());
|
log.info(printSystemLoadString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String printSystemLoadString() {
|
public static String printSystemLoadString() {
|
||||||
long used = getUsedMemoryInMB();
|
return "System load: Memory (MB)): " + getUsedMemoryInMB() + " / Nr. of threads: " + Thread.activeCount();
|
||||||
return "System load: Memory (MB)): " + used + " / Nr. of threads: " + Thread.activeCount();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static long getUsedMemoryInMB() {
|
public static long getUsedMemoryInMB() {
|
||||||
|
|
|
@ -33,9 +33,7 @@ import java.awt.*;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
|
||||||
import java.net.URLConnection;
|
import java.net.URLConnection;
|
||||||
import java.net.URLEncoder;
|
|
||||||
import java.security.Permission;
|
import java.security.Permission;
|
||||||
import java.security.PermissionCollection;
|
import java.security.PermissionCollection;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
@ -207,26 +205,6 @@ public class Utilities {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void openWebPage(String target) {
|
|
||||||
try {
|
|
||||||
openURI(new URI(target));
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
log.error(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void openMail(String to, String subject, String body) {
|
|
||||||
try {
|
|
||||||
subject = URLEncoder.encode(subject, "UTF-8").replace("+", "%20");
|
|
||||||
body = URLEncoder.encode(body, "UTF-8").replace("+", "%20");
|
|
||||||
openURI(new URI("mailto:" + to + "?subject=" + subject + "&body=" + body));
|
|
||||||
} catch (IOException | URISyntaxException e) {
|
|
||||||
log.error("openMail failed " + e.getMessage());
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void printSystemLoad() {
|
public static void printSystemLoad() {
|
||||||
Runtime runtime = Runtime.getRuntime();
|
Runtime runtime = Runtime.getRuntime();
|
||||||
long free = runtime.freeMemory() / 1024 / 1024;
|
long free = runtime.freeMemory() / 1024 / 1024;
|
||||||
|
|
|
@ -197,12 +197,12 @@ public class FileManager<T> {
|
||||||
|
|
||||||
renameTempFileToFile(tempFile, storageFile);
|
renameTempFileToFile(tempFile, storageFile);
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
log.debug("storageFile " + storageFile.toString());
|
log.error("storageFile " + storageFile.toString());
|
||||||
t.printStackTrace();
|
t.printStackTrace();
|
||||||
log.error("Error at saveToFile: " + t.getMessage());
|
log.error("Error at saveToFile: " + t.getMessage());
|
||||||
} finally {
|
} finally {
|
||||||
if (tempFile != null && tempFile.exists()) {
|
if (tempFile != null && tempFile.exists()) {
|
||||||
log.warn("Temp file still exists after failed save. storageFile=" + storageFile);
|
log.warn("Temp file still exists after failed save. We will delete it now. storageFile=" + storageFile);
|
||||||
if (!tempFile.delete())
|
if (!tempFile.delete())
|
||||||
log.error("Cannot delete temp file.");
|
log.error("Cannot delete temp file.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>parent</artifactId>
|
<artifactId>parent</artifactId>
|
||||||
<groupId>io.bitsquare</groupId>
|
<groupId>io.bitsquare</groupId>
|
||||||
<version>0.4.9.1</version>
|
<version>0.4.9.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>core</artifactId>
|
<artifactId>core</artifactId>
|
||||||
|
|
|
@ -62,7 +62,7 @@ public class BitsquareEnvironment extends StandardEnvironment {
|
||||||
public static final String DEFAULT_USER_DATA_DIR = defaultUserDataDir();
|
public static final String DEFAULT_USER_DATA_DIR = defaultUserDataDir();
|
||||||
public static final String DEFAULT_APP_DATA_DIR = appDataDir(DEFAULT_USER_DATA_DIR, DEFAULT_APP_NAME);
|
public static final String DEFAULT_APP_DATA_DIR = appDataDir(DEFAULT_USER_DATA_DIR, DEFAULT_APP_NAME);
|
||||||
|
|
||||||
public static final String LOG_LEVEL_DEFAULT = (DevFlags.STRESS_TEST_MODE || DevFlags.DEV_MODE) ? Level.TRACE.levelStr : Level.WARN.levelStr;
|
public static final String LOG_LEVEL_DEFAULT = (DevFlags.STRESS_TEST_MODE || DevFlags.DEV_MODE) ? Level.TRACE.levelStr : Level.INFO.levelStr;
|
||||||
|
|
||||||
static final String BITSQUARE_COMMANDLINE_PROPERTY_SOURCE_NAME = "bitsquareCommandLineProperties";
|
static final String BITSQUARE_COMMANDLINE_PROPERTY_SOURCE_NAME = "bitsquareCommandLineProperties";
|
||||||
static final String BITSQUARE_APP_DIR_PROPERTY_SOURCE_NAME = "bitsquareAppDirProperties";
|
static final String BITSQUARE_APP_DIR_PROPERTY_SOURCE_NAME = "bitsquareAppDirProperties";
|
||||||
|
|
|
@ -159,19 +159,26 @@ public final class Dispute implements Payload {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setIsClosed(boolean isClosed) {
|
public void setIsClosed(boolean isClosed) {
|
||||||
|
boolean changed = this.isClosed != isClosed;
|
||||||
this.isClosed = isClosed;
|
this.isClosed = isClosed;
|
||||||
isClosedProperty.set(isClosed);
|
isClosedProperty.set(isClosed);
|
||||||
|
if (changed)
|
||||||
storage.queueUpForSave();
|
storage.queueUpForSave();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDisputeResult(DisputeResult disputeResult) {
|
public void setDisputeResult(DisputeResult disputeResult) {
|
||||||
|
boolean changed = this.disputeResult == null || !this.disputeResult.equals(disputeResult);
|
||||||
this.disputeResult = disputeResult;
|
this.disputeResult = disputeResult;
|
||||||
disputeResultProperty.set(disputeResult);
|
disputeResultProperty.set(disputeResult);
|
||||||
|
if (changed)
|
||||||
storage.queueUpForSave();
|
storage.queueUpForSave();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDisputePayoutTxId(String disputePayoutTxId) {
|
public void setDisputePayoutTxId(String disputePayoutTxId) {
|
||||||
|
boolean changed = this.disputePayoutTxId == null || !this.disputePayoutTxId.equals(disputePayoutTxId);
|
||||||
this.disputePayoutTxId = disputePayoutTxId;
|
this.disputePayoutTxId = disputePayoutTxId;
|
||||||
|
if (changed)
|
||||||
|
storage.queueUpForSave();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -60,10 +60,11 @@ public final class DisputeList<DisputeCase> extends ArrayList<DisputeCase> imple
|
||||||
@Override
|
@Override
|
||||||
public boolean add(DisputeCase disputeCase) {
|
public boolean add(DisputeCase disputeCase) {
|
||||||
if (!super.contains(disputeCase)) {
|
if (!super.contains(disputeCase)) {
|
||||||
boolean result = super.add(disputeCase);
|
boolean changed = super.add(disputeCase);
|
||||||
getObservableList().add(disputeCase);
|
getObservableList().add(disputeCase);
|
||||||
|
if (changed)
|
||||||
storage.queueUpForSave();
|
storage.queueUpForSave();
|
||||||
return result;
|
return changed;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -71,10 +72,11 @@ public final class DisputeList<DisputeCase> extends ArrayList<DisputeCase> imple
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean remove(Object disputeCase) {
|
public boolean remove(Object disputeCase) {
|
||||||
boolean result = super.remove(disputeCase);
|
boolean changed = super.remove(disputeCase);
|
||||||
getObservableList().remove(disputeCase);
|
getObservableList().remove(disputeCase);
|
||||||
|
if (changed)
|
||||||
storage.queueUpForSave();
|
storage.queueUpForSave();
|
||||||
return result;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ObservableList<DisputeCase> getObservableList() {
|
private ObservableList<DisputeCase> getObservableList() {
|
||||||
|
|
|
@ -68,7 +68,8 @@ public final class AddressEntryList extends ArrayList<AddressEntry> implements P
|
||||||
}
|
}
|
||||||
|
|
||||||
public AddressEntry addAddressEntry(AddressEntry addressEntry) {
|
public AddressEntry addAddressEntry(AddressEntry addressEntry) {
|
||||||
add(addressEntry);
|
boolean changed = add(addressEntry);
|
||||||
|
if (changed)
|
||||||
storage.queueUpForSave();
|
storage.queueUpForSave();
|
||||||
return addressEntry;
|
return addressEntry;
|
||||||
}
|
}
|
||||||
|
@ -78,16 +79,18 @@ public final class AddressEntryList extends ArrayList<AddressEntry> implements P
|
||||||
Optional<AddressEntry> addressEntryOptional = this.stream().filter(addressEntry -> offerId.equals(addressEntry.getOfferId())).findAny();
|
Optional<AddressEntry> addressEntryOptional = this.stream().filter(addressEntry -> offerId.equals(addressEntry.getOfferId())).findAny();
|
||||||
if (addressEntryOptional.isPresent()) {
|
if (addressEntryOptional.isPresent()) {
|
||||||
AddressEntry addressEntry = addressEntryOptional.get();
|
AddressEntry addressEntry = addressEntryOptional.get();
|
||||||
add(new AddressEntry(addressEntry.getKeyPair(), wallet.getParams(), AddressEntry.Context.AVAILABLE));
|
boolean changed1 = add(new AddressEntry(addressEntry.getKeyPair(), wallet.getParams(), AddressEntry.Context.AVAILABLE));
|
||||||
remove(addressEntry);
|
boolean changed2 = remove(addressEntry);
|
||||||
|
if (changed1 || changed2)
|
||||||
storage.queueUpForSave();
|
storage.queueUpForSave();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void swapToAvailable(AddressEntry addressEntry) {
|
public void swapToAvailable(AddressEntry addressEntry) {
|
||||||
remove(addressEntry);
|
remove(addressEntry);
|
||||||
add(new AddressEntry(addressEntry.getKeyPair(), wallet.getParams(), AddressEntry.Context.AVAILABLE));
|
boolean changed1 = add(new AddressEntry(addressEntry.getKeyPair(), wallet.getParams(), AddressEntry.Context.AVAILABLE));
|
||||||
remove(addressEntry);
|
boolean changed2 = remove(addressEntry);
|
||||||
|
if (changed1 || changed2)
|
||||||
storage.queueUpForSave();
|
storage.queueUpForSave();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -145,7 +145,7 @@ public class SeedPeersSocks5Dns implements PeerDiscovery {
|
||||||
InetAddress addrResolved = proxySocket.getInetAddress();
|
InetAddress addrResolved = proxySocket.getInetAddress();
|
||||||
proxySocket.close();
|
proxySocket.close();
|
||||||
if( addrResolved != null ) {
|
if( addrResolved != null ) {
|
||||||
log.info("Resolved " + addr.getHostString() + " to " + addrResolved.getHostAddress() );
|
log.debug("Resolved " + addr.getHostString() + " to " + addrResolved.getHostAddress());
|
||||||
return new InetSocketAddress(addrResolved, addr.getPort() );
|
return new InetSocketAddress(addrResolved, addr.getPort() );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -981,7 +981,7 @@ public class TradeWalletService {
|
||||||
transaction.addOutput(buyerPayoutAmount, new Address(params, buyerAddressString));
|
transaction.addOutput(buyerPayoutAmount, new Address(params, buyerAddressString));
|
||||||
transaction.addOutput(sellerPayoutAmount, new Address(params, sellerAddressString));
|
transaction.addOutput(sellerPayoutAmount, new Address(params, sellerAddressString));
|
||||||
if (lockTime != 0) {
|
if (lockTime != 0) {
|
||||||
log.info("We use a lockTime of " + lockTime);
|
log.debug("We use a lockTime of " + lockTime);
|
||||||
// When using lockTime we need to set sequenceNumber to 0
|
// When using lockTime we need to set sequenceNumber to 0
|
||||||
transaction.getInputs().stream().forEach(i -> i.setSequenceNumber(0));
|
transaction.getInputs().stream().forEach(i -> i.setSequenceNumber(0));
|
||||||
transaction.setLockTime(lockTime);
|
transaction.setLockTime(lockTime);
|
||||||
|
|
|
@ -170,7 +170,7 @@ public class WalletService {
|
||||||
backupWallet();
|
backupWallet();
|
||||||
|
|
||||||
final Socks5Proxy socks5Proxy = preferences.getUseTorForBitcoinJ() ? socks5ProxyProvider.getSocks5Proxy() : null;
|
final Socks5Proxy socks5Proxy = preferences.getUseTorForBitcoinJ() ? socks5ProxyProvider.getSocks5Proxy() : null;
|
||||||
log.info("Use socks5Proxy for bitcoinj: " + socks5Proxy);
|
log.debug("Use socks5Proxy for bitcoinj: " + socks5Proxy);
|
||||||
|
|
||||||
// If seed is non-null it means we are restoring from backup.
|
// If seed is non-null it means we are restoring from backup.
|
||||||
walletAppKit = new WalletAppKitBitSquare(params, socks5Proxy, walletDir, "Bitsquare") {
|
walletAppKit = new WalletAppKitBitSquare(params, socks5Proxy, walletDir, "Bitsquare") {
|
||||||
|
@ -714,7 +714,7 @@ public class WalletService {
|
||||||
public void doubleSpendTransaction(Transaction txToDoubleSpend, Address toAddress, Runnable resultHandler, ErrorMessageHandler errorMessageHandler) throws InsufficientMoneyException, AddressFormatException, AddressEntryException {
|
public void doubleSpendTransaction(Transaction txToDoubleSpend, Address toAddress, Runnable resultHandler, ErrorMessageHandler errorMessageHandler) throws InsufficientMoneyException, AddressFormatException, AddressEntryException {
|
||||||
final TransactionConfidence.ConfidenceType confidenceType = txToDoubleSpend.getConfidence().getConfidenceType();
|
final TransactionConfidence.ConfidenceType confidenceType = txToDoubleSpend.getConfidence().getConfidenceType();
|
||||||
if (confidenceType == TransactionConfidence.ConfidenceType.PENDING) {
|
if (confidenceType == TransactionConfidence.ConfidenceType.PENDING) {
|
||||||
log.info("txToDoubleSpend nr. of inputs " + txToDoubleSpend.getInputs().size());
|
log.debug("txToDoubleSpend nr. of inputs " + txToDoubleSpend.getInputs().size());
|
||||||
|
|
||||||
Transaction newTransaction = new Transaction(params);
|
Transaction newTransaction = new Transaction(params);
|
||||||
txToDoubleSpend.getInputs().stream().forEach(input -> {
|
txToDoubleSpend.getInputs().stream().forEach(input -> {
|
||||||
|
@ -739,8 +739,8 @@ public class WalletService {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
log.info("newTransaction nr. of inputs " + newTransaction.getInputs().size());
|
log.debug("newTransaction nr. of inputs " + newTransaction.getInputs().size());
|
||||||
log.info("newTransaction size in kB " + newTransaction.bitcoinSerialize().length / 1024);
|
log.debug("newTransaction size in kB " + newTransaction.bitcoinSerialize().length / 1024);
|
||||||
|
|
||||||
if (!newTransaction.getInputs().isEmpty()) {
|
if (!newTransaction.getInputs().isEmpty()) {
|
||||||
Coin amount = Coin.valueOf(newTransaction.getInputs().stream()
|
Coin amount = Coin.valueOf(newTransaction.getInputs().stream()
|
||||||
|
@ -795,7 +795,7 @@ public class WalletService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sendResult != null) {
|
if (sendResult != null) {
|
||||||
log.info("Broadcasting double spending transaction. " + newTransaction);
|
log.debug("Broadcasting double spending transaction. " + newTransaction);
|
||||||
Futures.addCallback(sendResult.broadcastComplete, new FutureCallback<Transaction>() {
|
Futures.addCallback(sendResult.broadcastComplete, new FutureCallback<Transaction>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(Transaction result) {
|
public void onSuccess(Transaction result) {
|
||||||
|
@ -835,9 +835,9 @@ public class WalletService {
|
||||||
newSendRequest.feePerKb = FeePolicy.getNonTradeFeePerKb();
|
newSendRequest.feePerKb = FeePolicy.getNonTradeFeePerKb();
|
||||||
wallet.completeTx(newSendRequest);
|
wallet.completeTx(newSendRequest);
|
||||||
|
|
||||||
log.info("After fee check: amount " + amount.toFriendlyString());
|
log.debug("After fee check: amount " + amount.toFriendlyString());
|
||||||
log.info("Output fee " + sendRequest.tx.getFee().toFriendlyString());
|
log.debug("Output fee " + sendRequest.tx.getFee().toFriendlyString());
|
||||||
sendRequest.tx.getOutputs().stream().forEach(o -> log.info("Output value " + o.getValue().toFriendlyString()));
|
sendRequest.tx.getOutputs().stream().forEach(o -> log.debug("Output value " + o.getValue().toFriendlyString()));
|
||||||
} catch (InsufficientMoneyException e) {
|
} catch (InsufficientMoneyException e) {
|
||||||
if (e.missing != null) {
|
if (e.missing != null) {
|
||||||
log.trace("missing fee " + e.missing.toFriendlyString());
|
log.trace("missing fee " + e.missing.toFriendlyString());
|
||||||
|
|
|
@ -38,7 +38,7 @@ public class BlockchainService {
|
||||||
Futures.addCallback(future, new FutureCallback<Coin>() {
|
Futures.addCallback(future, new FutureCallback<Coin>() {
|
||||||
public void onSuccess(Coin fee) {
|
public void onSuccess(Coin fee) {
|
||||||
if (!resultFuture.isDone()) {
|
if (!resultFuture.isDone()) {
|
||||||
log.info("Request fee from providers done after {} ms.", (System.currentTimeMillis() - startTime));
|
log.debug("Request fee from providers done after {} ms.", (System.currentTimeMillis() - startTime));
|
||||||
resultFuture.set(fee);
|
resultFuture.set(fee);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ class GetFeeRequest {
|
||||||
try {
|
try {
|
||||||
return provider.getFee(transactionId);
|
return provider.getFee(transactionId);
|
||||||
} catch (IOException | HttpException e) {
|
} catch (IOException | HttpException e) {
|
||||||
log.info("Fee request failed for tx {} from provider {}\n" +
|
log.debug("Fee request failed for tx {} from provider {}\n" +
|
||||||
"That is expected if the tx was not propagated yet to the provider.\n" +
|
"That is expected if the tx was not propagated yet to the provider.\n" +
|
||||||
"error={}",
|
"error={}",
|
||||||
transactionId, provider, e.getMessage());
|
transactionId, provider, e.getMessage());
|
||||||
|
@ -43,7 +43,7 @@ class GetFeeRequest {
|
||||||
|
|
||||||
Futures.addCallback(future, new FutureCallback<Coin>() {
|
Futures.addCallback(future, new FutureCallback<Coin>() {
|
||||||
public void onSuccess(Coin fee) {
|
public void onSuccess(Coin fee) {
|
||||||
log.info("Received fee of {}\nfor tx {}\nfrom provider {}", fee.toFriendlyString(), transactionId, provider);
|
log.debug("Received fee of {}\nfor tx {}\nfrom provider {}", fee.toFriendlyString(), transactionId, provider);
|
||||||
resultFuture.set(fee);
|
resultFuture.set(fee);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,7 @@ class GetPriceRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onFailure(@NotNull Throwable throwable) {
|
public void onFailure(@NotNull Throwable throwable) {
|
||||||
|
log.error("requestPrice.onFailure: throwable=" + throwable.toString());
|
||||||
resultFuture.setException(throwable);
|
resultFuture.setException(throwable);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -46,7 +46,7 @@ public class PriceFeedService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final long PERIOD_FIAT_SEC = new Random().nextInt(5) + 90;
|
private static final long PERIOD_FIAT_SEC = new Random().nextInt(5) + 70;
|
||||||
private static final long PERIOD_ALL_FIAT_SEC = new Random().nextInt(5) + 180;
|
private static final long PERIOD_ALL_FIAT_SEC = new Random().nextInt(5) + 180;
|
||||||
private static final long PERIOD_ALL_CRYPTO_SEC = new Random().nextInt(5) + 180;
|
private static final long PERIOD_ALL_CRYPTO_SEC = new Random().nextInt(5) + 180;
|
||||||
|
|
||||||
|
@ -63,8 +63,7 @@ public class PriceFeedService {
|
||||||
private long bitcoinAveragePriceProviderLastCallAllTs;
|
private long bitcoinAveragePriceProviderLastCallAllTs;
|
||||||
private long poloniexPriceProviderLastCallAllTs;
|
private long poloniexPriceProviderLastCallAllTs;
|
||||||
private long bitcoinAveragePriceProviderLastCallTs;
|
private long bitcoinAveragePriceProviderLastCallTs;
|
||||||
private Timer cryptoCurrenciesTime;
|
private Timer requestFiatPriceTimer;
|
||||||
private Timer fiatCurrenciesTime;
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -86,20 +85,11 @@ public class PriceFeedService {
|
||||||
this.priceConsumer = resultHandler;
|
this.priceConsumer = resultHandler;
|
||||||
this.faultHandler = faultHandler;
|
this.faultHandler = faultHandler;
|
||||||
|
|
||||||
requestAllPrices(fiatPriceProvider, () -> {
|
requestAllPrices(fiatPriceProvider, () -> applyPriceToConsumer());
|
||||||
applyPrice();
|
UserThread.runPeriodically(() -> requestAllPrices(fiatPriceProvider, this::applyPriceToConsumer), PERIOD_ALL_FIAT_SEC);
|
||||||
if (fiatCurrenciesTime == null)
|
|
||||||
fiatCurrenciesTime = UserThread.runPeriodically(() -> requestPrice(fiatPriceProvider), PERIOD_FIAT_SEC);
|
|
||||||
});
|
|
||||||
|
|
||||||
requestAllPrices(cryptoCurrenciesPriceProvider, () -> {
|
requestAllPrices(cryptoCurrenciesPriceProvider, () -> applyPriceToConsumer());
|
||||||
applyPrice();
|
UserThread.runPeriodically(() -> requestAllPrices(cryptoCurrenciesPriceProvider, this::applyPriceToConsumer), PERIOD_ALL_CRYPTO_SEC);
|
||||||
if (cryptoCurrenciesTime == null)
|
|
||||||
cryptoCurrenciesTime = UserThread.runPeriodically(() -> requestAllPrices(cryptoCurrenciesPriceProvider, this::applyPrice),
|
|
||||||
PERIOD_ALL_CRYPTO_SEC);
|
|
||||||
});
|
|
||||||
|
|
||||||
UserThread.runPeriodically(() -> requestAllPrices(fiatPriceProvider, this::applyPrice), PERIOD_ALL_FIAT_SEC);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@ -110,7 +100,6 @@ public class PriceFeedService {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Setter
|
// Setter
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -118,19 +107,21 @@ public class PriceFeedService {
|
||||||
public void setType(Type type) {
|
public void setType(Type type) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
typeProperty.set(type);
|
typeProperty.set(type);
|
||||||
applyPrice();
|
applyPriceToConsumer();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCurrencyCode(String currencyCode) {
|
public void setCurrencyCode(String currencyCode) {
|
||||||
if (this.currencyCode == null || !this.currencyCode.equals(currencyCode)) {
|
if (this.currencyCode == null || !this.currencyCode.equals(currencyCode)) {
|
||||||
this.currencyCode = currencyCode;
|
this.currencyCode = currencyCode;
|
||||||
currencyCodeProperty.set(currencyCode);
|
currencyCodeProperty.set(currencyCode);
|
||||||
applyPrice();
|
applyPriceToConsumer();
|
||||||
|
|
||||||
if (CurrencyUtil.isCryptoCurrency(currencyCode)) {
|
if (CurrencyUtil.isCryptoCurrency(currencyCode)) {
|
||||||
|
stopRequestFiatPriceTimer();
|
||||||
// Poloniex does not support calls for one currency just for all which is quite a bit of data
|
// Poloniex does not support calls for one currency just for all which is quite a bit of data
|
||||||
requestAllPrices(cryptoCurrenciesPriceProvider, this::applyPrice);
|
requestAllPrices(cryptoCurrenciesPriceProvider, this::applyPriceToConsumer);
|
||||||
} else {
|
} else {
|
||||||
|
startRequestFiatPriceTimer();
|
||||||
requestPrice(fiatPriceProvider);
|
requestPrice(fiatPriceProvider);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -166,12 +157,27 @@ public class PriceFeedService {
|
||||||
// Private
|
// Private
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
private void applyPrice() {
|
|
||||||
|
private void startRequestFiatPriceTimer() {
|
||||||
|
stopRequestFiatPriceTimer();
|
||||||
|
requestFiatPriceTimer = UserThread.runPeriodically(() -> requestPrice(fiatPriceProvider), PERIOD_FIAT_SEC);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void stopRequestFiatPriceTimer() {
|
||||||
|
if (requestFiatPriceTimer != null)
|
||||||
|
requestFiatPriceTimer.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void applyPriceToConsumer() {
|
||||||
if (priceConsumer != null && currencyCode != null && type != null) {
|
if (priceConsumer != null && currencyCode != null && type != null) {
|
||||||
if (cache.containsKey(currencyCode)) {
|
if (cache.containsKey(currencyCode)) {
|
||||||
|
try {
|
||||||
MarketPrice marketPrice = cache.get(currencyCode);
|
MarketPrice marketPrice = cache.get(currencyCode);
|
||||||
if (marketPrice != null)
|
|
||||||
priceConsumer.accept(marketPrice.getPrice(type));
|
priceConsumer.accept(marketPrice.getPrice(type));
|
||||||
|
} catch (Throwable t) {
|
||||||
|
log.warn("Error at applyPriceToConsumer " + t.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
String errorMessage = "We don't have a price for currencyCode " + currencyCode;
|
String errorMessage = "We don't have a price for currencyCode " + currencyCode;
|
||||||
log.debug(errorMessage);
|
log.debug(errorMessage);
|
||||||
|
@ -192,6 +198,7 @@ public class PriceFeedService {
|
||||||
|
|
||||||
if (allowed) {
|
if (allowed) {
|
||||||
GetPriceRequest getPriceRequest = new GetPriceRequest();
|
GetPriceRequest getPriceRequest = new GetPriceRequest();
|
||||||
|
if (CurrencyUtil.isFiatCurrency(currencyCode)) {
|
||||||
SettableFuture<MarketPrice> future = getPriceRequest.requestPrice(currencyCode, provider);
|
SettableFuture<MarketPrice> future = getPriceRequest.requestPrice(currencyCode, provider);
|
||||||
Futures.addCallback(future, new FutureCallback<MarketPrice>() {
|
Futures.addCallback(future, new FutureCallback<MarketPrice>() {
|
||||||
public void onSuccess(MarketPrice marketPrice) {
|
public void onSuccess(MarketPrice marketPrice) {
|
||||||
|
@ -207,6 +214,9 @@ public class PriceFeedService {
|
||||||
log.debug("Could not load marketPrice\n" + throwable.getMessage());
|
log.debug("Could not load marketPrice\n" + throwable.getMessage());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
log.warn("We tried to call requestPrice with a non fiat currency selected: selectedCurrencyCode=" + currencyCode);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
log.debug("Ignore request. Too many attempt to call the API provider " + provider);
|
log.debug("Ignore request. Too many attempt to call the API provider " + provider);
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,11 +30,11 @@ public class ScryptUtil {
|
||||||
public static void deriveKeyWithScrypt(KeyCrypterScrypt keyCrypterScrypt, String password, DeriveKeyResultHandler resultHandler) {
|
public static void deriveKeyWithScrypt(KeyCrypterScrypt keyCrypterScrypt, String password, DeriveKeyResultHandler resultHandler) {
|
||||||
Utilities.getThreadPoolExecutor("ScryptUtil:deriveKeyWithScrypt-%d", 1, 2, 5L).submit(() -> {
|
Utilities.getThreadPoolExecutor("ScryptUtil:deriveKeyWithScrypt-%d", 1, 2, 5L).submit(() -> {
|
||||||
try {
|
try {
|
||||||
log.info("Doing key derivation");
|
log.debug("Doing key derivation");
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
KeyParameter aesKey = keyCrypterScrypt.deriveKey(password);
|
KeyParameter aesKey = keyCrypterScrypt.deriveKey(password);
|
||||||
long duration = System.currentTimeMillis() - start;
|
long duration = System.currentTimeMillis() - start;
|
||||||
log.info("Key derivation took {} msec", duration);
|
log.debug("Key derivation took {} msec", duration);
|
||||||
UserThread.execute(() -> {
|
UserThread.execute(() -> {
|
||||||
try {
|
try {
|
||||||
resultHandler.handleResult(aesKey);
|
resultHandler.handleResult(aesKey);
|
||||||
|
|
32
core/src/main/java/io/bitsquare/locale/CurrencyTuple.java
Normal file
32
core/src/main/java/io/bitsquare/locale/CurrencyTuple.java
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.locale;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
public class CurrencyTuple implements Serializable {
|
||||||
|
// That object is used for serializing to a Json file.
|
||||||
|
|
||||||
|
public final String code;
|
||||||
|
public final String name;
|
||||||
|
|
||||||
|
public CurrencyTuple(String code, String name) {
|
||||||
|
this.code = code;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
}
|
|
@ -65,18 +65,20 @@ public final class TradableList<T extends Tradable> extends ArrayList<T> impleme
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean add(T tradable) {
|
public boolean add(T tradable) {
|
||||||
boolean result = super.add(tradable);
|
boolean changed = super.add(tradable);
|
||||||
getObservableList().add(tradable);
|
getObservableList().add(tradable);
|
||||||
|
if (changed)
|
||||||
storage.queueUpForSave();
|
storage.queueUpForSave();
|
||||||
return result;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean remove(Object tradable) {
|
public boolean remove(Object tradable) {
|
||||||
boolean result = super.remove(tradable);
|
boolean changed = super.remove(tradable);
|
||||||
getObservableList().remove(tradable);
|
getObservableList().remove(tradable);
|
||||||
|
if (changed)
|
||||||
storage.queueUpForSave();
|
storage.queueUpForSave();
|
||||||
return result;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObservableList<T> getObservableList() {
|
public ObservableList<T> getObservableList() {
|
||||||
|
|
|
@ -316,15 +316,19 @@ public abstract class Trade implements Tradable, Model {
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
public void setState(State state) {
|
public void setState(State state) {
|
||||||
|
boolean changed = this.state != state;
|
||||||
this.state = state;
|
this.state = state;
|
||||||
stateProperty.set(state);
|
stateProperty.set(state);
|
||||||
|
if (changed)
|
||||||
persist();
|
persist();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDisputeState(DisputeState disputeState) {
|
public void setDisputeState(DisputeState disputeState) {
|
||||||
Log.traceCall("disputeState=" + disputeState + "\n\ttrade=" + this);
|
Log.traceCall("disputeState=" + disputeState + "\n\ttrade=" + this);
|
||||||
|
boolean changed = this.disputeState != disputeState;
|
||||||
this.disputeState = disputeState;
|
this.disputeState = disputeState;
|
||||||
disputeStateProperty.set(disputeState);
|
disputeStateProperty.set(disputeState);
|
||||||
|
if (changed)
|
||||||
persist();
|
persist();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -333,8 +337,10 @@ public abstract class Trade implements Tradable, Model {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTradePeriodState(TradePeriodState tradePeriodState) {
|
public void setTradePeriodState(TradePeriodState tradePeriodState) {
|
||||||
|
boolean changed = this.tradePeriodState != tradePeriodState;
|
||||||
this.tradePeriodState = tradePeriodState;
|
this.tradePeriodState = tradePeriodState;
|
||||||
tradePeriodStateProperty.set(tradePeriodState);
|
tradePeriodStateProperty.set(tradePeriodState);
|
||||||
|
if (changed)
|
||||||
persist();
|
persist();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,8 +75,6 @@ import static io.bitsquare.util.Validator.nonEmptyStringOf;
|
||||||
public class TradeManager {
|
public class TradeManager {
|
||||||
private static final Logger log = LoggerFactory.getLogger(TradeManager.class);
|
private static final Logger log = LoggerFactory.getLogger(TradeManager.class);
|
||||||
|
|
||||||
private static final long REPUBLISH_STATISTICS_INTERVAL_MIN = TimeUnit.HOURS.toMillis(1);
|
|
||||||
|
|
||||||
private final User user;
|
private final User user;
|
||||||
private final KeyRing keyRing;
|
private final KeyRing keyRing;
|
||||||
private final WalletService walletService;
|
private final WalletService walletService;
|
||||||
|
@ -223,17 +221,9 @@ public class TradeManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
// We start later to have better connectivity to the network
|
// We start later to have better connectivity to the network
|
||||||
UserThread.runPeriodically(() -> publishTradeStatistics(tradesForStatistics),
|
UserThread.runAfter(() -> publishTradeStatistics(tradesForStatistics),
|
||||||
30, TimeUnit.SECONDS);
|
30, TimeUnit.SECONDS);
|
||||||
|
|
||||||
//TODO can be removed at next release
|
|
||||||
// For the first 2 weeks of the release we re publish the trades to get faster good distribution
|
|
||||||
// otherwise the trades would only be published again at restart and if a client dont do that the stats might be missing
|
|
||||||
// for a longer time as initially there are not many peer upgraded and supporting flooding of the stats data.
|
|
||||||
if (new Date().before(new Date(2016 - 1900, Calendar.AUGUST, 8)))
|
|
||||||
UserThread.runPeriodically(() -> publishTradeStatistics(tradesForStatistics),
|
|
||||||
REPUBLISH_STATISTICS_INTERVAL_MIN, TimeUnit.MILLISECONDS);
|
|
||||||
|
|
||||||
pendingTradesInitialized.set(true);
|
pendingTradesInitialized.set(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,7 +239,8 @@ public class TradeManager {
|
||||||
tradeStatisticsManager.add(tradeStatistics);
|
tradeStatisticsManager.add(tradeStatistics);
|
||||||
|
|
||||||
// Only trades from last 30 days
|
// Only trades from last 30 days
|
||||||
if ((new Date().getTime() - trade.getDate().getTime()) < TimeUnit.DAYS.toMillis(30)) {
|
//TODO we want to get old trades published so we dont do the 30 days check for the first few weeks of the new version
|
||||||
|
if (new Date().before(new Date(2016 - 1900, Calendar.AUGUST, 30)) || (new Date().getTime() - trade.getDate().getTime()) < TimeUnit.DAYS.toMillis(30)) {
|
||||||
long delay = 3000;
|
long delay = 3000;
|
||||||
final long minDelay = (i + 1) * delay;
|
final long minDelay = (i + 1) * delay;
|
||||||
final long maxDelay = (i + 2) * delay;
|
final long maxDelay = (i + 2) * delay;
|
||||||
|
@ -289,7 +280,7 @@ public class TradeManager {
|
||||||
// TODO respond
|
// TODO respond
|
||||||
//(RequestDepositTxInputsMessage)message.
|
//(RequestDepositTxInputsMessage)message.
|
||||||
// messageService.sendEncryptedMessage(peerAddress,messageWithPubKey.getMessage().);
|
// messageService.sendEncryptedMessage(peerAddress,messageWithPubKey.getMessage().);
|
||||||
log.info("We received a take offer request but don't have that offer anymore.");
|
log.debug("We received a take offer request but don't have that offer anymore.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -391,7 +382,7 @@ public class TradeManager {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(@javax.annotation.Nullable Transaction transaction) {
|
public void onSuccess(@javax.annotation.Nullable Transaction transaction) {
|
||||||
if (transaction != null) {
|
if (transaction != null) {
|
||||||
log.info("onWithdraw onSuccess tx ID:" + transaction.getHashAsString());
|
log.debug("onWithdraw onSuccess tx ID:" + transaction.getHashAsString());
|
||||||
addTradeToClosedTrades(trade);
|
addTradeToClosedTrades(trade);
|
||||||
trade.setState(Trade.State.WITHDRAW_COMPLETED);
|
trade.setState(Trade.State.WITHDRAW_COMPLETED);
|
||||||
resultHandler.handleResult();
|
resultHandler.handleResult();
|
||||||
|
|
|
@ -68,6 +68,7 @@ public final class OpenOffer implements Tradable {
|
||||||
log.warn("Cannot be deserialized." + t.getMessage());
|
log.warn("Cannot be deserialized." + t.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Date getDate() {
|
public Date getDate() {
|
||||||
return offer.getDate();
|
return offer.getDate();
|
||||||
}
|
}
|
||||||
|
@ -92,7 +93,9 @@ public final class OpenOffer implements Tradable {
|
||||||
|
|
||||||
public void setState(State state) {
|
public void setState(State state) {
|
||||||
log.trace("setState" + state);
|
log.trace("setState" + state);
|
||||||
|
boolean changed = this.state != state;
|
||||||
this.state = state;
|
this.state = state;
|
||||||
|
if (changed)
|
||||||
storage.queueUpForSave();
|
storage.queueUpForSave();
|
||||||
|
|
||||||
// We keep it reserved for a limited time, if trade preparation fails we revert to available state
|
// We keep it reserved for a limited time, if trade preparation fails we revert to available state
|
||||||
|
@ -111,7 +114,7 @@ public final class OpenOffer implements Tradable {
|
||||||
stopTimeout();
|
stopTimeout();
|
||||||
|
|
||||||
timeoutTimer = UserThread.runAfter(() -> {
|
timeoutTimer = UserThread.runAfter(() -> {
|
||||||
log.info("Timeout for resettin State.RESERVED reached");
|
log.debug("Timeout for resettin State.RESERVED reached");
|
||||||
if (state == State.RESERVED)
|
if (state == State.RESERVED)
|
||||||
setState(State.AVAILABLE);
|
setState(State.AVAILABLE);
|
||||||
}, TIMEOUT_SEC);
|
}, TIMEOUT_SEC);
|
||||||
|
|
|
@ -152,7 +152,7 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
||||||
stopPeriodicRepublishOffersTimer();
|
stopPeriodicRepublishOffersTimer();
|
||||||
stopRetryRepublishOffersTimer();
|
stopRetryRepublishOffersTimer();
|
||||||
|
|
||||||
log.info("remove all open offers at shutDown");
|
log.debug("remove all open offers at shutDown");
|
||||||
// we remove own offers from offerbook when we go offline
|
// we remove own offers from offerbook when we go offline
|
||||||
// Normally we use a delay for broadcasting to the peers, but at shut down we want to get it fast out
|
// Normally we use a delay for broadcasting to the peers, but at shut down we want to get it fast out
|
||||||
|
|
||||||
|
@ -407,12 +407,12 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFault() {
|
public void onFault() {
|
||||||
log.info("Sending OfferAvailabilityResponse failed.");
|
log.debug("Sending OfferAvailabilityResponse failed.");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
t.printStackTrace();
|
t.printStackTrace();
|
||||||
log.info("Exception at handleRequestIsOfferAvailableMessage " + t.getMessage());
|
log.debug("Exception at handleRequestIsOfferAvailableMessage " + t.getMessage());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.debug("We have stopped already. We ignore that handleOfferAvailabilityRequest call.");
|
log.debug("We have stopped already. We ignore that handleOfferAvailabilityRequest call.");
|
||||||
|
@ -505,7 +505,7 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
||||||
// we delay to avoid reaching throttle limits
|
// we delay to avoid reaching throttle limits
|
||||||
// roughly 4 offers per second
|
// roughly 4 offers per second
|
||||||
|
|
||||||
long delay = 150;
|
long delay = 300;
|
||||||
final long minDelay = (i + 1) * delay;
|
final long minDelay = (i + 1) * delay;
|
||||||
final long maxDelay = (i + 2) * delay;
|
final long maxDelay = (i + 2) * delay;
|
||||||
final OpenOffer openOffer = openOffersList.get(i);
|
final OpenOffer openOffer = openOffersList.get(i);
|
||||||
|
@ -532,7 +532,7 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
||||||
}
|
}
|
||||||
|
|
||||||
private void restart() {
|
private void restart() {
|
||||||
log.info("Restart after connection loss");
|
log.debug("Restart after connection loss");
|
||||||
if (retryRepublishOffersTimer == null)
|
if (retryRepublishOffersTimer == null)
|
||||||
retryRepublishOffersTimer = UserThread.runAfter(() -> {
|
retryRepublishOffersTimer = UserThread.runAfter(() -> {
|
||||||
stopped = false;
|
stopped = false;
|
||||||
|
|
|
@ -135,7 +135,7 @@ public class OfferAvailabilityProtocol {
|
||||||
private void startTimeout() {
|
private void startTimeout() {
|
||||||
if (timeoutTimer == null) {
|
if (timeoutTimer == null) {
|
||||||
timeoutTimer = UserThread.runAfter(() -> {
|
timeoutTimer = UserThread.runAfter(() -> {
|
||||||
log.warn("Timeout reached at " + this);
|
log.debug("Timeout reached at " + this);
|
||||||
model.offer.setState(Offer.State.OFFERER_OFFLINE);
|
model.offer.setState(Offer.State.OFFERER_OFFLINE);
|
||||||
errorMessageHandler.handleErrorMessage("Timeout reached: Peer has not responded.");
|
errorMessageHandler.handleErrorMessage("Timeout reached: Peer has not responded.");
|
||||||
}, TIMEOUT_SEC);
|
}, TIMEOUT_SEC);
|
||||||
|
|
|
@ -44,7 +44,7 @@ public class BroadcastCreateOfferFeeTx extends Task<PlaceOfferModel> {
|
||||||
model.tradeWalletService.broadcastTx(model.getTransaction(), new FutureCallback<Transaction>() {
|
model.tradeWalletService.broadcastTx(model.getTransaction(), new FutureCallback<Transaction>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(Transaction transaction) {
|
public void onSuccess(Transaction transaction) {
|
||||||
log.info("Broadcast of offer fee payment succeeded: transaction = " + transaction.toString());
|
log.debug("Broadcast of offer fee payment succeeded: transaction = " + transaction.toString());
|
||||||
|
|
||||||
if (model.getTransaction().getHashAsString().equals(transaction.getHashAsString())) {
|
if (model.getTransaction().getHashAsString().equals(transaction.getHashAsString())) {
|
||||||
model.offer.setState(Offer.State.OFFER_FEE_PAID);
|
model.offer.setState(Offer.State.OFFER_FEE_PAID);
|
||||||
|
@ -57,7 +57,7 @@ public class BroadcastCreateOfferFeeTx extends Task<PlaceOfferModel> {
|
||||||
// Normally we use a delay for broadcasting to the peers, but at shut down we want to get it fast out
|
// Normally we use a delay for broadcasting to the peers, but at shut down we want to get it fast out
|
||||||
model.offerBookService.removeOffer(model.offer,
|
model.offerBookService.removeOffer(model.offer,
|
||||||
() -> {
|
() -> {
|
||||||
log.info("We store now the changed txID to the offer and add that again.");
|
log.debug("We store now the changed txID to the offer and add that again.");
|
||||||
// We store now the changed txID to the offer and add that again.
|
// We store now the changed txID to the offer and add that again.
|
||||||
model.offer.setOfferFeePaymentTxID(transaction.getHashAsString());
|
model.offer.setOfferFeePaymentTxID(transaction.getHashAsString());
|
||||||
model.setTransaction(transaction);
|
model.setTransaction(transaction);
|
||||||
|
@ -106,7 +106,7 @@ public class BroadcastCreateOfferFeeTx extends Task<PlaceOfferModel> {
|
||||||
if (!removeOfferFailed && !addOfferFailed) {
|
if (!removeOfferFailed && !addOfferFailed) {
|
||||||
// If broadcast fails we need to remove offer from offerbook
|
// If broadcast fails we need to remove offer from offerbook
|
||||||
model.offerBookService.removeOffer(model.offer,
|
model.offerBookService.removeOffer(model.offer,
|
||||||
() -> log.info("Offer removed from offerbook because broadcast failed."),
|
() -> log.debug("Offer removed from offerbook because broadcast failed."),
|
||||||
errorMessage -> log.error("removeOffer failed. " + errorMessage));
|
errorMessage -> log.error("removeOffer failed. " + errorMessage));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,7 @@ public abstract class TradeTask extends Task<Trade> {
|
||||||
if (processModel.getTradeMessage() instanceof MailboxMessage) {
|
if (processModel.getTradeMessage() instanceof MailboxMessage) {
|
||||||
DecryptedMsgWithPubKey mailboxMessage = trade.getMailboxMessage();
|
DecryptedMsgWithPubKey mailboxMessage = trade.getMailboxMessage();
|
||||||
if (mailboxMessage != null && mailboxMessage.message.equals(processModel.getTradeMessage())) {
|
if (mailboxMessage != null && mailboxMessage.message.equals(processModel.getTradeMessage())) {
|
||||||
log.info("Remove mailboxMessage from P2P network. mailboxMessage = " + mailboxMessage);
|
log.debug("Remove mailboxMessage from P2P network. mailboxMessage = " + mailboxMessage);
|
||||||
processModel.getP2PService().removeEntryFromMailbox(mailboxMessage);
|
processModel.getP2PService().removeEntryFromMailbox(mailboxMessage);
|
||||||
trade.setMailboxMessage(null);
|
trade.setMailboxMessage(null);
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ public class OffererCreatesAndSignsDepositTxAsBuyer extends TradeTask {
|
||||||
Coin buyerInputAmount = FeePolicy.getSecurityDeposit().add(FeePolicy.getFixedTxFeeForTrades());
|
Coin buyerInputAmount = FeePolicy.getSecurityDeposit().add(FeePolicy.getFixedTxFeeForTrades());
|
||||||
Coin msOutputAmount = buyerInputAmount.add(FeePolicy.getSecurityDeposit()).add(trade.getTradeAmount());
|
Coin msOutputAmount = buyerInputAmount.add(FeePolicy.getSecurityDeposit()).add(trade.getTradeAmount());
|
||||||
|
|
||||||
log.info("\n\n------------------------------------------------------------\n"
|
log.debug("\n\n------------------------------------------------------------\n"
|
||||||
+ "Contract as json\n"
|
+ "Contract as json\n"
|
||||||
+ trade.getContractAsJson()
|
+ trade.getContractAsJson()
|
||||||
+ "\n------------------------------------------------------------\n");
|
+ "\n------------------------------------------------------------\n");
|
||||||
|
|
|
@ -48,14 +48,14 @@ public class SendFiatTransferStartedMessage extends TradeTask {
|
||||||
new SendMailboxMessageListener() {
|
new SendMailboxMessageListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onArrived() {
|
public void onArrived() {
|
||||||
log.info("Message arrived at peer.");
|
log.debug("Message arrived at peer.");
|
||||||
trade.setState(Trade.State.BUYER_SENT_FIAT_PAYMENT_INITIATED_MSG);
|
trade.setState(Trade.State.BUYER_SENT_FIAT_PAYMENT_INITIATED_MSG);
|
||||||
complete();
|
complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStoredInMailbox() {
|
public void onStoredInMailbox() {
|
||||||
log.info("Message stored in mailbox.");
|
log.debug("Message stored in mailbox.");
|
||||||
trade.setState(Trade.State.BUYER_SENT_FIAT_PAYMENT_INITIATED_MSG);
|
trade.setState(Trade.State.BUYER_SENT_FIAT_PAYMENT_INITIATED_MSG);
|
||||||
complete();
|
complete();
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ public class SignAndPublishDepositTxAsBuyer extends TradeTask {
|
||||||
try {
|
try {
|
||||||
runInterceptHook();
|
runInterceptHook();
|
||||||
|
|
||||||
log.info("\n\n------------------------------------------------------------\n"
|
log.debug("\n\n------------------------------------------------------------\n"
|
||||||
+ "Contract as json\n"
|
+ "Contract as json\n"
|
||||||
+ trade.getContractAsJson()
|
+ trade.getContractAsJson()
|
||||||
+ "\n------------------------------------------------------------\n");
|
+ "\n------------------------------------------------------------\n");
|
||||||
|
|
|
@ -46,7 +46,7 @@ public class OffererCreatesAndSignsDepositTxAsSeller extends TradeTask {
|
||||||
Coin sellerInputAmount = FeePolicy.getSecurityDeposit().add(FeePolicy.getFixedTxFeeForTrades()).add(trade.getTradeAmount());
|
Coin sellerInputAmount = FeePolicy.getSecurityDeposit().add(FeePolicy.getFixedTxFeeForTrades()).add(trade.getTradeAmount());
|
||||||
Coin msOutputAmount = sellerInputAmount.add(FeePolicy.getSecurityDeposit());
|
Coin msOutputAmount = sellerInputAmount.add(FeePolicy.getSecurityDeposit());
|
||||||
|
|
||||||
log.info("\n\n------------------------------------------------------------\n"
|
log.debug("\n\n------------------------------------------------------------\n"
|
||||||
+ "Contract as json\n"
|
+ "Contract as json\n"
|
||||||
+ trade.getContractAsJson()
|
+ trade.getContractAsJson()
|
||||||
+ "\n------------------------------------------------------------\n");
|
+ "\n------------------------------------------------------------\n");
|
||||||
|
|
|
@ -46,7 +46,7 @@ public class SignAndPublishDepositTxAsSeller extends TradeTask {
|
||||||
protected void run() {
|
protected void run() {
|
||||||
try {
|
try {
|
||||||
runInterceptHook();
|
runInterceptHook();
|
||||||
log.info("\n\n------------------------------------------------------------\n"
|
log.debug("\n\n------------------------------------------------------------\n"
|
||||||
+ "Contract as json\n"
|
+ "Contract as json\n"
|
||||||
+ trade.getContractAsJson()
|
+ trade.getContractAsJson()
|
||||||
+ "\n------------------------------------------------------------\n");
|
+ "\n------------------------------------------------------------\n");
|
||||||
|
|
|
@ -64,7 +64,7 @@ public class PublishTradeStatistics extends TradeTask {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!matches) {
|
if (!matches) {
|
||||||
log.warn("We publish tradeStatistics because the offerer uses an old version.");
|
log.debug("We publish tradeStatistics because the offerer uses an old version so we publish to have at least 1 data item published.");
|
||||||
processModel.getP2PService().addData(tradeStatistics, true);
|
processModel.getP2PService().addData(tradeStatistics, true);
|
||||||
} else {
|
} else {
|
||||||
log.trace("We do not publish tradeStatistics because the offerer support the capabilities.");
|
log.trace("We do not publish tradeStatistics because the offerer support the capabilities.");
|
||||||
|
|
|
@ -4,6 +4,8 @@ import com.google.inject.Inject;
|
||||||
import com.google.inject.name.Named;
|
import com.google.inject.name.Named;
|
||||||
import io.bitsquare.app.CoreOptionKeys;
|
import io.bitsquare.app.CoreOptionKeys;
|
||||||
import io.bitsquare.common.util.Utilities;
|
import io.bitsquare.common.util.Utilities;
|
||||||
|
import io.bitsquare.locale.CurrencyTuple;
|
||||||
|
import io.bitsquare.locale.CurrencyUtil;
|
||||||
import io.bitsquare.p2p.P2PService;
|
import io.bitsquare.p2p.P2PService;
|
||||||
import io.bitsquare.p2p.storage.HashMapChangedListener;
|
import io.bitsquare.p2p.storage.HashMapChangedListener;
|
||||||
import io.bitsquare.p2p.storage.payload.StoragePayload;
|
import io.bitsquare.p2p.storage.payload.StoragePayload;
|
||||||
|
@ -14,6 +16,7 @@ import javafx.collections.ObservableSet;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
@ -21,22 +24,44 @@ import java.util.stream.Collectors;
|
||||||
public class TradeStatisticsManager {
|
public class TradeStatisticsManager {
|
||||||
private static final Logger log = LoggerFactory.getLogger(TradeStatisticsManager.class);
|
private static final Logger log = LoggerFactory.getLogger(TradeStatisticsManager.class);
|
||||||
|
|
||||||
private final Storage<HashSet<TradeStatistics>> storage;
|
private final Storage<HashSet<TradeStatistics>> statisticsStorage;
|
||||||
private Storage<String> jsonStorage;
|
private Storage<String> fiatCurrencyListJsonStorage;
|
||||||
|
private Storage<String> cryptoCurrencyListJsonStorage;
|
||||||
|
private Storage<String> statisticsJsonStorage;
|
||||||
private boolean dumpStatistics;
|
private boolean dumpStatistics;
|
||||||
private ObservableSet<TradeStatistics> observableTradeStatisticsSet = FXCollections.observableSet();
|
private ObservableSet<TradeStatistics> observableTradeStatisticsSet = FXCollections.observableSet();
|
||||||
private HashSet<TradeStatistics> tradeStatisticsSet = new HashSet<>();
|
private HashSet<TradeStatistics> tradeStatisticsSet = new HashSet<>();
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public TradeStatisticsManager(Storage<HashSet<TradeStatistics>> storage, Storage<String> jsonStorage, P2PService p2PService, @Named(CoreOptionKeys.DUMP_STATISTICS) boolean dumpStatistics) {
|
public TradeStatisticsManager(Storage<HashSet<TradeStatistics>> statisticsStorage,
|
||||||
this.storage = storage;
|
Storage<String> fiatCurrencyListJsonStorage,
|
||||||
this.jsonStorage = jsonStorage;
|
Storage<String> cryptoCurrencyListJsonStorage,
|
||||||
|
Storage<String> statisticsJsonStorage,
|
||||||
|
P2PService p2PService,
|
||||||
|
@Named(CoreOptionKeys.DUMP_STATISTICS) boolean dumpStatistics) {
|
||||||
|
this.statisticsStorage = statisticsStorage;
|
||||||
|
this.fiatCurrencyListJsonStorage = fiatCurrencyListJsonStorage;
|
||||||
|
this.cryptoCurrencyListJsonStorage = cryptoCurrencyListJsonStorage;
|
||||||
|
this.statisticsJsonStorage = statisticsJsonStorage;
|
||||||
this.dumpStatistics = dumpStatistics;
|
this.dumpStatistics = dumpStatistics;
|
||||||
|
|
||||||
if (dumpStatistics)
|
if (dumpStatistics) {
|
||||||
this.jsonStorage.initAndGetPersistedWithFileName("trade_statistics.json");
|
this.statisticsJsonStorage.initAndGetPersistedWithFileName("trade_statistics.json");
|
||||||
|
|
||||||
HashSet<TradeStatistics> persisted = storage.initAndGetPersistedWithFileName("TradeStatistics");
|
this.fiatCurrencyListJsonStorage.initAndGetPersistedWithFileName("fiat_currency_list.json");
|
||||||
|
ArrayList<CurrencyTuple> fiatCurrencyList = new ArrayList<>(CurrencyUtil.getAllSortedFiatCurrencies().stream()
|
||||||
|
.map(e -> new CurrencyTuple(e.getCode(), e.getName()))
|
||||||
|
.collect(Collectors.toList()));
|
||||||
|
fiatCurrencyListJsonStorage.queueUpForSave(Utilities.objectToJson(fiatCurrencyList), 2000);
|
||||||
|
|
||||||
|
this.cryptoCurrencyListJsonStorage.initAndGetPersistedWithFileName("crypto_currency_list.json");
|
||||||
|
ArrayList<CurrencyTuple> cryptoCurrencyList = new ArrayList<>(CurrencyUtil.getAllSortedCryptoCurrencies().stream()
|
||||||
|
.map(e -> new CurrencyTuple(e.getCode(), e.getName()))
|
||||||
|
.collect(Collectors.toList()));
|
||||||
|
cryptoCurrencyListJsonStorage.queueUpForSave(Utilities.objectToJson(cryptoCurrencyList), 2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
HashSet<TradeStatistics> persisted = statisticsStorage.initAndGetPersistedWithFileName("TradeStatistics");
|
||||||
if (persisted != null)
|
if (persisted != null)
|
||||||
persisted.stream().forEach(this::add);
|
persisted.stream().forEach(this::add);
|
||||||
|
|
||||||
|
@ -61,7 +86,7 @@ public class TradeStatisticsManager {
|
||||||
if (!itemAlreadyAdded) {
|
if (!itemAlreadyAdded) {
|
||||||
tradeStatisticsSet.add(tradeStatistics);
|
tradeStatisticsSet.add(tradeStatistics);
|
||||||
observableTradeStatisticsSet.add(tradeStatistics);
|
observableTradeStatisticsSet.add(tradeStatistics);
|
||||||
storage.queueUpForSave(tradeStatisticsSet, 2000);
|
statisticsStorage.queueUpForSave(new HashSet<>(tradeStatisticsSet), 2000);
|
||||||
|
|
||||||
dump();
|
dump();
|
||||||
} else {
|
} else {
|
||||||
|
@ -86,7 +111,7 @@ public class TradeStatisticsManager {
|
||||||
list.sort((o1, o2) -> (o1.tradeDate < o2.tradeDate ? 1 : (o1.tradeDate == o2.tradeDate ? 0 : -1)));
|
list.sort((o1, o2) -> (o1.tradeDate < o2.tradeDate ? 1 : (o1.tradeDate == o2.tradeDate ? 0 : -1)));
|
||||||
TradeStatistics[] array = new TradeStatistics[tradeStatisticsSet.size()];
|
TradeStatistics[] array = new TradeStatistics[tradeStatisticsSet.size()];
|
||||||
list.toArray(array);
|
list.toArray(array);
|
||||||
jsonStorage.queueUpForSave(Utilities.objectToJson(array), 5_000);
|
statisticsJsonStorage.queueUpForSave(Utilities.objectToJson(array), 5000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -121,8 +121,10 @@ public final class Preferences implements Persistable {
|
||||||
private long nonTradeTxFeePerKB = FeePolicy.getNonTradeFeePerKb().value;
|
private long nonTradeTxFeePerKB = FeePolicy.getNonTradeFeePerKb().value;
|
||||||
private double maxPriceDistanceInPercent;
|
private double maxPriceDistanceInPercent;
|
||||||
private boolean useInvertedMarketPrice;
|
private boolean useInvertedMarketPrice;
|
||||||
private String marketScreenCurrencyCode = CurrencyUtil.getDefaultTradeCurrency().getCode();
|
|
||||||
private String tradeStatisticsScreenCurrencyCode = CurrencyUtil.getDefaultTradeCurrency().getCode();
|
private String offerBookChartScreenCurrencyCode = CurrencyUtil.getDefaultTradeCurrency().getCode();
|
||||||
|
private String tradeChartsScreenCurrencyCode = CurrencyUtil.getDefaultTradeCurrency().getCode();
|
||||||
|
|
||||||
private String buyScreenCurrencyCode = CurrencyUtil.getDefaultTradeCurrency().getCode();
|
private String buyScreenCurrencyCode = CurrencyUtil.getDefaultTradeCurrency().getCode();
|
||||||
private String sellScreenCurrencyCode = CurrencyUtil.getDefaultTradeCurrency().getCode();
|
private String sellScreenCurrencyCode = CurrencyUtil.getDefaultTradeCurrency().getCode();
|
||||||
private int tradeStatisticsTickUnitIndex = 0;
|
private int tradeStatisticsTickUnitIndex = 0;
|
||||||
|
@ -215,10 +217,10 @@ public final class Preferences implements Persistable {
|
||||||
if (persisted.getPeerTagMap() != null)
|
if (persisted.getPeerTagMap() != null)
|
||||||
peerTagMap = persisted.getPeerTagMap();
|
peerTagMap = persisted.getPeerTagMap();
|
||||||
|
|
||||||
marketScreenCurrencyCode = persisted.getMarketScreenCurrencyCode();
|
offerBookChartScreenCurrencyCode = persisted.getOfferBookChartScreenCurrencyCode();
|
||||||
buyScreenCurrencyCode = persisted.getBuyScreenCurrencyCode();
|
buyScreenCurrencyCode = persisted.getBuyScreenCurrencyCode();
|
||||||
sellScreenCurrencyCode = persisted.getSellScreenCurrencyCode();
|
sellScreenCurrencyCode = persisted.getSellScreenCurrencyCode();
|
||||||
tradeStatisticsScreenCurrencyCode = persisted.getTradeStatisticsScreenCurrencyCode();
|
tradeChartsScreenCurrencyCode = persisted.getTradeChartsScreenCurrencyCode();
|
||||||
tradeStatisticsTickUnitIndex = persisted.getTradeStatisticsTickUnitIndex();
|
tradeStatisticsTickUnitIndex = persisted.getTradeStatisticsTickUnitIndex();
|
||||||
|
|
||||||
if (persisted.getIgnoreTradersList() != null)
|
if (persisted.getIgnoreTradersList() != null)
|
||||||
|
@ -449,8 +451,8 @@ public final class Preferences implements Persistable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMarketScreenCurrencyCode(String marketScreenCurrencyCode) {
|
public void setOfferBookChartScreenCurrencyCode(String offerBookChartScreenCurrencyCode) {
|
||||||
this.marketScreenCurrencyCode = marketScreenCurrencyCode;
|
this.offerBookChartScreenCurrencyCode = offerBookChartScreenCurrencyCode;
|
||||||
storage.queueUpForSave();
|
storage.queueUpForSave();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -474,8 +476,8 @@ public final class Preferences implements Persistable {
|
||||||
storage.queueUpForSave();
|
storage.queueUpForSave();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTradeStatisticsScreenCurrencyCode(String tradeStatisticsScreenCurrencyCode) {
|
public void setTradeChartsScreenCurrencyCode(String tradeChartsScreenCurrencyCode) {
|
||||||
this.tradeStatisticsScreenCurrencyCode = tradeStatisticsScreenCurrencyCode;
|
this.tradeChartsScreenCurrencyCode = tradeChartsScreenCurrencyCode;
|
||||||
storage.queueUpForSave();
|
storage.queueUpForSave();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -486,6 +488,7 @@ public final class Preferences implements Persistable {
|
||||||
|
|
||||||
public void setUseTorForHttpRequests(boolean useTorForHttpRequests) {
|
public void setUseTorForHttpRequests(boolean useTorForHttpRequests) {
|
||||||
useTorForHttpRequestsProperty.set(useTorForHttpRequests);
|
useTorForHttpRequestsProperty.set(useTorForHttpRequests);
|
||||||
|
storage.queueUpForSave();
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -620,8 +623,8 @@ public final class Preferences implements Persistable {
|
||||||
return bridgeAddresses;
|
return bridgeAddresses;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getMarketScreenCurrencyCode() {
|
public String getOfferBookChartScreenCurrencyCode() {
|
||||||
return marketScreenCurrencyCode;
|
return offerBookChartScreenCurrencyCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getBuyScreenCurrencyCode() {
|
public String getBuyScreenCurrencyCode() {
|
||||||
|
@ -640,8 +643,8 @@ public final class Preferences implements Persistable {
|
||||||
return defaultPath;
|
return defaultPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTradeStatisticsScreenCurrencyCode() {
|
public String getTradeChartsScreenCurrencyCode() {
|
||||||
return tradeStatisticsScreenCurrencyCode;
|
return tradeChartsScreenCurrencyCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getTradeStatisticsTickUnitIndex() {
|
public int getTradeStatisticsTickUnitIndex() {
|
||||||
|
@ -679,11 +682,11 @@ public final class Preferences implements Persistable {
|
||||||
|
|
||||||
private void setBlockChainExplorerTestNet(BlockChainExplorer blockChainExplorerTestNet) {
|
private void setBlockChainExplorerTestNet(BlockChainExplorer blockChainExplorerTestNet) {
|
||||||
this.blockChainExplorerTestNet = blockChainExplorerTestNet;
|
this.blockChainExplorerTestNet = blockChainExplorerTestNet;
|
||||||
storage.queueUpForSave(2000);
|
storage.queueUpForSave();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setBlockChainExplorerMainNet(BlockChainExplorer blockChainExplorerMainNet) {
|
private void setBlockChainExplorerMainNet(BlockChainExplorer blockChainExplorerMainNet) {
|
||||||
this.blockChainExplorerMainNet = blockChainExplorerMainNet;
|
this.blockChainExplorerMainNet = blockChainExplorerMainNet;
|
||||||
storage.queueUpForSave(2000);
|
storage.queueUpForSave();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -181,7 +181,8 @@ public final class User implements Persistable {
|
||||||
|
|
||||||
public void addAcceptedArbitrator(Arbitrator arbitrator) {
|
public void addAcceptedArbitrator(Arbitrator arbitrator) {
|
||||||
if (!acceptedArbitrators.contains(arbitrator) && !isMyOwnRegisteredArbitrator(arbitrator)) {
|
if (!acceptedArbitrators.contains(arbitrator) && !isMyOwnRegisteredArbitrator(arbitrator)) {
|
||||||
acceptedArbitrators.add(arbitrator);
|
boolean changed = acceptedArbitrators.add(arbitrator);
|
||||||
|
if (changed)
|
||||||
storage.queueUpForSave();
|
storage.queueUpForSave();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -191,7 +192,8 @@ public final class User implements Persistable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeAcceptedArbitrator(Arbitrator arbitrator) {
|
public void removeAcceptedArbitrator(Arbitrator arbitrator) {
|
||||||
acceptedArbitrators.remove(arbitrator);
|
boolean changed = acceptedArbitrators.remove(arbitrator);
|
||||||
|
if (changed)
|
||||||
storage.queueUpForSave();
|
storage.queueUpForSave();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,7 +202,7 @@ public final class User implements Persistable {
|
||||||
storage.queueUpForSave();
|
storage.queueUpForSave();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRegisteredArbitrator(@org.jetbrains.annotations.Nullable Arbitrator arbitrator) {
|
public void setRegisteredArbitrator(@Nullable Arbitrator arbitrator) {
|
||||||
this.registeredArbitrator = arbitrator;
|
this.registeredArbitrator = arbitrator;
|
||||||
storage.queueUpForSave();
|
storage.queueUpForSave();
|
||||||
}
|
}
|
||||||
|
@ -330,7 +332,7 @@ public final class User implements Persistable {
|
||||||
|
|
||||||
public void setDevelopersAlert(Alert developersAlert) {
|
public void setDevelopersAlert(Alert developersAlert) {
|
||||||
this.developersAlert = developersAlert;
|
this.developersAlert = developersAlert;
|
||||||
storage.queueUpForSave(2000);
|
storage.queueUpForSave();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Alert getDevelopersAlert() {
|
public Alert getDevelopersAlert() {
|
||||||
|
@ -339,7 +341,7 @@ public final class User implements Persistable {
|
||||||
|
|
||||||
public void setDisplayedAlert(Alert displayedAlert) {
|
public void setDisplayedAlert(Alert displayedAlert) {
|
||||||
this.displayedAlert = displayedAlert;
|
this.displayedAlert = displayedAlert;
|
||||||
storage.queueUpForSave(2000);
|
storage.queueUpForSave();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Alert getDisplayedAlert() {
|
public Alert getDisplayedAlert() {
|
||||||
|
|
|
@ -71,11 +71,11 @@ You need to get the Bitsquare dependencies first as we need to copy the BountyCa
|
||||||
|
|
||||||
### 4. Copy the jdkfix jar file
|
### 4. Copy the jdkfix jar file
|
||||||
|
|
||||||
Copy the jdkfix-0.4.9.1.jar from the Bitsquare jdkfix/target directory to $JAVA_HOME/jre/lib/ext/.
|
Copy the jdkfix-0.4.9.2.jar from the Bitsquare jdkfix/target directory to $JAVA_HOME/jre/lib/ext/.
|
||||||
jdkfix-0.4.9.1.jar includes a bugfix of the SortedList class which will be released with the next JDK version.
|
jdkfix-0.4.9.2.jar includes a bugfix of the SortedList class which will be released with the next JDK version.
|
||||||
We need to load that class before the default java class. This step will be removed once the bugfix is in the official JDK.
|
We need to load that class before the default java class. This step will be removed once the bugfix is in the official JDK.
|
||||||
|
|
||||||
$ sudo cp bitsquare/jdkfix/target/jdkfix-0.4.9.1.jar $JAVA_HOME/jre/lib/ext/jdkfix-0.4.9.1.jar
|
$ sudo cp bitsquare/jdkfix/target/jdkfix-0.4.9.2.jar $JAVA_HOME/jre/lib/ext/jdkfix-0.4.9.2.jar
|
||||||
|
|
||||||
### 5. Copy the BountyCastle provider jar file
|
### 5. Copy the BountyCastle provider jar file
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>parent</artifactId>
|
<artifactId>parent</artifactId>
|
||||||
<groupId>io.bitsquare</groupId>
|
<groupId>io.bitsquare</groupId>
|
||||||
<version>0.4.9.1</version>
|
<version>0.4.9.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|
|
@ -265,7 +265,7 @@ public class BitsquareApp extends Application {
|
||||||
private void showErrorPopup(Throwable throwable, boolean doShutDown) {
|
private void showErrorPopup(Throwable throwable, boolean doShutDown) {
|
||||||
if (!shutDownRequested) {
|
if (!shutDownRequested) {
|
||||||
if (scene == null) {
|
if (scene == null) {
|
||||||
log.warn("Scene not available yet, we create a new scene. The bug might be caused by a guice circular dependency.");
|
log.warn("Scene not available yet, we create a new scene. The bug might be caused by an exception in a constructor or by a circular dependency in guice.");
|
||||||
scene = new Scene(new StackPane(), 1000, 650);
|
scene = new Scene(new StackPane(), 1000, 650);
|
||||||
scene.getStylesheets().setAll(
|
scene.getStylesheets().setAll(
|
||||||
"/io/bitsquare/gui/bitsquare.css",
|
"/io/bitsquare/gui/bitsquare.css",
|
||||||
|
@ -357,7 +357,7 @@ public class BitsquareApp extends Application {
|
||||||
.show();
|
.show();
|
||||||
UserThread.runAfter(() -> {
|
UserThread.runAfter(() -> {
|
||||||
gracefulShutDown(() -> {
|
gracefulShutDown(() -> {
|
||||||
log.info("App shutdown complete");
|
log.debug("App shutdown complete");
|
||||||
System.exit(0);
|
System.exit(0);
|
||||||
});
|
});
|
||||||
}, 200, TimeUnit.MILLISECONDS);
|
}, 200, TimeUnit.MILLISECONDS);
|
||||||
|
@ -376,7 +376,7 @@ public class BitsquareApp extends Application {
|
||||||
injector.getInstance(P2PService.class).shutDown(() -> {
|
injector.getInstance(P2PService.class).shutDown(() -> {
|
||||||
injector.getInstance(WalletService.class).shutDownDone.addListener((ov, o, n) -> {
|
injector.getInstance(WalletService.class).shutDownDone.addListener((ov, o, n) -> {
|
||||||
bitsquareAppModule.close(injector);
|
bitsquareAppModule.close(injector);
|
||||||
log.info("Graceful shutdown completed");
|
log.debug("Graceful shutdown completed");
|
||||||
resultHandler.handleResult();
|
resultHandler.handleResult();
|
||||||
});
|
});
|
||||||
injector.getInstance(WalletService.class).shutDown();
|
injector.getInstance(WalletService.class).shutDown();
|
||||||
|
@ -388,7 +388,7 @@ public class BitsquareApp extends Application {
|
||||||
UserThread.runAfter(resultHandler::handleResult, 1);
|
UserThread.runAfter(resultHandler::handleResult, 1);
|
||||||
}
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
log.info("App shutdown failed with exception");
|
log.debug("App shutdown failed with exception");
|
||||||
t.printStackTrace();
|
t.printStackTrace();
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,10 +80,6 @@
|
||||||
-fx-background-insets: 0, 1, 2;
|
-fx-background-insets: 0, 1, 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.volume-bar.bg {
|
|
||||||
-demo-bar-fill: #70bfc6;
|
|
||||||
}
|
|
||||||
|
|
||||||
.volume-bar {
|
.volume-bar {
|
||||||
-fx-effect: dropshadow(two-pass-box, rgba(0, 0, 0, 0.4), 10, 0.0, 2, 4);
|
-fx-effect: dropshadow(two-pass-box, rgba(0, 0, 0, 0.4), 10, 0.0, 2, 4);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ import io.bitsquare.common.persistance.Persistable;
|
||||||
import io.bitsquare.gui.common.view.View;
|
import io.bitsquare.gui.common.view.View;
|
||||||
import io.bitsquare.gui.common.view.ViewPath;
|
import io.bitsquare.gui.common.view.ViewPath;
|
||||||
import io.bitsquare.gui.main.MainView;
|
import io.bitsquare.gui.main.MainView;
|
||||||
import io.bitsquare.gui.main.markets.MarketView;
|
import io.bitsquare.gui.main.market.MarketView;
|
||||||
import io.bitsquare.storage.Storage;
|
import io.bitsquare.storage.Storage;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
@ -101,7 +101,7 @@ public final class Navigation implements Persistable {
|
||||||
|
|
||||||
currentPath = newPath;
|
currentPath = newPath;
|
||||||
previousPath = currentPath;
|
previousPath = currentPath;
|
||||||
storage.queueUpForSave(2000);
|
storage.queueUpForSave(1000);
|
||||||
listeners.stream().forEach((e) -> e.onNavigationRequested(currentPath));
|
listeners.stream().forEach((e) -> e.onNavigationRequested(currentPath));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ package io.bitsquare.gui;
|
||||||
import io.bitsquare.BitsquareException;
|
import io.bitsquare.BitsquareException;
|
||||||
import io.bitsquare.common.UserThread;
|
import io.bitsquare.common.UserThread;
|
||||||
import io.bitsquare.common.util.Utilities;
|
import io.bitsquare.common.util.Utilities;
|
||||||
|
import io.bitsquare.gui.util.GUIUtil;
|
||||||
import io.bitsquare.gui.util.ImageUtil;
|
import io.bitsquare.gui.util.ImageUtil;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
|
@ -123,7 +124,7 @@ public class SystemTray {
|
||||||
|
|
||||||
aboutItem.addActionListener(e -> {
|
aboutItem.addActionListener(e -> {
|
||||||
try {
|
try {
|
||||||
Utilities.openWebPage("https://bitsquare.io");
|
GUIUtil.openWebPage("https://bitsquare.io");
|
||||||
} catch (Exception e1) {
|
} catch (Exception e1) {
|
||||||
e1.printStackTrace();
|
e1.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,8 @@ Theme colors:
|
||||||
|
|
||||||
logo colors:
|
logo colors:
|
||||||
|
|
||||||
new blue: 0f87c3
|
Bitsquare blue: 0f86c3
|
||||||
new grey: 666666
|
Bitsquare grey: 666666
|
||||||
|
|
||||||
00abff
|
00abff
|
||||||
orange web page quotes : ff7f00
|
orange web page quotes : ff7f00
|
||||||
|
|
|
@ -24,6 +24,7 @@ import io.bitsquare.btc.listeners.TxConfidenceListener;
|
||||||
import io.bitsquare.common.util.Utilities;
|
import io.bitsquare.common.util.Utilities;
|
||||||
import io.bitsquare.gui.components.indicator.TxConfidenceIndicator;
|
import io.bitsquare.gui.components.indicator.TxConfidenceIndicator;
|
||||||
import io.bitsquare.gui.main.overlays.popups.Popup;
|
import io.bitsquare.gui.main.overlays.popups.Popup;
|
||||||
|
import io.bitsquare.gui.util.GUIUtil;
|
||||||
import io.bitsquare.user.Preferences;
|
import io.bitsquare.user.Preferences;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
import javafx.scene.control.TextField;
|
import javafx.scene.control.TextField;
|
||||||
|
@ -135,7 +136,7 @@ public class TxIdTextField extends AnchorPane {
|
||||||
private void openBlockExplorer(String txID) {
|
private void openBlockExplorer(String txID) {
|
||||||
try {
|
try {
|
||||||
if (preferences != null)
|
if (preferences != null)
|
||||||
Utilities.openWebPage(preferences.getBlockChainExplorer().txUrl + txID);
|
GUIUtil.openWebPage(preferences.getBlockChainExplorer().txUrl + txID);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error(e.getMessage());
|
log.error(e.getMessage());
|
||||||
new Popup().warning("Opening browser failed. Please check your internet " +
|
new Popup().warning("Opening browser failed. Please check your internet " +
|
||||||
|
|
|
@ -24,20 +24,20 @@ import io.bitsquare.btc.pricefeed.PriceFeedService;
|
||||||
import io.bitsquare.common.UserThread;
|
import io.bitsquare.common.UserThread;
|
||||||
import io.bitsquare.common.util.Tuple2;
|
import io.bitsquare.common.util.Tuple2;
|
||||||
import io.bitsquare.common.util.Tuple3;
|
import io.bitsquare.common.util.Tuple3;
|
||||||
import io.bitsquare.common.util.Utilities;
|
|
||||||
import io.bitsquare.gui.Navigation;
|
import io.bitsquare.gui.Navigation;
|
||||||
import io.bitsquare.gui.common.view.*;
|
import io.bitsquare.gui.common.view.*;
|
||||||
import io.bitsquare.gui.components.BusyAnimation;
|
import io.bitsquare.gui.components.BusyAnimation;
|
||||||
import io.bitsquare.gui.main.account.AccountView;
|
import io.bitsquare.gui.main.account.AccountView;
|
||||||
import io.bitsquare.gui.main.disputes.DisputesView;
|
import io.bitsquare.gui.main.disputes.DisputesView;
|
||||||
import io.bitsquare.gui.main.funds.FundsView;
|
import io.bitsquare.gui.main.funds.FundsView;
|
||||||
import io.bitsquare.gui.main.markets.MarketView;
|
import io.bitsquare.gui.main.market.MarketView;
|
||||||
import io.bitsquare.gui.main.offer.BuyOfferView;
|
import io.bitsquare.gui.main.offer.BuyOfferView;
|
||||||
import io.bitsquare.gui.main.offer.SellOfferView;
|
import io.bitsquare.gui.main.offer.SellOfferView;
|
||||||
import io.bitsquare.gui.main.overlays.Overlay;
|
import io.bitsquare.gui.main.overlays.Overlay;
|
||||||
import io.bitsquare.gui.main.overlays.popups.Popup;
|
import io.bitsquare.gui.main.overlays.popups.Popup;
|
||||||
import io.bitsquare.gui.main.portfolio.PortfolioView;
|
import io.bitsquare.gui.main.portfolio.PortfolioView;
|
||||||
import io.bitsquare.gui.main.settings.SettingsView;
|
import io.bitsquare.gui.main.settings.SettingsView;
|
||||||
|
import io.bitsquare.gui.util.GUIUtil;
|
||||||
import io.bitsquare.gui.util.Transitions;
|
import io.bitsquare.gui.util.Transitions;
|
||||||
import javafx.beans.value.ChangeListener;
|
import javafx.beans.value.ChangeListener;
|
||||||
import javafx.geometry.Insets;
|
import javafx.geometry.Insets;
|
||||||
|
@ -227,6 +227,7 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
|
||||||
navigation.navigateToPreviousVisitedView();
|
navigation.navigateToPreviousVisitedView();
|
||||||
|
|
||||||
if (!persistedFilesCorrupted.isEmpty()) {
|
if (!persistedFilesCorrupted.isEmpty()) {
|
||||||
|
if (persistedFilesCorrupted.size() > 1 || !persistedFilesCorrupted.get(0).equals("Navigation")) {
|
||||||
// show warning that some files has been corrupted
|
// show warning that some files has been corrupted
|
||||||
new Popup().warning("We detected incompatible data base files!\n\n" +
|
new Popup().warning("We detected incompatible data base files!\n\n" +
|
||||||
"Those database file(s) are not compatible with our current code base:" +
|
"Those database file(s) are not compatible with our current code base:" +
|
||||||
|
@ -240,6 +241,10 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
|
||||||
.closeButtonText("Shut down")
|
.closeButtonText("Shut down")
|
||||||
.onClose(BitsquareApp.shutDownHandler::run)
|
.onClose(BitsquareApp.shutDownHandler::run)
|
||||||
.show();
|
.show();
|
||||||
|
} else {
|
||||||
|
log.debug("We detected incompatible data base file for Navigation. That is a minor issue happening with refactoring of UI classes " +
|
||||||
|
"and we don't display a warning popup to the user.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
transitions.fadeOutAndRemove(splashScreen, 1500, actionEvent -> disposeSplashScreen());
|
transitions.fadeOutAndRemove(splashScreen, 1500, actionEvent -> disposeSplashScreen());
|
||||||
|
@ -320,7 +325,7 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
|
||||||
btcAverageIconButton.setFocusTraversable(false);
|
btcAverageIconButton.setFocusTraversable(false);
|
||||||
btcAverageIconButton.setStyle("-fx-background-color: transparent;");
|
btcAverageIconButton.setStyle("-fx-background-color: transparent;");
|
||||||
HBox.setMargin(btcAverageIconButton, new Insets(0, 27, 0, 0));
|
HBox.setMargin(btcAverageIconButton, new Insets(0, 27, 0, 0));
|
||||||
btcAverageIconButton.setOnAction(e -> Utilities.openWebPage("https://bitcoinaverage.com"));
|
btcAverageIconButton.setOnAction(e -> GUIUtil.openWebPage("https://bitcoinaverage.com"));
|
||||||
btcAverageIconButton.visibleProperty().bind(model.isFiatCurrencyPriceFeedSelected);
|
btcAverageIconButton.visibleProperty().bind(model.isFiatCurrencyPriceFeedSelected);
|
||||||
btcAverageIconButton.managedProperty().bind(model.isFiatCurrencyPriceFeedSelected);
|
btcAverageIconButton.managedProperty().bind(model.isFiatCurrencyPriceFeedSelected);
|
||||||
btcAverageIconButton.setTooltip(new Tooltip("Market price is provided by https://bitcoinaverage.com"));
|
btcAverageIconButton.setTooltip(new Tooltip("Market price is provided by https://bitcoinaverage.com"));
|
||||||
|
@ -332,7 +337,7 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
|
||||||
poloniexIconButton.setFocusTraversable(false);
|
poloniexIconButton.setFocusTraversable(false);
|
||||||
poloniexIconButton.setStyle("-fx-background-color: transparent;");
|
poloniexIconButton.setStyle("-fx-background-color: transparent;");
|
||||||
HBox.setMargin(poloniexIconButton, new Insets(1, 27, 0, 0));
|
HBox.setMargin(poloniexIconButton, new Insets(1, 27, 0, 0));
|
||||||
poloniexIconButton.setOnAction(e -> Utilities.openWebPage("https://poloniex.com"));
|
poloniexIconButton.setOnAction(e -> GUIUtil.openWebPage("https://poloniex.com"));
|
||||||
poloniexIconButton.visibleProperty().bind(model.isCryptoCurrencyPriceFeedSelected);
|
poloniexIconButton.visibleProperty().bind(model.isCryptoCurrencyPriceFeedSelected);
|
||||||
poloniexIconButton.managedProperty().bind(model.isCryptoCurrencyPriceFeedSelected);
|
poloniexIconButton.managedProperty().bind(model.isCryptoCurrencyPriceFeedSelected);
|
||||||
poloniexIconButton.setTooltip(new Tooltip("Market price is provided by https://poloniex.com"));
|
poloniexIconButton.setTooltip(new Tooltip("Market price is provided by https://poloniex.com"));
|
||||||
|
|
|
@ -39,7 +39,6 @@ import io.bitsquare.common.Clock;
|
||||||
import io.bitsquare.common.Timer;
|
import io.bitsquare.common.Timer;
|
||||||
import io.bitsquare.common.UserThread;
|
import io.bitsquare.common.UserThread;
|
||||||
import io.bitsquare.common.crypto.*;
|
import io.bitsquare.common.crypto.*;
|
||||||
import io.bitsquare.common.util.Utilities;
|
|
||||||
import io.bitsquare.filter.FilterManager;
|
import io.bitsquare.filter.FilterManager;
|
||||||
import io.bitsquare.gui.Navigation;
|
import io.bitsquare.gui.Navigation;
|
||||||
import io.bitsquare.gui.common.model.ViewModel;
|
import io.bitsquare.gui.common.model.ViewModel;
|
||||||
|
@ -53,6 +52,7 @@ import io.bitsquare.gui.main.overlays.windows.DisplayAlertMessageWindow;
|
||||||
import io.bitsquare.gui.main.overlays.windows.TacWindow;
|
import io.bitsquare.gui.main.overlays.windows.TacWindow;
|
||||||
import io.bitsquare.gui.main.overlays.windows.WalletPasswordWindow;
|
import io.bitsquare.gui.main.overlays.windows.WalletPasswordWindow;
|
||||||
import io.bitsquare.gui.util.BSFormatter;
|
import io.bitsquare.gui.util.BSFormatter;
|
||||||
|
import io.bitsquare.gui.util.GUIUtil;
|
||||||
import io.bitsquare.locale.CurrencyUtil;
|
import io.bitsquare.locale.CurrencyUtil;
|
||||||
import io.bitsquare.locale.TradeCurrency;
|
import io.bitsquare.locale.TradeCurrency;
|
||||||
import io.bitsquare.p2p.P2PService;
|
import io.bitsquare.p2p.P2PService;
|
||||||
|
@ -322,8 +322,8 @@ public class MainViewModel implements ViewModel {
|
||||||
// Other disconnects might be caused by peers running an older version
|
// Other disconnects might be caused by peers running an older version
|
||||||
if (connection.getPeerType() == Connection.PeerType.SEED_NODE &&
|
if (connection.getPeerType() == Connection.PeerType.SEED_NODE &&
|
||||||
closeConnectionReason == CloseConnectionReason.RULE_VIOLATION) {
|
closeConnectionReason == CloseConnectionReason.RULE_VIOLATION) {
|
||||||
log.warn("onDisconnect closeConnectionReason=" + closeConnectionReason);
|
log.warn("RULE_VIOLATION onDisconnect closeConnectionReason=" + closeConnectionReason);
|
||||||
log.warn("onDisconnect connection=" + connection);
|
log.warn("RULE_VIOLATION onDisconnect connection=" + connection);
|
||||||
//TODO
|
//TODO
|
||||||
/* new Popup()
|
/* new Popup()
|
||||||
.warning("You got disconnected from a seed node.\n\n" +
|
.warning("You got disconnected from a seed node.\n\n" +
|
||||||
|
@ -590,7 +590,7 @@ public class MainViewModel implements ViewModel {
|
||||||
.actionButtonText("Shut down")
|
.actionButtonText("Shut down")
|
||||||
.onAction(BitsquareApp.shutDownHandler::run)
|
.onAction(BitsquareApp.shutDownHandler::run)
|
||||||
.closeButtonText("Report bug at Github issues")
|
.closeButtonText("Report bug at Github issues")
|
||||||
.onClose(() -> Utilities.openWebPage("https://github.com/bitsquare/bitsquare/issues"))
|
.onClose(() -> GUIUtil.openWebPage("https://github.com/bitsquare/bitsquare/issues"))
|
||||||
.show());
|
.show());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -602,7 +602,7 @@ public class MainViewModel implements ViewModel {
|
||||||
.actionButtonText("Shut down")
|
.actionButtonText("Shut down")
|
||||||
.onAction(BitsquareApp.shutDownHandler::run)
|
.onAction(BitsquareApp.shutDownHandler::run)
|
||||||
.closeButtonText("Report bug at Github issues")
|
.closeButtonText("Report bug at Github issues")
|
||||||
.onClose(() -> Utilities.openWebPage("https://github.com/bitsquare/bitsquare/issues"))
|
.onClose(() -> GUIUtil.openWebPage("https://github.com/bitsquare/bitsquare/issues"))
|
||||||
.show();
|
.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -846,6 +846,8 @@ public class MainViewModel implements ViewModel {
|
||||||
else
|
else
|
||||||
findPriceFeedComboBoxItem(preferences.getPreferredTradeCurrency().getCode())
|
findPriceFeedComboBoxItem(preferences.getPreferredTradeCurrency().getCode())
|
||||||
.ifPresent(item2 -> selectedPriceFeedComboBoxItemProperty.set(item2));
|
.ifPresent(item2 -> selectedPriceFeedComboBoxItemProperty.set(item2));
|
||||||
|
|
||||||
|
priceFeedService.setCurrencyCode(item.currencyCode);
|
||||||
} else if (item != null) {
|
} else if (item != null) {
|
||||||
selectedPriceFeedComboBoxItemProperty.set(item);
|
selectedPriceFeedComboBoxItemProperty.set(item);
|
||||||
priceFeedService.setCurrencyCode(item.currencyCode);
|
priceFeedService.setCurrencyCode(item.currencyCode);
|
||||||
|
|
|
@ -20,17 +20,13 @@ package io.bitsquare.gui.main.account.content.altcoinaccounts;
|
||||||
import io.bitsquare.common.UserThread;
|
import io.bitsquare.common.UserThread;
|
||||||
import io.bitsquare.common.util.Tuple2;
|
import io.bitsquare.common.util.Tuple2;
|
||||||
import io.bitsquare.common.util.Tuple3;
|
import io.bitsquare.common.util.Tuple3;
|
||||||
import io.bitsquare.common.util.Utilities;
|
|
||||||
import io.bitsquare.gui.common.view.ActivatableViewAndModel;
|
import io.bitsquare.gui.common.view.ActivatableViewAndModel;
|
||||||
import io.bitsquare.gui.common.view.FxmlView;
|
import io.bitsquare.gui.common.view.FxmlView;
|
||||||
import io.bitsquare.gui.components.TitledGroupBg;
|
import io.bitsquare.gui.components.TitledGroupBg;
|
||||||
import io.bitsquare.gui.components.paymentmethods.CryptoCurrencyForm;
|
import io.bitsquare.gui.components.paymentmethods.CryptoCurrencyForm;
|
||||||
import io.bitsquare.gui.components.paymentmethods.PaymentMethodForm;
|
import io.bitsquare.gui.components.paymentmethods.PaymentMethodForm;
|
||||||
import io.bitsquare.gui.main.overlays.popups.Popup;
|
import io.bitsquare.gui.main.overlays.popups.Popup;
|
||||||
import io.bitsquare.gui.util.BSFormatter;
|
import io.bitsquare.gui.util.*;
|
||||||
import io.bitsquare.gui.util.FormBuilder;
|
|
||||||
import io.bitsquare.gui.util.ImageUtil;
|
|
||||||
import io.bitsquare.gui.util.Layout;
|
|
||||||
import io.bitsquare.gui.util.validation.*;
|
import io.bitsquare.gui.util.validation.*;
|
||||||
import io.bitsquare.locale.CryptoCurrency;
|
import io.bitsquare.locale.CryptoCurrency;
|
||||||
import io.bitsquare.locale.TradeCurrency;
|
import io.bitsquare.locale.TradeCurrency;
|
||||||
|
@ -173,7 +169,7 @@ public class AltCoinAccountsView extends ActivatableViewAndModel<GridPane, AltCo
|
||||||
new Popup().information("The EHT/ETC fork situation carries considerable risks.\n" +
|
new Popup().information("The EHT/ETC fork situation carries considerable risks.\n" +
|
||||||
"Be sure you fully understand the situation and check out the information on the \"Ethereum Classic\" and \"Ethereum\" project web pages.")
|
"Be sure you fully understand the situation and check out the information on the \"Ethereum Classic\" and \"Ethereum\" project web pages.")
|
||||||
.closeButtonText("I understand")
|
.closeButtonText("I understand")
|
||||||
.onAction(() -> Utilities.openWebPage("https://ethereumclassic.github.io/"))
|
.onAction(() -> GUIUtil.openWebPage("https://ethereumclassic.github.io/"))
|
||||||
.actionButtonText("Open Ethereum Classic web page")
|
.actionButtonText("Open Ethereum Classic web page")
|
||||||
.show();
|
.show();
|
||||||
}
|
}
|
||||||
|
|
|
@ -263,7 +263,6 @@ public class SeedWordsView extends ActivatableView<GridPane, Void> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doRestore() {
|
private void doRestore() {
|
||||||
log.info("Attempting wallet restore using seed '{}' from date {}", restoreSeedWordsTextArea.getText(), restoreDatePicker.getValue());
|
|
||||||
long date = restoreDatePicker.getValue().atStartOfDay().toEpochSecond(ZoneOffset.UTC);
|
long date = restoreDatePicker.getValue().atStartOfDay().toEpochSecond(ZoneOffset.UTC);
|
||||||
DeterministicSeed seed = new DeterministicSeed(Splitter.on(" ").splitToList(restoreSeedWordsTextArea.getText()), null, "", date);
|
DeterministicSeed seed = new DeterministicSeed(Splitter.on(" ").splitToList(restoreSeedWordsTextArea.getText()), null, "", date);
|
||||||
walletService.restoreSeedWords(seed,
|
walletService.restoreSeedWords(seed,
|
||||||
|
|
|
@ -25,7 +25,6 @@ import io.bitsquare.btc.WalletService;
|
||||||
import io.bitsquare.btc.listeners.BalanceListener;
|
import io.bitsquare.btc.listeners.BalanceListener;
|
||||||
import io.bitsquare.common.UserThread;
|
import io.bitsquare.common.UserThread;
|
||||||
import io.bitsquare.common.util.Tuple2;
|
import io.bitsquare.common.util.Tuple2;
|
||||||
import io.bitsquare.common.util.Utilities;
|
|
||||||
import io.bitsquare.gui.common.view.ActivatableView;
|
import io.bitsquare.gui.common.view.ActivatableView;
|
||||||
import io.bitsquare.gui.common.view.FxmlView;
|
import io.bitsquare.gui.common.view.FxmlView;
|
||||||
import io.bitsquare.gui.components.AddressTextField;
|
import io.bitsquare.gui.components.AddressTextField;
|
||||||
|
@ -278,7 +277,7 @@ public class DepositView extends ActivatableView<VBox, Void> {
|
||||||
private void openBlockExplorer(DepositListItem item) {
|
private void openBlockExplorer(DepositListItem item) {
|
||||||
if (item.getAddressString() != null) {
|
if (item.getAddressString() != null) {
|
||||||
try {
|
try {
|
||||||
Utilities.openWebPage(preferences.getBlockChainExplorer().addressUrl + item.getAddressString());
|
GUIUtil.openWebPage(preferences.getBlockChainExplorer().addressUrl + item.getAddressString());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error(e.getMessage());
|
log.error(e.getMessage());
|
||||||
new Popup().warning("Opening browser failed. Please check your internet " +
|
new Popup().warning("Opening browser failed. Please check your internet " +
|
||||||
|
|
|
@ -21,7 +21,6 @@ import de.jensd.fx.fontawesome.AwesomeIcon;
|
||||||
import io.bitsquare.btc.AddressEntry;
|
import io.bitsquare.btc.AddressEntry;
|
||||||
import io.bitsquare.btc.WalletService;
|
import io.bitsquare.btc.WalletService;
|
||||||
import io.bitsquare.btc.listeners.BalanceListener;
|
import io.bitsquare.btc.listeners.BalanceListener;
|
||||||
import io.bitsquare.common.util.Utilities;
|
|
||||||
import io.bitsquare.gui.common.view.ActivatableView;
|
import io.bitsquare.gui.common.view.ActivatableView;
|
||||||
import io.bitsquare.gui.common.view.FxmlView;
|
import io.bitsquare.gui.common.view.FxmlView;
|
||||||
import io.bitsquare.gui.components.HyperlinkWithIcon;
|
import io.bitsquare.gui.components.HyperlinkWithIcon;
|
||||||
|
@ -29,6 +28,7 @@ import io.bitsquare.gui.main.overlays.popups.Popup;
|
||||||
import io.bitsquare.gui.main.overlays.windows.OfferDetailsWindow;
|
import io.bitsquare.gui.main.overlays.windows.OfferDetailsWindow;
|
||||||
import io.bitsquare.gui.main.overlays.windows.TradeDetailsWindow;
|
import io.bitsquare.gui.main.overlays.windows.TradeDetailsWindow;
|
||||||
import io.bitsquare.gui.util.BSFormatter;
|
import io.bitsquare.gui.util.BSFormatter;
|
||||||
|
import io.bitsquare.gui.util.GUIUtil;
|
||||||
import io.bitsquare.trade.Tradable;
|
import io.bitsquare.trade.Tradable;
|
||||||
import io.bitsquare.trade.Trade;
|
import io.bitsquare.trade.Trade;
|
||||||
import io.bitsquare.trade.TradeManager;
|
import io.bitsquare.trade.TradeManager;
|
||||||
|
@ -157,7 +157,7 @@ public class LockedView extends ActivatableView<VBox, Void> {
|
||||||
|
|
||||||
private void openBlockExplorer(LockedListItem item) {
|
private void openBlockExplorer(LockedListItem item) {
|
||||||
try {
|
try {
|
||||||
Utilities.openWebPage(preferences.getBlockChainExplorer().addressUrl + item.getAddressString());
|
GUIUtil.openWebPage(preferences.getBlockChainExplorer().addressUrl + item.getAddressString());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error(e.getMessage());
|
log.error(e.getMessage());
|
||||||
new Popup().warning("Opening browser failed. Please check your internet " +
|
new Popup().warning("Opening browser failed. Please check your internet " +
|
||||||
|
|
|
@ -21,7 +21,6 @@ import de.jensd.fx.fontawesome.AwesomeIcon;
|
||||||
import io.bitsquare.btc.AddressEntry;
|
import io.bitsquare.btc.AddressEntry;
|
||||||
import io.bitsquare.btc.WalletService;
|
import io.bitsquare.btc.WalletService;
|
||||||
import io.bitsquare.btc.listeners.BalanceListener;
|
import io.bitsquare.btc.listeners.BalanceListener;
|
||||||
import io.bitsquare.common.util.Utilities;
|
|
||||||
import io.bitsquare.gui.common.view.ActivatableView;
|
import io.bitsquare.gui.common.view.ActivatableView;
|
||||||
import io.bitsquare.gui.common.view.FxmlView;
|
import io.bitsquare.gui.common.view.FxmlView;
|
||||||
import io.bitsquare.gui.components.HyperlinkWithIcon;
|
import io.bitsquare.gui.components.HyperlinkWithIcon;
|
||||||
|
@ -29,6 +28,7 @@ import io.bitsquare.gui.main.overlays.popups.Popup;
|
||||||
import io.bitsquare.gui.main.overlays.windows.OfferDetailsWindow;
|
import io.bitsquare.gui.main.overlays.windows.OfferDetailsWindow;
|
||||||
import io.bitsquare.gui.main.overlays.windows.TradeDetailsWindow;
|
import io.bitsquare.gui.main.overlays.windows.TradeDetailsWindow;
|
||||||
import io.bitsquare.gui.util.BSFormatter;
|
import io.bitsquare.gui.util.BSFormatter;
|
||||||
|
import io.bitsquare.gui.util.GUIUtil;
|
||||||
import io.bitsquare.trade.Tradable;
|
import io.bitsquare.trade.Tradable;
|
||||||
import io.bitsquare.trade.Trade;
|
import io.bitsquare.trade.Trade;
|
||||||
import io.bitsquare.trade.TradeManager;
|
import io.bitsquare.trade.TradeManager;
|
||||||
|
@ -157,7 +157,7 @@ public class ReservedView extends ActivatableView<VBox, Void> {
|
||||||
|
|
||||||
private void openBlockExplorer(ReservedListItem item) {
|
private void openBlockExplorer(ReservedListItem item) {
|
||||||
try {
|
try {
|
||||||
Utilities.openWebPage(preferences.getBlockChainExplorer().addressUrl + item.getAddressString());
|
GUIUtil.openWebPage(preferences.getBlockChainExplorer().addressUrl + item.getAddressString());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error(e.getMessage());
|
log.error(e.getMessage());
|
||||||
new Popup().warning("Opening browser failed. Please check your internet " +
|
new Popup().warning("Opening browser failed. Please check your internet " +
|
||||||
|
|
|
@ -294,7 +294,7 @@ public class TransactionsView extends ActivatableView<VBox, Void> {
|
||||||
private void openTxInBlockExplorer(TransactionsListItem item) {
|
private void openTxInBlockExplorer(TransactionsListItem item) {
|
||||||
if (item.getTxId() != null) {
|
if (item.getTxId() != null) {
|
||||||
try {
|
try {
|
||||||
Utilities.openWebPage(preferences.getBlockChainExplorer().txUrl + item.getTxId());
|
GUIUtil.openWebPage(preferences.getBlockChainExplorer().txUrl + item.getTxId());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error(e.getMessage());
|
log.error(e.getMessage());
|
||||||
new Popup().warning("Opening browser failed. Please check your internet " +
|
new Popup().warning("Opening browser failed. Please check your internet " +
|
||||||
|
@ -306,7 +306,7 @@ public class TransactionsView extends ActivatableView<VBox, Void> {
|
||||||
private void openAddressInBlockExplorer(TransactionsListItem item) {
|
private void openAddressInBlockExplorer(TransactionsListItem item) {
|
||||||
if (item.getAddressString() != null) {
|
if (item.getAddressString() != null) {
|
||||||
try {
|
try {
|
||||||
Utilities.openWebPage(preferences.getBlockChainExplorer().addressUrl + item.getAddressString());
|
GUIUtil.openWebPage(preferences.getBlockChainExplorer().addressUrl + item.getAddressString());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error(e.getMessage());
|
log.error(e.getMessage());
|
||||||
new Popup().warning("Opening browser failed. Please check your internet " +
|
new Popup().warning("Opening browser failed. Please check your internet " +
|
||||||
|
|
|
@ -25,13 +25,13 @@ import io.bitsquare.btc.AddressEntryException;
|
||||||
import io.bitsquare.btc.WalletService;
|
import io.bitsquare.btc.WalletService;
|
||||||
import io.bitsquare.btc.listeners.BalanceListener;
|
import io.bitsquare.btc.listeners.BalanceListener;
|
||||||
import io.bitsquare.common.UserThread;
|
import io.bitsquare.common.UserThread;
|
||||||
import io.bitsquare.common.util.Utilities;
|
|
||||||
import io.bitsquare.gui.common.view.ActivatableView;
|
import io.bitsquare.gui.common.view.ActivatableView;
|
||||||
import io.bitsquare.gui.common.view.FxmlView;
|
import io.bitsquare.gui.common.view.FxmlView;
|
||||||
import io.bitsquare.gui.components.HyperlinkWithIcon;
|
import io.bitsquare.gui.components.HyperlinkWithIcon;
|
||||||
import io.bitsquare.gui.main.overlays.popups.Popup;
|
import io.bitsquare.gui.main.overlays.popups.Popup;
|
||||||
import io.bitsquare.gui.main.overlays.windows.WalletPasswordWindow;
|
import io.bitsquare.gui.main.overlays.windows.WalletPasswordWindow;
|
||||||
import io.bitsquare.gui.util.BSFormatter;
|
import io.bitsquare.gui.util.BSFormatter;
|
||||||
|
import io.bitsquare.gui.util.GUIUtil;
|
||||||
import io.bitsquare.gui.util.validation.BtcAddressValidator;
|
import io.bitsquare.gui.util.validation.BtcAddressValidator;
|
||||||
import io.bitsquare.trade.Tradable;
|
import io.bitsquare.trade.Tradable;
|
||||||
import io.bitsquare.trade.Trade;
|
import io.bitsquare.trade.Trade;
|
||||||
|
@ -185,7 +185,7 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(@javax.annotation.Nullable Transaction transaction) {
|
public void onSuccess(@javax.annotation.Nullable Transaction transaction) {
|
||||||
if (transaction != null) {
|
if (transaction != null) {
|
||||||
log.info("onWithdraw onSuccess tx ID:" + transaction.getHashAsString());
|
log.debug("onWithdraw onSuccess tx ID:" + transaction.getHashAsString());
|
||||||
} else {
|
} else {
|
||||||
log.error("onWithdraw transaction is null");
|
log.error("onWithdraw transaction is null");
|
||||||
}
|
}
|
||||||
|
@ -287,7 +287,7 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
|
||||||
private void openBlockExplorer(WithdrawalListItem item) {
|
private void openBlockExplorer(WithdrawalListItem item) {
|
||||||
if (item.getAddressString() != null) {
|
if (item.getAddressString() != null) {
|
||||||
try {
|
try {
|
||||||
Utilities.openWebPage(preferences.getBlockChainExplorer().addressUrl + item.getAddressString());
|
GUIUtil.openWebPage(preferences.getBlockChainExplorer().addressUrl + item.getAddressString());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error(e.getMessage());
|
log.error(e.getMessage());
|
||||||
new Popup().warning("Opening browser failed. Please check your internet " +
|
new Popup().warning("Opening browser failed. Please check your internet " +
|
||||||
|
|
|
@ -17,8 +17,8 @@
|
||||||
|
|
||||||
package io.bitsquare.gui.main.help;
|
package io.bitsquare.gui.main.help;
|
||||||
|
|
||||||
import io.bitsquare.common.util.Utilities;
|
|
||||||
import io.bitsquare.gui.main.overlays.popups.Popup;
|
import io.bitsquare.gui.main.overlays.popups.Popup;
|
||||||
|
import io.bitsquare.gui.util.GUIUtil;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ public class Help {
|
||||||
public static void openWindow(HelpId id) {
|
public static void openWindow(HelpId id) {
|
||||||
try {
|
try {
|
||||||
// TODO create user guide
|
// TODO create user guide
|
||||||
Utilities.openWebPage("http://bitsquare.io/faq");
|
GUIUtil.openWebPage("http://bitsquare.io/faq");
|
||||||
// Utilities.openWebPage("https://github.com/bitsquare/bitsquare/wiki/User-Guide");
|
// Utilities.openWebPage("https://github.com/bitsquare/bitsquare/wiki/User-Guide");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error(e.getMessage());
|
log.error(e.getMessage());
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
<?import javafx.scene.control.Tab?>
|
<?import javafx.scene.control.Tab?>
|
||||||
<?import javafx.scene.control.TabPane?>
|
<?import javafx.scene.control.TabPane?>
|
||||||
<?import javafx.scene.layout.AnchorPane?>
|
<?import javafx.scene.layout.AnchorPane?>
|
||||||
<TabPane fx:id="root" fx:controller="io.bitsquare.gui.main.markets.MarketView"
|
<TabPane fx:id="root" fx:controller="io.bitsquare.gui.main.market.MarketView"
|
||||||
AnchorPane.bottomAnchor="0" AnchorPane.leftAnchor="0"
|
AnchorPane.bottomAnchor="0" AnchorPane.leftAnchor="0"
|
||||||
AnchorPane.rightAnchor="0" AnchorPane.topAnchor="0"
|
AnchorPane.rightAnchor="0" AnchorPane.topAnchor="0"
|
||||||
xmlns:fx="http://javafx.com/fxml">
|
xmlns:fx="http://javafx.com/fxml">
|
|
@ -15,15 +15,15 @@
|
||||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.bitsquare.gui.main.markets;
|
package io.bitsquare.gui.main.market;
|
||||||
|
|
||||||
import io.bitsquare.gui.Navigation;
|
import io.bitsquare.gui.Navigation;
|
||||||
import io.bitsquare.gui.common.model.Activatable;
|
import io.bitsquare.gui.common.model.Activatable;
|
||||||
import io.bitsquare.gui.common.view.*;
|
import io.bitsquare.gui.common.view.*;
|
||||||
import io.bitsquare.gui.main.MainView;
|
import io.bitsquare.gui.main.MainView;
|
||||||
import io.bitsquare.gui.main.markets.charts.MarketsChartsView;
|
import io.bitsquare.gui.main.market.offerbook.OfferBookChartView;
|
||||||
import io.bitsquare.gui.main.markets.statistics.MarketsStatisticsView;
|
import io.bitsquare.gui.main.market.spread.SpreadView;
|
||||||
import io.bitsquare.gui.main.markets.trades.TradesChartsView;
|
import io.bitsquare.gui.main.market.trades.TradesChartsView;
|
||||||
import javafx.beans.value.ChangeListener;
|
import javafx.beans.value.ChangeListener;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.scene.control.Tab;
|
import javafx.scene.control.Tab;
|
||||||
|
@ -55,11 +55,11 @@ public class MarketView extends ActivatableViewAndModel<TabPane, Activatable> {
|
||||||
|
|
||||||
tabChangeListener = (ov, oldValue, newValue) -> {
|
tabChangeListener = (ov, oldValue, newValue) -> {
|
||||||
if (newValue == chartsTab)
|
if (newValue == chartsTab)
|
||||||
navigation.navigateTo(MainView.class, MarketView.class, MarketsChartsView.class);
|
navigation.navigateTo(MainView.class, MarketView.class, OfferBookChartView.class);
|
||||||
else if (newValue == tradesTab)
|
else if (newValue == tradesTab)
|
||||||
navigation.navigateTo(MainView.class, MarketView.class, TradesChartsView.class);
|
navigation.navigateTo(MainView.class, MarketView.class, TradesChartsView.class);
|
||||||
else if (newValue == statisticsTab)
|
else if (newValue == statisticsTab)
|
||||||
navigation.navigateTo(MainView.class, MarketView.class, MarketsStatisticsView.class);
|
navigation.navigateTo(MainView.class, MarketView.class, SpreadView.class);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,11 +69,11 @@ public class MarketView extends ActivatableViewAndModel<TabPane, Activatable> {
|
||||||
navigation.addListener(navigationListener);
|
navigation.addListener(navigationListener);
|
||||||
|
|
||||||
if (root.getSelectionModel().getSelectedItem() == chartsTab)
|
if (root.getSelectionModel().getSelectedItem() == chartsTab)
|
||||||
navigation.navigateTo(MainView.class, MarketView.class, MarketsChartsView.class);
|
navigation.navigateTo(MainView.class, MarketView.class, OfferBookChartView.class);
|
||||||
else if (root.getSelectionModel().getSelectedItem() == tradesTab)
|
else if (root.getSelectionModel().getSelectedItem() == tradesTab)
|
||||||
navigation.navigateTo(MainView.class, MarketView.class, TradesChartsView.class);
|
navigation.navigateTo(MainView.class, MarketView.class, TradesChartsView.class);
|
||||||
else
|
else
|
||||||
navigation.navigateTo(MainView.class, MarketView.class, MarketsStatisticsView.class);
|
navigation.navigateTo(MainView.class, MarketView.class, SpreadView.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -86,9 +86,9 @@ public class MarketView extends ActivatableViewAndModel<TabPane, Activatable> {
|
||||||
final Tab tab;
|
final Tab tab;
|
||||||
View view = viewLoader.load(viewClass);
|
View view = viewLoader.load(viewClass);
|
||||||
|
|
||||||
if (view instanceof MarketsChartsView) tab = chartsTab;
|
if (view instanceof OfferBookChartView) tab = chartsTab;
|
||||||
else if (view instanceof TradesChartsView) tab = tradesTab;
|
else if (view instanceof TradesChartsView) tab = tradesTab;
|
||||||
else if (view instanceof MarketsStatisticsView) tab = statisticsTab;
|
else if (view instanceof SpreadView) tab = statisticsTab;
|
||||||
else throw new IllegalArgumentException("Navigation to " + viewClass + " is not supported");
|
else throw new IllegalArgumentException("Navigation to " + viewClass + " is not supported");
|
||||||
|
|
||||||
tab.setContent(view.getRoot());
|
tab.setContent(view.getRoot());
|
|
@ -0,0 +1,32 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
~ This file is part of Bitsquare.
|
||||||
|
~
|
||||||
|
~ Bitsquare is free software: you can redistribute it and/or modify it
|
||||||
|
~ under the terms of the GNU Affero General Public License as published by
|
||||||
|
~ the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
~ your option) any later version.
|
||||||
|
~
|
||||||
|
~ Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
~ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
~ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||||
|
~ License for more details.
|
||||||
|
~
|
||||||
|
~ You should have received a copy of the GNU Affero General Public License
|
||||||
|
~ along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
<?import javafx.geometry.Insets?>
|
||||||
|
<?import javafx.scene.layout.*?>
|
||||||
|
<VBox fx:id="root" fx:controller="io.bitsquare.gui.main.market.offerbook.OfferBookChartView"
|
||||||
|
spacing="20.0" fillWidth="true"
|
||||||
|
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0"
|
||||||
|
AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"
|
||||||
|
xmlns:fx="http://javafx.com/fxml">
|
||||||
|
<padding>
|
||||||
|
<Insets bottom="10.0" left="20.0" top="10.0" right="20"/>
|
||||||
|
</padding>
|
||||||
|
|
||||||
|
</VBox>
|
|
@ -15,7 +15,7 @@
|
||||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.bitsquare.gui.main.markets.charts;
|
package io.bitsquare.gui.main.market.offerbook;
|
||||||
|
|
||||||
import io.bitsquare.common.UserThread;
|
import io.bitsquare.common.UserThread;
|
||||||
import io.bitsquare.common.util.Tuple3;
|
import io.bitsquare.common.util.Tuple3;
|
||||||
|
@ -27,7 +27,10 @@ import io.bitsquare.gui.main.offer.BuyOfferView;
|
||||||
import io.bitsquare.gui.main.offer.SellOfferView;
|
import io.bitsquare.gui.main.offer.SellOfferView;
|
||||||
import io.bitsquare.gui.main.offer.offerbook.OfferBookListItem;
|
import io.bitsquare.gui.main.offer.offerbook.OfferBookListItem;
|
||||||
import io.bitsquare.gui.util.BSFormatter;
|
import io.bitsquare.gui.util.BSFormatter;
|
||||||
import io.bitsquare.locale.*;
|
import io.bitsquare.gui.util.GUIUtil;
|
||||||
|
import io.bitsquare.locale.BSResources;
|
||||||
|
import io.bitsquare.locale.CurrencyUtil;
|
||||||
|
import io.bitsquare.locale.TradeCurrency;
|
||||||
import io.bitsquare.trade.offer.Offer;
|
import io.bitsquare.trade.offer.Offer;
|
||||||
import javafx.beans.property.ReadOnlyObjectWrapper;
|
import javafx.beans.property.ReadOnlyObjectWrapper;
|
||||||
import javafx.beans.property.SimpleStringProperty;
|
import javafx.beans.property.SimpleStringProperty;
|
||||||
|
@ -45,7 +48,6 @@ import javafx.scene.image.ImageView;
|
||||||
import javafx.scene.layout.HBox;
|
import javafx.scene.layout.HBox;
|
||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.VBox;
|
||||||
import javafx.util.Callback;
|
import javafx.util.Callback;
|
||||||
import javafx.util.StringConverter;
|
|
||||||
import org.fxmisc.easybind.EasyBind;
|
import org.fxmisc.easybind.EasyBind;
|
||||||
import org.fxmisc.easybind.Subscription;
|
import org.fxmisc.easybind.Subscription;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -54,8 +56,8 @@ import org.slf4j.LoggerFactory;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
@FxmlView
|
@FxmlView
|
||||||
public class MarketsChartsView extends ActivatableViewAndModel<VBox, MarketsChartsViewModel> {
|
public class OfferBookChartView extends ActivatableViewAndModel<VBox, OfferBookChartViewModel> {
|
||||||
private static final Logger log = LoggerFactory.getLogger(MarketsChartsView.class);
|
private static final Logger log = LoggerFactory.getLogger(OfferBookChartView.class);
|
||||||
|
|
||||||
private NumberAxis xAxis, yAxis;
|
private NumberAxis xAxis, yAxis;
|
||||||
XYChart.Series seriesBuy, seriesSell;
|
XYChart.Series seriesBuy, seriesSell;
|
||||||
|
@ -71,6 +73,8 @@ public class MarketsChartsView extends ActivatableViewAndModel<VBox, MarketsChar
|
||||||
private final StringProperty volumeColumnLabel = new SimpleStringProperty();
|
private final StringProperty volumeColumnLabel = new SimpleStringProperty();
|
||||||
private Button buyOfferButton;
|
private Button buyOfferButton;
|
||||||
private Button sellOfferButton;
|
private Button sellOfferButton;
|
||||||
|
private ChangeListener<Number> selectedTabIndexListener;
|
||||||
|
private SingleSelectionModel<Tab> tabPaneSelectionModel;
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -78,7 +82,7 @@ public class MarketsChartsView extends ActivatableViewAndModel<VBox, MarketsChar
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public MarketsChartsView(MarketsChartsViewModel model, Navigation navigation, BSFormatter formatter) {
|
public OfferBookChartView(OfferBookChartViewModel model, Navigation navigation, BSFormatter formatter) {
|
||||||
super(model);
|
super(model);
|
||||||
this.navigation = navigation;
|
this.navigation = navigation;
|
||||||
this.formatter = formatter;
|
this.formatter = formatter;
|
||||||
|
@ -90,24 +94,7 @@ public class MarketsChartsView extends ActivatableViewAndModel<VBox, MarketsChar
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
currencyComboBox = new ComboBox<>();
|
currencyComboBox = new ComboBox<>();
|
||||||
currencyComboBox.setPromptText("Select currency");
|
currencyComboBox.setPromptText("Select currency");
|
||||||
currencyComboBox.setConverter(new StringConverter<TradeCurrency>() {
|
currencyComboBox.setConverter(GUIUtil.getCurrencyListConverter());
|
||||||
@Override
|
|
||||||
public String toString(TradeCurrency tradeCurrency) {
|
|
||||||
// http://boschista.deviantart.com/journal/Cool-ASCII-Symbols-214218618
|
|
||||||
if (tradeCurrency instanceof FiatCurrency)
|
|
||||||
return "★ " + tradeCurrency.getNameAndCode();
|
|
||||||
else if (tradeCurrency instanceof CryptoCurrency)
|
|
||||||
return "✦ " + tradeCurrency.getNameAndCode();
|
|
||||||
else
|
|
||||||
return "-";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TradeCurrency fromString(String s) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
Label currencyLabel = new Label("Currency:");
|
Label currencyLabel = new Label("Currency:");
|
||||||
HBox currencyHBox = new HBox();
|
HBox currencyHBox = new HBox();
|
||||||
|
@ -135,8 +122,15 @@ public class MarketsChartsView extends ActivatableViewAndModel<VBox, MarketsChar
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void activate() {
|
protected void activate() {
|
||||||
|
// root.getParent() is null at initialize
|
||||||
|
tabPaneSelectionModel = ((TabPane) root.getParent().getParent()).getSelectionModel();
|
||||||
|
selectedTabIndexListener = (observable, oldValue, newValue) -> model.setSelectedTabIndex((int) newValue);
|
||||||
|
|
||||||
|
model.setSelectedTabIndex(tabPaneSelectionModel.getSelectedIndex());
|
||||||
|
tabPaneSelectionModel.selectedIndexProperty().addListener(selectedTabIndexListener);
|
||||||
|
|
||||||
currencyComboBox.setItems(model.getTradeCurrencies());
|
currencyComboBox.setItems(model.getTradeCurrencies());
|
||||||
currencyComboBox.getSelectionModel().select(model.getTradeCurrency());
|
currencyComboBox.getSelectionModel().select(model.getSelectedTradeCurrencyProperty());
|
||||||
currencyComboBox.setVisibleRowCount(Math.min(currencyComboBox.getItems().size(), 25));
|
currencyComboBox.setVisibleRowCount(Math.min(currencyComboBox.getItems().size(), 25));
|
||||||
currencyComboBox.setOnAction(e -> {
|
currencyComboBox.setOnAction(e -> {
|
||||||
TradeCurrency tradeCurrency = currencyComboBox.getSelectionModel().getSelectedItem();
|
TradeCurrency tradeCurrency = currencyComboBox.getSelectionModel().getSelectedItem();
|
||||||
|
@ -145,7 +139,7 @@ public class MarketsChartsView extends ActivatableViewAndModel<VBox, MarketsChar
|
||||||
});
|
});
|
||||||
|
|
||||||
model.getOfferBookListItems().addListener(changeListener);
|
model.getOfferBookListItems().addListener(changeListener);
|
||||||
tradeCurrencySubscriber = EasyBind.subscribe(model.tradeCurrency,
|
tradeCurrencySubscriber = EasyBind.subscribe(model.selectedTradeCurrencyProperty,
|
||||||
tradeCurrency -> {
|
tradeCurrency -> {
|
||||||
String code = tradeCurrency.getCode();
|
String code = tradeCurrency.getCode();
|
||||||
String tradeCurrencyName = tradeCurrency.getName();
|
String tradeCurrencyName = tradeCurrency.getName();
|
||||||
|
@ -173,6 +167,7 @@ public class MarketsChartsView extends ActivatableViewAndModel<VBox, MarketsChar
|
||||||
@Override
|
@Override
|
||||||
protected void deactivate() {
|
protected void deactivate() {
|
||||||
model.getOfferBookListItems().removeListener(changeListener);
|
model.getOfferBookListItems().removeListener(changeListener);
|
||||||
|
tabPaneSelectionModel.selectedIndexProperty().removeListener(selectedTabIndexListener);
|
||||||
tradeCurrencySubscriber.unsubscribe();
|
tradeCurrencySubscriber.unsubscribe();
|
||||||
currencyComboBox.setOnAction(null);
|
currencyComboBox.setOnAction(null);
|
||||||
}
|
}
|
|
@ -15,14 +15,20 @@
|
||||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.bitsquare.gui.main.markets.charts;
|
package io.bitsquare.gui.main.market.offerbook;
|
||||||
|
|
||||||
import com.google.common.math.LongMath;
|
import com.google.common.math.LongMath;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import io.bitsquare.btc.pricefeed.PriceFeedService;
|
import io.bitsquare.btc.pricefeed.PriceFeedService;
|
||||||
|
import io.bitsquare.gui.Navigation;
|
||||||
import io.bitsquare.gui.common.model.ActivatableViewModel;
|
import io.bitsquare.gui.common.model.ActivatableViewModel;
|
||||||
|
import io.bitsquare.gui.main.MainView;
|
||||||
import io.bitsquare.gui.main.offer.offerbook.OfferBook;
|
import io.bitsquare.gui.main.offer.offerbook.OfferBook;
|
||||||
import io.bitsquare.gui.main.offer.offerbook.OfferBookListItem;
|
import io.bitsquare.gui.main.offer.offerbook.OfferBookListItem;
|
||||||
|
import io.bitsquare.gui.main.settings.SettingsView;
|
||||||
|
import io.bitsquare.gui.main.settings.preferences.PreferencesView;
|
||||||
|
import io.bitsquare.gui.util.GUIUtil;
|
||||||
|
import io.bitsquare.locale.CryptoCurrency;
|
||||||
import io.bitsquare.locale.CurrencyUtil;
|
import io.bitsquare.locale.CurrencyUtil;
|
||||||
import io.bitsquare.locale.TradeCurrency;
|
import io.bitsquare.locale.TradeCurrency;
|
||||||
import io.bitsquare.trade.offer.Offer;
|
import io.bitsquare.trade.offer.Offer;
|
||||||
|
@ -44,16 +50,17 @@ import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
class MarketsChartsViewModel extends ActivatableViewModel {
|
class OfferBookChartViewModel extends ActivatableViewModel {
|
||||||
private static final Logger log = LoggerFactory.getLogger(MarketsChartsViewModel.class);
|
private static final Logger log = LoggerFactory.getLogger(OfferBookChartViewModel.class);
|
||||||
|
|
||||||
final static String EDIT_FLAG = "EDIT_FLAG";
|
private static final int TAB_INDEX = 0;
|
||||||
|
|
||||||
private final OfferBook offerBook;
|
private final OfferBook offerBook;
|
||||||
private final Preferences preferences;
|
private final Preferences preferences;
|
||||||
final PriceFeedService priceFeedService;
|
final PriceFeedService priceFeedService;
|
||||||
|
private Navigation navigation;
|
||||||
|
|
||||||
final ObjectProperty<TradeCurrency> tradeCurrency = new SimpleObjectProperty<>();
|
final ObjectProperty<TradeCurrency> selectedTradeCurrencyProperty = new SimpleObjectProperty<>();
|
||||||
private final List<XYChart.Data> buyData = new ArrayList<>();
|
private final List<XYChart.Data> buyData = new ArrayList<>();
|
||||||
private final List<XYChart.Data> sellData = new ArrayList<>();
|
private final List<XYChart.Data> sellData = new ArrayList<>();
|
||||||
private final ObservableList<OfferBookListItem> offerBookListItems;
|
private final ObservableList<OfferBookListItem> offerBookListItems;
|
||||||
|
@ -61,22 +68,25 @@ class MarketsChartsViewModel extends ActivatableViewModel {
|
||||||
private final ObservableList<Offer> top3BuyOfferList = FXCollections.observableArrayList();
|
private final ObservableList<Offer> top3BuyOfferList = FXCollections.observableArrayList();
|
||||||
private final ObservableList<Offer> top3SellOfferList = FXCollections.observableArrayList();
|
private final ObservableList<Offer> top3SellOfferList = FXCollections.observableArrayList();
|
||||||
private final ChangeListener<Number> currenciesUpdatedListener;
|
private final ChangeListener<Number> currenciesUpdatedListener;
|
||||||
|
private int selectedTabIndex;
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Constructor, lifecycle
|
// Constructor, lifecycle
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public MarketsChartsViewModel(OfferBook offerBook, Preferences preferences, PriceFeedService priceFeedService) {
|
public OfferBookChartViewModel(OfferBook offerBook, Preferences preferences, PriceFeedService priceFeedService, Navigation navigation) {
|
||||||
this.offerBook = offerBook;
|
this.offerBook = offerBook;
|
||||||
this.preferences = preferences;
|
this.preferences = preferences;
|
||||||
this.priceFeedService = priceFeedService;
|
this.priceFeedService = priceFeedService;
|
||||||
|
this.navigation = navigation;
|
||||||
|
|
||||||
Optional<TradeCurrency> tradeCurrencyOptional = CurrencyUtil.getTradeCurrency(preferences.getMarketScreenCurrencyCode());
|
Optional<TradeCurrency> tradeCurrencyOptional = CurrencyUtil.getTradeCurrency(preferences.getOfferBookChartScreenCurrencyCode());
|
||||||
if (tradeCurrencyOptional.isPresent())
|
if (tradeCurrencyOptional.isPresent())
|
||||||
tradeCurrency.set(tradeCurrencyOptional.get());
|
selectedTradeCurrencyProperty.set(tradeCurrencyOptional.get());
|
||||||
else {
|
else {
|
||||||
tradeCurrency.set(CurrencyUtil.getDefaultTradeCurrency());
|
selectedTradeCurrencyProperty.set(CurrencyUtil.getDefaultTradeCurrency());
|
||||||
}
|
}
|
||||||
|
|
||||||
offerBookListItems = offerBook.getOfferBookListItems();
|
offerBookListItems = offerBook.getOfferBookListItems();
|
||||||
|
@ -87,7 +97,7 @@ class MarketsChartsViewModel extends ActivatableViewModel {
|
||||||
list.addAll(c.getAddedSubList());
|
list.addAll(c.getAddedSubList());
|
||||||
if (list.stream()
|
if (list.stream()
|
||||||
.map(OfferBookListItem::getOffer)
|
.map(OfferBookListItem::getOffer)
|
||||||
.filter(e -> e.getCurrencyCode().equals(tradeCurrency.get().getCode()))
|
.filter(e -> e.getCurrencyCode().equals(selectedTradeCurrencyProperty.get().getCode()))
|
||||||
.findAny()
|
.findAny()
|
||||||
.isPresent())
|
.isPresent())
|
||||||
updateChartData();
|
updateChartData();
|
||||||
|
@ -117,8 +127,7 @@ class MarketsChartsViewModel extends ActivatableViewModel {
|
||||||
if (isAnyPricePresent())
|
if (isAnyPricePresent())
|
||||||
priceFeedService.currenciesUpdateFlagProperty().addListener(currenciesUpdatedListener);
|
priceFeedService.currenciesUpdateFlagProperty().addListener(currenciesUpdatedListener);
|
||||||
|
|
||||||
if (!preferences.getUseStickyMarketPrice())
|
syncPriceFeedCurrency();
|
||||||
priceFeedService.setCurrencyCode(tradeCurrency.get().getCode());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -126,6 +135,83 @@ class MarketsChartsViewModel extends ActivatableViewModel {
|
||||||
offerBookListItems.removeListener(listChangeListener);
|
offerBookListItems.removeListener(listChangeListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// UI actions
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public void onSetTradeCurrency(TradeCurrency tradeCurrency) {
|
||||||
|
if (tradeCurrency != null) {
|
||||||
|
final String code = tradeCurrency.getCode();
|
||||||
|
|
||||||
|
if (isEditEntry(code)) {
|
||||||
|
navigation.navigateTo(MainView.class, SettingsView.class, PreferencesView.class);
|
||||||
|
} else {
|
||||||
|
selectedTradeCurrencyProperty.set(tradeCurrency);
|
||||||
|
preferences.setOfferBookChartScreenCurrencyCode(code);
|
||||||
|
|
||||||
|
updateChartData();
|
||||||
|
|
||||||
|
if (!preferences.getUseStickyMarketPrice())
|
||||||
|
priceFeedService.setCurrencyCode(code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSelectedTabIndex(int selectedTabIndex) {
|
||||||
|
this.selectedTabIndex = selectedTabIndex;
|
||||||
|
syncPriceFeedCurrency();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Getters
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public List<XYChart.Data> getBuyData() {
|
||||||
|
return buyData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<XYChart.Data> getSellData() {
|
||||||
|
return sellData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCurrencyCode() {
|
||||||
|
return selectedTradeCurrencyProperty.get().getCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObservableList<OfferBookListItem> getOfferBookListItems() {
|
||||||
|
return offerBookListItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObservableList<Offer> getTop3BuyOfferList() {
|
||||||
|
return top3BuyOfferList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObservableList<Offer> getTop3SellOfferList() {
|
||||||
|
return top3SellOfferList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObservableList<TradeCurrency> getTradeCurrencies() {
|
||||||
|
final ObservableList<TradeCurrency> list = FXCollections.observableArrayList(preferences.getTradeCurrenciesAsObservable());
|
||||||
|
list.add(new CryptoCurrency(GUIUtil.EDIT_FLAG, GUIUtil.EDIT_FLAG));
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TradeCurrency getSelectedTradeCurrencyProperty() {
|
||||||
|
return selectedTradeCurrencyProperty.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Private
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
private void syncPriceFeedCurrency() {
|
||||||
|
if (!preferences.getUseStickyMarketPrice() && selectedTabIndex == TAB_INDEX)
|
||||||
|
priceFeedService.setCurrencyCode(selectedTradeCurrencyProperty.get().getCode());
|
||||||
|
}
|
||||||
|
|
||||||
private boolean isAnyPricePresent() {
|
private boolean isAnyPricePresent() {
|
||||||
return offerBookListItems.stream().filter(item -> item.getOffer().getPrice() == null).findAny().isPresent();
|
return offerBookListItems.stream().filter(item -> item.getOffer().getPrice() == null).findAny().isPresent();
|
||||||
}
|
}
|
||||||
|
@ -133,7 +219,7 @@ class MarketsChartsViewModel extends ActivatableViewModel {
|
||||||
private void updateChartData() {
|
private void updateChartData() {
|
||||||
List<Offer> allBuyOffers = offerBookListItems.stream()
|
List<Offer> allBuyOffers = offerBookListItems.stream()
|
||||||
.map(OfferBookListItem::getOffer)
|
.map(OfferBookListItem::getOffer)
|
||||||
.filter(e -> e.getCurrencyCode().equals(tradeCurrency.get().getCode())
|
.filter(e -> e.getCurrencyCode().equals(selectedTradeCurrencyProperty.get().getCode())
|
||||||
&& e.getDirection().equals(Offer.Direction.BUY))
|
&& e.getDirection().equals(Offer.Direction.BUY))
|
||||||
.sorted((o1, o2) -> {
|
.sorted((o1, o2) -> {
|
||||||
long a = o1.getPrice() != null ? o1.getPrice().value : 0;
|
long a = o1.getPrice() != null ? o1.getPrice().value : 0;
|
||||||
|
@ -148,7 +234,7 @@ class MarketsChartsViewModel extends ActivatableViewModel {
|
||||||
|
|
||||||
List<Offer> allSellOffers = offerBookListItems.stream()
|
List<Offer> allSellOffers = offerBookListItems.stream()
|
||||||
.map(OfferBookListItem::getOffer)
|
.map(OfferBookListItem::getOffer)
|
||||||
.filter(e -> e.getCurrencyCode().equals(tradeCurrency.get().getCode())
|
.filter(e -> e.getCurrencyCode().equals(selectedTradeCurrencyProperty.get().getCode())
|
||||||
&& e.getDirection().equals(Offer.Direction.SELL))
|
&& e.getDirection().equals(Offer.Direction.SELL))
|
||||||
.sorted((o1, o2) -> {
|
.sorted((o1, o2) -> {
|
||||||
long a = o1.getPrice() != null ? o1.getPrice().value : 0;
|
long a = o1.getPrice() != null ? o1.getPrice().value : 0;
|
||||||
|
@ -179,54 +265,7 @@ class MarketsChartsViewModel extends ActivatableViewModel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isEditEntry(String id) {
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
return id.equals(GUIUtil.EDIT_FLAG);
|
||||||
// UI actions
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
public void onSetTradeCurrency(TradeCurrency tradeCurrency) {
|
|
||||||
this.tradeCurrency.set(tradeCurrency);
|
|
||||||
updateChartData();
|
|
||||||
|
|
||||||
if (!preferences.getUseStickyMarketPrice())
|
|
||||||
priceFeedService.setCurrencyCode(tradeCurrency.getCode());
|
|
||||||
|
|
||||||
preferences.setMarketScreenCurrencyCode(tradeCurrency.getCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Getters
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
public List<XYChart.Data> getBuyData() {
|
|
||||||
return buyData;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<XYChart.Data> getSellData() {
|
|
||||||
return sellData;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCurrencyCode() {
|
|
||||||
return tradeCurrency.get().getCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ObservableList<OfferBookListItem> getOfferBookListItems() {
|
|
||||||
return offerBookListItems;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ObservableList<Offer> getTop3BuyOfferList() {
|
|
||||||
return top3BuyOfferList;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ObservableList<Offer> getTop3SellOfferList() {
|
|
||||||
return top3SellOfferList;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ObservableList<TradeCurrency> getTradeCurrencies() {
|
|
||||||
return preferences.getTradeCurrenciesAsObservable();
|
|
||||||
}
|
|
||||||
|
|
||||||
public TradeCurrency getTradeCurrency() {
|
|
||||||
return tradeCurrency.get();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package io.bitsquare.gui.main.markets.statistics;
|
package io.bitsquare.gui.main.market.spread;
|
||||||
|
|
||||||
import org.bitcoinj.core.Coin;
|
import org.bitcoinj.core.Coin;
|
||||||
import org.bitcoinj.utils.Fiat;
|
import org.bitcoinj.utils.Fiat;
|
||||||
|
@ -7,8 +7,8 @@ import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public class MarketStatisticItem {
|
public class SpreadItem {
|
||||||
private static final Logger log = LoggerFactory.getLogger(MarketStatisticItem.class);
|
private static final Logger log = LoggerFactory.getLogger(SpreadItem.class);
|
||||||
public final String currencyCode;
|
public final String currencyCode;
|
||||||
public final int numberOfBuyOffers;
|
public final int numberOfBuyOffers;
|
||||||
public final int numberOfSellOffers;
|
public final int numberOfSellOffers;
|
||||||
|
@ -17,7 +17,7 @@ public class MarketStatisticItem {
|
||||||
public final Fiat spread;
|
public final Fiat spread;
|
||||||
public final Coin totalAmount;
|
public final Coin totalAmount;
|
||||||
|
|
||||||
public MarketStatisticItem(String currencyCode, int numberOfBuyOffers, int numberOfSellOffers, int numberOfOffers, @Nullable Fiat spread, Coin totalAmount) {
|
public SpreadItem(String currencyCode, int numberOfBuyOffers, int numberOfSellOffers, int numberOfOffers, @Nullable Fiat spread, Coin totalAmount) {
|
||||||
this.currencyCode = currencyCode;
|
this.currencyCode = currencyCode;
|
||||||
this.numberOfBuyOffers = numberOfBuyOffers;
|
this.numberOfBuyOffers = numberOfBuyOffers;
|
||||||
this.numberOfSellOffers = numberOfSellOffers;
|
this.numberOfSellOffers = numberOfSellOffers;
|
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
<?import javafx.geometry.Insets?>
|
<?import javafx.geometry.Insets?>
|
||||||
<?import javafx.scene.layout.*?>
|
<?import javafx.scene.layout.*?>
|
||||||
<GridPane fx:id="root" fx:controller="io.bitsquare.gui.main.markets.statistics.MarketsStatisticsView"
|
<GridPane fx:id="root" fx:controller="io.bitsquare.gui.main.market.spread.SpreadView"
|
||||||
hgap="5.0" vgap="5.0"
|
hgap="5.0" vgap="5.0"
|
||||||
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0"
|
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0"
|
||||||
AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"
|
AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"
|
|
@ -15,7 +15,7 @@
|
||||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.bitsquare.gui.main.markets.statistics;
|
package io.bitsquare.gui.main.market.spread;
|
||||||
|
|
||||||
import io.bitsquare.gui.common.view.ActivatableViewAndModel;
|
import io.bitsquare.gui.common.view.ActivatableViewAndModel;
|
||||||
import io.bitsquare.gui.common.view.FxmlView;
|
import io.bitsquare.gui.common.view.FxmlView;
|
||||||
|
@ -38,13 +38,13 @@ import org.bitcoinj.core.Coin;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
@FxmlView
|
@FxmlView
|
||||||
public class MarketsStatisticsView extends ActivatableViewAndModel<GridPane, MarketsStatisticViewModel> {
|
public class SpreadView extends ActivatableViewAndModel<GridPane, SpreadViewModel> {
|
||||||
private final BSFormatter formatter;
|
private final BSFormatter formatter;
|
||||||
private final int gridRow = 0;
|
private final int gridRow = 0;
|
||||||
private TableView<MarketStatisticItem> tableView;
|
private TableView<SpreadItem> tableView;
|
||||||
private SortedList<MarketStatisticItem> sortedList;
|
private SortedList<SpreadItem> sortedList;
|
||||||
private ListChangeListener<MarketStatisticItem> itemListChangeListener;
|
private ListChangeListener<SpreadItem> itemListChangeListener;
|
||||||
private TableColumn<MarketStatisticItem, MarketStatisticItem> totalAmountColumn, numberOfOffersColumn, numberOfBuyOffersColumn, numberOfSellOffersColumn;
|
private TableColumn<SpreadItem, SpreadItem> totalAmountColumn, numberOfOffersColumn, numberOfBuyOffersColumn, numberOfSellOffersColumn;
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -52,7 +52,7 @@ public class MarketsStatisticsView extends ActivatableViewAndModel<GridPane, Mar
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public MarketsStatisticsView(MarketsStatisticViewModel model, BSFormatter formatter) {
|
public SpreadView(SpreadViewModel model, BSFormatter formatter) {
|
||||||
super(model);
|
super(model);
|
||||||
this.formatter = formatter;
|
this.formatter = formatter;
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ public class MarketsStatisticsView extends ActivatableViewAndModel<GridPane, Mar
|
||||||
placeholder.setWrapText(true);
|
placeholder.setWrapText(true);
|
||||||
tableView.setPlaceholder(placeholder);
|
tableView.setPlaceholder(placeholder);
|
||||||
|
|
||||||
TableColumn<MarketStatisticItem, MarketStatisticItem> currencyColumn = getCurrencyColumn();
|
TableColumn<SpreadItem, SpreadItem> currencyColumn = getCurrencyColumn();
|
||||||
tableView.getColumns().add(currencyColumn);
|
tableView.getColumns().add(currencyColumn);
|
||||||
numberOfOffersColumn = getNumberOfOffersColumn();
|
numberOfOffersColumn = getNumberOfOffersColumn();
|
||||||
tableView.getColumns().add(numberOfOffersColumn);
|
tableView.getColumns().add(numberOfOffersColumn);
|
||||||
|
@ -84,7 +84,7 @@ public class MarketsStatisticsView extends ActivatableViewAndModel<GridPane, Mar
|
||||||
tableView.getColumns().add(numberOfSellOffersColumn);
|
tableView.getColumns().add(numberOfSellOffersColumn);
|
||||||
totalAmountColumn = getTotalAmountColumn();
|
totalAmountColumn = getTotalAmountColumn();
|
||||||
tableView.getColumns().add(totalAmountColumn);
|
tableView.getColumns().add(totalAmountColumn);
|
||||||
TableColumn<MarketStatisticItem, MarketStatisticItem> spreadColumn = getSpreadColumn();
|
TableColumn<SpreadItem, SpreadItem> spreadColumn = getSpreadColumn();
|
||||||
tableView.getColumns().add(spreadColumn);
|
tableView.getColumns().add(spreadColumn);
|
||||||
tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
|
tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ public class MarketsStatisticsView extends ActivatableViewAndModel<GridPane, Mar
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void activate() {
|
protected void activate() {
|
||||||
sortedList = new SortedList<>(model.marketStatisticItems);
|
sortedList = new SortedList<>(model.spreadItems);
|
||||||
sortedList.comparatorProperty().bind(tableView.comparatorProperty());
|
sortedList.comparatorProperty().bind(tableView.comparatorProperty());
|
||||||
tableView.setItems(sortedList);
|
tableView.setItems(sortedList);
|
||||||
sortedList.addListener(itemListChangeListener);
|
sortedList.addListener(itemListChangeListener);
|
||||||
|
@ -127,22 +127,22 @@ public class MarketsStatisticsView extends ActivatableViewAndModel<GridPane, Mar
|
||||||
// Columns
|
// Columns
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
private TableColumn<MarketStatisticItem, MarketStatisticItem> getCurrencyColumn() {
|
private TableColumn<SpreadItem, SpreadItem> getCurrencyColumn() {
|
||||||
TableColumn<MarketStatisticItem, MarketStatisticItem> column = new TableColumn<MarketStatisticItem, MarketStatisticItem>("Currency") {
|
TableColumn<SpreadItem, SpreadItem> column = new TableColumn<SpreadItem, SpreadItem>("Currency") {
|
||||||
{
|
{
|
||||||
setMinWidth(100);
|
setMinWidth(100);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue()));
|
column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue()));
|
||||||
column.setCellFactory(
|
column.setCellFactory(
|
||||||
new Callback<TableColumn<MarketStatisticItem, MarketStatisticItem>, TableCell<MarketStatisticItem,
|
new Callback<TableColumn<SpreadItem, SpreadItem>, TableCell<SpreadItem,
|
||||||
MarketStatisticItem>>() {
|
SpreadItem>>() {
|
||||||
@Override
|
@Override
|
||||||
public TableCell<MarketStatisticItem, MarketStatisticItem> call(
|
public TableCell<SpreadItem, SpreadItem> call(
|
||||||
TableColumn<MarketStatisticItem, MarketStatisticItem> column) {
|
TableColumn<SpreadItem, SpreadItem> column) {
|
||||||
return new TableCell<MarketStatisticItem, MarketStatisticItem>() {
|
return new TableCell<SpreadItem, SpreadItem>() {
|
||||||
@Override
|
@Override
|
||||||
public void updateItem(final MarketStatisticItem item, boolean empty) {
|
public void updateItem(final SpreadItem item, boolean empty) {
|
||||||
super.updateItem(item, empty);
|
super.updateItem(item, empty);
|
||||||
if (item != null && !empty)
|
if (item != null && !empty)
|
||||||
setText(CurrencyUtil.getNameByCode(item.currencyCode));
|
setText(CurrencyUtil.getNameByCode(item.currencyCode));
|
||||||
|
@ -155,22 +155,22 @@ public class MarketsStatisticsView extends ActivatableViewAndModel<GridPane, Mar
|
||||||
return column;
|
return column;
|
||||||
}
|
}
|
||||||
|
|
||||||
private TableColumn<MarketStatisticItem, MarketStatisticItem> getNumberOfOffersColumn() {
|
private TableColumn<SpreadItem, SpreadItem> getNumberOfOffersColumn() {
|
||||||
TableColumn<MarketStatisticItem, MarketStatisticItem> column = new TableColumn<MarketStatisticItem, MarketStatisticItem>("Total offers") {
|
TableColumn<SpreadItem, SpreadItem> column = new TableColumn<SpreadItem, SpreadItem>("Total offers") {
|
||||||
{
|
{
|
||||||
setMinWidth(100);
|
setMinWidth(100);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue()));
|
column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue()));
|
||||||
column.setCellFactory(
|
column.setCellFactory(
|
||||||
new Callback<TableColumn<MarketStatisticItem, MarketStatisticItem>, TableCell<MarketStatisticItem,
|
new Callback<TableColumn<SpreadItem, SpreadItem>, TableCell<SpreadItem,
|
||||||
MarketStatisticItem>>() {
|
SpreadItem>>() {
|
||||||
@Override
|
@Override
|
||||||
public TableCell<MarketStatisticItem, MarketStatisticItem> call(
|
public TableCell<SpreadItem, SpreadItem> call(
|
||||||
TableColumn<MarketStatisticItem, MarketStatisticItem> column) {
|
TableColumn<SpreadItem, SpreadItem> column) {
|
||||||
return new TableCell<MarketStatisticItem, MarketStatisticItem>() {
|
return new TableCell<SpreadItem, SpreadItem>() {
|
||||||
@Override
|
@Override
|
||||||
public void updateItem(final MarketStatisticItem item, boolean empty) {
|
public void updateItem(final SpreadItem item, boolean empty) {
|
||||||
super.updateItem(item, empty);
|
super.updateItem(item, empty);
|
||||||
if (item != null && !empty)
|
if (item != null && !empty)
|
||||||
setText(String.valueOf(item.numberOfOffers));
|
setText(String.valueOf(item.numberOfOffers));
|
||||||
|
@ -183,22 +183,22 @@ public class MarketsStatisticsView extends ActivatableViewAndModel<GridPane, Mar
|
||||||
return column;
|
return column;
|
||||||
}
|
}
|
||||||
|
|
||||||
private TableColumn<MarketStatisticItem, MarketStatisticItem> getNumberOfBuyOffersColumn() {
|
private TableColumn<SpreadItem, SpreadItem> getNumberOfBuyOffersColumn() {
|
||||||
TableColumn<MarketStatisticItem, MarketStatisticItem> column = new TableColumn<MarketStatisticItem, MarketStatisticItem>("Buy offers") {
|
TableColumn<SpreadItem, SpreadItem> column = new TableColumn<SpreadItem, SpreadItem>("Buy offers") {
|
||||||
{
|
{
|
||||||
setMinWidth(100);
|
setMinWidth(100);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue()));
|
column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue()));
|
||||||
column.setCellFactory(
|
column.setCellFactory(
|
||||||
new Callback<TableColumn<MarketStatisticItem, MarketStatisticItem>, TableCell<MarketStatisticItem,
|
new Callback<TableColumn<SpreadItem, SpreadItem>, TableCell<SpreadItem,
|
||||||
MarketStatisticItem>>() {
|
SpreadItem>>() {
|
||||||
@Override
|
@Override
|
||||||
public TableCell<MarketStatisticItem, MarketStatisticItem> call(
|
public TableCell<SpreadItem, SpreadItem> call(
|
||||||
TableColumn<MarketStatisticItem, MarketStatisticItem> column) {
|
TableColumn<SpreadItem, SpreadItem> column) {
|
||||||
return new TableCell<MarketStatisticItem, MarketStatisticItem>() {
|
return new TableCell<SpreadItem, SpreadItem>() {
|
||||||
@Override
|
@Override
|
||||||
public void updateItem(final MarketStatisticItem item, boolean empty) {
|
public void updateItem(final SpreadItem item, boolean empty) {
|
||||||
super.updateItem(item, empty);
|
super.updateItem(item, empty);
|
||||||
if (item != null && !empty)
|
if (item != null && !empty)
|
||||||
setText(String.valueOf(item.numberOfBuyOffers));
|
setText(String.valueOf(item.numberOfBuyOffers));
|
||||||
|
@ -211,22 +211,22 @@ public class MarketsStatisticsView extends ActivatableViewAndModel<GridPane, Mar
|
||||||
return column;
|
return column;
|
||||||
}
|
}
|
||||||
|
|
||||||
private TableColumn<MarketStatisticItem, MarketStatisticItem> getNumberOfSellOffersColumn() {
|
private TableColumn<SpreadItem, SpreadItem> getNumberOfSellOffersColumn() {
|
||||||
TableColumn<MarketStatisticItem, MarketStatisticItem> column = new TableColumn<MarketStatisticItem, MarketStatisticItem>("Sell offers") {
|
TableColumn<SpreadItem, SpreadItem> column = new TableColumn<SpreadItem, SpreadItem>("Sell offers") {
|
||||||
{
|
{
|
||||||
setMinWidth(100);
|
setMinWidth(100);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue()));
|
column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue()));
|
||||||
column.setCellFactory(
|
column.setCellFactory(
|
||||||
new Callback<TableColumn<MarketStatisticItem, MarketStatisticItem>, TableCell<MarketStatisticItem,
|
new Callback<TableColumn<SpreadItem, SpreadItem>, TableCell<SpreadItem,
|
||||||
MarketStatisticItem>>() {
|
SpreadItem>>() {
|
||||||
@Override
|
@Override
|
||||||
public TableCell<MarketStatisticItem, MarketStatisticItem> call(
|
public TableCell<SpreadItem, SpreadItem> call(
|
||||||
TableColumn<MarketStatisticItem, MarketStatisticItem> column) {
|
TableColumn<SpreadItem, SpreadItem> column) {
|
||||||
return new TableCell<MarketStatisticItem, MarketStatisticItem>() {
|
return new TableCell<SpreadItem, SpreadItem>() {
|
||||||
@Override
|
@Override
|
||||||
public void updateItem(final MarketStatisticItem item, boolean empty) {
|
public void updateItem(final SpreadItem item, boolean empty) {
|
||||||
super.updateItem(item, empty);
|
super.updateItem(item, empty);
|
||||||
if (item != null && !empty)
|
if (item != null && !empty)
|
||||||
setText(String.valueOf(item.numberOfSellOffers));
|
setText(String.valueOf(item.numberOfSellOffers));
|
||||||
|
@ -239,22 +239,22 @@ public class MarketsStatisticsView extends ActivatableViewAndModel<GridPane, Mar
|
||||||
return column;
|
return column;
|
||||||
}
|
}
|
||||||
|
|
||||||
private TableColumn<MarketStatisticItem, MarketStatisticItem> getTotalAmountColumn() {
|
private TableColumn<SpreadItem, SpreadItem> getTotalAmountColumn() {
|
||||||
TableColumn<MarketStatisticItem, MarketStatisticItem> column = new TableColumn<MarketStatisticItem, MarketStatisticItem>("Total amount") {
|
TableColumn<SpreadItem, SpreadItem> column = new TableColumn<SpreadItem, SpreadItem>("Total amount") {
|
||||||
{
|
{
|
||||||
setMinWidth(150);
|
setMinWidth(150);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue()));
|
column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue()));
|
||||||
column.setCellFactory(
|
column.setCellFactory(
|
||||||
new Callback<TableColumn<MarketStatisticItem, MarketStatisticItem>, TableCell<MarketStatisticItem,
|
new Callback<TableColumn<SpreadItem, SpreadItem>, TableCell<SpreadItem,
|
||||||
MarketStatisticItem>>() {
|
SpreadItem>>() {
|
||||||
@Override
|
@Override
|
||||||
public TableCell<MarketStatisticItem, MarketStatisticItem> call(
|
public TableCell<SpreadItem, SpreadItem> call(
|
||||||
TableColumn<MarketStatisticItem, MarketStatisticItem> column) {
|
TableColumn<SpreadItem, SpreadItem> column) {
|
||||||
return new TableCell<MarketStatisticItem, MarketStatisticItem>() {
|
return new TableCell<SpreadItem, SpreadItem>() {
|
||||||
@Override
|
@Override
|
||||||
public void updateItem(final MarketStatisticItem item, boolean empty) {
|
public void updateItem(final SpreadItem item, boolean empty) {
|
||||||
super.updateItem(item, empty);
|
super.updateItem(item, empty);
|
||||||
if (item != null && !empty)
|
if (item != null && !empty)
|
||||||
setText(formatter.formatCoin(item.totalAmount));
|
setText(formatter.formatCoin(item.totalAmount));
|
||||||
|
@ -267,22 +267,22 @@ public class MarketsStatisticsView extends ActivatableViewAndModel<GridPane, Mar
|
||||||
return column;
|
return column;
|
||||||
}
|
}
|
||||||
|
|
||||||
private TableColumn<MarketStatisticItem, MarketStatisticItem> getSpreadColumn() {
|
private TableColumn<SpreadItem, SpreadItem> getSpreadColumn() {
|
||||||
TableColumn<MarketStatisticItem, MarketStatisticItem> column = new TableColumn<MarketStatisticItem, MarketStatisticItem>("Spread") {
|
TableColumn<SpreadItem, SpreadItem> column = new TableColumn<SpreadItem, SpreadItem>("Spread") {
|
||||||
{
|
{
|
||||||
setMinWidth(130);
|
setMinWidth(130);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue()));
|
column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue()));
|
||||||
column.setCellFactory(
|
column.setCellFactory(
|
||||||
new Callback<TableColumn<MarketStatisticItem, MarketStatisticItem>, TableCell<MarketStatisticItem,
|
new Callback<TableColumn<SpreadItem, SpreadItem>, TableCell<SpreadItem,
|
||||||
MarketStatisticItem>>() {
|
SpreadItem>>() {
|
||||||
@Override
|
@Override
|
||||||
public TableCell<MarketStatisticItem, MarketStatisticItem> call(
|
public TableCell<SpreadItem, SpreadItem> call(
|
||||||
TableColumn<MarketStatisticItem, MarketStatisticItem> column) {
|
TableColumn<SpreadItem, SpreadItem> column) {
|
||||||
return new TableCell<MarketStatisticItem, MarketStatisticItem>() {
|
return new TableCell<SpreadItem, SpreadItem>() {
|
||||||
@Override
|
@Override
|
||||||
public void updateItem(final MarketStatisticItem item, boolean empty) {
|
public void updateItem(final SpreadItem item, boolean empty) {
|
||||||
super.updateItem(item, empty);
|
super.updateItem(item, empty);
|
||||||
if (item != null && !empty) {
|
if (item != null && !empty) {
|
||||||
if (item.spread != null)
|
if (item.spread != null)
|
|
@ -15,7 +15,7 @@
|
||||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.bitsquare.gui.main.markets.statistics;
|
package io.bitsquare.gui.main.market.spread;
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import io.bitsquare.gui.common.model.ActivatableViewModel;
|
import io.bitsquare.gui.common.model.ActivatableViewModel;
|
||||||
|
@ -34,12 +34,12 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
class MarketsStatisticViewModel extends ActivatableViewModel {
|
class SpreadViewModel extends ActivatableViewModel {
|
||||||
|
|
||||||
private final OfferBook offerBook;
|
private final OfferBook offerBook;
|
||||||
private final ObservableList<OfferBookListItem> offerBookListItems;
|
private final ObservableList<OfferBookListItem> offerBookListItems;
|
||||||
private final ListChangeListener<OfferBookListItem> listChangeListener;
|
private final ListChangeListener<OfferBookListItem> listChangeListener;
|
||||||
final ObservableList<MarketStatisticItem> marketStatisticItems = FXCollections.observableArrayList();
|
final ObservableList<SpreadItem> spreadItems = FXCollections.observableArrayList();
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -47,7 +47,7 @@ class MarketsStatisticViewModel extends ActivatableViewModel {
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public MarketsStatisticViewModel(OfferBook offerBook) {
|
public SpreadViewModel(OfferBook offerBook) {
|
||||||
this.offerBook = offerBook;
|
this.offerBook = offerBook;
|
||||||
|
|
||||||
offerBookListItems = offerBook.getOfferBookListItems();
|
offerBookListItems = offerBook.getOfferBookListItems();
|
||||||
|
@ -75,7 +75,7 @@ class MarketsStatisticViewModel extends ActivatableViewModel {
|
||||||
offersByCurrencyMap.put(currencyCode, new ArrayList<>());
|
offersByCurrencyMap.put(currencyCode, new ArrayList<>());
|
||||||
offersByCurrencyMap.get(currencyCode).add(offer);
|
offersByCurrencyMap.get(currencyCode).add(offer);
|
||||||
}
|
}
|
||||||
marketStatisticItems.clear();
|
spreadItems.clear();
|
||||||
for (String currencyCode : offersByCurrencyMap.keySet()) {
|
for (String currencyCode : offersByCurrencyMap.keySet()) {
|
||||||
List<Offer> offers = offersByCurrencyMap.get(currencyCode);
|
List<Offer> offers = offersByCurrencyMap.get(currencyCode);
|
||||||
List<Offer> buyOffers = offers
|
List<Offer> buyOffers = offers
|
||||||
|
@ -109,7 +109,7 @@ class MarketsStatisticViewModel extends ActivatableViewModel {
|
||||||
spread = bestSellOfferPrice.subtract(bestBuyOfferPrice);
|
spread = bestSellOfferPrice.subtract(bestBuyOfferPrice);
|
||||||
|
|
||||||
Coin totalAmount = Coin.valueOf(offers.stream().mapToLong(offer -> offer.getAmount().getValue()).sum());
|
Coin totalAmount = Coin.valueOf(offers.stream().mapToLong(offer -> offer.getAmount().getValue()).sum());
|
||||||
marketStatisticItems.add(new MarketStatisticItem(currencyCode, buyOffers.size(), sellOffers.size(), offers.size(), spread, totalAmount));
|
spreadItems.add(new SpreadItem(currencyCode, buyOffers.size(), sellOffers.size(), offers.size(), spread, totalAmount));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
<?import javafx.geometry.Insets?>
|
<?import javafx.geometry.Insets?>
|
||||||
<?import javafx.scene.layout.*?>
|
<?import javafx.scene.layout.*?>
|
||||||
<VBox fx:id="root" fx:controller="io.bitsquare.gui.main.markets.trades.TradesChartsView"
|
<VBox fx:id="root" fx:controller="io.bitsquare.gui.main.market.trades.TradesChartsView"
|
||||||
spacing="10.0" fillWidth="true"
|
spacing="10.0" fillWidth="true"
|
||||||
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0"
|
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0"
|
||||||
AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"
|
AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"
|
|
@ -15,16 +15,15 @@
|
||||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.bitsquare.gui.main.markets.trades;
|
package io.bitsquare.gui.main.market.trades;
|
||||||
|
|
||||||
import io.bitsquare.common.UserThread;
|
import io.bitsquare.common.UserThread;
|
||||||
import io.bitsquare.gui.common.view.ActivatableViewAndModel;
|
import io.bitsquare.gui.common.view.ActivatableViewAndModel;
|
||||||
import io.bitsquare.gui.common.view.FxmlView;
|
import io.bitsquare.gui.common.view.FxmlView;
|
||||||
import io.bitsquare.gui.main.markets.trades.charts.price.CandleStickChart;
|
import io.bitsquare.gui.main.market.trades.charts.price.CandleStickChart;
|
||||||
import io.bitsquare.gui.main.markets.trades.charts.volume.VolumeChart;
|
import io.bitsquare.gui.main.market.trades.charts.volume.VolumeChart;
|
||||||
import io.bitsquare.gui.util.BSFormatter;
|
import io.bitsquare.gui.util.BSFormatter;
|
||||||
import io.bitsquare.locale.CryptoCurrency;
|
import io.bitsquare.gui.util.GUIUtil;
|
||||||
import io.bitsquare.locale.FiatCurrency;
|
|
||||||
import io.bitsquare.locale.TradeCurrency;
|
import io.bitsquare.locale.TradeCurrency;
|
||||||
import io.bitsquare.trade.statistics.TradeStatistics;
|
import io.bitsquare.trade.statistics.TradeStatistics;
|
||||||
import javafx.beans.property.ReadOnlyObjectWrapper;
|
import javafx.beans.property.ReadOnlyObjectWrapper;
|
||||||
|
@ -81,6 +80,11 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
|
||||||
private SortedList<TradeStatistics> sortedList;
|
private SortedList<TradeStatistics> sortedList;
|
||||||
private Label nrOfTradeStatisticsLabel;
|
private Label nrOfTradeStatisticsLabel;
|
||||||
private ListChangeListener<TradeStatistics> tradeStatisticsByCurrencyListener;
|
private ListChangeListener<TradeStatistics> tradeStatisticsByCurrencyListener;
|
||||||
|
private TableColumn<TradeStatistics, TradeStatistics> priceColumn;
|
||||||
|
private ChangeListener<Number> selectedTabIndexListener;
|
||||||
|
private SingleSelectionModel<Tab> tabPaneSelectionModel;
|
||||||
|
private ChangeListener<Boolean> showAllTradeCurrenciesListener;
|
||||||
|
private TableColumn<TradeStatistics, TradeStatistics> volumeColumn;
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -122,12 +126,30 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
|
||||||
layoutChart();
|
layoutChart();
|
||||||
};
|
};
|
||||||
tradeStatisticsByCurrencyListener = c -> nrOfTradeStatisticsLabel.setText("Nr. of trades: " + model.tradeStatisticsByCurrency.size());
|
tradeStatisticsByCurrencyListener = c -> nrOfTradeStatisticsLabel.setText("Nr. of trades: " + model.tradeStatisticsByCurrency.size());
|
||||||
|
showAllTradeCurrenciesListener = (observable, oldValue, newValue) -> {
|
||||||
|
priceChart.setVisible(!newValue);
|
||||||
|
priceChart.setManaged(!newValue);
|
||||||
|
priceColumn.setSortable(!newValue);
|
||||||
|
priceColumnLabel.set("Price" + (newValue ? "" : (" (" + model.getCurrencyCode() + ")")));
|
||||||
|
volumeColumn.setText("Volume" + (newValue ? "" : (" (" + model.getCurrencyCode() + ")")));
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void activate() {
|
protected void activate() {
|
||||||
|
// root.getParent() is null at initialize
|
||||||
|
tabPaneSelectionModel = ((TabPane) root.getParent().getParent()).getSelectionModel();
|
||||||
|
selectedTabIndexListener = (observable, oldValue, newValue) -> model.setSelectedTabIndex((int) newValue);
|
||||||
|
model.setSelectedTabIndex(tabPaneSelectionModel.getSelectedIndex());
|
||||||
|
tabPaneSelectionModel.selectedIndexProperty().addListener(selectedTabIndexListener);
|
||||||
|
|
||||||
currencyComboBox.setItems(model.getTradeCurrencies());
|
currencyComboBox.setItems(model.getTradeCurrencies());
|
||||||
currencyComboBox.getSelectionModel().select(model.getTradeCurrency());
|
|
||||||
|
if (model.showAllTradeCurrenciesProperty.get())
|
||||||
|
currencyComboBox.getSelectionModel().select(0);
|
||||||
|
else
|
||||||
|
currencyComboBox.getSelectionModel().select(model.getSelectedTradeCurrency());
|
||||||
|
|
||||||
currencyComboBox.setVisibleRowCount(Math.min(currencyComboBox.getItems().size(), 25));
|
currencyComboBox.setVisibleRowCount(Math.min(currencyComboBox.getItems().size(), 25));
|
||||||
currencyComboBox.setOnAction(e -> model.onSetTradeCurrency(currencyComboBox.getSelectionModel().getSelectedItem()));
|
currencyComboBox.setOnAction(e -> model.onSetTradeCurrency(currencyComboBox.getSelectionModel().getSelectedItem()));
|
||||||
|
|
||||||
|
@ -137,15 +159,22 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
|
||||||
toggleGroup.selectedToggleProperty().addListener(toggleChangeListener);
|
toggleGroup.selectedToggleProperty().addListener(toggleChangeListener);
|
||||||
priceAxisY.widthProperty().addListener(priceAxisYWidthListener);
|
priceAxisY.widthProperty().addListener(priceAxisYWidthListener);
|
||||||
volumeAxisY.widthProperty().addListener(volumeAxisYWidthListener);
|
volumeAxisY.widthProperty().addListener(volumeAxisYWidthListener);
|
||||||
|
model.tradeStatisticsByCurrency.addListener(tradeStatisticsByCurrencyListener);
|
||||||
|
model.showAllTradeCurrenciesProperty.addListener(showAllTradeCurrenciesListener);
|
||||||
|
|
||||||
tradeCurrencySubscriber = EasyBind.subscribe(model.tradeCurrencyProperty,
|
priceAxisY.labelProperty().bind(priceColumnLabel);
|
||||||
|
priceColumn.textProperty().bind(priceColumnLabel);
|
||||||
|
|
||||||
|
tradeCurrencySubscriber = EasyBind.subscribe(model.selectedTradeCurrencyProperty,
|
||||||
tradeCurrency -> {
|
tradeCurrency -> {
|
||||||
String code = tradeCurrency.getCode();
|
String code = tradeCurrency.getCode();
|
||||||
String tradeCurrencyName = tradeCurrency.getName();
|
String tradeCurrencyName = tradeCurrency.getName();
|
||||||
|
|
||||||
priceSeries.setName(tradeCurrencyName);
|
priceSeries.setName(tradeCurrencyName);
|
||||||
final String currencyPair = formatter.getCurrencyPair(code);
|
final String currencyPair = formatter.getCurrencyPair(code);
|
||||||
priceColumnLabel.set("Price (" + currencyPair + ")");
|
final boolean showAllTradeCurrencies = model.showAllTradeCurrenciesProperty.get();
|
||||||
|
priceColumnLabel.set("Price" + (showAllTradeCurrencies ? "" : (" (" + currencyPair + ")")));
|
||||||
|
volumeColumn.setText("Volume" + (showAllTradeCurrencies ? "" : (" (" + code + ")")));
|
||||||
});
|
});
|
||||||
|
|
||||||
sortedList = new SortedList<>(model.tradeStatisticsByCurrency);
|
sortedList = new SortedList<>(model.tradeStatisticsByCurrency);
|
||||||
|
@ -158,23 +187,30 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
|
||||||
priceAxisX.setTickLabelFormatter(getTimeAxisStringConverter());
|
priceAxisX.setTickLabelFormatter(getTimeAxisStringConverter());
|
||||||
volumeAxisX.setTickLabelFormatter(getTimeAxisStringConverter());
|
volumeAxisX.setTickLabelFormatter(getTimeAxisStringConverter());
|
||||||
|
|
||||||
model.tradeStatisticsByCurrency.addListener(tradeStatisticsByCurrencyListener);
|
|
||||||
nrOfTradeStatisticsLabel.setText("Nr. of trades: " + model.tradeStatisticsByCurrency.size());
|
nrOfTradeStatisticsLabel.setText("Nr. of trades: " + model.tradeStatisticsByCurrency.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void deactivate() {
|
protected void deactivate() {
|
||||||
|
currencyComboBox.setOnAction(null);
|
||||||
|
|
||||||
|
tabPaneSelectionModel.selectedIndexProperty().removeListener(selectedTabIndexListener);
|
||||||
model.priceItems.removeListener(itemsChangeListener);
|
model.priceItems.removeListener(itemsChangeListener);
|
||||||
toggleGroup.selectedToggleProperty().removeListener(toggleChangeListener);
|
toggleGroup.selectedToggleProperty().removeListener(toggleChangeListener);
|
||||||
priceAxisY.widthProperty().removeListener(priceAxisYWidthListener);
|
priceAxisY.widthProperty().removeListener(priceAxisYWidthListener);
|
||||||
volumeAxisY.widthProperty().removeListener(volumeAxisYWidthListener);
|
volumeAxisY.widthProperty().removeListener(volumeAxisYWidthListener);
|
||||||
model.tradeStatisticsByCurrency.removeListener(tradeStatisticsByCurrencyListener);
|
model.tradeStatisticsByCurrency.removeListener(tradeStatisticsByCurrencyListener);
|
||||||
tradeCurrencySubscriber.unsubscribe();
|
model.showAllTradeCurrenciesProperty.removeListener(showAllTradeCurrenciesListener);
|
||||||
currencyComboBox.setOnAction(null);
|
|
||||||
priceAxisY.labelProperty().unbind();
|
priceAxisY.labelProperty().unbind();
|
||||||
|
priceColumn.textProperty().unbind();
|
||||||
|
|
||||||
|
tradeCurrencySubscriber.unsubscribe();
|
||||||
|
|
||||||
|
sortedList.comparatorProperty().unbind();
|
||||||
|
|
||||||
priceSeries.getData().clear();
|
priceSeries.getData().clear();
|
||||||
priceChart.getData().clear();
|
priceChart.getData().clear();
|
||||||
sortedList.comparatorProperty().unbind();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -194,7 +230,6 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
|
||||||
priceAxisY = new NumberAxis();
|
priceAxisY = new NumberAxis();
|
||||||
priceAxisY.setForceZeroInRange(false);
|
priceAxisY.setForceZeroInRange(false);
|
||||||
priceAxisY.setAutoRanging(true);
|
priceAxisY.setAutoRanging(true);
|
||||||
priceAxisY.labelProperty().bind(priceColumnLabel);
|
|
||||||
priceAxisY.setTickLabelFormatter(new StringConverter<Number>() {
|
priceAxisY.setTickLabelFormatter(new StringConverter<Number>() {
|
||||||
@Override
|
@Override
|
||||||
public String toString(Number object) {
|
public String toString(Number object) {
|
||||||
|
@ -207,11 +242,7 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
priceChart = new CandleStickChart(priceAxisX, priceAxisY);
|
priceChart = new CandleStickChart(priceAxisX, priceAxisY, new StringConverter<Number>() {
|
||||||
priceChart.setMinHeight(250);
|
|
||||||
priceChart.setLegendVisible(false);
|
|
||||||
priceChart.setData(FXCollections.observableArrayList(priceSeries));
|
|
||||||
priceChart.setToolTipStringConverter(new StringConverter<Number>() {
|
|
||||||
@Override
|
@Override
|
||||||
public String toString(Number object) {
|
public String toString(Number object) {
|
||||||
return formatter.formatFiatWithCode(Fiat.valueOf(model.getCurrencyCode(), (long) object));
|
return formatter.formatFiatWithCode(Fiat.valueOf(model.getCurrencyCode(), (long) object));
|
||||||
|
@ -222,6 +253,10 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
priceChart.setMinHeight(250);
|
||||||
|
priceChart.setMaxHeight(300);
|
||||||
|
priceChart.setLegendVisible(false);
|
||||||
|
priceChart.setData(FXCollections.observableArrayList(priceSeries));
|
||||||
|
|
||||||
|
|
||||||
volumeSeries = new XYChart.Series<>();
|
volumeSeries = new XYChart.Series<>();
|
||||||
|
@ -248,14 +283,10 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
volumeChart = new VolumeChart(volumeAxisX, volumeAxisY);
|
volumeChart = new VolumeChart(volumeAxisX, volumeAxisY, new StringConverter<Number>() {
|
||||||
volumeChart.setData(FXCollections.observableArrayList(volumeSeries));
|
|
||||||
volumeChart.setMinHeight(140);
|
|
||||||
volumeChart.setLegendVisible(false);
|
|
||||||
volumeChart.setToolTipStringConverter(new StringConverter<Number>() {
|
|
||||||
@Override
|
@Override
|
||||||
public String toString(Number object) {
|
public String toString(Number object) {
|
||||||
return formatter.formatCoinWithCode(Coin.valueOf(new Double((double) object).longValue()));
|
return formatter.formatCoinWithCode(Coin.valueOf((long) object));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -263,6 +294,10 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
volumeChart.setData(FXCollections.observableArrayList(volumeSeries));
|
||||||
|
volumeChart.setMinHeight(140);
|
||||||
|
volumeChart.setMaxHeight(200);
|
||||||
|
volumeChart.setLegendVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateChartData() {
|
private void updateChartData() {
|
||||||
|
@ -320,23 +355,7 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
|
||||||
|
|
||||||
currencyComboBox = new ComboBox<>();
|
currencyComboBox = new ComboBox<>();
|
||||||
currencyComboBox.setPromptText("Select currency");
|
currencyComboBox.setPromptText("Select currency");
|
||||||
currencyComboBox.setConverter(new StringConverter<TradeCurrency>() {
|
currencyComboBox.setConverter(GUIUtil.getCurrencyListConverter());
|
||||||
@Override
|
|
||||||
public String toString(TradeCurrency tradeCurrency) {
|
|
||||||
// http://boschista.deviantart.com/journal/Cool-ASCII-Symbols-214218618
|
|
||||||
if (tradeCurrency instanceof FiatCurrency)
|
|
||||||
return "★ " + tradeCurrency.getNameAndCode();
|
|
||||||
else if (tradeCurrency instanceof CryptoCurrency)
|
|
||||||
return "✦ " + tradeCurrency.getNameAndCode();
|
|
||||||
else
|
|
||||||
return "-";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TradeCurrency fromString(String s) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Pane spacer = new Pane();
|
Pane spacer = new Pane();
|
||||||
HBox.setHgrow(spacer, Priority.ALWAYS);
|
HBox.setHgrow(spacer, Priority.ALWAYS);
|
||||||
|
@ -377,6 +396,7 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
|
||||||
private void createTable() {
|
private void createTable() {
|
||||||
tableView = new TableView<>();
|
tableView = new TableView<>();
|
||||||
tableView.setMinHeight(120);
|
tableView.setMinHeight(120);
|
||||||
|
VBox.setVgrow(tableView, Priority.ALWAYS);
|
||||||
|
|
||||||
// date
|
// date
|
||||||
TableColumn<TradeStatistics, TradeStatistics> dateColumn = new TableColumn<>("Date/Time");
|
TableColumn<TradeStatistics, TradeStatistics> dateColumn = new TableColumn<>("Date/Time");
|
||||||
|
@ -427,9 +447,8 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
|
||||||
tableView.getColumns().add(amountColumn);
|
tableView.getColumns().add(amountColumn);
|
||||||
|
|
||||||
// price
|
// price
|
||||||
TableColumn<TradeStatistics, TradeStatistics> priceColumn = new TableColumn<>();
|
priceColumn = new TableColumn<>();
|
||||||
priceColumn.setCellValueFactory((tradeStatistics) -> new ReadOnlyObjectWrapper<>(tradeStatistics.getValue()));
|
priceColumn.setCellValueFactory((tradeStatistics) -> new ReadOnlyObjectWrapper<>(tradeStatistics.getValue()));
|
||||||
priceColumn.textProperty().bind(priceColumnLabel);
|
|
||||||
priceColumn.setCellFactory(
|
priceColumn.setCellFactory(
|
||||||
new Callback<TableColumn<TradeStatistics, TradeStatistics>, TableCell<TradeStatistics,
|
new Callback<TableColumn<TradeStatistics, TradeStatistics>, TableCell<TradeStatistics,
|
||||||
TradeStatistics>>() {
|
TradeStatistics>>() {
|
||||||
|
@ -441,7 +460,9 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
|
||||||
public void updateItem(final TradeStatistics item, boolean empty) {
|
public void updateItem(final TradeStatistics item, boolean empty) {
|
||||||
super.updateItem(item, empty);
|
super.updateItem(item, empty);
|
||||||
if (item != null)
|
if (item != null)
|
||||||
setText(formatter.formatFiat(item.getTradePrice()));
|
setText(model.showAllTradeCurrenciesProperty.get() ?
|
||||||
|
formatter.formatFiatWithCode(item.getTradePrice()) :
|
||||||
|
formatter.formatFiat(item.getTradePrice()));
|
||||||
else
|
else
|
||||||
setText("");
|
setText("");
|
||||||
}
|
}
|
||||||
|
@ -452,9 +473,8 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
|
||||||
tableView.getColumns().add(priceColumn);
|
tableView.getColumns().add(priceColumn);
|
||||||
|
|
||||||
// volume
|
// volume
|
||||||
TableColumn<TradeStatistics, TradeStatistics> volumeColumn = new TableColumn<>();
|
volumeColumn = new TableColumn<>();
|
||||||
volumeColumn.setCellValueFactory((tradeStatistics) -> new ReadOnlyObjectWrapper<>(tradeStatistics.getValue()));
|
volumeColumn.setCellValueFactory((tradeStatistics) -> new ReadOnlyObjectWrapper<>(tradeStatistics.getValue()));
|
||||||
volumeColumn.setText("Volume (BTC)");
|
|
||||||
volumeColumn.setCellFactory(
|
volumeColumn.setCellFactory(
|
||||||
new Callback<TableColumn<TradeStatistics, TradeStatistics>, TableCell<TradeStatistics,
|
new Callback<TableColumn<TradeStatistics, TradeStatistics>, TableCell<TradeStatistics,
|
||||||
TradeStatistics>>() {
|
TradeStatistics>>() {
|
||||||
|
@ -466,7 +486,9 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
|
||||||
public void updateItem(final TradeStatistics item, boolean empty) {
|
public void updateItem(final TradeStatistics item, boolean empty) {
|
||||||
super.updateItem(item, empty);
|
super.updateItem(item, empty);
|
||||||
if (item != null)
|
if (item != null)
|
||||||
setText(formatter.formatFiatWithCode(item.getTradeVolume()));
|
setText(model.showAllTradeCurrenciesProperty.get() ?
|
||||||
|
formatter.formatFiatWithCode(item.getTradeVolume()) :
|
||||||
|
formatter.formatFiat(item.getTradeVolume()));
|
||||||
else
|
else
|
||||||
setText("");
|
setText("");
|
||||||
}
|
}
|
|
@ -15,19 +15,28 @@
|
||||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.bitsquare.gui.main.markets.trades;
|
package io.bitsquare.gui.main.market.trades;
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import io.bitsquare.btc.pricefeed.PriceFeedService;
|
import io.bitsquare.btc.pricefeed.PriceFeedService;
|
||||||
|
import io.bitsquare.gui.Navigation;
|
||||||
import io.bitsquare.gui.common.model.ActivatableViewModel;
|
import io.bitsquare.gui.common.model.ActivatableViewModel;
|
||||||
import io.bitsquare.gui.main.markets.trades.charts.CandleData;
|
import io.bitsquare.gui.main.MainView;
|
||||||
|
import io.bitsquare.gui.main.market.trades.charts.CandleData;
|
||||||
|
import io.bitsquare.gui.main.settings.SettingsView;
|
||||||
|
import io.bitsquare.gui.main.settings.preferences.PreferencesView;
|
||||||
|
import io.bitsquare.gui.util.BSFormatter;
|
||||||
|
import io.bitsquare.gui.util.GUIUtil;
|
||||||
|
import io.bitsquare.locale.CryptoCurrency;
|
||||||
import io.bitsquare.locale.CurrencyUtil;
|
import io.bitsquare.locale.CurrencyUtil;
|
||||||
import io.bitsquare.locale.TradeCurrency;
|
import io.bitsquare.locale.TradeCurrency;
|
||||||
import io.bitsquare.trade.statistics.TradeStatistics;
|
import io.bitsquare.trade.statistics.TradeStatistics;
|
||||||
import io.bitsquare.trade.statistics.TradeStatisticsManager;
|
import io.bitsquare.trade.statistics.TradeStatisticsManager;
|
||||||
import io.bitsquare.user.Preferences;
|
import io.bitsquare.user.Preferences;
|
||||||
|
import javafx.beans.property.BooleanProperty;
|
||||||
import javafx.beans.property.ObjectProperty;
|
import javafx.beans.property.ObjectProperty;
|
||||||
|
import javafx.beans.property.SimpleBooleanProperty;
|
||||||
import javafx.beans.property.SimpleObjectProperty;
|
import javafx.beans.property.SimpleObjectProperty;
|
||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
import javafx.collections.ObservableList;
|
import javafx.collections.ObservableList;
|
||||||
|
@ -42,6 +51,8 @@ import java.util.stream.Collectors;
|
||||||
|
|
||||||
class TradesChartsViewModel extends ActivatableViewModel {
|
class TradesChartsViewModel extends ActivatableViewModel {
|
||||||
private static final Logger log = LoggerFactory.getLogger(TradesChartsViewModel.class);
|
private static final Logger log = LoggerFactory.getLogger(TradesChartsViewModel.class);
|
||||||
|
private static final int TAB_INDEX = 2;
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Enum
|
// Enum
|
||||||
|
@ -59,9 +70,12 @@ class TradesChartsViewModel extends ActivatableViewModel {
|
||||||
private final TradeStatisticsManager tradeStatisticsManager;
|
private final TradeStatisticsManager tradeStatisticsManager;
|
||||||
final Preferences preferences;
|
final Preferences preferences;
|
||||||
private PriceFeedService priceFeedService;
|
private PriceFeedService priceFeedService;
|
||||||
|
private Navigation navigation;
|
||||||
|
private BSFormatter formatter;
|
||||||
|
|
||||||
private final SetChangeListener<TradeStatistics> setChangeListener;
|
private final SetChangeListener<TradeStatistics> setChangeListener;
|
||||||
final ObjectProperty<TradeCurrency> tradeCurrencyProperty = new SimpleObjectProperty<>();
|
final ObjectProperty<TradeCurrency> selectedTradeCurrencyProperty = new SimpleObjectProperty<>();
|
||||||
|
final BooleanProperty showAllTradeCurrenciesProperty = new SimpleBooleanProperty(false);
|
||||||
|
|
||||||
final ObservableList<TradeStatistics> tradeStatisticsByCurrency = FXCollections.observableArrayList();
|
final ObservableList<TradeStatistics> tradeStatisticsByCurrency = FXCollections.observableArrayList();
|
||||||
ObservableList<XYChart.Data<Number, Number>> priceItems = FXCollections.observableArrayList();
|
ObservableList<XYChart.Data<Number, Number>> priceItems = FXCollections.observableArrayList();
|
||||||
|
@ -69,6 +83,7 @@ class TradesChartsViewModel extends ActivatableViewModel {
|
||||||
|
|
||||||
TickUnit tickUnit = TickUnit.MONTH;
|
TickUnit tickUnit = TickUnit.MONTH;
|
||||||
int maxTicks = 30;
|
int maxTicks = 30;
|
||||||
|
private int selectedTabIndex;
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -76,19 +91,20 @@ class TradesChartsViewModel extends ActivatableViewModel {
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public TradesChartsViewModel(TradeStatisticsManager tradeStatisticsManager, Preferences preferences, PriceFeedService priceFeedService) {
|
public TradesChartsViewModel(TradeStatisticsManager tradeStatisticsManager, Preferences preferences, PriceFeedService priceFeedService, Navigation navigation, BSFormatter formatter) {
|
||||||
this.tradeStatisticsManager = tradeStatisticsManager;
|
this.tradeStatisticsManager = tradeStatisticsManager;
|
||||||
this.preferences = preferences;
|
this.preferences = preferences;
|
||||||
this.priceFeedService = priceFeedService;
|
this.priceFeedService = priceFeedService;
|
||||||
|
this.navigation = navigation;
|
||||||
|
this.formatter = formatter;
|
||||||
|
|
||||||
setChangeListener = change -> updateChartData();
|
setChangeListener = change -> updateChartData();
|
||||||
|
|
||||||
Optional<TradeCurrency> tradeCurrencyOptional = CurrencyUtil.getTradeCurrency(preferences.getTradeStatisticsScreenCurrencyCode());
|
Optional<TradeCurrency> tradeCurrencyOptional = CurrencyUtil.getTradeCurrency(preferences.getTradeChartsScreenCurrencyCode());
|
||||||
if (tradeCurrencyOptional.isPresent())
|
if (tradeCurrencyOptional.isPresent())
|
||||||
tradeCurrencyProperty.set(tradeCurrencyOptional.get());
|
selectedTradeCurrencyProperty.set(tradeCurrencyOptional.get());
|
||||||
else {
|
else
|
||||||
tradeCurrencyProperty.set(CurrencyUtil.getDefaultTradeCurrency());
|
selectedTradeCurrencyProperty.set(CurrencyUtil.getDefaultTradeCurrency());
|
||||||
}
|
|
||||||
|
|
||||||
tickUnit = TickUnit.values()[preferences.getTradeStatisticsTickUnitIndex()];
|
tickUnit = TickUnit.values()[preferences.getTradeStatisticsTickUnitIndex()];
|
||||||
}
|
}
|
||||||
|
@ -105,9 +121,8 @@ class TradesChartsViewModel extends ActivatableViewModel {
|
||||||
protected void activate() {
|
protected void activate() {
|
||||||
tradeStatisticsManager.getObservableTradeStatisticsSet().addListener(setChangeListener);
|
tradeStatisticsManager.getObservableTradeStatisticsSet().addListener(setChangeListener);
|
||||||
updateChartData();
|
updateChartData();
|
||||||
|
syncPriceFeedCurrency();
|
||||||
if (!preferences.getUseStickyMarketPrice())
|
setMarketPriceFeedCurrency();
|
||||||
priceFeedService.setCurrencyCode(tradeCurrencyProperty.get().getCode());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -120,37 +135,62 @@ class TradesChartsViewModel extends ActivatableViewModel {
|
||||||
// UI actions
|
// UI actions
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
public void onSetTradeCurrency(TradeCurrency tradeCurrency) {
|
void onSetTradeCurrency(TradeCurrency tradeCurrency) {
|
||||||
this.tradeCurrencyProperty.set(tradeCurrency);
|
if (tradeCurrency != null) {
|
||||||
preferences.setTradeStatisticsScreenCurrencyCode(tradeCurrency.getCode());
|
final String code = tradeCurrency.getCode();
|
||||||
updateChartData();
|
|
||||||
|
|
||||||
if (!preferences.getUseStickyMarketPrice())
|
|
||||||
priceFeedService.setCurrencyCode(tradeCurrency.getCode());
|
|
||||||
|
|
||||||
|
if (isEditEntry(code)) {
|
||||||
|
navigation.navigateTo(MainView.class, SettingsView.class, PreferencesView.class);
|
||||||
|
} else {
|
||||||
|
boolean showAllEntry = isShowAllEntry(code);
|
||||||
|
showAllTradeCurrenciesProperty.set(showAllEntry);
|
||||||
|
if (!showAllEntry) {
|
||||||
|
selectedTradeCurrencyProperty.set(tradeCurrency);
|
||||||
|
preferences.setTradeChartsScreenCurrencyCode(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTickUnit(TickUnit tickUnit) {
|
updateChartData();
|
||||||
|
|
||||||
|
if (!preferences.getUseStickyMarketPrice()) {
|
||||||
|
if (showAllEntry)
|
||||||
|
priceFeedService.setCurrencyCode(CurrencyUtil.getDefaultTradeCurrency().getCode());
|
||||||
|
else
|
||||||
|
priceFeedService.setCurrencyCode(code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setTickUnit(TickUnit tickUnit) {
|
||||||
this.tickUnit = tickUnit;
|
this.tickUnit = tickUnit;
|
||||||
preferences.setTradeStatisticsTickUnitIndex(tickUnit.ordinal());
|
preferences.setTradeStatisticsTickUnitIndex(tickUnit.ordinal());
|
||||||
updateChartData();
|
updateChartData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setSelectedTabIndex(int selectedTabIndex) {
|
||||||
|
this.selectedTabIndex = selectedTabIndex;
|
||||||
|
syncPriceFeedCurrency();
|
||||||
|
setMarketPriceFeedCurrency();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Getters
|
// Getters
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
public String getCurrencyCode() {
|
public String getCurrencyCode() {
|
||||||
return tradeCurrencyProperty.get().getCode();
|
return selectedTradeCurrencyProperty.get().getCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObservableList<TradeCurrency> getTradeCurrencies() {
|
public ObservableList<TradeCurrency> getTradeCurrencies() {
|
||||||
return preferences.getTradeCurrenciesAsObservable();
|
final ObservableList<TradeCurrency> list = FXCollections.observableArrayList(preferences.getTradeCurrenciesAsObservable());
|
||||||
|
list.add(0, new CryptoCurrency(GUIUtil.SHOW_ALL_FLAG, GUIUtil.SHOW_ALL_FLAG));
|
||||||
|
list.add(new CryptoCurrency(GUIUtil.EDIT_FLAG, GUIUtil.EDIT_FLAG));
|
||||||
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TradeCurrency getTradeCurrency() {
|
public TradeCurrency getSelectedTradeCurrency() {
|
||||||
return tradeCurrencyProperty.get();
|
return selectedTradeCurrencyProperty.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -158,10 +198,23 @@ class TradesChartsViewModel extends ActivatableViewModel {
|
||||||
// Private
|
// Private
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
private void setMarketPriceFeedCurrency() {
|
||||||
|
if (!preferences.getUseStickyMarketPrice() && selectedTabIndex == TAB_INDEX) {
|
||||||
|
if (showAllTradeCurrenciesProperty.get())
|
||||||
|
priceFeedService.setCurrencyCode(CurrencyUtil.getDefaultTradeCurrency().getCode());
|
||||||
|
else
|
||||||
|
priceFeedService.setCurrencyCode(getCurrencyCode());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void syncPriceFeedCurrency() {
|
||||||
|
if (!preferences.getUseStickyMarketPrice() && selectedTabIndex == TAB_INDEX)
|
||||||
|
priceFeedService.setCurrencyCode(selectedTradeCurrencyProperty.get().getCode());
|
||||||
|
}
|
||||||
|
|
||||||
private void updateChartData() {
|
private void updateChartData() {
|
||||||
tradeStatisticsByCurrency.setAll(tradeStatisticsManager.getObservableTradeStatisticsSet().stream()
|
tradeStatisticsByCurrency.setAll(tradeStatisticsManager.getObservableTradeStatisticsSet().stream()
|
||||||
.filter(e -> e.currency.equals(getCurrencyCode()))
|
.filter(e -> showAllTradeCurrenciesProperty.get() || e.currency.equals(getCurrencyCode()))
|
||||||
.collect(Collectors.toList()));
|
.collect(Collectors.toList()));
|
||||||
|
|
||||||
// Get all entries for the defined time interval
|
// Get all entries for the defined time interval
|
||||||
|
@ -183,6 +236,7 @@ class TradesChartsViewModel extends ActivatableViewModel {
|
||||||
// create CandleData for defined time interval
|
// create CandleData for defined time interval
|
||||||
List<CandleData> candleDataList = itemsPerInterval.entrySet().stream()
|
List<CandleData> candleDataList = itemsPerInterval.entrySet().stream()
|
||||||
.map(entry -> getCandleData(entry.getKey(), entry.getValue()))
|
.map(entry -> getCandleData(entry.getKey(), entry.getValue()))
|
||||||
|
.filter(e -> e.tick >= 0)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
candleDataList.sort((o1, o2) -> (o1.tick < o2.tick ? -1 : (o1.tick == o2.tick ? 0 : 1)));
|
candleDataList.sort((o1, o2) -> (o1.tick < o2.tick ? -1 : (o1.tick == o2.tick ? 0 : 1)));
|
||||||
|
|
||||||
|
@ -221,7 +275,12 @@ class TradesChartsViewModel extends ActivatableViewModel {
|
||||||
close = list.get(list.size() - 1).tradePrice;
|
close = list.get(list.size() - 1).tradePrice;
|
||||||
}
|
}
|
||||||
boolean isBullish = close > open;
|
boolean isBullish = close > open;
|
||||||
return new CandleData(tick, open, close, high, low, averagePrice, accumulatedAmount, accumulatedVolume, isBullish);
|
final Date date = new Date(getTimeFromTickIndex(tick));
|
||||||
|
String dateString = tickUnit.ordinal() > TickUnit.DAY.ordinal() ?
|
||||||
|
formatter.formatDateTime(date) :
|
||||||
|
formatter.formatDate(date);
|
||||||
|
return new CandleData(tick, open, close, high, low, averagePrice, accumulatedAmount, accumulatedVolume,
|
||||||
|
isBullish, dateString);
|
||||||
}
|
}
|
||||||
|
|
||||||
long getTickFromTime(long tradeDateAsTime, TickUnit tickUnit) {
|
long getTickFromTime(long tradeDateAsTime, TickUnit tickUnit) {
|
||||||
|
@ -267,4 +326,12 @@ class TradesChartsViewModel extends ActivatableViewModel {
|
||||||
long tick = now - (maxTicks - index);
|
long tick = now - (maxTicks - index);
|
||||||
return getTimeFromTick(tick, tickUnit);
|
return getTimeFromTick(tick, tickUnit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isShowAllEntry(String id) {
|
||||||
|
return id.equals(GUIUtil.SHOW_ALL_FLAG);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isEditEntry(String id) {
|
||||||
|
return id.equals(GUIUtil.EDIT_FLAG);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -15,7 +15,7 @@
|
||||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.bitsquare.gui.main.markets.trades.charts;
|
package io.bitsquare.gui.main.market.trades.charts;
|
||||||
|
|
||||||
public class CandleData {
|
public class CandleData {
|
||||||
public final long tick; // Is the time tick in the chosen time interval
|
public final long tick; // Is the time tick in the chosen time interval
|
||||||
|
@ -27,8 +27,9 @@ public class CandleData {
|
||||||
public final long accumulatedAmount;
|
public final long accumulatedAmount;
|
||||||
public final long accumulatedVolume;
|
public final long accumulatedVolume;
|
||||||
public final boolean isBullish;
|
public final boolean isBullish;
|
||||||
|
public final String date;
|
||||||
|
|
||||||
public CandleData(long tick, long open, long close, long high, long low, long average, long accumulatedAmount, long accumulatedVolume, boolean isBullish) {
|
public CandleData(long tick, long open, long close, long high, long low, long average, long accumulatedAmount, long accumulatedVolume, boolean isBullish, String date) {
|
||||||
this.tick = tick;
|
this.tick = tick;
|
||||||
this.open = open;
|
this.open = open;
|
||||||
this.close = close;
|
this.close = close;
|
||||||
|
@ -38,5 +39,6 @@ public class CandleData {
|
||||||
this.accumulatedAmount = accumulatedAmount;
|
this.accumulatedAmount = accumulatedAmount;
|
||||||
this.accumulatedVolume = accumulatedVolume;
|
this.accumulatedVolume = accumulatedVolume;
|
||||||
this.isBullish = isBullish;
|
this.isBullish = isBullish;
|
||||||
|
this.date = date;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -29,9 +29,9 @@
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
package io.bitsquare.gui.main.markets.trades.charts.price;
|
package io.bitsquare.gui.main.market.trades.charts.price;
|
||||||
|
|
||||||
import io.bitsquare.gui.main.markets.trades.charts.CandleData;
|
import io.bitsquare.gui.main.market.trades.charts.CandleData;
|
||||||
import javafx.scene.Group;
|
import javafx.scene.Group;
|
||||||
import javafx.scene.control.Tooltip;
|
import javafx.scene.control.Tooltip;
|
||||||
import javafx.scene.layout.Region;
|
import javafx.scene.layout.Region;
|
||||||
|
@ -48,7 +48,7 @@ public class Candle extends Group {
|
||||||
|
|
||||||
private String seriesStyleClass;
|
private String seriesStyleClass;
|
||||||
private String dataStyleClass;
|
private String dataStyleClass;
|
||||||
private final TooltipContent tooltipContent;
|
private final CandleTooltip candleTooltip;
|
||||||
private final Line highLowLine = new Line();
|
private final Line highLowLine = new Line();
|
||||||
private final Region bar = new Region();
|
private final Region bar = new Region();
|
||||||
|
|
||||||
|
@ -65,8 +65,8 @@ public class Candle extends Group {
|
||||||
getStyleClass().setAll("candlestick-candle", seriesStyleClass, dataStyleClass);
|
getStyleClass().setAll("candlestick-candle", seriesStyleClass, dataStyleClass);
|
||||||
updateStyleClasses();
|
updateStyleClasses();
|
||||||
|
|
||||||
tooltipContent = new TooltipContent(priceStringConverter);
|
candleTooltip = new CandleTooltip(priceStringConverter);
|
||||||
tooltip.setGraphic(tooltipContent);
|
tooltip.setGraphic(candleTooltip);
|
||||||
Tooltip.install(this, tooltip);
|
Tooltip.install(this, tooltip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ public class Candle extends Group {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateTooltip(CandleData candleData) {
|
public void updateTooltip(CandleData candleData) {
|
||||||
tooltipContent.update(candleData);
|
candleTooltip.update(candleData);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateStyleClasses() {
|
private void updateStyleClasses() {
|
|
@ -29,9 +29,9 @@
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
package io.bitsquare.gui.main.markets.trades.charts.price;
|
package io.bitsquare.gui.main.market.trades.charts.price;
|
||||||
|
|
||||||
import io.bitsquare.gui.main.markets.trades.charts.CandleData;
|
import io.bitsquare.gui.main.market.trades.charts.CandleData;
|
||||||
import javafx.animation.FadeTransition;
|
import javafx.animation.FadeTransition;
|
||||||
import javafx.event.ActionEvent;
|
import javafx.event.ActionEvent;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
|
@ -70,16 +70,13 @@ public class CandleStickChart extends XYChart<Number, Number> {
|
||||||
* @param xAxis The x axis to use
|
* @param xAxis The x axis to use
|
||||||
* @param yAxis The y axis to use
|
* @param yAxis The y axis to use
|
||||||
*/
|
*/
|
||||||
public CandleStickChart(Axis<Number> xAxis, Axis<Number> yAxis) {
|
public CandleStickChart(Axis<Number> xAxis, Axis<Number> yAxis, StringConverter<Number> priceStringConverter) {
|
||||||
super(xAxis, yAxis);
|
super(xAxis, yAxis);
|
||||||
|
this.priceStringConverter = priceStringConverter;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------- METHODS ------------------------------------------------------------------------------------------
|
// -------------- METHODS ------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
public final void setToolTipStringConverter(StringConverter<Number> priceStringConverter) {
|
|
||||||
this.priceStringConverter = priceStringConverter;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called to update and layout the content for the plot
|
* Called to update and layout the content for the plot
|
||||||
*/
|
*/
|
|
@ -29,29 +29,34 @@
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
package io.bitsquare.gui.main.markets.trades.charts.price;
|
package io.bitsquare.gui.main.market.trades.charts.price;
|
||||||
|
|
||||||
import io.bitsquare.gui.main.markets.trades.charts.CandleData;
|
import io.bitsquare.gui.main.market.trades.charts.CandleData;
|
||||||
import io.bitsquare.gui.util.Layout;
|
import io.bitsquare.gui.util.Layout;
|
||||||
|
import javafx.geometry.HPos;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
|
import javafx.scene.layout.ColumnConstraints;
|
||||||
import javafx.scene.layout.GridPane;
|
import javafx.scene.layout.GridPane;
|
||||||
|
import javafx.scene.layout.Priority;
|
||||||
import javafx.util.StringConverter;
|
import javafx.util.StringConverter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The content for Candle tool tips
|
* The content for Candle tool tips
|
||||||
*/
|
*/
|
||||||
public class TooltipContent extends GridPane {
|
public class CandleTooltip extends GridPane {
|
||||||
private final StringConverter<Number> priceStringConverter;
|
private final StringConverter<Number> priceStringConverter;
|
||||||
private final Label openValue = new Label();
|
private final Label openValue = new Label();
|
||||||
private final Label closeValue = new Label();
|
private final Label closeValue = new Label();
|
||||||
private final Label highValue = new Label();
|
private final Label highValue = new Label();
|
||||||
private final Label lowValue = new Label();
|
private final Label lowValue = new Label();
|
||||||
private final Label averageValue = new Label();
|
private final Label averageValue = new Label();
|
||||||
|
private final Label dateValue = new Label();
|
||||||
|
|
||||||
TooltipContent(StringConverter<Number> priceStringConverter) {
|
CandleTooltip(StringConverter<Number> priceStringConverter) {
|
||||||
this.priceStringConverter = priceStringConverter;
|
this.priceStringConverter = priceStringConverter;
|
||||||
|
|
||||||
setHgap(Layout.GRID_GAP);
|
setHgap(Layout.GRID_GAP);
|
||||||
|
|
||||||
setVgap(2);
|
setVgap(2);
|
||||||
|
|
||||||
Label open = new Label("Open:");
|
Label open = new Label("Open:");
|
||||||
|
@ -59,10 +64,7 @@ public class TooltipContent extends GridPane {
|
||||||
Label high = new Label("High:");
|
Label high = new Label("High:");
|
||||||
Label low = new Label("Low:");
|
Label low = new Label("Low:");
|
||||||
Label average = new Label("Average:");
|
Label average = new Label("Average:");
|
||||||
/* open.getStyleClass().add("candlestick-tooltip-label");
|
Label date = new Label("Date:");
|
||||||
close.getStyleClass().add("candlestick-tooltip-label");
|
|
||||||
high.getStyleClass().add("candlestick-tooltip-label");
|
|
||||||
low.getStyleClass().add("candlestick-tooltip-label");*/
|
|
||||||
setConstraints(open, 0, 0);
|
setConstraints(open, 0, 0);
|
||||||
setConstraints(openValue, 1, 0);
|
setConstraints(openValue, 1, 0);
|
||||||
setConstraints(close, 0, 1);
|
setConstraints(close, 0, 1);
|
||||||
|
@ -73,7 +75,17 @@ public class TooltipContent extends GridPane {
|
||||||
setConstraints(lowValue, 1, 3);
|
setConstraints(lowValue, 1, 3);
|
||||||
setConstraints(average, 0, 4);
|
setConstraints(average, 0, 4);
|
||||||
setConstraints(averageValue, 1, 4);
|
setConstraints(averageValue, 1, 4);
|
||||||
getChildren().addAll(open, openValue, close, closeValue, high, highValue, low, lowValue, average, averageValue);
|
setConstraints(date, 0, 5);
|
||||||
|
setConstraints(dateValue, 1, 5);
|
||||||
|
|
||||||
|
ColumnConstraints columnConstraints1 = new ColumnConstraints();
|
||||||
|
columnConstraints1.setHalignment(HPos.RIGHT);
|
||||||
|
columnConstraints1.setHgrow(Priority.NEVER);
|
||||||
|
ColumnConstraints columnConstraints2 = new ColumnConstraints();
|
||||||
|
columnConstraints2.setHgrow(Priority.ALWAYS);
|
||||||
|
getColumnConstraints().addAll(columnConstraints1, columnConstraints2);
|
||||||
|
|
||||||
|
getChildren().addAll(open, openValue, close, closeValue, high, highValue, low, lowValue, average, averageValue, date, dateValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update(CandleData candleData) {
|
public void update(CandleData candleData) {
|
||||||
|
@ -82,5 +94,6 @@ public class TooltipContent extends GridPane {
|
||||||
highValue.setText(priceStringConverter.toString(candleData.high));
|
highValue.setText(priceStringConverter.toString(candleData.high));
|
||||||
lowValue.setText(priceStringConverter.toString(candleData.low));
|
lowValue.setText(priceStringConverter.toString(candleData.low));
|
||||||
averageValue.setText(priceStringConverter.toString(candleData.average));
|
averageValue.setText(priceStringConverter.toString(candleData.average));
|
||||||
|
dateValue.setText(candleData.date);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -14,8 +14,9 @@
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package io.bitsquare.gui.main.markets.trades.charts.volume;
|
package io.bitsquare.gui.main.market.trades.charts.volume;
|
||||||
|
|
||||||
|
import io.bitsquare.gui.main.market.trades.charts.CandleData;
|
||||||
import javafx.scene.Group;
|
import javafx.scene.Group;
|
||||||
import javafx.scene.control.Tooltip;
|
import javafx.scene.control.Tooltip;
|
||||||
import javafx.scene.layout.Region;
|
import javafx.scene.layout.Region;
|
||||||
|
@ -51,9 +52,10 @@ public class VolumeBar extends Group {
|
||||||
updateStyleClasses();
|
updateStyleClasses();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update(double height, double candleWidth, double accumulatedAmount) {
|
public void update(double height, double candleWidth, CandleData candleData) {
|
||||||
bar.resizeRelocate(-candleWidth / 2, 0, candleWidth, height);
|
bar.resizeRelocate(-candleWidth / 2, 0, candleWidth, height);
|
||||||
tooltip.setText("Volume: " + volumeStringConverter.toString(accumulatedAmount));
|
tooltip.setText("Volume: " + volumeStringConverter.toString(candleData.accumulatedAmount) + "\n" +
|
||||||
|
"Date: " + candleData.date);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateStyleClasses() {
|
private void updateStyleClasses() {
|
|
@ -14,10 +14,10 @@
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package io.bitsquare.gui.main.markets.trades.charts.volume;
|
package io.bitsquare.gui.main.market.trades.charts.volume;
|
||||||
|
|
||||||
import io.bitsquare.gui.main.markets.trades.charts.CandleData;
|
import io.bitsquare.gui.main.market.trades.charts.CandleData;
|
||||||
import io.bitsquare.gui.main.markets.trades.charts.price.CandleStickChart;
|
import io.bitsquare.gui.main.market.trades.charts.price.CandleStickChart;
|
||||||
import javafx.animation.FadeTransition;
|
import javafx.animation.FadeTransition;
|
||||||
import javafx.event.ActionEvent;
|
import javafx.event.ActionEvent;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
|
@ -38,11 +38,8 @@ public class VolumeChart extends XYChart<Number, Number> {
|
||||||
|
|
||||||
private StringConverter<Number> toolTipStringConverter;
|
private StringConverter<Number> toolTipStringConverter;
|
||||||
|
|
||||||
public VolumeChart(Axis<Number> xAxis, Axis<Number> yAxis) {
|
public VolumeChart(Axis<Number> xAxis, Axis<Number> yAxis, StringConverter<Number> toolTipStringConverter) {
|
||||||
super(xAxis, yAxis);
|
super(xAxis, yAxis);
|
||||||
}
|
|
||||||
|
|
||||||
public final void setToolTipStringConverter(StringConverter<Number> toolTipStringConverter) {
|
|
||||||
this.toolTipStringConverter = toolTipStringConverter;
|
this.toolTipStringConverter = toolTipStringConverter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +70,7 @@ public class VolumeChart extends XYChart<Number, Number> {
|
||||||
// Did not find a way how to request the chart data height
|
// Did not find a way how to request the chart data height
|
||||||
final double height = getHeight() - 43;
|
final double height = getHeight() - 43;
|
||||||
double upperYPos = Math.min(height - 5, y); // We want min 5px height to allow tooltips
|
double upperYPos = Math.min(height - 5, y); // We want min 5px height to allow tooltips
|
||||||
volumeBar.update(height - upperYPos, candleWidth, candleData.accumulatedAmount);
|
volumeBar.update(height - upperYPos, candleWidth, candleData);
|
||||||
volumeBar.setLayoutX(x);
|
volumeBar.setLayoutX(x);
|
||||||
volumeBar.setLayoutY(upperYPos);
|
volumeBar.setLayoutY(upperYPos);
|
||||||
}
|
}
|
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
<?import javafx.geometry.Insets?>
|
<?import javafx.geometry.Insets?>
|
||||||
<?import javafx.scene.layout.*?>
|
<?import javafx.scene.layout.*?>
|
||||||
<VBox fx:id="root" fx:controller="io.bitsquare.gui.main.markets.charts.MarketsChartsView"
|
<VBox fx:id="root" fx:controller="io.bitsquare.gui.main.markets.offerbook.OfferBookChartView"
|
||||||
spacing="20.0" fillWidth="true"
|
spacing="20.0" fillWidth="true"
|
||||||
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0"
|
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0"
|
||||||
AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"
|
AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"
|
|
@ -333,7 +333,7 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
|
||||||
"When another trader wants to take your offer it requires that your application is online and able to react.\n" +
|
"When another trader wants to take your offer it requires that your application is online and able to react.\n" +
|
||||||
"Be sure that you have standby mode deactivated as that would disconnect your client from the network (standby of the monitor is not a problem).")
|
"Be sure that you have standby mode deactivated as that would disconnect your client from the network (standby of the monitor is not a problem).")
|
||||||
.actionButtonText("Visit FAQ web page")
|
.actionButtonText("Visit FAQ web page")
|
||||||
.onAction(() -> Utilities.openWebPage("https://bitsquare.io/faq#6"))
|
.onAction(() -> GUIUtil.openWebPage("https://bitsquare.io/faq#6"))
|
||||||
.closeButtonText("I understand")
|
.closeButtonText("I understand")
|
||||||
.dontShowAgainId(key, preferences)
|
.dontShowAgainId(key, preferences)
|
||||||
.show();
|
.show();
|
||||||
|
|
|
@ -22,7 +22,6 @@ import io.bitsquare.btc.pricefeed.MarketPrice;
|
||||||
import io.bitsquare.btc.pricefeed.PriceFeedService;
|
import io.bitsquare.btc.pricefeed.PriceFeedService;
|
||||||
import io.bitsquare.common.Timer;
|
import io.bitsquare.common.Timer;
|
||||||
import io.bitsquare.common.UserThread;
|
import io.bitsquare.common.UserThread;
|
||||||
import io.bitsquare.common.util.Utilities;
|
|
||||||
import io.bitsquare.gui.Navigation;
|
import io.bitsquare.gui.Navigation;
|
||||||
import io.bitsquare.gui.common.model.ActivatableWithDataModel;
|
import io.bitsquare.gui.common.model.ActivatableWithDataModel;
|
||||||
import io.bitsquare.gui.common.model.ViewModel;
|
import io.bitsquare.gui.common.model.ViewModel;
|
||||||
|
@ -33,6 +32,7 @@ import io.bitsquare.gui.main.overlays.popups.Popup;
|
||||||
import io.bitsquare.gui.main.settings.SettingsView;
|
import io.bitsquare.gui.main.settings.SettingsView;
|
||||||
import io.bitsquare.gui.main.settings.preferences.PreferencesView;
|
import io.bitsquare.gui.main.settings.preferences.PreferencesView;
|
||||||
import io.bitsquare.gui.util.BSFormatter;
|
import io.bitsquare.gui.util.BSFormatter;
|
||||||
|
import io.bitsquare.gui.util.GUIUtil;
|
||||||
import io.bitsquare.gui.util.validation.BtcValidator;
|
import io.bitsquare.gui.util.validation.BtcValidator;
|
||||||
import io.bitsquare.gui.util.validation.FiatValidator;
|
import io.bitsquare.gui.util.validation.FiatValidator;
|
||||||
import io.bitsquare.gui.util.validation.InputValidator;
|
import io.bitsquare.gui.util.validation.InputValidator;
|
||||||
|
@ -355,7 +355,7 @@ class CreateOfferViewModel extends ActivatableWithDataModel<CreateOfferDataModel
|
||||||
"Be sure you fully understand the situation and check out the information on the \"Ethereum Classic\" and \"Ethereum\" project web pages.\n\n" +
|
"Be sure you fully understand the situation and check out the information on the \"Ethereum Classic\" and \"Ethereum\" project web pages.\n\n" +
|
||||||
"Please note, that the price is denominated as ETC/BTC not BTC/ETC!")
|
"Please note, that the price is denominated as ETC/BTC not BTC/ETC!")
|
||||||
.closeButtonText("I understand")
|
.closeButtonText("I understand")
|
||||||
.onAction(() -> Utilities.openWebPage("https://ethereumclassic.github.io/"))
|
.onAction(() -> GUIUtil.openWebPage("https://ethereumclassic.github.io/"))
|
||||||
.actionButtonText("Open Ethereum Classic web page")
|
.actionButtonText("Open Ethereum Classic web page")
|
||||||
.dontShowAgainId(key, preferences)
|
.dontShowAgainId(key, preferences)
|
||||||
.show();
|
.show();
|
||||||
|
|
|
@ -35,9 +35,9 @@ import io.bitsquare.gui.main.offer.OfferView;
|
||||||
import io.bitsquare.gui.main.overlays.popups.Popup;
|
import io.bitsquare.gui.main.overlays.popups.Popup;
|
||||||
import io.bitsquare.gui.main.overlays.windows.OfferDetailsWindow;
|
import io.bitsquare.gui.main.overlays.windows.OfferDetailsWindow;
|
||||||
import io.bitsquare.gui.util.BSFormatter;
|
import io.bitsquare.gui.util.BSFormatter;
|
||||||
|
import io.bitsquare.gui.util.GUIUtil;
|
||||||
import io.bitsquare.gui.util.Layout;
|
import io.bitsquare.gui.util.Layout;
|
||||||
import io.bitsquare.locale.BSResources;
|
import io.bitsquare.locale.BSResources;
|
||||||
import io.bitsquare.locale.CryptoCurrency;
|
|
||||||
import io.bitsquare.locale.FiatCurrency;
|
import io.bitsquare.locale.FiatCurrency;
|
||||||
import io.bitsquare.locale.TradeCurrency;
|
import io.bitsquare.locale.TradeCurrency;
|
||||||
import io.bitsquare.payment.PaymentMethod;
|
import io.bitsquare.payment.PaymentMethod;
|
||||||
|
@ -107,28 +107,7 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi
|
||||||
|
|
||||||
currencyComboBox = addLabelComboBox(root, gridRow, "Filter by currency:", Layout.FIRST_ROW_DISTANCE).second;
|
currencyComboBox = addLabelComboBox(root, gridRow, "Filter by currency:", Layout.FIRST_ROW_DISTANCE).second;
|
||||||
currencyComboBox.setPromptText("Select currency");
|
currencyComboBox.setPromptText("Select currency");
|
||||||
currencyComboBox.setConverter(new StringConverter<TradeCurrency>() {
|
currencyComboBox.setConverter(GUIUtil.getCurrencyListConverter());
|
||||||
@Override
|
|
||||||
public String toString(TradeCurrency tradeCurrency) {
|
|
||||||
String code = tradeCurrency.getCode();
|
|
||||||
// http://boschista.deviantart.com/journal/Cool-ASCII-Symbols-214218618
|
|
||||||
if (code.equals(OfferBookViewModel.SHOW_ALL_FLAG))
|
|
||||||
return "▶ Show all";
|
|
||||||
else if (code.equals(OfferBookViewModel.EDIT_FLAG))
|
|
||||||
return "▼ Edit currency list";
|
|
||||||
else if (tradeCurrency instanceof FiatCurrency)
|
|
||||||
return "★ " + tradeCurrency.getNameAndCode();
|
|
||||||
else if (tradeCurrency instanceof CryptoCurrency)
|
|
||||||
return "✦ " + tradeCurrency.getNameAndCode();
|
|
||||||
else
|
|
||||||
return "-";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TradeCurrency fromString(String s) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
paymentMethodComboBox = addLabelComboBox(root, ++gridRow, "Filter by payment method:").second;
|
paymentMethodComboBox = addLabelComboBox(root, ++gridRow, "Filter by payment method:").second;
|
||||||
paymentMethodComboBox.setPromptText("Select payment method");
|
paymentMethodComboBox.setPromptText("Select payment method");
|
||||||
|
@ -136,7 +115,7 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi
|
||||||
@Override
|
@Override
|
||||||
public String toString(PaymentMethod paymentMethod) {
|
public String toString(PaymentMethod paymentMethod) {
|
||||||
String id = paymentMethod.getId();
|
String id = paymentMethod.getId();
|
||||||
if (id.equals(OfferBookViewModel.SHOW_ALL_FLAG))
|
if (id.equals(GUIUtil.SHOW_ALL_FLAG))
|
||||||
return "▶ Show all";
|
return "▶ Show all";
|
||||||
else if (paymentMethod.equals(PaymentMethod.BLOCK_CHAINS))
|
else if (paymentMethod.equals(PaymentMethod.BLOCK_CHAINS))
|
||||||
return "✦ " + BSResources.get(id);
|
return "✦ " + BSResources.get(id);
|
||||||
|
|
|
@ -30,6 +30,7 @@ import io.bitsquare.gui.main.MainView;
|
||||||
import io.bitsquare.gui.main.settings.SettingsView;
|
import io.bitsquare.gui.main.settings.SettingsView;
|
||||||
import io.bitsquare.gui.main.settings.preferences.PreferencesView;
|
import io.bitsquare.gui.main.settings.preferences.PreferencesView;
|
||||||
import io.bitsquare.gui.util.BSFormatter;
|
import io.bitsquare.gui.util.BSFormatter;
|
||||||
|
import io.bitsquare.gui.util.GUIUtil;
|
||||||
import io.bitsquare.locale.*;
|
import io.bitsquare.locale.*;
|
||||||
import io.bitsquare.p2p.NodeAddress;
|
import io.bitsquare.p2p.NodeAddress;
|
||||||
import io.bitsquare.p2p.P2PService;
|
import io.bitsquare.p2p.P2PService;
|
||||||
|
@ -60,9 +61,6 @@ import java.util.stream.Collectors;
|
||||||
class OfferBookViewModel extends ActivatableViewModel {
|
class OfferBookViewModel extends ActivatableViewModel {
|
||||||
protected final static Logger log = LoggerFactory.getLogger(OfferBookViewModel.class);
|
protected final static Logger log = LoggerFactory.getLogger(OfferBookViewModel.class);
|
||||||
|
|
||||||
final static String SHOW_ALL_FLAG = "SHOW_ALL_FLAG";
|
|
||||||
final static String EDIT_FLAG = "EDIT_FLAG";
|
|
||||||
|
|
||||||
private final OpenOfferManager openOfferManager;
|
private final OpenOfferManager openOfferManager;
|
||||||
private final User user;
|
private final User user;
|
||||||
private final OfferBook offerBook;
|
private final OfferBook offerBook;
|
||||||
|
@ -87,8 +85,7 @@ class OfferBookViewModel extends ActivatableViewModel {
|
||||||
|
|
||||||
// If id is empty string we ignore filter (display all methods)
|
// If id is empty string we ignore filter (display all methods)
|
||||||
|
|
||||||
PaymentMethod selectedPaymentMethod = new PaymentMethod(SHOW_ALL_FLAG, 0, 0, null);
|
PaymentMethod selectedPaymentMethod = new PaymentMethod(GUIUtil.SHOW_ALL_FLAG, 0, 0, null);
|
||||||
private CryptoCurrency showAllCurrenciesItem = new CryptoCurrency(SHOW_ALL_FLAG, SHOW_ALL_FLAG);
|
|
||||||
|
|
||||||
private final ObservableList<OfferBookListItem> offerBookListItems;
|
private final ObservableList<OfferBookListItem> offerBookListItems;
|
||||||
private boolean isTabSelected;
|
private boolean isTabSelected;
|
||||||
|
@ -146,9 +143,9 @@ class OfferBookViewModel extends ActivatableViewModel {
|
||||||
private void fillAllTradeCurrencies() {
|
private void fillAllTradeCurrencies() {
|
||||||
allTradeCurrencies.clear();
|
allTradeCurrencies.clear();
|
||||||
// Used for ignoring filter (show all)
|
// Used for ignoring filter (show all)
|
||||||
allTradeCurrencies.add(showAllCurrenciesItem);
|
allTradeCurrencies.add(new CryptoCurrency(GUIUtil.SHOW_ALL_FLAG, GUIUtil.SHOW_ALL_FLAG));
|
||||||
allTradeCurrencies.addAll(preferences.getTradeCurrenciesAsObservable());
|
allTradeCurrencies.addAll(preferences.getTradeCurrenciesAsObservable());
|
||||||
allTradeCurrencies.add(new CryptoCurrency(EDIT_FLAG, EDIT_FLAG));
|
allTradeCurrencies.add(new CryptoCurrency(GUIUtil.EDIT_FLAG, GUIUtil.EDIT_FLAG));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setMarketPriceFeedCurrency() {
|
private void setMarketPriceFeedCurrency() {
|
||||||
|
@ -254,7 +251,7 @@ class OfferBookViewModel extends ActivatableViewModel {
|
||||||
|
|
||||||
public ObservableList<PaymentMethod> getPaymentMethods() {
|
public ObservableList<PaymentMethod> getPaymentMethods() {
|
||||||
ObservableList<PaymentMethod> list = FXCollections.observableArrayList(PaymentMethod.ALL_VALUES);
|
ObservableList<PaymentMethod> list = FXCollections.observableArrayList(PaymentMethod.ALL_VALUES);
|
||||||
list.add(0, new PaymentMethod(SHOW_ALL_FLAG, 0, 0, null));
|
list.add(0, new PaymentMethod(GUIUtil.SHOW_ALL_FLAG, 0, 0, null));
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -418,11 +415,11 @@ class OfferBookViewModel extends ActivatableViewModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isShowAllEntry(String id) {
|
private boolean isShowAllEntry(String id) {
|
||||||
return id.equals(SHOW_ALL_FLAG);
|
return id.equals(GUIUtil.SHOW_ALL_FLAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isEditEntry(String id) {
|
private boolean isEditEntry(String id) {
|
||||||
return id.equals(EDIT_FLAG);
|
return id.equals(GUIUtil.EDIT_FLAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
int getNumPastTrades(Offer offer) {
|
int getNumPastTrades(Offer offer) {
|
||||||
|
|
|
@ -334,7 +334,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
||||||
"The deposit will stay in your local trading wallet until the offer gets accepted by another trader.\n" +
|
"The deposit will stay in your local trading wallet until the offer gets accepted by another trader.\n" +
|
||||||
"It will be refunded to you after the trade has successfully completed.")
|
"It will be refunded to you after the trade has successfully completed.")
|
||||||
.actionButtonText("Visit FAQ web page")
|
.actionButtonText("Visit FAQ web page")
|
||||||
.onAction(() -> Utilities.openWebPage("https://bitsquare.io/faq#6"))
|
.onAction(() -> GUIUtil.openWebPage("https://bitsquare.io/faq#6"))
|
||||||
.closeButtonText("I understand")
|
.closeButtonText("I understand")
|
||||||
.dontShowAgainId(key, preferences)
|
.dontShowAgainId(key, preferences)
|
||||||
.show();
|
.show();
|
||||||
|
|
|
@ -19,7 +19,6 @@ package io.bitsquare.gui.main.offer.takeoffer;
|
||||||
|
|
||||||
import io.bitsquare.arbitration.Arbitrator;
|
import io.bitsquare.arbitration.Arbitrator;
|
||||||
import io.bitsquare.btc.pricefeed.PriceFeedService;
|
import io.bitsquare.btc.pricefeed.PriceFeedService;
|
||||||
import io.bitsquare.common.util.Utilities;
|
|
||||||
import io.bitsquare.gui.Navigation;
|
import io.bitsquare.gui.Navigation;
|
||||||
import io.bitsquare.gui.common.model.ActivatableWithDataModel;
|
import io.bitsquare.gui.common.model.ActivatableWithDataModel;
|
||||||
import io.bitsquare.gui.common.model.ViewModel;
|
import io.bitsquare.gui.common.model.ViewModel;
|
||||||
|
@ -28,6 +27,7 @@ import io.bitsquare.gui.main.funds.FundsView;
|
||||||
import io.bitsquare.gui.main.funds.deposit.DepositView;
|
import io.bitsquare.gui.main.funds.deposit.DepositView;
|
||||||
import io.bitsquare.gui.main.overlays.popups.Popup;
|
import io.bitsquare.gui.main.overlays.popups.Popup;
|
||||||
import io.bitsquare.gui.util.BSFormatter;
|
import io.bitsquare.gui.util.BSFormatter;
|
||||||
|
import io.bitsquare.gui.util.GUIUtil;
|
||||||
import io.bitsquare.gui.util.validation.BtcValidator;
|
import io.bitsquare.gui.util.validation.BtcValidator;
|
||||||
import io.bitsquare.gui.util.validation.InputValidator;
|
import io.bitsquare.gui.util.validation.InputValidator;
|
||||||
import io.bitsquare.locale.BSResources;
|
import io.bitsquare.locale.BSResources;
|
||||||
|
@ -148,7 +148,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
|
||||||
"Be sure you fully understand the situation and check out the information on the \"Ethereum Classic\" and \"Ethereum\" project web pages.\n\n" +
|
"Be sure you fully understand the situation and check out the information on the \"Ethereum Classic\" and \"Ethereum\" project web pages.\n\n" +
|
||||||
"Please note, that the price is denominated as ETC/BTC not BTC/ETC!")
|
"Please note, that the price is denominated as ETC/BTC not BTC/ETC!")
|
||||||
.closeButtonText("I understand")
|
.closeButtonText("I understand")
|
||||||
.onAction(() -> Utilities.openWebPage("https://ethereumclassic.github.io/"))
|
.onAction(() -> GUIUtil.openWebPage("https://ethereumclassic.github.io/"))
|
||||||
.actionButtonText("Open Ethereum Classic web page")
|
.actionButtonText("Open Ethereum Classic web page")
|
||||||
.dontShowAgainId(key, dataModel.getPreferences())
|
.dontShowAgainId(key, dataModel.getPreferences())
|
||||||
.show();
|
.show();
|
||||||
|
|
|
@ -22,6 +22,7 @@ import io.bitsquare.common.UserThread;
|
||||||
import io.bitsquare.common.util.Utilities;
|
import io.bitsquare.common.util.Utilities;
|
||||||
import io.bitsquare.gui.components.BusyAnimation;
|
import io.bitsquare.gui.components.BusyAnimation;
|
||||||
import io.bitsquare.gui.main.MainView;
|
import io.bitsquare.gui.main.MainView;
|
||||||
|
import io.bitsquare.gui.util.GUIUtil;
|
||||||
import io.bitsquare.gui.util.Transitions;
|
import io.bitsquare.gui.util.Transitions;
|
||||||
import io.bitsquare.locale.BSResources;
|
import io.bitsquare.locale.BSResources;
|
||||||
import io.bitsquare.user.Preferences;
|
import io.bitsquare.user.Preferences;
|
||||||
|
@ -680,7 +681,7 @@ public abstract class Overlay<T extends Overlay> {
|
||||||
|
|
||||||
githubButton.setOnAction(event -> {
|
githubButton.setOnAction(event -> {
|
||||||
Utilities.copyToClipboard(message);
|
Utilities.copyToClipboard(message);
|
||||||
Utilities.openWebPage("https://github.com/bitsquare/bitsquare/issues");
|
GUIUtil.openWebPage("https://github.com/bitsquare/bitsquare/issues");
|
||||||
});
|
});
|
||||||
|
|
||||||
Button mailButton = new Button("Report by email");
|
Button mailButton = new Button("Report by email");
|
||||||
|
@ -690,7 +691,7 @@ public abstract class Overlay<T extends Overlay> {
|
||||||
gridPane.getChildren().add(mailButton);
|
gridPane.getChildren().add(mailButton);
|
||||||
mailButton.setOnAction(event -> {
|
mailButton.setOnAction(event -> {
|
||||||
Utilities.copyToClipboard(message);
|
Utilities.copyToClipboard(message);
|
||||||
Utilities.openMail("manfred@bitsquare.io",
|
GUIUtil.openMail("manfred@bitsquare.io",
|
||||||
"Error report",
|
"Error report",
|
||||||
"Error message:\n" + message);
|
"Error message:\n" + message);
|
||||||
});
|
});
|
||||||
|
|
|
@ -19,8 +19,8 @@ package io.bitsquare.gui.main.overlays.windows;
|
||||||
|
|
||||||
import io.bitsquare.alert.Alert;
|
import io.bitsquare.alert.Alert;
|
||||||
import io.bitsquare.common.util.Tuple2;
|
import io.bitsquare.common.util.Tuple2;
|
||||||
import io.bitsquare.common.util.Utilities;
|
|
||||||
import io.bitsquare.gui.main.overlays.Overlay;
|
import io.bitsquare.gui.main.overlays.Overlay;
|
||||||
|
import io.bitsquare.gui.util.GUIUtil;
|
||||||
import io.bitsquare.user.Preferences;
|
import io.bitsquare.user.Preferences;
|
||||||
import javafx.geometry.HPos;
|
import javafx.geometry.HPos;
|
||||||
import javafx.geometry.Insets;
|
import javafx.geometry.Insets;
|
||||||
|
@ -90,7 +90,7 @@ public class AddBridgeEntriesWindow extends Overlay<AddBridgeEntriesWindow> {
|
||||||
actionButton.setOnAction(event -> save());
|
actionButton.setOnAction(event -> save());
|
||||||
|
|
||||||
Button urlButton = new Button("Open Tor project web page");
|
Button urlButton = new Button("Open Tor project web page");
|
||||||
urlButton.setOnAction(event -> Utilities.openWebPage("https://bridges.torproject.org/bridges"));
|
urlButton.setOnAction(event -> GUIUtil.openWebPage("https://bridges.torproject.org/bridges"));
|
||||||
|
|
||||||
Pane spacer = new Pane();
|
Pane spacer = new Pane();
|
||||||
HBox hBox = new HBox();
|
HBox hBox = new HBox();
|
||||||
|
|
|
@ -199,18 +199,23 @@ public class OfferDetailsWindow extends Overlay<OfferDetailsWindow> {
|
||||||
final PaymentMethod paymentMethod = offer.getPaymentMethod();
|
final PaymentMethod paymentMethod = offer.getPaymentMethod();
|
||||||
final String offererPaymentAccountId = offer.getOffererPaymentAccountId();
|
final String offererPaymentAccountId = offer.getOffererPaymentAccountId();
|
||||||
final PaymentAccount paymentAccount = user.getPaymentAccount(offererPaymentAccountId);
|
final PaymentAccount paymentAccount = user.getPaymentAccount(offererPaymentAccountId);
|
||||||
final String bankId = offer.getBankId();
|
String bankId = offer.getBankId();
|
||||||
|
if (bankId == null || bankId.equals("null"))
|
||||||
|
bankId = "";
|
||||||
|
else
|
||||||
|
bankId = " (" + bankId + ")";
|
||||||
final boolean isSpecificBanks = paymentMethod.equals(PaymentMethod.SPECIFIC_BANKS);
|
final boolean isSpecificBanks = paymentMethod.equals(PaymentMethod.SPECIFIC_BANKS);
|
||||||
final boolean isNationalBanks = paymentMethod.equals(PaymentMethod.NATIONAL_BANK);
|
final boolean isNationalBanks = paymentMethod.equals(PaymentMethod.NATIONAL_BANK);
|
||||||
|
final boolean isSepa = paymentMethod.equals(PaymentMethod.SEPA);
|
||||||
if (offer.isMyOffer(keyRing) && offererPaymentAccountId != null && paymentAccount != null) {
|
if (offer.isMyOffer(keyRing) && offererPaymentAccountId != null && paymentAccount != null) {
|
||||||
addLabelTextField(gridPane, ++rowIndex, "Payment account:", paymentAccount.getAccountName());
|
addLabelTextField(gridPane, ++rowIndex, "Payment account:", paymentAccount.getAccountName());
|
||||||
} else {
|
} else {
|
||||||
final String method = BSResources.get(paymentMethod.getId());
|
final String method = BSResources.get(paymentMethod.getId());
|
||||||
if (isNationalBanks || isSpecificBanks) {
|
if (isNationalBanks || isSpecificBanks || isSepa) {
|
||||||
if (BankUtil.isBankIdRequired(offer.getCountryCode()))
|
if (BankUtil.isBankIdRequired(offer.getCountryCode()))
|
||||||
addLabelTextField(gridPane, ++rowIndex, "Payment method (offerers bank ID):", method + " (" + bankId + ")");
|
addLabelTextField(gridPane, ++rowIndex, "Payment method (offerers bank ID):", method + bankId);
|
||||||
else if (BankUtil.isBankNameRequired(offer.getCountryCode()))
|
else if (BankUtil.isBankNameRequired(offer.getCountryCode()))
|
||||||
addLabelTextField(gridPane, ++rowIndex, "Payment method (offerers bank name):", method + " (" + bankId + ")");
|
addLabelTextField(gridPane, ++rowIndex, "Payment method (offerers bank name):", method + bankId);
|
||||||
} else {
|
} else {
|
||||||
addLabelTextField(gridPane, ++rowIndex, "Payment method:", method);
|
addLabelTextField(gridPane, ++rowIndex, "Payment method:", method);
|
||||||
}
|
}
|
||||||
|
|
|
@ -372,7 +372,6 @@ public class WalletPasswordWindow extends Overlay<WalletPasswordWindow> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doRestore() {
|
private void doRestore() {
|
||||||
log.info("Attempting wallet restore using seed '{}' from date {}", restoreSeedWordsTextArea.getText(), restoreDatePicker.getValue());
|
|
||||||
long date = restoreDatePicker.getValue().atStartOfDay().toEpochSecond(ZoneOffset.UTC);
|
long date = restoreDatePicker.getValue().atStartOfDay().toEpochSecond(ZoneOffset.UTC);
|
||||||
DeterministicSeed seed = new DeterministicSeed(Splitter.on(" ").splitToList(restoreSeedWordsTextArea.getText()), null, "", date);
|
DeterministicSeed seed = new DeterministicSeed(Splitter.on(" ").splitToList(restoreSeedWordsTextArea.getText()), null, "", date);
|
||||||
walletService.restoreSeedWords(seed,
|
walletService.restoreSeedWords(seed,
|
||||||
|
|
|
@ -92,14 +92,15 @@ public class ClosedTradesView extends ActivatableViewAndModel<VBox, ClosedTrades
|
||||||
dateColumn.setComparator((o1, o2) -> o1.getTradable().getDate().compareTo(o2.getTradable().getDate()));
|
dateColumn.setComparator((o1, o2) -> o1.getTradable().getDate().compareTo(o2.getTradable().getDate()));
|
||||||
directionColumn.setComparator((o1, o2) -> o1.getTradable().getOffer().getDirection().compareTo(o2.getTradable().getOffer().getDirection()));
|
directionColumn.setComparator((o1, o2) -> o1.getTradable().getOffer().getDirection().compareTo(o2.getTradable().getOffer().getDirection()));
|
||||||
priceColumn.setComparator((o1, o2) -> {
|
priceColumn.setComparator((o1, o2) -> {
|
||||||
Tradable tradable = o1.getTradable();
|
final Tradable tradable1 = o1.getTradable();
|
||||||
if (tradable instanceof Trade)
|
final Tradable tradable2 = o2.getTradable();
|
||||||
return ((Trade) o1.getTradable()).getTradePrice().compareTo(((Trade) o2.getTradable()).getTradePrice());
|
Fiat price1 = null;
|
||||||
else {
|
Fiat price2 = null;
|
||||||
Fiat price1 = o1.getTradable().getOffer().getPrice();
|
if (tradable1 != null)
|
||||||
Fiat price2 = o2.getTradable().getOffer().getPrice();
|
price1 = tradable1 instanceof Trade ? ((Trade) tradable1).getTradePrice() : tradable1.getOffer().getPrice();
|
||||||
|
if (tradable2 != null)
|
||||||
|
price2 = tradable2 instanceof Trade ? ((Trade) tradable2).getTradePrice() : tradable2.getOffer().getPrice();
|
||||||
return price1 != null && price2 != null ? price1.compareTo(price2) : 0;
|
return price1 != null && price2 != null ? price1.compareTo(price2) : 0;
|
||||||
}
|
|
||||||
});
|
});
|
||||||
volumeColumn.setComparator((o1, o2) -> {
|
volumeColumn.setComparator((o1, o2) -> {
|
||||||
if (o1.getTradable() instanceof Trade && o2.getTradable() instanceof Trade) {
|
if (o1.getTradable() instanceof Trade && o2.getTradable() instanceof Trade) {
|
||||||
|
|
|
@ -304,7 +304,7 @@ public class PendingTradesDataModel extends ActivatableDataModel {
|
||||||
if (depositTx != null) {
|
if (depositTx != null) {
|
||||||
doOpenDispute(isSupportTicket, getTrade().getDepositTx());
|
doOpenDispute(isSupportTicket, getTrade().getDepositTx());
|
||||||
} else {
|
} else {
|
||||||
log.warn("Trade.depositTx is null. We try to find the tx in our wallet.");
|
log.info("Trade.depositTx is null. We try to find the tx in our wallet.");
|
||||||
List<Transaction> candidates = new ArrayList<>();
|
List<Transaction> candidates = new ArrayList<>();
|
||||||
List<Transaction> transactions = walletService.getWallet().getRecentTransactions(100, true);
|
List<Transaction> transactions = walletService.getWallet().getRecentTransactions(100, true);
|
||||||
transactions.stream().forEach(transaction -> {
|
transactions.stream().forEach(transaction -> {
|
||||||
|
|
|
@ -21,7 +21,6 @@ import de.jensd.fx.fontawesome.AwesomeIcon;
|
||||||
import io.bitsquare.common.util.Tuple2;
|
import io.bitsquare.common.util.Tuple2;
|
||||||
import io.bitsquare.common.util.Tuple3;
|
import io.bitsquare.common.util.Tuple3;
|
||||||
import io.bitsquare.common.util.Tuple4;
|
import io.bitsquare.common.util.Tuple4;
|
||||||
import io.bitsquare.common.util.Utilities;
|
|
||||||
import io.bitsquare.gui.components.*;
|
import io.bitsquare.gui.components.*;
|
||||||
import javafx.geometry.HPos;
|
import javafx.geometry.HPos;
|
||||||
import javafx.geometry.Insets;
|
import javafx.geometry.Insets;
|
||||||
|
@ -170,7 +169,7 @@ public class FormBuilder {
|
||||||
|
|
||||||
public static HyperlinkWithIcon addHyperlinkWithIcon(GridPane gridPane, int rowIndex, String title, String url, double top) {
|
public static HyperlinkWithIcon addHyperlinkWithIcon(GridPane gridPane, int rowIndex, String title, String url, double top) {
|
||||||
HyperlinkWithIcon hyperlinkWithIcon = new HyperlinkWithIcon(title, AwesomeIcon.EXTERNAL_LINK);
|
HyperlinkWithIcon hyperlinkWithIcon = new HyperlinkWithIcon(title, AwesomeIcon.EXTERNAL_LINK);
|
||||||
hyperlinkWithIcon.setOnAction(e -> Utilities.openWebPage(url));
|
hyperlinkWithIcon.setOnAction(e -> GUIUtil.openWebPage(url));
|
||||||
GridPane.setRowIndex(hyperlinkWithIcon, rowIndex);
|
GridPane.setRowIndex(hyperlinkWithIcon, rowIndex);
|
||||||
GridPane.setColumnIndex(hyperlinkWithIcon, 0);
|
GridPane.setColumnIndex(hyperlinkWithIcon, 0);
|
||||||
GridPane.setMargin(hyperlinkWithIcon, new Insets(top, 0, 0, -4));
|
GridPane.setMargin(hyperlinkWithIcon, new Insets(top, 0, 0, -4));
|
||||||
|
@ -191,7 +190,7 @@ public class FormBuilder {
|
||||||
Label label = addLabel(gridPane, rowIndex, labelTitle, top);
|
Label label = addLabel(gridPane, rowIndex, labelTitle, top);
|
||||||
|
|
||||||
HyperlinkWithIcon hyperlinkWithIcon = new HyperlinkWithIcon(title, AwesomeIcon.EXTERNAL_LINK);
|
HyperlinkWithIcon hyperlinkWithIcon = new HyperlinkWithIcon(title, AwesomeIcon.EXTERNAL_LINK);
|
||||||
hyperlinkWithIcon.setOnAction(e -> Utilities.openWebPage(url));
|
hyperlinkWithIcon.setOnAction(e -> GUIUtil.openWebPage(url));
|
||||||
GridPane.setRowIndex(hyperlinkWithIcon, rowIndex);
|
GridPane.setRowIndex(hyperlinkWithIcon, rowIndex);
|
||||||
GridPane.setColumnIndex(hyperlinkWithIcon, 1);
|
GridPane.setColumnIndex(hyperlinkWithIcon, 1);
|
||||||
GridPane.setMargin(hyperlinkWithIcon, new Insets(top, 0, 0, -4));
|
GridPane.setMargin(hyperlinkWithIcon, new Insets(top, 0, 0, -4));
|
||||||
|
|
|
@ -23,7 +23,11 @@ import com.googlecode.jcsv.writer.CSVEntryConverter;
|
||||||
import com.googlecode.jcsv.writer.CSVWriter;
|
import com.googlecode.jcsv.writer.CSVWriter;
|
||||||
import com.googlecode.jcsv.writer.internal.CSVWriterBuilder;
|
import com.googlecode.jcsv.writer.internal.CSVWriterBuilder;
|
||||||
import io.bitsquare.app.DevFlags;
|
import io.bitsquare.app.DevFlags;
|
||||||
|
import io.bitsquare.common.util.Utilities;
|
||||||
import io.bitsquare.gui.main.overlays.popups.Popup;
|
import io.bitsquare.gui.main.overlays.popups.Popup;
|
||||||
|
import io.bitsquare.locale.CryptoCurrency;
|
||||||
|
import io.bitsquare.locale.FiatCurrency;
|
||||||
|
import io.bitsquare.locale.TradeCurrency;
|
||||||
import io.bitsquare.payment.PaymentAccount;
|
import io.bitsquare.payment.PaymentAccount;
|
||||||
import io.bitsquare.storage.Storage;
|
import io.bitsquare.storage.Storage;
|
||||||
import io.bitsquare.user.Preferences;
|
import io.bitsquare.user.Preferences;
|
||||||
|
@ -34,6 +38,7 @@ import javafx.scene.control.ScrollBar;
|
||||||
import javafx.stage.DirectoryChooser;
|
import javafx.stage.DirectoryChooser;
|
||||||
import javafx.stage.FileChooser;
|
import javafx.stage.FileChooser;
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
|
import javafx.util.StringConverter;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -41,6 +46,9 @@ import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStreamWriter;
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.net.URLEncoder;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -48,6 +56,9 @@ import java.util.List;
|
||||||
public class GUIUtil {
|
public class GUIUtil {
|
||||||
private static final Logger log = LoggerFactory.getLogger(GUIUtil.class);
|
private static final Logger log = LoggerFactory.getLogger(GUIUtil.class);
|
||||||
|
|
||||||
|
public final static String SHOW_ALL_FLAG = "SHOW_ALL_FLAG";
|
||||||
|
public final static String EDIT_FLAG = "EDIT_FLAG";
|
||||||
|
|
||||||
public static double getScrollbarWidth(Node scrollablePane) {
|
public static double getScrollbarWidth(Node scrollablePane) {
|
||||||
Node node = scrollablePane.lookup(".scroll-bar");
|
Node node = scrollablePane.lookup(".scroll-bar");
|
||||||
if (node instanceof ScrollBar) {
|
if (node instanceof ScrollBar) {
|
||||||
|
@ -81,7 +92,7 @@ public class GUIUtil {
|
||||||
String directory = getDirectoryFormChooser(preferences, stage);
|
String directory = getDirectoryFormChooser(preferences, stage);
|
||||||
Storage<ArrayList<PaymentAccount>> paymentAccountsStorage = new Storage<>(new File(directory));
|
Storage<ArrayList<PaymentAccount>> paymentAccountsStorage = new Storage<>(new File(directory));
|
||||||
paymentAccountsStorage.initAndGetPersisted(accounts, fileName);
|
paymentAccountsStorage.initAndGetPersisted(accounts, fileName);
|
||||||
paymentAccountsStorage.queueUpForSave(20);
|
paymentAccountsStorage.queueUpForSave();
|
||||||
new Popup<>().feedback("Payment accounts saved to path:\n" + Paths.get(directory, fileName).toAbsolutePath()).show();
|
new Popup<>().feedback("Payment accounts saved to path:\n" + Paths.get(directory, fileName).toAbsolutePath()).show();
|
||||||
} else {
|
} else {
|
||||||
new Popup<>().warning("You don't have payment accounts set up for exporting.").show();
|
new Popup<>().warning("You don't have payment accounts set up for exporting.").show();
|
||||||
|
@ -163,4 +174,73 @@ public class GUIUtil {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static StringConverter<TradeCurrency> getCurrencyListConverter() {
|
||||||
|
return new StringConverter<TradeCurrency>() {
|
||||||
|
@Override
|
||||||
|
public String toString(TradeCurrency tradeCurrency) {
|
||||||
|
String code = tradeCurrency.getCode();
|
||||||
|
// http://boschista.deviantart.com/journal/Cool-ASCII-Symbols-214218618
|
||||||
|
if (code.equals(GUIUtil.SHOW_ALL_FLAG))
|
||||||
|
return "▶ Show all";
|
||||||
|
else if (code.equals(GUIUtil.EDIT_FLAG))
|
||||||
|
return "▼ Edit currency list";
|
||||||
|
else if (tradeCurrency instanceof FiatCurrency)
|
||||||
|
return "★ " + tradeCurrency.getNameAndCode();
|
||||||
|
else if (tradeCurrency instanceof CryptoCurrency)
|
||||||
|
return "✦ " + tradeCurrency.getNameAndCode();
|
||||||
|
else
|
||||||
|
return "-";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TradeCurrency fromString(String s) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void openWebPage(String target) {
|
||||||
|
String key = "warnOpenURLWhenTorEnabled";
|
||||||
|
final Preferences preferences = Preferences.INSTANCE;
|
||||||
|
if (preferences.getUseTorForHttpRequests() && preferences.showAgain(key)) {
|
||||||
|
new Popup<>().information("You have Tor enabled for Http requests and are going to open a web page " +
|
||||||
|
"in your system web browser.\n" +
|
||||||
|
"Do you want to open the web page now?\n\n" +
|
||||||
|
"If you are not using the \"Tor Browser\" as your default system web browser you " +
|
||||||
|
"will connect to the web page in clear net.\n\n" +
|
||||||
|
"URL: \"" + target)
|
||||||
|
.actionButtonText("Open the web page and don't ask again")
|
||||||
|
.onAction(() -> {
|
||||||
|
preferences.dontShowAgain(key, true);
|
||||||
|
doOpenWebPage(target);
|
||||||
|
})
|
||||||
|
.closeButtonText("Copy URL and cancel")
|
||||||
|
.onClose(() -> Utilities.copyToClipboard(target))
|
||||||
|
.show();
|
||||||
|
} else {
|
||||||
|
doOpenWebPage(target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void doOpenWebPage(String target) {
|
||||||
|
try {
|
||||||
|
Utilities.openURI(new URI(target));
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
log.error(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void openMail(String to, String subject, String body) {
|
||||||
|
try {
|
||||||
|
subject = URLEncoder.encode(subject, "UTF-8").replace("+", "%20");
|
||||||
|
body = URLEncoder.encode(body, "UTF-8").replace("+", "%20");
|
||||||
|
Utilities.openURI(new URI("mailto:" + to + "?subject=" + subject + "&body=" + body));
|
||||||
|
} catch (IOException | URISyntaxException e) {
|
||||||
|
log.error("openMail failed " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ public class ImageUtil {
|
||||||
public static boolean isRetina() {
|
public static boolean isRetina() {
|
||||||
float maxRenderScale = ((QuantumToolkit) QuantumToolkit.getToolkit()).getMaxRenderScale();
|
float maxRenderScale = ((QuantumToolkit) QuantumToolkit.getToolkit()).getMaxRenderScale();
|
||||||
boolean isRetina = maxRenderScale > 1.9f;
|
boolean isRetina = maxRenderScale > 1.9f;
|
||||||
//log.info("isRetina=" + isRetina + " / maxRenderScale=" + maxRenderScale);
|
//log.debug("isRetina=" + isRetina + " / maxRenderScale=" + maxRenderScale);
|
||||||
return isRetina;
|
return isRetina;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,11 +10,11 @@
|
||||||
<appender-ref ref="CONSOLE_APPENDER"/>
|
<appender-ref ref="CONSOLE_APPENDER"/>
|
||||||
</root>
|
</root>
|
||||||
|
|
||||||
<logger name="io.bitsquare.storage.Storage" level="WARN"/>
|
<!-- <logger name="io.bitsquare.storage.Storage" level="WARN"/>
|
||||||
<logger name="io.bitsquare.storage.FileManager" level="WARN"/>
|
<logger name="io.bitsquare.storage.FileManager" level="WARN"/>
|
||||||
<logger name="io.bitsquare.locale.BSResources" level="ERROR"/>
|
<logger name="io.bitsquare.locale.BSResources" level="ERROR"/>
|
||||||
|
|
||||||
<!--<logger name="io.bitsquare.p2p" level="WARN"/>-->
|
<!–<logger name="io.bitsquare.p2p" level="WARN"/>–>
|
||||||
<logger name="io.bitsquare.btc.pricefeed" level="WARN"/>
|
<logger name="io.bitsquare.btc.pricefeed" level="WARN"/>
|
||||||
|
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@
|
||||||
<logger name="io.bitsquare.p2p.peers" level="WARN"/>
|
<logger name="io.bitsquare.p2p.peers" level="WARN"/>
|
||||||
<logger name="io.bitsquare.p2p.peers.getdata" level="WARN"/>
|
<logger name="io.bitsquare.p2p.peers.getdata" level="WARN"/>
|
||||||
<logger name="io.bitsquare.p2p.peers.keepalive" level="WARN"/>
|
<logger name="io.bitsquare.p2p.peers.keepalive" level="WARN"/>
|
||||||
<logger name="io.bitsquare.p2p.peers.peerexchange" level="WARN"/>
|
<logger name="io.bitsquare.p2p.peers.peerexchange" level="WARN"/>-->
|
||||||
|
|
||||||
<!--<logger name="io.bitsquare.p2p.network" level="WARN"/>-->
|
<!--<logger name="io.bitsquare.p2p.network" level="WARN"/>-->
|
||||||
<!-- <logger name="io.bitsquare.p2p.P2PService" level="WARN"/>-->
|
<!-- <logger name="io.bitsquare.p2p.P2PService" level="WARN"/>-->
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package io.bitsquare.gui.main.markets.trades;
|
package io.bitsquare.gui.main.market.trades;
|
||||||
|
|
||||||
import io.bitsquare.gui.main.markets.trades.charts.CandleData;
|
import io.bitsquare.gui.main.market.trades.charts.CandleData;
|
||||||
import io.bitsquare.trade.offer.Offer;
|
import io.bitsquare.trade.offer.Offer;
|
||||||
import io.bitsquare.trade.statistics.TradeStatistics;
|
import io.bitsquare.trade.statistics.TradeStatistics;
|
||||||
import org.bitcoinj.core.Coin;
|
import org.bitcoinj.core.Coin;
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>parent</artifactId>
|
<artifactId>parent</artifactId>
|
||||||
<groupId>io.bitsquare</groupId>
|
<groupId>io.bitsquare</groupId>
|
||||||
<version>0.4.9.1</version>
|
<version>0.4.9.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|
|
@ -127,7 +127,7 @@ public class Headless {
|
||||||
|
|
||||||
public void shutDown() {
|
public void shutDown() {
|
||||||
gracefulShutDown(() -> {
|
gracefulShutDown(() -> {
|
||||||
log.info("Shutdown complete");
|
log.debug("Shutdown complete");
|
||||||
System.exit(0);
|
System.exit(0);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -141,7 +141,7 @@ public class Headless {
|
||||||
injector.getInstance(P2PService.class).shutDown(() -> {
|
injector.getInstance(P2PService.class).shutDown(() -> {
|
||||||
injector.getInstance(WalletService.class).shutDownDone.addListener((ov, o, n) -> {
|
injector.getInstance(WalletService.class).shutDownDone.addListener((ov, o, n) -> {
|
||||||
headlessModule.close(injector);
|
headlessModule.close(injector);
|
||||||
log.info("Graceful shutdown completed");
|
log.debug("Graceful shutdown completed");
|
||||||
resultHandler.handleResult();
|
resultHandler.handleResult();
|
||||||
});
|
});
|
||||||
injector.getInstance(WalletService.class).shutDown();
|
injector.getInstance(WalletService.class).shutDown();
|
||||||
|
@ -153,7 +153,7 @@ public class Headless {
|
||||||
UserThread.runAfter(resultHandler::handleResult, 1);
|
UserThread.runAfter(resultHandler::handleResult, 1);
|
||||||
}
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
log.info("App shutdown failed with exception");
|
log.debug("App shutdown failed with exception");
|
||||||
t.printStackTrace();
|
t.printStackTrace();
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>parent</artifactId>
|
<artifactId>parent</artifactId>
|
||||||
<groupId>io.bitsquare</groupId>
|
<groupId>io.bitsquare</groupId>
|
||||||
<version>0.4.9.1</version>
|
<version>0.4.9.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>parent</artifactId>
|
<artifactId>parent</artifactId>
|
||||||
<groupId>io.bitsquare</groupId>
|
<groupId>io.bitsquare</groupId>
|
||||||
<version>0.4.9.1</version>
|
<version>0.4.9.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|
|
@ -257,7 +257,7 @@ public class SOCKS {
|
||||||
// /////////////////
|
// /////////////////
|
||||||
|
|
||||||
static void inform(String s) {
|
static void inform(String s) {
|
||||||
log.info(s);
|
log.debug(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void exit(String msg) {
|
static void exit(String msg) {
|
||||||
|
|
|
@ -158,13 +158,13 @@ public class ProxyServer implements Runnable {
|
||||||
ss = new ServerSocket(port, backlog, localIP);
|
ss = new ServerSocket(port, backlog, localIP);
|
||||||
final String address = ss.getInetAddress().getHostAddress();
|
final String address = ss.getInetAddress().getHostAddress();
|
||||||
final int localPort = ss.getLocalPort();
|
final int localPort = ss.getLocalPort();
|
||||||
log.info("Starting SOCKS Proxy on: {}:{}", address, localPort);
|
log.debug("Starting SOCKS Proxy on: {}:{}", address, localPort);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
final Socket s = ss.accept();
|
final Socket s = ss.accept();
|
||||||
final String hostName = s.getInetAddress().getHostName();
|
final String hostName = s.getInetAddress().getHostName();
|
||||||
final int port2 = s.getPort();
|
final int port2 = s.getPort();
|
||||||
log.info("Accepted from:{}:{}", hostName, port2);
|
log.debug("Accepted from:{}:{}", hostName, port2);
|
||||||
|
|
||||||
final ProxyServer ps = new ProxyServer(auth, s);
|
final ProxyServer ps = new ProxyServer(auth, s);
|
||||||
(new Thread(ps)).start();
|
(new Thread(ps)).start();
|
||||||
|
@ -203,7 +203,7 @@ public class ProxyServer implements Runnable {
|
||||||
if (auth != null) {
|
if (auth != null) {
|
||||||
auth.endSession();
|
auth.endSession();
|
||||||
}
|
}
|
||||||
log.info("Main thread(client->remote)stopped.");
|
log.debug("Main thread(client->remote)stopped.");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ACCEPT_MODE:
|
case ACCEPT_MODE:
|
||||||
|
@ -219,7 +219,7 @@ public class ProxyServer implements Runnable {
|
||||||
handleException(ioe);
|
handleException(ioe);
|
||||||
} finally {
|
} finally {
|
||||||
abort();
|
abort();
|
||||||
log.info("Accept thread(remote->client) stopped");
|
log.debug("Accept thread(remote->client) stopped");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PIPE_MODE:
|
case PIPE_MODE:
|
||||||
|
@ -228,7 +228,7 @@ public class ProxyServer implements Runnable {
|
||||||
} catch (final IOException ioe) {
|
} catch (final IOException ioe) {
|
||||||
} finally {
|
} finally {
|
||||||
abort();
|
abort();
|
||||||
log.info("Support thread(remote->client) stopped");
|
log.debug("Support thread(remote->client) stopped");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ABORT_MODE:
|
case ABORT_MODE:
|
||||||
|
@ -252,7 +252,7 @@ public class ProxyServer implements Runnable {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auth == null) { // Authentication failed
|
if (auth == null) { // Authentication failed
|
||||||
log.info("Authentication failed");
|
log.debug("Authentication failed");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -336,7 +336,7 @@ public class ProxyServer implements Runnable {
|
||||||
s = new SocksSocket(proxy, msg.ip, msg.port);
|
s = new SocksSocket(proxy, msg.ip, msg.port);
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info("Connected to " + s.getInetAddress() + ":" + s.getPort());
|
log.debug("Connected to " + s.getInetAddress() + ":" + s.getPort());
|
||||||
|
|
||||||
ProxyMessage response = null;
|
ProxyMessage response = null;
|
||||||
final InetAddress localAddress = s.getLocalAddress();
|
final InetAddress localAddress = s.getLocalAddress();
|
||||||
|
@ -367,7 +367,7 @@ public class ProxyServer implements Runnable {
|
||||||
|
|
||||||
final InetAddress inetAddress = ss.getInetAddress();
|
final InetAddress inetAddress = ss.getInetAddress();
|
||||||
final int localPort = ss.getLocalPort();
|
final int localPort = ss.getLocalPort();
|
||||||
log.info("Trying accept on {}:{}", inetAddress, localPort);
|
log.debug("Trying accept on {}:{}", inetAddress, localPort);
|
||||||
|
|
||||||
if (msg.version == 5) {
|
if (msg.version == 5) {
|
||||||
final int cmd = SocksProxyBase.SOCKS_SUCCESS;
|
final int cmd = SocksProxyBase.SOCKS_SUCCESS;
|
||||||
|
@ -425,7 +425,7 @@ public class ProxyServer implements Runnable {
|
||||||
if (msg.ip.getHostAddress().equals("0.0.0.0")) {
|
if (msg.ip.getHostAddress().equals("0.0.0.0")) {
|
||||||
msg.ip = sock.getInetAddress();
|
msg.ip = sock.getInetAddress();
|
||||||
}
|
}
|
||||||
log.info("Creating UDP relay server for {}:{}", msg.ip, msg.port);
|
log.debug("Creating UDP relay server for {}:{}", msg.ip, msg.port);
|
||||||
|
|
||||||
relayServer = new UDPRelayServer(msg.ip, msg.port,
|
relayServer = new UDPRelayServer(msg.ip, msg.port,
|
||||||
Thread.currentThread(), sock, auth);
|
Thread.currentThread(), sock, auth);
|
||||||
|
@ -494,7 +494,7 @@ public class ProxyServer implements Runnable {
|
||||||
|
|
||||||
final InetAddress inetAddress = s.getInetAddress();
|
final InetAddress inetAddress = s.getInetAddress();
|
||||||
final int port = s.getPort();
|
final int port = s.getPort();
|
||||||
log.info("Accepted from {}:{}", s.getInetAddress(), port);
|
log.debug("Accepted from {}:{}", s.getInetAddress(), port);
|
||||||
|
|
||||||
ProxyMessage response;
|
ProxyMessage response;
|
||||||
|
|
||||||
|
@ -564,7 +564,7 @@ public class ProxyServer implements Runnable {
|
||||||
}
|
}
|
||||||
mode = ABORT_MODE;
|
mode = ABORT_MODE;
|
||||||
try {
|
try {
|
||||||
log.info("Aborting operation");
|
log.debug("Aborting operation");
|
||||||
if (remote_sock != null) {
|
if (remote_sock != null) {
|
||||||
remote_sock.close();
|
remote_sock.close();
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,8 +115,8 @@ class UDPRelayServer implements Runnable {
|
||||||
remote_sock.setSoTimeout(iddleTimeout);
|
remote_sock.setSoTimeout(iddleTimeout);
|
||||||
client_sock.setSoTimeout(iddleTimeout);
|
client_sock.setSoTimeout(iddleTimeout);
|
||||||
|
|
||||||
log.info("Starting UDP relay server on {}:{}", relayIP, relayPort);
|
log.debug("Starting UDP relay server on {}:{}", relayIP, relayPort);
|
||||||
log.info("Remote socket {}:{}", remote_sock.getLocalAddress(),
|
log.debug("Remote socket {}:{}", remote_sock.getLocalAddress(),
|
||||||
remote_sock.getLocalPort());
|
remote_sock.getLocalPort());
|
||||||
|
|
||||||
pipe_thread1 = new Thread(this, "pipe1");
|
pipe_thread1 = new Thread(this, "pipe1");
|
||||||
|
@ -151,7 +151,7 @@ class UDPRelayServer implements Runnable {
|
||||||
} catch (final IOException ioe) {
|
} catch (final IOException ioe) {
|
||||||
} finally {
|
} finally {
|
||||||
abort();
|
abort();
|
||||||
log.info("UDP Pipe thread " + Thread.currentThread().getName()
|
log.debug("UDP Pipe thread " + Thread.currentThread().getName()
|
||||||
+ " stopped.");
|
+ " stopped.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,7 +164,7 @@ class UDPRelayServer implements Runnable {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info("Aborting UDP Relay Server");
|
log.debug("Aborting UDP Relay Server");
|
||||||
|
|
||||||
remote_sock.close();
|
remote_sock.close();
|
||||||
client_sock.close();
|
client_sock.close();
|
||||||
|
@ -201,7 +201,7 @@ class UDPRelayServer implements Runnable {
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (final UnknownHostException uhe) {
|
} catch (final UnknownHostException uhe) {
|
||||||
log.info("Dropping datagram for unknown host");
|
log.debug("Dropping datagram for unknown host");
|
||||||
} catch (final InterruptedIOException iioe) {
|
} catch (final InterruptedIOException iioe) {
|
||||||
// log("Interrupted: "+iioe);
|
// log("Interrupted: "+iioe);
|
||||||
// If we were interrupted by other thread.
|
// If we were interrupted by other thread.
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>parent</artifactId>
|
<artifactId>parent</artifactId>
|
||||||
<groupId>io.bitsquare</groupId>
|
<groupId>io.bitsquare</groupId>
|
||||||
<version>0.4.9.1</version>
|
<version>0.4.9.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>parent</artifactId>
|
<artifactId>parent</artifactId>
|
||||||
<groupId>io.bitsquare</groupId>
|
<groupId>io.bitsquare</groupId>
|
||||||
<version>0.4.9.1</version>
|
<version>0.4.9.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue