mirror of
https://github.com/bisq-network/bisq.git
synced 2024-11-19 18:03:12 +01:00
Add support for customized currency lists
This commit is contained in:
parent
59ad7653b5
commit
2f0f58c478
@ -33,7 +33,7 @@ public class PoloniexPriceProvider implements PriceProvider {
|
||||
String response = httpClient.requestWithGET("?command=returnTicker");
|
||||
LinkedTreeMap<String, Object> treeMap = new Gson().fromJson(response, LinkedTreeMap.class);
|
||||
Map<String, String> temp = new HashMap<>();
|
||||
Set<String> supported = CurrencyUtil.getSortedCryptoCurrencies().stream()
|
||||
Set<String> supported = CurrencyUtil.getAllSortedCryptoCurrencies().stream()
|
||||
.map(TradeCurrency::getCode)
|
||||
.collect(Collectors.toSet());
|
||||
treeMap.entrySet().stream().forEach(e -> {
|
||||
|
@ -126,7 +126,7 @@ public class CountryUtil {
|
||||
selectedRegion != null && country != null && selectedRegion.equals(country.region)));
|
||||
}
|
||||
|
||||
private static List<Country> getAllCountries() {
|
||||
public static List<Country> getAllCountries() {
|
||||
final List<Country> allCountries = new ArrayList<>();
|
||||
for (final Locale locale : getAllCountryLocales()) {
|
||||
String regionCode = getRegionCode(locale.getCountry());
|
||||
|
@ -27,14 +27,96 @@ import java.util.stream.Collectors;
|
||||
public class CurrencyUtil {
|
||||
private static final Logger log = LoggerFactory.getLogger(CurrencyUtil.class);
|
||||
|
||||
private static final List<TradeCurrency> allSortedCurrencies = createAllSortedCurrenciesList();
|
||||
private static final List<FiatCurrency> allSortedFiatCurrencies = createAllSortedFiatCurrenciesList();
|
||||
|
||||
public static List<TradeCurrency> getAllSortedCurrencies() {
|
||||
return allSortedCurrencies;
|
||||
private static List<FiatCurrency> createAllSortedFiatCurrenciesList() {
|
||||
Set<FiatCurrency> set = CountryUtil.getAllCountries().stream()
|
||||
.map(country -> getCurrencyByCountryCode(country.code))
|
||||
.collect(Collectors.toSet());
|
||||
List<FiatCurrency> list = new ArrayList<>(set);
|
||||
list.sort(TradeCurrency::compareTo);
|
||||
return list;
|
||||
}
|
||||
|
||||
// We add all currencies supported by payment methods
|
||||
private static List<TradeCurrency> createAllSortedCurrenciesList() {
|
||||
public static List<FiatCurrency> getAllSortedFiatCurrencies() {
|
||||
return allSortedFiatCurrencies;
|
||||
}
|
||||
|
||||
public static List<FiatCurrency> getAllMainFiatCurrencies() {
|
||||
List<FiatCurrency> list = new ArrayList<>();
|
||||
// Top traded currencies
|
||||
list.add(new FiatCurrency("USD"));
|
||||
list.add(new FiatCurrency("EUR"));
|
||||
list.add(new FiatCurrency("GBP"));
|
||||
list.add(new FiatCurrency("CAD"));
|
||||
list.add(new FiatCurrency("AUD"));
|
||||
list.add(new FiatCurrency("RUB"));
|
||||
list.add(new FiatCurrency("INR"));
|
||||
|
||||
TradeCurrency defaultTradeCurrency = getDefaultTradeCurrency();
|
||||
FiatCurrency defaultFiatCurrency = defaultTradeCurrency instanceof FiatCurrency ? (FiatCurrency) defaultTradeCurrency : null;
|
||||
if (defaultFiatCurrency != null && list.contains(defaultFiatCurrency)) {
|
||||
list.remove(defaultTradeCurrency);
|
||||
list.add(0, defaultFiatCurrency);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
private static final List<CryptoCurrency> allSortedCryptoCurrencies = createAllSortedCryptoCurrenciesList();
|
||||
|
||||
public static List<CryptoCurrency> getAllSortedCryptoCurrencies() {
|
||||
return allSortedCryptoCurrencies;
|
||||
}
|
||||
|
||||
public static List<CryptoCurrency> getMainCryptoCurrencies() {
|
||||
final List<CryptoCurrency> result = new ArrayList<>();
|
||||
result.add(new CryptoCurrency("ETH", "Ethereum"));
|
||||
result.add(new CryptoCurrency("LTC", "Litecoin"));
|
||||
result.add(new CryptoCurrency("NMC", "Namecoin"));
|
||||
result.add(new CryptoCurrency("DASH", "Dash"));
|
||||
result.add(new CryptoCurrency("NBT", "NuBits"));
|
||||
result.add(new CryptoCurrency("DOGE", "Dogecoin"));
|
||||
result.add(new CryptoCurrency("NXT", "Nxt"));
|
||||
result.add(new CryptoCurrency("BTS", "BitShares"));
|
||||
return result;
|
||||
}
|
||||
|
||||
public static List<CryptoCurrency> createAllSortedCryptoCurrenciesList() {
|
||||
final List<CryptoCurrency> result = new ArrayList<>();
|
||||
result.add(new CryptoCurrency("ETH", "Ethereum"));
|
||||
result.add(new CryptoCurrency("LTC", "Litecoin"));
|
||||
result.add(new CryptoCurrency("NMC", "Namecoin"));
|
||||
result.add(new CryptoCurrency("DASH", "Dash"));
|
||||
result.add(new CryptoCurrency("NBT", "NuBits"));
|
||||
result.add(new CryptoCurrency("NSR", "NuShares"));
|
||||
result.add(new CryptoCurrency("PPC", "Peercoin"));
|
||||
result.add(new CryptoCurrency("XPM", "Primecoin"));
|
||||
result.add(new CryptoCurrency("SC", "Siacoin"));
|
||||
result.add(new CryptoCurrency("SJCX", "StorjcoinX"));
|
||||
result.add(new CryptoCurrency("GEMZ", "Gemz"));
|
||||
result.add(new CryptoCurrency("DOGE", "Dogecoin"));
|
||||
result.add(new CryptoCurrency("BLK", "Blackcoin"));
|
||||
result.add(new CryptoCurrency("FCT", "Factom"));
|
||||
result.add(new CryptoCurrency("NXT", "Nxt"));
|
||||
result.add(new CryptoCurrency("BTS", "BitShares"));
|
||||
result.add(new CryptoCurrency("XCP", "Counterparty"));
|
||||
result.add(new CryptoCurrency("XRP", "Ripple"));
|
||||
|
||||
// Unfortunately we cannot support CryptoNote coins yet as there is no way to proof the transaction. Payment ID helps only locate the tx but the
|
||||
// arbitrator cannot see if the receiving key matches the receivers address. They might add support for exposing the tx key, but that is not
|
||||
// implemented yet. To use the view key (also not available in GUI wallets) would reveal the complete wallet history for incoming payments, which is
|
||||
// not acceptable from privacy point of view.
|
||||
// result.add(new CryptoCurrency("XMR", "Monero"));
|
||||
// result.add(new CryptoCurrency("BCN", "Bytecoin"));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* // We add all currencies supported by payment methods
|
||||
// TODO not used anymore
|
||||
private static List<TradeCurrency> createAllSortedCurrenciesListDerivedFromPaymentMethods() {
|
||||
Set<TradeCurrency> set = new HashSet<>();
|
||||
|
||||
// Sepa: EUR at first place
|
||||
@ -52,11 +134,11 @@ public class CurrencyUtil {
|
||||
// Swish: it is already added by SEPA
|
||||
|
||||
// for printing out all codes
|
||||
/* String res;
|
||||
*//* String res;
|
||||
result.stream().forEach(e -> {
|
||||
res += "list.add(new FiatCurrency(\""+e.code+"\"));\n";
|
||||
});
|
||||
log.debug(res);*/
|
||||
log.debug(res);*//*
|
||||
|
||||
|
||||
List<TradeCurrency> list = getAllManuallySortedFiatCurrencies();
|
||||
@ -84,9 +166,10 @@ public class CurrencyUtil {
|
||||
getSortedCryptoCurrencies().stream().forEach(list::add);
|
||||
|
||||
return list;
|
||||
}
|
||||
}*/
|
||||
|
||||
private static List<TradeCurrency> getAllManuallySortedFiatCurrencies() {
|
||||
|
||||
/* private static List<TradeCurrency> getAllManuallySortedFiatCurrencies() {
|
||||
List<TradeCurrency> list = new ArrayList<>();
|
||||
list.add(new FiatCurrency("EUR"));
|
||||
list.add(new FiatCurrency("USD"));
|
||||
@ -116,7 +199,7 @@ public class CurrencyUtil {
|
||||
list.add(new FiatCurrency("RON"));
|
||||
|
||||
return list;
|
||||
}
|
||||
}*/
|
||||
|
||||
/**
|
||||
* @return Sorted list of SEPA currencies with EUR as first item
|
||||
@ -160,41 +243,11 @@ public class CurrencyUtil {
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public static boolean isCryptoCurrency(String currencyCode) {
|
||||
return getSortedCryptoCurrencies().stream().filter(e -> e.getCode().equals(currencyCode)).findAny().isPresent();
|
||||
return getAllSortedCryptoCurrencies().stream().filter(e -> e.getCode().equals(currencyCode)).findAny().isPresent();
|
||||
}
|
||||
|
||||
public static Optional<TradeCurrency> getCryptoCurrency(String currencyCode) {
|
||||
return getSortedCryptoCurrencies().stream().filter(e -> e.getCode().equals(currencyCode)).findAny();
|
||||
}
|
||||
|
||||
public static List<TradeCurrency> getSortedCryptoCurrencies() {
|
||||
final List<TradeCurrency> result = new ArrayList<>();
|
||||
result.add(new CryptoCurrency("ETH", "Ethereum"));
|
||||
result.add(new CryptoCurrency("LTC", "Litecoin"));
|
||||
result.add(new CryptoCurrency("NMC", "Namecoin"));
|
||||
result.add(new CryptoCurrency("DASH", "Dash"));
|
||||
result.add(new CryptoCurrency("NBT", "NuBits"));
|
||||
result.add(new CryptoCurrency("NSR", "NuShares"));
|
||||
result.add(new CryptoCurrency("PPC", "Peercoin"));
|
||||
result.add(new CryptoCurrency("XPM", "Primecoin"));
|
||||
result.add(new CryptoCurrency("SC", "Siacoin"));
|
||||
result.add(new CryptoCurrency("SJCX", "StorjcoinX"));
|
||||
result.add(new CryptoCurrency("GEMZ", "Gemz"));
|
||||
result.add(new CryptoCurrency("DOGE", "Dogecoin"));
|
||||
result.add(new CryptoCurrency("BLK", "Blackcoin"));
|
||||
result.add(new CryptoCurrency("FCT", "Factom"));
|
||||
result.add(new CryptoCurrency("NXT", "Nxt"));
|
||||
result.add(new CryptoCurrency("BTS", "BitShares"));
|
||||
result.add(new CryptoCurrency("XCP", "Counterparty"));
|
||||
result.add(new CryptoCurrency("XRP", "Ripple"));
|
||||
|
||||
// Unfortunately we cannot support CryptoNote coins yet as there is no way to proof the transaction. Payment ID helps only locate the tx but the
|
||||
// arbitrator cannot see if the receiving key matches the receivers address. They might add support for exposing the tx key, but that is not
|
||||
// implemented yet. To use the view key (also not available in GUI wallets) would reveal the complete wallet history for incoming payments, which is
|
||||
// not acceptable from privacy point of view.
|
||||
// result.add(new CryptoCurrency("XMR", "Monero"));
|
||||
// result.add(new CryptoCurrency("BCN", "Bytecoin"));
|
||||
return result;
|
||||
public static Optional<CryptoCurrency> getCryptoCurrency(String currencyCode) {
|
||||
return getAllSortedCryptoCurrencies().stream().filter(e -> e.getCode().equals(currencyCode)).findAny();
|
||||
}
|
||||
|
||||
public static boolean isCryptoNoteCoin(String currencyCode) {
|
||||
@ -206,6 +259,9 @@ public class CurrencyUtil {
|
||||
if (!countryCode.equals("LT"))
|
||||
return new FiatCurrency(Currency.getInstance(new Locale(LanguageUtil.getDefaultLanguage(), countryCode)).getCurrencyCode());
|
||||
else {
|
||||
if (!Currency.getInstance(new Locale(LanguageUtil.getDefaultLanguage(), countryCode)).getCurrencyCode().equals("EUR"))
|
||||
log.error("wrong currency reported for LT");
|
||||
|
||||
return new FiatCurrency("EUR");
|
||||
}
|
||||
}
|
||||
@ -216,7 +272,7 @@ public class CurrencyUtil {
|
||||
return Currency.getInstance(currencyCode).getDisplayName(Preferences.getDefaultLocale());
|
||||
} catch (Throwable t) {
|
||||
// Seems that it is a cryptocurrency
|
||||
return getSortedCryptoCurrencies().stream().filter(e -> e.getCode().equals(currencyCode)).findFirst().get().getName();
|
||||
return getAllSortedCryptoCurrencies().stream().filter(e -> e.getCode().equals(currencyCode)).findFirst().get().getName();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,8 +19,9 @@ package io.bitsquare.locale;
|
||||
|
||||
import io.bitsquare.app.Version;
|
||||
import io.bitsquare.common.persistance.Persistable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public abstract class TradeCurrency implements Persistable {
|
||||
public abstract class TradeCurrency implements Persistable, Comparable<TradeCurrency> {
|
||||
// That object is saved to disc. We need to take care of changes to not break deserialization.
|
||||
private static final long serialVersionUID = Version.LOCAL_DB_VERSION;
|
||||
|
||||
@ -65,6 +66,11 @@ public abstract class TradeCurrency implements Persistable {
|
||||
return code + " (" + name + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@NotNull TradeCurrency other) {
|
||||
return this.getName().compareTo(other.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
|
@ -29,12 +29,12 @@ public abstract class BankAccountContractData extends PaymentAccountContractData
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(BankAccountContractData.class);
|
||||
|
||||
private String holderName;
|
||||
private String bankName;
|
||||
private String bankId;
|
||||
private String branchId;
|
||||
private String accountNr;
|
||||
private String holderId;
|
||||
protected String holderName;
|
||||
protected String bankName;
|
||||
protected String bankId;
|
||||
protected String branchId;
|
||||
protected String accountNr;
|
||||
protected String holderId;
|
||||
|
||||
public BankAccountContractData(String paymentMethod, String id, int maxTradePeriod) {
|
||||
super(paymentMethod, id, maxTradePeriod);
|
||||
|
@ -31,4 +31,8 @@ public final class SameBankAccount extends PaymentAccount {
|
||||
protected PaymentAccountContractData setContractData() {
|
||||
return new SameBankAccountContractData(paymentMethod.getId(), id, paymentMethod.getMaxTradePeriod());
|
||||
}
|
||||
|
||||
public String getAcceptedBank() {
|
||||
return ((SameBankAccountContractData) contractData).getBankName();
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,8 @@ package io.bitsquare.payment;
|
||||
|
||||
import io.bitsquare.app.Version;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public final class SpecificBankAccount extends PaymentAccount {
|
||||
// That object is saved to disc. We need to take care of changes to not break deserialization.
|
||||
private static final long serialVersionUID = Version.LOCAL_DB_VERSION;
|
||||
@ -31,4 +33,8 @@ public final class SpecificBankAccount extends PaymentAccount {
|
||||
protected PaymentAccountContractData setContractData() {
|
||||
return new SpecificBanksAccountContractData(paymentMethod.getId(), id, paymentMethod.getMaxTradePeriod());
|
||||
}
|
||||
|
||||
public ArrayList<String> getAcceptedBanks() {
|
||||
return ((SpecificBanksAccountContractData) contractData).getAcceptedBanks();
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,10 @@
|
||||
|
||||
package io.bitsquare.payment;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import io.bitsquare.app.Version;
|
||||
import io.bitsquare.locale.BankUtil;
|
||||
import io.bitsquare.locale.CountryUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -56,4 +59,17 @@ public final class SpecificBanksAccountContractData extends BankAccountContractD
|
||||
public String getPaymentDetails() {
|
||||
return "Transfers with specific banks - " + getPaymentDetailsForTradePopup().replace("\n", ", ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPaymentDetailsForTradePopup() {
|
||||
String holderIdString = BankUtil.requiresHolderId(countryCode) ? (getHolderIdLabel() + ": " + holderId + "\n") : "";
|
||||
return "Holder name: " + holderName + "\n" +
|
||||
holderIdString +
|
||||
"Bank name: " + bankName + "\n" +
|
||||
"Bank Nr.: " + bankId + "\n" +
|
||||
"Branch Nr.: " + branchId + "\n" +
|
||||
"Account Nr.: " + accountNr + "\n" +
|
||||
"Accepted banks: " + Joiner.on(", ").join(acceptedBanks) + "\n" +
|
||||
"Country of bank: " + CountryUtil.getNameAndCode(getCountryCode());
|
||||
}
|
||||
}
|
||||
|
@ -102,6 +102,8 @@ public final class Offer implements StoragePayload, RequiresOwnerIsOnlinePayload
|
||||
|
||||
@Nullable
|
||||
private final ArrayList<String> acceptedCountryCodes;
|
||||
@Nullable
|
||||
private final ArrayList<String> acceptedBanks;
|
||||
private final ArrayList<NodeAddress> arbitratorNodeAddresses;
|
||||
|
||||
// Mutable property. Has to be set before offer is save in P2P network as it changes the objects hash!
|
||||
@ -136,7 +138,8 @@ public final class Offer implements StoragePayload, RequiresOwnerIsOnlinePayload
|
||||
@Nullable Country paymentMethodCountry,
|
||||
String offererPaymentAccountId,
|
||||
ArrayList<NodeAddress> arbitratorNodeAddresses,
|
||||
@Nullable ArrayList<String> acceptedCountryCodes) {
|
||||
@Nullable ArrayList<String> acceptedCountryCodes,
|
||||
@Nullable ArrayList<String> acceptedBanks) {
|
||||
this.id = id;
|
||||
this.offererNodeAddress = offererNodeAddress;
|
||||
this.pubKeyRing = pubKeyRing;
|
||||
@ -150,6 +153,7 @@ public final class Offer implements StoragePayload, RequiresOwnerIsOnlinePayload
|
||||
this.offererPaymentAccountId = offererPaymentAccountId;
|
||||
this.arbitratorNodeAddresses = arbitratorNodeAddresses;
|
||||
this.acceptedCountryCodes = acceptedCountryCodes;
|
||||
this.acceptedBanks = acceptedBanks;
|
||||
|
||||
protocolVersion = Version.TRADE_PROTOCOL_VERSION;
|
||||
|
||||
@ -336,6 +340,11 @@ public final class Offer implements StoragePayload, RequiresOwnerIsOnlinePayload
|
||||
return acceptedCountryCodes;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public List<String> getAcceptedBanks() {
|
||||
return acceptedBanks;
|
||||
}
|
||||
|
||||
public String getOfferFeePaymentTxID() {
|
||||
return offerFeePaymentTxID;
|
||||
}
|
||||
@ -389,6 +398,8 @@ public final class Offer implements StoragePayload, RequiresOwnerIsOnlinePayload
|
||||
return false;
|
||||
if (acceptedCountryCodes != null ? !acceptedCountryCodes.equals(offer.acceptedCountryCodes) : offer.acceptedCountryCodes != null)
|
||||
return false;
|
||||
if (acceptedBanks != null ? !acceptedBanks.equals(offer.acceptedBanks) : offer.acceptedBanks != null)
|
||||
return false;
|
||||
if (arbitratorNodeAddresses != null ? !arbitratorNodeAddresses.equals(offer.arbitratorNodeAddresses) : offer.arbitratorNodeAddresses != null)
|
||||
return false;
|
||||
return !(offerFeePaymentTxID != null ? !offerFeePaymentTxID.equals(offer.offerFeePaymentTxID) : offer.offerFeePaymentTxID != null);
|
||||
@ -410,6 +421,7 @@ public final class Offer implements StoragePayload, RequiresOwnerIsOnlinePayload
|
||||
result = 31 * result + (paymentMethodCountryCode != null ? paymentMethodCountryCode.hashCode() : 0);
|
||||
result = 31 * result + (offererPaymentAccountId != null ? offererPaymentAccountId.hashCode() : 0);
|
||||
result = 31 * result + (acceptedCountryCodes != null ? acceptedCountryCodes.hashCode() : 0);
|
||||
result = 31 * result + (acceptedBanks != null ? acceptedBanks.hashCode() : 0);
|
||||
result = 31 * result + (arbitratorNodeAddresses != null ? arbitratorNodeAddresses.hashCode() : 0);
|
||||
result = 31 * result + (offerFeePaymentTxID != null ? offerFeePaymentTxID.hashCode() : 0);
|
||||
return result;
|
||||
@ -431,6 +443,7 @@ public final class Offer implements StoragePayload, RequiresOwnerIsOnlinePayload
|
||||
"\n\tpaymentMethodCountryCode='" + paymentMethodCountryCode + '\'' +
|
||||
"\n\toffererPaymentAccountId='" + offererPaymentAccountId + '\'' +
|
||||
"\n\tacceptedCountryCodes=" + acceptedCountryCodes +
|
||||
"\n\tacceptedBanks=" + acceptedBanks +
|
||||
"\n\tarbitratorAddresses=" + arbitratorNodeAddresses +
|
||||
"\n\tofferFeePaymentTxID='" + offerFeePaymentTxID + '\'' +
|
||||
"\n\tstate=" + state +
|
||||
|
@ -22,10 +22,7 @@ import io.bitsquare.app.Version;
|
||||
import io.bitsquare.btc.BitcoinNetwork;
|
||||
import io.bitsquare.btc.FeePolicy;
|
||||
import io.bitsquare.common.persistance.Persistable;
|
||||
import io.bitsquare.locale.CountryUtil;
|
||||
import io.bitsquare.locale.CurrencyUtil;
|
||||
import io.bitsquare.locale.FiatCurrency;
|
||||
import io.bitsquare.locale.TradeCurrency;
|
||||
import io.bitsquare.locale.*;
|
||||
import io.bitsquare.storage.Storage;
|
||||
import javafx.beans.Observable;
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
@ -33,6 +30,7 @@ import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ListChangeListener;
|
||||
import javafx.collections.ObservableList;
|
||||
import org.bitcoinj.core.Coin;
|
||||
import org.bitcoinj.core.Transaction;
|
||||
@ -94,7 +92,8 @@ public final class Preferences implements Persistable {
|
||||
private String btcDenomination = MonetaryFormat.CODE_BTC;
|
||||
private boolean useAnimations = true;
|
||||
private boolean useEffects = true;
|
||||
private final ArrayList<TradeCurrency> tradeCurrencies;
|
||||
private final ArrayList<FiatCurrency> fiatCurrencies;
|
||||
private final ArrayList<CryptoCurrency> cryptoCurrencies;
|
||||
private BlockChainExplorer blockChainExplorerMainNet;
|
||||
private BlockChainExplorer blockChainExplorerTestNet;
|
||||
private boolean showNotifications = true;
|
||||
@ -112,6 +111,8 @@ public final class Preferences implements Persistable {
|
||||
transient private final StringProperty btcDenominationProperty = new SimpleStringProperty(btcDenomination);
|
||||
transient private final BooleanProperty useAnimationsProperty = new SimpleBooleanProperty(useAnimations);
|
||||
transient private final BooleanProperty useEffectsProperty = new SimpleBooleanProperty(useEffects);
|
||||
transient private final ObservableList<FiatCurrency> fiatCurrenciesAsObservable = FXCollections.observableArrayList();
|
||||
transient private final ObservableList<CryptoCurrency> cryptoCurrenciesAsObservable = FXCollections.observableArrayList();
|
||||
transient private final ObservableList<TradeCurrency> tradeCurrenciesAsObservable = FXCollections.observableArrayList();
|
||||
|
||||
|
||||
@ -130,8 +131,12 @@ public final class Preferences implements Persistable {
|
||||
setBtcDenomination(persisted.btcDenomination);
|
||||
setUseAnimations(persisted.useAnimations);
|
||||
setUseEffects(persisted.useEffects);
|
||||
setTradeCurrencies(persisted.tradeCurrencies);
|
||||
tradeCurrencies = new ArrayList<>(tradeCurrenciesAsObservable);
|
||||
|
||||
setFiatCurrencies(persisted.fiatCurrencies);
|
||||
fiatCurrencies = new ArrayList<>(fiatCurrenciesAsObservable);
|
||||
|
||||
setCryptoCurrencies(persisted.cryptoCurrencies);
|
||||
cryptoCurrencies = new ArrayList<>(cryptoCurrenciesAsObservable);
|
||||
|
||||
setBlockChainExplorerTestNet(persisted.getBlockChainExplorerTestNet());
|
||||
setBlockChainExplorerMainNet(persisted.getBlockChainExplorerMainNet());
|
||||
@ -160,8 +165,12 @@ public final class Preferences implements Persistable {
|
||||
// leave default value
|
||||
}
|
||||
} else {
|
||||
setTradeCurrencies(CurrencyUtil.getAllSortedCurrencies());
|
||||
tradeCurrencies = new ArrayList<>(tradeCurrenciesAsObservable);
|
||||
setFiatCurrencies(CurrencyUtil.getAllMainFiatCurrencies());
|
||||
fiatCurrencies = new ArrayList<>(fiatCurrenciesAsObservable);
|
||||
|
||||
setCryptoCurrencies(CurrencyUtil.getMainCryptoCurrencies());
|
||||
cryptoCurrencies = new ArrayList<>(cryptoCurrenciesAsObservable);
|
||||
|
||||
setBlockChainExplorerTestNet(blockChainExplorersTestNet.get(0));
|
||||
setBlockChainExplorerMainNet(blockChainExplorersMainNet.get(0));
|
||||
|
||||
@ -193,11 +202,21 @@ public final class Preferences implements Persistable {
|
||||
useEffects = useEffectsProperty.get();
|
||||
storage.queueUpForSave(2000);
|
||||
});
|
||||
tradeCurrenciesAsObservable.addListener((Observable ov) -> {
|
||||
tradeCurrencies.clear();
|
||||
tradeCurrencies.addAll(tradeCurrenciesAsObservable);
|
||||
fiatCurrenciesAsObservable.addListener((Observable ov) -> {
|
||||
fiatCurrencies.clear();
|
||||
fiatCurrencies.addAll(fiatCurrenciesAsObservable);
|
||||
storage.queueUpForSave();
|
||||
});
|
||||
cryptoCurrenciesAsObservable.addListener((Observable ov) -> {
|
||||
cryptoCurrencies.clear();
|
||||
cryptoCurrencies.addAll(cryptoCurrenciesAsObservable);
|
||||
storage.queueUpForSave();
|
||||
});
|
||||
|
||||
fiatCurrenciesAsObservable.addListener((ListChangeListener<FiatCurrency>) this::updateTradeCurrencies);
|
||||
cryptoCurrenciesAsObservable.addListener((ListChangeListener<CryptoCurrency>) this::updateTradeCurrencies);
|
||||
tradeCurrenciesAsObservable.addAll(fiatCurrencies);
|
||||
tradeCurrenciesAsObservable.addAll(cryptoCurrencies);
|
||||
}
|
||||
|
||||
public void dontShowAgain(String id) {
|
||||
@ -205,6 +224,14 @@ public final class Preferences implements Persistable {
|
||||
storage.queueUpForSave(2000);
|
||||
}
|
||||
|
||||
private void updateTradeCurrencies(ListChangeListener.Change<? extends TradeCurrency> change) {
|
||||
change.next();
|
||||
if (change.wasAdded() && change.getAddedSize() == 1)
|
||||
tradeCurrenciesAsObservable.add(change.getAddedSubList().get(0));
|
||||
else if (change.wasRemoved() && change.getRemovedSize() == 1)
|
||||
tradeCurrenciesAsObservable.remove(change.getRemoved().get(0));
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Setter
|
||||
@ -231,8 +258,46 @@ public final class Preferences implements Persistable {
|
||||
// We don't store the bitcoinNetwork locally as BitcoinNetwork is not serializable!
|
||||
}
|
||||
|
||||
private void setTradeCurrencies(List<TradeCurrency> tradeCurrencies) {
|
||||
tradeCurrenciesAsObservable.setAll(tradeCurrencies);
|
||||
private void setFiatCurrencies(List<FiatCurrency> currencies) {
|
||||
fiatCurrenciesAsObservable.setAll(currencies);
|
||||
}
|
||||
|
||||
private void setCryptoCurrencies(List<CryptoCurrency> currencies) {
|
||||
cryptoCurrenciesAsObservable.setAll(currencies);
|
||||
}
|
||||
|
||||
public void addFiatCurrency(FiatCurrency tradeCurrency) {
|
||||
if (!fiatCurrenciesAsObservable.contains(tradeCurrency))
|
||||
fiatCurrenciesAsObservable.add(tradeCurrency);
|
||||
}
|
||||
|
||||
public void removeFiatCurrency(FiatCurrency tradeCurrency) {
|
||||
if (tradeCurrenciesAsObservable.size() > 1) {
|
||||
if (fiatCurrenciesAsObservable.contains(tradeCurrency))
|
||||
fiatCurrenciesAsObservable.remove(tradeCurrency);
|
||||
|
||||
if (preferredTradeCurrency.equals(tradeCurrency))
|
||||
setPreferredTradeCurrency(tradeCurrenciesAsObservable.get(0));
|
||||
} else {
|
||||
log.error("you cannot remove the last currency");
|
||||
}
|
||||
}
|
||||
|
||||
public void addCryptoCurrency(CryptoCurrency tradeCurrency) {
|
||||
if (!cryptoCurrenciesAsObservable.contains(tradeCurrency))
|
||||
cryptoCurrenciesAsObservable.add(tradeCurrency);
|
||||
}
|
||||
|
||||
public void removeCryptoCurrency(CryptoCurrency tradeCurrency) {
|
||||
if (tradeCurrenciesAsObservable.size() > 1) {
|
||||
if (cryptoCurrenciesAsObservable.contains(tradeCurrency))
|
||||
cryptoCurrenciesAsObservable.remove(tradeCurrency);
|
||||
|
||||
if (preferredTradeCurrency.equals(tradeCurrency))
|
||||
setPreferredTradeCurrency(tradeCurrenciesAsObservable.get(0));
|
||||
} else {
|
||||
log.error("you cannot remove the last currency");
|
||||
}
|
||||
}
|
||||
|
||||
private void setBlockChainExplorerTestNet(BlockChainExplorer blockChainExplorerTestNet) {
|
||||
@ -274,9 +339,11 @@ public final class Preferences implements Persistable {
|
||||
}
|
||||
|
||||
public void setPreferredTradeCurrency(TradeCurrency preferredTradeCurrency) {
|
||||
this.preferredTradeCurrency = preferredTradeCurrency;
|
||||
defaultTradeCurrency = preferredTradeCurrency;
|
||||
storage.queueUpForSave();
|
||||
if (preferredTradeCurrency != null) {
|
||||
this.preferredTradeCurrency = preferredTradeCurrency;
|
||||
defaultTradeCurrency = preferredTradeCurrency;
|
||||
storage.queueUpForSave();
|
||||
}
|
||||
}
|
||||
|
||||
public void setTxFeePerKB(long txFeePerKB) throws Exception {
|
||||
@ -329,6 +396,14 @@ public final class Preferences implements Persistable {
|
||||
return bitcoinNetwork;
|
||||
}
|
||||
|
||||
public ObservableList<FiatCurrency> getFiatCurrenciesAsObservable() {
|
||||
return fiatCurrenciesAsObservable;
|
||||
}
|
||||
|
||||
public ObservableList<CryptoCurrency> getCryptoCurrenciesAsObservable() {
|
||||
return cryptoCurrenciesAsObservable;
|
||||
}
|
||||
|
||||
public ObservableList<TradeCurrency> getTradeCurrenciesAsObservable() {
|
||||
return tradeCurrenciesAsObservable;
|
||||
}
|
||||
|
@ -53,14 +53,15 @@ abstract class BankForm extends PaymentMethodForm {
|
||||
|
||||
static int addFormForBuyer(GridPane gridPane, int gridRow, PaymentAccountContractData paymentAccountContractData) {
|
||||
BankAccountContractData bankAccountContractData = (BankAccountContractData) paymentAccountContractData;
|
||||
addLabelTextFieldWithCopyIcon(gridPane, ++gridRow, "Account holder name:", bankAccountContractData.getHolderName());
|
||||
addLabelTextFieldWithCopyIcon(gridPane, ++gridRow, "Country of bank:", CountryUtil.getNameAndCode(bankAccountContractData.getCountryCode()));
|
||||
addLabelTextFieldWithCopyIcon(gridPane, ++gridRow, "Bank name:", bankAccountContractData.getBankName());
|
||||
addLabelTextFieldWithCopyIcon(gridPane, ++gridRow, "Bank number:", bankAccountContractData.getBankId());
|
||||
addLabelTextFieldWithCopyIcon(gridPane, ++gridRow, "Branch number:", bankAccountContractData.getBranchId());
|
||||
addLabelTextFieldWithCopyIcon(gridPane, ++gridRow, "Account number:", bankAccountContractData.getAccountNr());
|
||||
if (bankAccountContractData.getHolderId() != null)
|
||||
addLabelTextFieldWithCopyIcon(gridPane, ++gridRow, bankAccountContractData.getHolderIdLabel(), bankAccountContractData.getHolderId());
|
||||
addLabelTextFieldWithCopyIcon(gridPane, ++gridRow, "Account holder name / " + bankAccountContractData.getHolderIdLabel(),
|
||||
bankAccountContractData.getHolderName() + " / " + bankAccountContractData.getHolderId());
|
||||
else
|
||||
addLabelTextFieldWithCopyIcon(gridPane, ++gridRow, "Account holder name:", bankAccountContractData.getHolderName());
|
||||
|
||||
addLabelTextFieldWithCopyIcon(gridPane, ++gridRow, "Country of bank:", CountryUtil.getNameAndCode(bankAccountContractData.getCountryCode()));
|
||||
addLabelTextFieldWithCopyIcon(gridPane, ++gridRow, "Bank name / number:", bankAccountContractData.getBankName() + " / " + bankAccountContractData.getBankId());
|
||||
addLabelTextFieldWithCopyIcon(gridPane, ++gridRow, "Branch number / Account number:", bankAccountContractData.getBranchId() + " / " + bankAccountContractData.getAccountNr());
|
||||
return gridRow;
|
||||
}
|
||||
|
||||
|
@ -114,7 +114,7 @@ public class BlockChainForm extends PaymentMethodForm {
|
||||
protected void addTradeCurrencyComboBox() {
|
||||
currencyComboBox = addLabelComboBox(gridPane, ++gridRow, "Crypto currency:", Layout.FIRST_ROW_AND_GROUP_DISTANCE).second;
|
||||
currencyComboBox.setPromptText("Select cryptocurrency");
|
||||
currencyComboBox.setItems(FXCollections.observableArrayList(CurrencyUtil.getSortedCryptoCurrencies()));
|
||||
currencyComboBox.setItems(FXCollections.observableArrayList(CurrencyUtil.getAllSortedCryptoCurrencies()));
|
||||
currencyComboBox.setVisibleRowCount(Math.min(currencyComboBox.getItems().size(), 20));
|
||||
currencyComboBox.setConverter(new StringConverter<TradeCurrency>() {
|
||||
@Override
|
||||
|
@ -28,8 +28,7 @@ public class NationalBankForm extends BankForm {
|
||||
private static final Logger log = LoggerFactory.getLogger(NationalBankForm.class);
|
||||
|
||||
public static int addFormForBuyer(GridPane gridPane, int gridRow, PaymentAccountContractData paymentAccountContractData) {
|
||||
BankForm.addFormForBuyer(gridPane, gridRow, paymentAccountContractData);
|
||||
return gridRow;
|
||||
return BankForm.addFormForBuyer(gridPane, gridRow, paymentAccountContractData);
|
||||
}
|
||||
|
||||
public NationalBankForm(PaymentAccount paymentAccount, InputValidator inputValidator,
|
||||
|
@ -61,7 +61,7 @@ public abstract class PaymentMethodForm {
|
||||
protected void addTradeCurrencyComboBox() {
|
||||
currencyComboBox = addLabelComboBox(gridPane, ++gridRow, "Currency:").second;
|
||||
currencyComboBox.setPromptText("Select currency");
|
||||
currencyComboBox.setItems(FXCollections.observableArrayList(CurrencyUtil.getAllSortedCurrencies()));
|
||||
currencyComboBox.setItems(FXCollections.observableArrayList(CurrencyUtil.getAllMainFiatCurrencies()));
|
||||
currencyComboBox.setConverter(new StringConverter<TradeCurrency>() {
|
||||
@Override
|
||||
public String toString(TradeCurrency tradeCurrency) {
|
||||
|
@ -35,8 +35,7 @@ public class SameBankForm extends BankForm {
|
||||
private static final Logger log = LoggerFactory.getLogger(SameBankForm.class);
|
||||
|
||||
public static int addFormForBuyer(GridPane gridPane, int gridRow, PaymentAccountContractData paymentAccountContractData) {
|
||||
BankForm.addFormForBuyer(gridPane, gridRow, paymentAccountContractData);
|
||||
return gridRow;
|
||||
return BankForm.addFormForBuyer(gridPane, gridRow, paymentAccountContractData);
|
||||
}
|
||||
|
||||
public SameBankForm(PaymentAccount paymentAccount, InputValidator inputValidator,
|
||||
@ -72,10 +71,7 @@ public class SameBankForm extends BankForm {
|
||||
Tuple2<Label, TextField> tuple = addLabelTextField(gridPane, ++gridRow, "Account holder name:");
|
||||
TextField holderNameTextField = tuple.second;
|
||||
holderNameTextField.setMinWidth(300);
|
||||
holderNameTextField.textProperty().addListener((ov, oldValue, newValue) -> {
|
||||
bankAccountContractData.setHolderName(newValue);
|
||||
updateFromInputs();
|
||||
});
|
||||
holderNameTextField.setText(bankAccountContractData.getHolderName());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -43,8 +43,7 @@ public class SpecificBankForm extends BankForm {
|
||||
private Tooltip acceptedBanksTooltip;
|
||||
|
||||
public static int addFormForBuyer(GridPane gridPane, int gridRow, PaymentAccountContractData paymentAccountContractData) {
|
||||
BankForm.addFormForBuyer(gridPane, gridRow, paymentAccountContractData);
|
||||
return gridRow;
|
||||
return BankForm.addFormForBuyer(gridPane, gridRow, paymentAccountContractData);
|
||||
}
|
||||
|
||||
public SpecificBankForm(PaymentAccount paymentAccount, InputValidator inputValidator,
|
||||
|
@ -20,15 +20,24 @@ package io.bitsquare.gui.main.account.content.altcoinaccounts;
|
||||
import com.google.inject.Inject;
|
||||
import io.bitsquare.gui.common.model.ActivatableWithDataModel;
|
||||
import io.bitsquare.gui.common.model.ViewModel;
|
||||
import io.bitsquare.locale.CryptoCurrency;
|
||||
import io.bitsquare.locale.FiatCurrency;
|
||||
import io.bitsquare.locale.TradeCurrency;
|
||||
import io.bitsquare.payment.PaymentAccount;
|
||||
import io.bitsquare.user.Preferences;
|
||||
import javafx.collections.ObservableList;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
class AltCoinAccountsViewModel extends ActivatableWithDataModel<AltCoinAccountsDataModel> implements ViewModel {
|
||||
|
||||
|
||||
private Preferences preferences;
|
||||
|
||||
@Inject
|
||||
public AltCoinAccountsViewModel(AltCoinAccountsDataModel dataModel) {
|
||||
public AltCoinAccountsViewModel(AltCoinAccountsDataModel dataModel, Preferences preferences) {
|
||||
super(dataModel);
|
||||
this.preferences = preferences;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -46,6 +55,21 @@ class AltCoinAccountsViewModel extends ActivatableWithDataModel<AltCoinAccountsD
|
||||
|
||||
public void onSaveNewAccount(PaymentAccount paymentAccount) {
|
||||
dataModel.onSaveNewAccount(paymentAccount);
|
||||
TradeCurrency singleTradeCurrency = paymentAccount.getSingleTradeCurrency();
|
||||
List<TradeCurrency> tradeCurrencies = paymentAccount.getTradeCurrencies();
|
||||
if (singleTradeCurrency != null) {
|
||||
if (singleTradeCurrency instanceof FiatCurrency)
|
||||
preferences.addFiatCurrency((FiatCurrency) singleTradeCurrency);
|
||||
else
|
||||
preferences.addCryptoCurrency((CryptoCurrency) singleTradeCurrency);
|
||||
} else if (tradeCurrencies != null && !tradeCurrencies.isEmpty()) {
|
||||
tradeCurrencies.stream().forEach(tradeCurrency -> {
|
||||
if (tradeCurrency instanceof FiatCurrency)
|
||||
preferences.addFiatCurrency((FiatCurrency) tradeCurrency);
|
||||
else
|
||||
preferences.addCryptoCurrency((CryptoCurrency) tradeCurrency);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void onDeleteAccount(PaymentAccount paymentAccount) {
|
||||
|
@ -19,8 +19,12 @@ package io.bitsquare.gui.main.account.content.fiataccounts;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import io.bitsquare.gui.common.model.ActivatableDataModel;
|
||||
import io.bitsquare.locale.CryptoCurrency;
|
||||
import io.bitsquare.locale.FiatCurrency;
|
||||
import io.bitsquare.locale.TradeCurrency;
|
||||
import io.bitsquare.payment.PaymentAccount;
|
||||
import io.bitsquare.payment.PaymentMethod;
|
||||
import io.bitsquare.user.Preferences;
|
||||
import io.bitsquare.user.User;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
@ -32,12 +36,14 @@ import java.util.stream.Collectors;
|
||||
class FiatAccountsDataModel extends ActivatableDataModel {
|
||||
|
||||
private final User user;
|
||||
private Preferences preferences;
|
||||
final ObservableList<PaymentAccount> paymentAccounts = FXCollections.observableArrayList();
|
||||
private final SetChangeListener<PaymentAccount> setChangeListener;
|
||||
|
||||
@Inject
|
||||
public FiatAccountsDataModel(User user) {
|
||||
public FiatAccountsDataModel(User user, Preferences preferences) {
|
||||
this.user = user;
|
||||
this.preferences = preferences;
|
||||
setChangeListener = change -> fillAndSortPaymentAccounts();
|
||||
}
|
||||
|
||||
@ -67,6 +73,21 @@ class FiatAccountsDataModel extends ActivatableDataModel {
|
||||
|
||||
public void onSaveNewAccount(PaymentAccount paymentAccount) {
|
||||
user.addPaymentAccount(paymentAccount);
|
||||
TradeCurrency singleTradeCurrency = paymentAccount.getSingleTradeCurrency();
|
||||
List<TradeCurrency> tradeCurrencies = paymentAccount.getTradeCurrencies();
|
||||
if (singleTradeCurrency != null) {
|
||||
if (singleTradeCurrency instanceof FiatCurrency)
|
||||
preferences.addFiatCurrency((FiatCurrency) singleTradeCurrency);
|
||||
else
|
||||
preferences.addCryptoCurrency((CryptoCurrency) singleTradeCurrency);
|
||||
} else if (tradeCurrencies != null && !tradeCurrencies.isEmpty()) {
|
||||
tradeCurrencies.stream().forEach(tradeCurrency -> {
|
||||
if (tradeCurrency instanceof FiatCurrency)
|
||||
preferences.addFiatCurrency((FiatCurrency) tradeCurrency);
|
||||
else
|
||||
preferences.addCryptoCurrency((CryptoCurrency) tradeCurrency);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void onDeleteAccount(PaymentAccount paymentAccount) {
|
||||
|
@ -149,6 +149,7 @@ public class MarketsChartsView extends ActivatableViewAndModel<VBox, MarketsChar
|
||||
protected void deactivate() {
|
||||
model.getOfferBookListItems().removeListener(changeListener);
|
||||
tradeCurrencySubscriber.unsubscribe();
|
||||
currencyComboBox.setOnAction(null);
|
||||
}
|
||||
|
||||
|
||||
|
@ -36,7 +36,9 @@ import io.bitsquare.locale.Country;
|
||||
import io.bitsquare.locale.TradeCurrency;
|
||||
import io.bitsquare.p2p.P2PService;
|
||||
import io.bitsquare.payment.PaymentAccount;
|
||||
import io.bitsquare.payment.SameBankAccount;
|
||||
import io.bitsquare.payment.SepaAccount;
|
||||
import io.bitsquare.payment.SpecificBankAccount;
|
||||
import io.bitsquare.trade.handlers.TransactionResultHandler;
|
||||
import io.bitsquare.trade.offer.Offer;
|
||||
import io.bitsquare.trade.offer.OpenOfferManager;
|
||||
@ -242,6 +244,12 @@ class CreateOfferDataModel extends ActivatableDataModel {
|
||||
if (paymentAccount instanceof SepaAccount)
|
||||
acceptedCountryCodes.addAll(((SepaAccount) paymentAccount).getAcceptedCountryCodes());
|
||||
|
||||
ArrayList<String> acceptedBanks = new ArrayList<>();
|
||||
if (paymentAccount instanceof SpecificBankAccount)
|
||||
acceptedBanks.addAll(((SpecificBankAccount) paymentAccount).getAcceptedBanks());
|
||||
else if (paymentAccount instanceof SameBankAccount)
|
||||
acceptedBanks.add(((SameBankAccount) paymentAccount).getAcceptedBank());
|
||||
|
||||
// That is optional and set to null if not supported (AltCoins, OKPay,...)
|
||||
Country country = paymentAccount.getCountry();
|
||||
|
||||
@ -258,7 +266,8 @@ class CreateOfferDataModel extends ActivatableDataModel {
|
||||
country,
|
||||
paymentAccount.getId(),
|
||||
new ArrayList<>(user.getAcceptedArbitratorAddresses()),
|
||||
acceptedCountryCodes);
|
||||
acceptedCountryCodes,
|
||||
acceptedBanks);
|
||||
}
|
||||
|
||||
void onPlaceOffer(Offer offer, TransactionResultHandler resultHandler) {
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
package io.bitsquare.gui.main.offer.offerbook;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.inject.Inject;
|
||||
import io.bitsquare.app.Version;
|
||||
import io.bitsquare.btc.pricefeed.PriceFeed;
|
||||
@ -60,6 +61,7 @@ class OfferBookViewModel extends ActivatableViewModel {
|
||||
|
||||
private final FilteredList<OfferBookListItem> filteredItems;
|
||||
private final SortedList<OfferBookListItem> sortedItems;
|
||||
private final ListChangeListener<TradeCurrency> tradeCurrencyListChangeListener;
|
||||
private TradeCurrency selectedTradeCurrency;
|
||||
private final ObservableList<TradeCurrency> allTradeCurrencies = FXCollections.observableArrayList();
|
||||
|
||||
@ -106,13 +108,7 @@ class OfferBookViewModel extends ActivatableViewModel {
|
||||
selectedTradeCurrency = CurrencyUtil.getDefaultTradeCurrency();
|
||||
tradeCurrencyCode.set(selectedTradeCurrency.getCode());
|
||||
|
||||
preferences.getTradeCurrenciesAsObservable().addListener(new ListChangeListener<TradeCurrency>() {
|
||||
@Override
|
||||
public void onChanged(Change<? extends TradeCurrency> c) {
|
||||
fillAllTradeCurrencies();
|
||||
}
|
||||
});
|
||||
|
||||
tradeCurrencyListChangeListener = c -> fillAllTradeCurrencies();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -120,6 +116,7 @@ class OfferBookViewModel extends ActivatableViewModel {
|
||||
fillAllTradeCurrencies();
|
||||
btcCode.bind(preferences.btcDenominationProperty());
|
||||
offerBookListItems.addListener(listChangeListener);
|
||||
preferences.getTradeCurrenciesAsObservable().addListener(tradeCurrencyListChangeListener);
|
||||
offerBook.fillOfferBookListItems();
|
||||
filterList();
|
||||
setMarketPriceFeedCurrency();
|
||||
@ -130,6 +127,7 @@ class OfferBookViewModel extends ActivatableViewModel {
|
||||
protected void deactivate() {
|
||||
btcCode.unbind();
|
||||
offerBookListItems.removeListener(listChangeListener);
|
||||
preferences.getTradeCurrenciesAsObservable().removeListener(tradeCurrencyListChangeListener);
|
||||
}
|
||||
|
||||
private void fillAllTradeCurrencies() {
|
||||
@ -255,7 +253,7 @@ class OfferBookViewModel extends ActivatableViewModel {
|
||||
String result = "";
|
||||
if (item != null) {
|
||||
Offer offer = item.getOffer();
|
||||
String method = BSResources.get(offer.getPaymentMethod().getId());
|
||||
String method = BSResources.get(offer.getPaymentMethod().getId() + "_SHORT");
|
||||
String methodCountryCode = offer.getPaymentMethodCountryCode();
|
||||
|
||||
if (methodCountryCode != null)
|
||||
@ -279,11 +277,17 @@ class OfferBookViewModel extends ActivatableViewModel {
|
||||
result = method;
|
||||
|
||||
List<String> acceptedCountryCodes = offer.getAcceptedCountryCodes();
|
||||
if (acceptedCountryCodes != null && acceptedCountryCodes.size() > 0) {
|
||||
List<String> acceptedBanks = offer.getAcceptedBanks();
|
||||
if (acceptedCountryCodes != null && !acceptedCountryCodes.isEmpty()) {
|
||||
if (CountryUtil.containsAllSepaEuroCountries(acceptedCountryCodes))
|
||||
result += "\n\nAccepted takers seat of bank countries:\nAll Euro countries";
|
||||
else
|
||||
result += "\n\nAccepted taker seat of bank countries:\n" + CountryUtil.getNamesByCodesString(acceptedCountryCodes);
|
||||
} else if (acceptedBanks != null && !acceptedBanks.isEmpty()) {
|
||||
if (offer.getPaymentMethod().equals(PaymentMethod.SAME_BANK))
|
||||
result += "\n\nBank name: " + acceptedBanks.get(0);
|
||||
else if (offer.getPaymentMethod().equals(PaymentMethod.SPECIFIC_BANKS))
|
||||
result += "\n\nAccepted banks: " + Joiner.on(", ").join(acceptedBanks);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@ -303,7 +307,7 @@ class OfferBookViewModel extends ActivatableViewModel {
|
||||
}
|
||||
|
||||
boolean isPaymentAccountValidForOffer(Offer offer) {
|
||||
|
||||
// TODO not supporting yet check for acceptedBanks in cae of SpecificBankAccount and SameBankAccount
|
||||
Optional<TradeCurrency> result1 = user.getPaymentAccounts().stream()
|
||||
.filter(paymentAccount -> paymentAccount.getPaymentMethod().equals(offer.getPaymentMethod()))
|
||||
.filter(paymentAccount -> {
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
package io.bitsquare.gui.main.popups;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import io.bitsquare.arbitration.Dispute;
|
||||
import io.bitsquare.gui.util.BSFormatter;
|
||||
import io.bitsquare.gui.util.Layout;
|
||||
@ -24,6 +25,7 @@ import io.bitsquare.locale.BSResources;
|
||||
import io.bitsquare.locale.CountryUtil;
|
||||
import io.bitsquare.payment.BlockChainAccountContractData;
|
||||
import io.bitsquare.payment.PaymentAccountContractData;
|
||||
import io.bitsquare.payment.PaymentMethod;
|
||||
import io.bitsquare.trade.Contract;
|
||||
import io.bitsquare.trade.offer.Offer;
|
||||
import javafx.geometry.Insets;
|
||||
@ -35,6 +37,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import static io.bitsquare.gui.util.FormBuilder.*;
|
||||
@ -90,12 +93,19 @@ public class ContractPopup extends Popup {
|
||||
Contract contract = dispute.getContract();
|
||||
Offer offer = contract.offer;
|
||||
|
||||
List<String> acceptedBanks = offer.getAcceptedBanks();
|
||||
boolean showAcceptedBanks = acceptedBanks != null && !acceptedBanks.isEmpty();
|
||||
List<String> acceptedCountryCodes = offer.getAcceptedCountryCodes();
|
||||
boolean showAcceptedCountryCodes = acceptedCountryCodes != null && !acceptedCountryCodes.isEmpty();
|
||||
|
||||
int rows = 16;
|
||||
if (dispute.getDepositTxSerialized() != null)
|
||||
rows++;
|
||||
if (dispute.getPayoutTxSerialized() != null)
|
||||
rows++;
|
||||
if (offer.getAcceptedCountryCodes() != null)
|
||||
if (showAcceptedCountryCodes)
|
||||
rows++;
|
||||
if (showAcceptedBanks)
|
||||
rows++;
|
||||
|
||||
boolean isPaymentIdAvailable = false;
|
||||
@ -130,20 +140,31 @@ public class ContractPopup extends Popup {
|
||||
addLabelTextField(gridPane, ++rowIndex, "Seller payment ID:",
|
||||
((BlockChainAccountContractData) sellerPaymentAccountContractData).getPaymentId());
|
||||
|
||||
if (offer.getAcceptedCountryCodes() != null && !offer.getAcceptedCountryCodes().isEmpty()) {
|
||||
if (showAcceptedCountryCodes) {
|
||||
String countries;
|
||||
Tooltip tooltip = null;
|
||||
if (CountryUtil.containsAllSepaEuroCountries(offer.getAcceptedCountryCodes())) {
|
||||
if (CountryUtil.containsAllSepaEuroCountries(acceptedCountryCodes)) {
|
||||
countries = "All Euro countries";
|
||||
} else {
|
||||
countries = CountryUtil.getCodesString(offer.getAcceptedCountryCodes());
|
||||
tooltip = new Tooltip(CountryUtil.getNamesByCodesString(offer.getAcceptedCountryCodes()));
|
||||
countries = CountryUtil.getCodesString(acceptedCountryCodes);
|
||||
tooltip = new Tooltip(CountryUtil.getNamesByCodesString(acceptedCountryCodes));
|
||||
}
|
||||
TextField acceptedCountries = addLabelTextField(gridPane, ++rowIndex, "Accepted taker countries:", countries).second;
|
||||
if (tooltip != null) acceptedCountries.setTooltip(new Tooltip());
|
||||
}
|
||||
//addLabelTextField(gridPane, ++rowIndex, "Buyer Bitsquare account ID:", contract.getBuyerAccountId()).second.setMouseTransparent(false);
|
||||
//addLabelTextField(gridPane, ++rowIndex, "Seller Bitsquare account ID:", contract.getSellerAccountId()).second.setMouseTransparent(false);
|
||||
|
||||
if (showAcceptedBanks) {
|
||||
if (offer.getPaymentMethod().equals(PaymentMethod.SAME_BANK)) {
|
||||
addLabelTextField(gridPane, ++rowIndex, "Bank name:", acceptedBanks.get(0));
|
||||
} else if (offer.getPaymentMethod().equals(PaymentMethod.SPECIFIC_BANKS)) {
|
||||
String value = Joiner.on(", ").join(acceptedBanks);
|
||||
Tooltip tooltip = new Tooltip("Accepted banks: " + value);
|
||||
TextField acceptedBanksTextField = addLabelTextField(gridPane, ++rowIndex, "Accepted banks:", value).second;
|
||||
acceptedBanksTextField.setMouseTransparent(false);
|
||||
acceptedBanksTextField.setTooltip(tooltip);
|
||||
}
|
||||
}
|
||||
|
||||
addLabelTxIdTextField(gridPane, ++rowIndex, "Offer fee transaction ID:", offer.getOfferFeePaymentTxID());
|
||||
addLabelTxIdTextField(gridPane, ++rowIndex, "Trading fee transaction ID:", contract.takeOfferFeeTxID);
|
||||
if (dispute.getDepositTxSerialized() != null)
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
package io.bitsquare.gui.main.popups;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import io.bitsquare.common.crypto.KeyRing;
|
||||
import io.bitsquare.common.util.Tuple2;
|
||||
import io.bitsquare.gui.Navigation;
|
||||
@ -28,6 +29,7 @@ import io.bitsquare.gui.util.BSFormatter;
|
||||
import io.bitsquare.gui.util.Layout;
|
||||
import io.bitsquare.locale.BSResources;
|
||||
import io.bitsquare.locale.CountryUtil;
|
||||
import io.bitsquare.payment.PaymentMethod;
|
||||
import io.bitsquare.trade.offer.Offer;
|
||||
import io.bitsquare.user.Preferences;
|
||||
import io.bitsquare.user.User;
|
||||
@ -41,6 +43,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@ -134,8 +137,18 @@ public class OfferDetailsPopup extends Popup {
|
||||
|
||||
private void addContent() {
|
||||
int rows = 5;
|
||||
|
||||
List<String> acceptedBanks = offer.getAcceptedBanks();
|
||||
boolean showAcceptedBanks = acceptedBanks != null && !acceptedBanks.isEmpty();
|
||||
List<String> acceptedCountryCodes = offer.getAcceptedCountryCodes();
|
||||
boolean showAcceptedCountryCodes = acceptedCountryCodes != null && !acceptedCountryCodes.isEmpty();
|
||||
|
||||
if (!takeOfferHandlerOptional.isPresent())
|
||||
rows++;
|
||||
if (showAcceptedBanks)
|
||||
rows++;
|
||||
if (showAcceptedCountryCodes)
|
||||
rows++;
|
||||
|
||||
addTitledGroupBg(gridPane, ++rowIndex, rows, "Offer");
|
||||
|
||||
@ -154,22 +167,46 @@ public class OfferDetailsPopup extends Popup {
|
||||
addLabelTextField(gridPane, ++rowIndex, "Price:", formatter.formatFiat(offer.getPrice()) + " " + offer.getCurrencyCode() + "/" + "BTC");
|
||||
|
||||
addLabelTextField(gridPane, ++rowIndex, "Currency:", offer.getCurrencyCode());
|
||||
|
||||
|
||||
if (offer.isMyOffer(keyRing) && user.getPaymentAccount(offer.getOffererPaymentAccountId()) != null)
|
||||
addLabelTextField(gridPane, ++rowIndex, "Payment account:", user.getPaymentAccount(offer.getOffererPaymentAccountId()).getAccountName());
|
||||
else
|
||||
addLabelTextField(gridPane, ++rowIndex, "Payment method:", BSResources.get(offer.getPaymentMethod().getId()));
|
||||
|
||||
if (showAcceptedBanks) {
|
||||
if (offer.getPaymentMethod().equals(PaymentMethod.SAME_BANK)) {
|
||||
addLabelTextField(gridPane, ++rowIndex, "Bank name:", acceptedBanks.get(0));
|
||||
} else if (offer.getPaymentMethod().equals(PaymentMethod.SPECIFIC_BANKS)) {
|
||||
String value = Joiner.on(", ").join(acceptedBanks);
|
||||
Tooltip tooltip = new Tooltip("Accepted banks: " + value);
|
||||
TextField acceptedBanksTextField = addLabelTextField(gridPane, ++rowIndex, "Accepted banks:", value).second;
|
||||
acceptedBanksTextField.setMouseTransparent(false);
|
||||
acceptedBanksTextField.setTooltip(tooltip);
|
||||
}
|
||||
}
|
||||
|
||||
if (showAcceptedCountryCodes) {
|
||||
String countries;
|
||||
Tooltip tooltip = null;
|
||||
if (CountryUtil.containsAllSepaEuroCountries(acceptedCountryCodes)) {
|
||||
countries = "All Euro countries";
|
||||
} else {
|
||||
countries = CountryUtil.getCodesString(acceptedCountryCodes);
|
||||
tooltip = new Tooltip(CountryUtil.getNamesByCodesString(acceptedCountryCodes));
|
||||
}
|
||||
TextField acceptedCountries = addLabelTextField(gridPane, ++rowIndex, "Accepted taker countries:", countries).second;
|
||||
if (tooltip != null) {
|
||||
acceptedCountries.setMouseTransparent(false);
|
||||
acceptedCountries.setTooltip(tooltip);
|
||||
}
|
||||
}
|
||||
|
||||
rows = 3;
|
||||
String paymentMethodCountryCode = offer.getPaymentMethodCountryCode();
|
||||
if (paymentMethodCountryCode != null)
|
||||
rows++;
|
||||
if (offer.getOfferFeePaymentTxID() != null)
|
||||
rows++;
|
||||
if (offer.getAcceptedCountryCodes() != null)
|
||||
rows++;
|
||||
/* if (placeOfferHandlerOptional.isPresent())
|
||||
rows -= 2;*/
|
||||
|
||||
addTitledGroupBg(gridPane, ++rowIndex, rows, "Details", Layout.GROUP_DISTANCE);
|
||||
addLabelTextField(gridPane, rowIndex, "Offer ID:", offer.getId(), Layout.FIRST_ROW_AND_GROUP_DISTANCE);
|
||||
@ -178,21 +215,7 @@ public class OfferDetailsPopup extends Popup {
|
||||
if (paymentMethodCountryCode != null)
|
||||
addLabelTextField(gridPane, ++rowIndex, "Offerers country of bank:",
|
||||
CountryUtil.getNameAndCode(paymentMethodCountryCode));
|
||||
if (offer.getAcceptedCountryCodes() != null) {
|
||||
String countries;
|
||||
Tooltip tooltip = null;
|
||||
if (CountryUtil.containsAllSepaEuroCountries(offer.getAcceptedCountryCodes())) {
|
||||
countries = "All Euro countries";
|
||||
} else {
|
||||
countries = CountryUtil.getCodesString(offer.getAcceptedCountryCodes());
|
||||
tooltip = new Tooltip(CountryUtil.getNamesByCodesString(offer.getAcceptedCountryCodes()));
|
||||
}
|
||||
TextField acceptedCountries = addLabelTextField(gridPane, ++rowIndex, "Accepted taker countries:", countries).second;
|
||||
if (tooltip != null) {
|
||||
acceptedCountries.setMouseTransparent(false);
|
||||
acceptedCountries.setTooltip(tooltip);
|
||||
}
|
||||
}
|
||||
|
||||
addLabelTextField(gridPane, ++rowIndex, "Accepted arbitrators:", formatter.arbitratorAddressesToString(offer.getArbitratorNodeAddresses()));
|
||||
if (offer.getOfferFeePaymentTxID() != null)
|
||||
addLabelTxIdTextField(gridPane, ++rowIndex, "Offer fee transaction ID:", offer.getOfferFeePaymentTxID());
|
||||
|
@ -123,8 +123,10 @@ public class TradeDetailsPopup extends Popup {
|
||||
PaymentAccountContractData buyerPaymentAccountContractData = null;
|
||||
PaymentAccountContractData sellerPaymentAccountContractData = null;
|
||||
|
||||
if (offer.getAcceptedCountryCodes() != null)
|
||||
/* if (offer.getAcceptedCountryCodes() != null)
|
||||
rows++;
|
||||
if (offer.getAcceptedBanks() != null)
|
||||
rows++;*/
|
||||
|
||||
if (contract != null) {
|
||||
rows++;
|
||||
|
@ -112,7 +112,7 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
|
||||
if (selectedItem != null)
|
||||
tradeStateSubscription = EasyBind.subscribe(selectedItem.getTrade().stateProperty(), this::onTradeStateChanged);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void deactivate() {
|
||||
if (tradeStateSubscription != null) {
|
||||
@ -185,7 +185,7 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
|
||||
String result = "";
|
||||
if (item != null) {
|
||||
Offer offer = item.getTrade().getOffer();
|
||||
String method = BSResources.get(offer.getPaymentMethod().getId());
|
||||
String method = BSResources.get(offer.getPaymentMethod().getId() + "_SHORT");
|
||||
String methodCountryCode = offer.getPaymentMethodCountryCode();
|
||||
|
||||
if (methodCountryCode != null)
|
||||
|
@ -25,6 +25,6 @@
|
||||
AnchorPane.rightAnchor="0" AnchorPane.topAnchor="0"
|
||||
xmlns:fx="http://javafx.com/fxml">
|
||||
|
||||
<Tab fx:id="networkSettingsTab" text="Network info" closable="false"/>
|
||||
<Tab fx:id="preferencesTab" text="Preferences" closable="false"/>
|
||||
<Tab fx:id="networkSettingsTab" text="Network info" closable="false"/>
|
||||
</TabPane>
|
||||
|
@ -80,6 +80,7 @@ public class NetworkSettingsView extends ActivatableViewAndModel<GridPane, Activ
|
||||
@Inject
|
||||
public NetworkSettingsView(WalletService walletService, P2PService p2PService, Preferences preferences, Clock clock,
|
||||
BSFormatter formatter) {
|
||||
super();
|
||||
this.walletService = walletService;
|
||||
this.p2PService = p2PService;
|
||||
this.preferences = preferences;
|
||||
|
@ -1,75 +0,0 @@
|
||||
/*
|
||||
* This file is part of Bitsquare.
|
||||
*
|
||||
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.gui.main.settings.preferences;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import io.bitsquare.gui.common.model.ActivatableDataModel;
|
||||
import io.bitsquare.user.Preferences;
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
|
||||
class PreferencesDataModel extends ActivatableDataModel {
|
||||
|
||||
private final Preferences preferences;
|
||||
|
||||
private final ChangeListener<Boolean> useAnimationsListener;
|
||||
private final ChangeListener<Boolean> useEffectsListener;
|
||||
private final ChangeListener<String> btcDenominationListener;
|
||||
|
||||
private final ObservableList<String> btcDenominations;
|
||||
|
||||
private final BooleanProperty useAnimations = new SimpleBooleanProperty();
|
||||
private final BooleanProperty useEffects = new SimpleBooleanProperty();
|
||||
private final StringProperty btcDenomination = new SimpleStringProperty();
|
||||
|
||||
|
||||
@Inject
|
||||
public PreferencesDataModel(Preferences preferences) {
|
||||
this.preferences = preferences;
|
||||
|
||||
btcDenominations = FXCollections.observableArrayList(Preferences.getBtcDenominations());
|
||||
btcDenominationListener = (ov, oldValue, newValue) -> preferences.setBtcDenomination(newValue);
|
||||
useAnimationsListener = (ov, oldValue, newValue) -> preferences.setUseAnimations(newValue);
|
||||
useEffectsListener = (ov, oldValue, newValue) -> preferences.setUseEffects(newValue);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void activate() {
|
||||
useAnimations.set(preferences.getUseAnimations());
|
||||
useEffects.set(preferences.getUseEffects());
|
||||
btcDenomination.set(preferences.getBtcDenomination());
|
||||
|
||||
useAnimations.addListener(useAnimationsListener);
|
||||
useEffects.addListener(useEffectsListener);
|
||||
btcDenomination.addListener(btcDenominationListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void deactivate() {
|
||||
useAnimations.removeListener(useAnimationsListener);
|
||||
useEffects.removeListener(useEffectsListener);
|
||||
btcDenomination.removeListener(btcDenominationListener);
|
||||
}
|
||||
}
|
||||
|
@ -32,5 +32,7 @@
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" halignment="RIGHT" minWidth="140.0"/>
|
||||
<ColumnConstraints hgrow="ALWAYS" minWidth="300.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" halignment="RIGHT" minWidth="140.0"/>
|
||||
<ColumnConstraints hgrow="ALWAYS" minWidth="300.0"/>
|
||||
</columnConstraints>
|
||||
</GridPane>
|
@ -17,30 +17,44 @@
|
||||
|
||||
package io.bitsquare.gui.main.settings.preferences;
|
||||
|
||||
import io.bitsquare.common.UserThread;
|
||||
import io.bitsquare.common.util.Tuple2;
|
||||
import io.bitsquare.gui.common.model.Activatable;
|
||||
import io.bitsquare.gui.common.view.ActivatableViewAndModel;
|
||||
import io.bitsquare.gui.common.view.FxmlView;
|
||||
import io.bitsquare.gui.components.TitledGroupBg;
|
||||
import io.bitsquare.gui.main.popups.Popup;
|
||||
import io.bitsquare.gui.util.ImageUtil;
|
||||
import io.bitsquare.gui.util.Layout;
|
||||
import io.bitsquare.locale.LanguageUtil;
|
||||
import io.bitsquare.locale.TradeCurrency;
|
||||
import io.bitsquare.locale.*;
|
||||
import io.bitsquare.user.BlockChainExplorer;
|
||||
import io.bitsquare.user.Preferences;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.scene.control.CheckBox;
|
||||
import javafx.scene.control.ComboBox;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.VPos;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.util.Callback;
|
||||
import javafx.util.StringConverter;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Locale;
|
||||
|
||||
import static io.bitsquare.gui.util.FormBuilder.*;
|
||||
|
||||
@FxmlView
|
||||
public class PreferencesView extends ActivatableViewAndModel<GridPane, PreferencesViewModel> {
|
||||
public class PreferencesView extends ActivatableViewAndModel<GridPane, Activatable> {
|
||||
|
||||
// not supported yet
|
||||
//private ComboBox<String> btcDenominationComboBox;
|
||||
private ComboBox<BlockChainExplorer> blockChainExplorerComboBox;
|
||||
private ComboBox<String> languageComboBox;
|
||||
private ComboBox<String> userLanguageComboBox;
|
||||
private ComboBox<TradeCurrency> preferredTradeCurrencyComboBox;
|
||||
|
||||
private CheckBox useAnimationsCheckBox, useEffectsCheckBox, showNotificationsCheckBox, showInstructionsCheckBox,
|
||||
@ -50,43 +64,76 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Preferenc
|
||||
private ChangeListener<Boolean> transactionFeeFocusedListener;
|
||||
private final Preferences preferences;
|
||||
|
||||
private ListView<FiatCurrency> fiatCurrenciesListView;
|
||||
private ComboBox<FiatCurrency> fiatCurrenciesComboBox;
|
||||
private ListView<CryptoCurrency> cryptoCurrenciesListView;
|
||||
private ComboBox<CryptoCurrency> cryptoCurrenciesComboBox;
|
||||
// private ListChangeListener<TradeCurrency> displayCurrenciesListChangeListener;
|
||||
final ObservableList<String> btcDenominations = FXCollections.observableArrayList(Preferences.getBtcDenominations());
|
||||
final ObservableList<BlockChainExplorer> blockExplorers;
|
||||
final ObservableList<String> languageCodes;
|
||||
final StringProperty transactionFeePerByte = new SimpleStringProperty();
|
||||
public final ObservableList<FiatCurrency> fiatCurrencies;
|
||||
public final ObservableList<FiatCurrency> allFiatCurrencies;
|
||||
public final ObservableList<CryptoCurrency> cryptoCurrencies;
|
||||
public final ObservableList<CryptoCurrency> allCryptoCurrencies;
|
||||
public final ObservableList<TradeCurrency> tradeCurrencies;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor, initialisation
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Inject
|
||||
public PreferencesView(PreferencesViewModel model, Preferences preferences) {
|
||||
super(model);
|
||||
public PreferencesView(Preferences preferences) {
|
||||
super();
|
||||
this.preferences = preferences;
|
||||
|
||||
blockExplorers = FXCollections.observableArrayList(preferences.getBlockChainExplorers());
|
||||
languageCodes = FXCollections.observableArrayList(LanguageUtil.getAllLanguageCodes());
|
||||
fiatCurrencies = preferences.getFiatCurrenciesAsObservable();
|
||||
cryptoCurrencies = preferences.getCryptoCurrenciesAsObservable();
|
||||
tradeCurrencies = preferences.getTradeCurrenciesAsObservable();
|
||||
|
||||
allFiatCurrencies = FXCollections.observableArrayList(CurrencyUtil.getAllSortedFiatCurrencies());
|
||||
allCryptoCurrencies = FXCollections.observableArrayList(CurrencyUtil.getAllSortedCryptoCurrencies());
|
||||
|
||||
allFiatCurrencies.removeAll(fiatCurrencies);
|
||||
allCryptoCurrencies.removeAll(cryptoCurrencies);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
addTitledGroupBg(root, gridRow, 4, "Preferences");
|
||||
preferredTradeCurrencyComboBox = addLabelComboBox(root, gridRow, "Preferred currency:", Layout.FIRST_ROW_DISTANCE).second;
|
||||
languageComboBox = addLabelComboBox(root, ++gridRow, "Language:").second;
|
||||
// btcDenominationComboBox = addLabelComboBox(root, ++gridRow, "Bitcoin denomination:").second;
|
||||
blockChainExplorerComboBox = addLabelComboBox(root, ++gridRow, "Bitcoin block explorer:").second;
|
||||
autoSelectArbitratorsCheckBox = addLabelCheckBox(root, ++gridRow, "Auto select arbitrators by language:", "").second;
|
||||
|
||||
// TODO need a bit extra work to separate trade and non trade tx fees before it can be used
|
||||
/*transactionFeeInputTextField = addLabelInputTextField(root, ++gridRow, "Transaction fee (satoshi/byte):").second;
|
||||
transactionFeeFocusedListener = (o, oldValue, newValue) -> {
|
||||
model.onFocusOutTransactionFeeTextField(oldValue, newValue);
|
||||
};*/
|
||||
|
||||
addTitledGroupBg(root, ++gridRow, 4, "Display options", Layout.GROUP_DISTANCE);
|
||||
useAnimationsCheckBox = addLabelCheckBox(root, gridRow, "Use animations:", "", Layout.FIRST_ROW_AND_GROUP_DISTANCE).second;
|
||||
useEffectsCheckBox = addLabelCheckBox(root, ++gridRow, "Use effects:", "").second;
|
||||
showNotificationsCheckBox = addLabelCheckBox(root, ++gridRow, "Show notifications:", "").second;
|
||||
showInstructionsCheckBox = addLabelCheckBox(root, ++gridRow, "Show instruction popups:", "").second;
|
||||
initializeDisplayCurrencies();
|
||||
initializeOtherOptions();
|
||||
initializeDisplayOptions();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void activate() {
|
||||
/* btcDenominationComboBox.setDisable(true);
|
||||
btcDenominationComboBox.setItems(model.btcDenominations);
|
||||
btcDenominationComboBox.getSelectionModel().select(model.getBtcDenomination());
|
||||
btcDenominationComboBox.setOnAction(e -> model.onSelectBtcDenomination(btcDenominationComboBox.getSelectionModel().getSelectedItem()));*/
|
||||
activateDisplayCurrencies();
|
||||
activateOtherOptions();
|
||||
activateDisplayPreferences();
|
||||
}
|
||||
|
||||
preferredTradeCurrencyComboBox.setItems(model.tradeCurrencies);
|
||||
preferredTradeCurrencyComboBox.getSelectionModel().select(preferences.getPreferredTradeCurrency());
|
||||
@Override
|
||||
protected void deactivate() {
|
||||
deactivateDisplayCurrencies();
|
||||
deactivateOtherOptions();
|
||||
deactivateDisplayPreferences();
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Initialize
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private void initializeDisplayCurrencies() {
|
||||
TitledGroupBg titledGroupBg = addTitledGroupBg(root, gridRow, 3, "Currencies");
|
||||
GridPane.setColumnSpan(titledGroupBg, 4);
|
||||
|
||||
preferredTradeCurrencyComboBox = addLabelComboBox(root, gridRow, "Preferred currency:", Layout.FIRST_ROW_DISTANCE).second;
|
||||
preferredTradeCurrencyComboBox.setConverter(new StringConverter<TradeCurrency>() {
|
||||
@Override
|
||||
public String toString(TradeCurrency tradeCurrency) {
|
||||
@ -98,11 +145,224 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Preferenc
|
||||
return null;
|
||||
}
|
||||
});
|
||||
preferredTradeCurrencyComboBox.setOnAction(e -> preferences.setPreferredTradeCurrency(preferredTradeCurrencyComboBox.getSelectionModel().getSelectedItem()));
|
||||
|
||||
languageComboBox.setItems(model.languageCodes);
|
||||
languageComboBox.getSelectionModel().select(model.getLanguageCode());
|
||||
languageComboBox.setConverter(new StringConverter<String>() {
|
||||
Tuple2<Label, ListView> fiatTuple = addLabelListView(root, ++gridRow, "Display national currencies:");
|
||||
GridPane.setValignment(fiatTuple.first, VPos.TOP);
|
||||
fiatCurrenciesListView = fiatTuple.second;
|
||||
fiatCurrenciesListView.setMinHeight(2 * Layout.LIST_ROW_HEIGHT + 2);
|
||||
fiatCurrenciesListView.setMaxHeight(6 * Layout.LIST_ROW_HEIGHT + 2);
|
||||
Label placeholder = new Label("There are no national currencies selected");
|
||||
placeholder.setWrapText(true);
|
||||
fiatCurrenciesListView.setPlaceholder(placeholder);
|
||||
fiatCurrenciesListView.setCellFactory(new Callback<ListView<FiatCurrency>, ListCell<FiatCurrency>>() {
|
||||
@Override
|
||||
public ListCell<FiatCurrency> call(ListView<FiatCurrency> list) {
|
||||
return new ListCell<FiatCurrency>() {
|
||||
final Label label = new Label();
|
||||
final ImageView icon = ImageUtil.getImageViewById(ImageUtil.REMOVE_ICON);
|
||||
final Button removeButton = new Button("", icon);
|
||||
final AnchorPane pane = new AnchorPane(label, removeButton);
|
||||
|
||||
{
|
||||
label.setLayoutY(5);
|
||||
removeButton.setId("icon-button");
|
||||
AnchorPane.setRightAnchor(removeButton, 0d);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateItem(final FiatCurrency item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
if (item != null && !empty) {
|
||||
label.setText(item.getNameAndCode());
|
||||
removeButton.setOnAction(e -> {
|
||||
if (item.equals(preferences.getPreferredTradeCurrency())) {
|
||||
new Popup().warning("You cannot remove your selected preferred display currency").show();
|
||||
} else {
|
||||
preferences.removeFiatCurrency(item);
|
||||
if (!allFiatCurrencies.contains(item))
|
||||
allFiatCurrencies.add(item);
|
||||
}
|
||||
});
|
||||
setGraphic(pane);
|
||||
} else {
|
||||
setGraphic(null);
|
||||
removeButton.setOnAction(null);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
Tuple2<Label, ListView> cryptoCurrenciesTuple = addLabelListView(root, gridRow, "Display crypto currencies:");
|
||||
GridPane.setValignment(cryptoCurrenciesTuple.first, VPos.TOP);
|
||||
GridPane.setMargin(cryptoCurrenciesTuple.first, new Insets(0, 0, 0, 20));
|
||||
cryptoCurrenciesListView = cryptoCurrenciesTuple.second;
|
||||
GridPane.setColumnIndex(cryptoCurrenciesTuple.first, 2);
|
||||
GridPane.setColumnIndex(cryptoCurrenciesListView, 3);
|
||||
cryptoCurrenciesListView.setMinHeight(2 * Layout.LIST_ROW_HEIGHT + 2);
|
||||
cryptoCurrenciesListView.setMaxHeight(6 * Layout.LIST_ROW_HEIGHT + 2);
|
||||
placeholder = new Label("There are no crypto currencies selected");
|
||||
placeholder.setWrapText(true);
|
||||
cryptoCurrenciesListView.setPlaceholder(placeholder);
|
||||
cryptoCurrenciesListView.setCellFactory(new Callback<ListView<CryptoCurrency>, ListCell<CryptoCurrency>>() {
|
||||
@Override
|
||||
public ListCell<CryptoCurrency> call(ListView<CryptoCurrency> list) {
|
||||
return new ListCell<CryptoCurrency>() {
|
||||
final Label label = new Label();
|
||||
final ImageView icon = ImageUtil.getImageViewById(ImageUtil.REMOVE_ICON);
|
||||
final Button removeButton = new Button("", icon);
|
||||
final AnchorPane pane = new AnchorPane(label, removeButton);
|
||||
|
||||
{
|
||||
label.setLayoutY(5);
|
||||
removeButton.setId("icon-button");
|
||||
AnchorPane.setRightAnchor(removeButton, 0d);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateItem(final CryptoCurrency item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
if (item != null && !empty) {
|
||||
label.setText(item.getNameAndCode());
|
||||
removeButton.setOnAction(e -> {
|
||||
if (item.equals(preferences.getPreferredTradeCurrency())) {
|
||||
new Popup().warning("You cannot remove your selected preferred display currency").show();
|
||||
} else {
|
||||
preferences.removeCryptoCurrency(item);
|
||||
if (!allCryptoCurrencies.contains(item))
|
||||
allCryptoCurrencies.add(item);
|
||||
}
|
||||
});
|
||||
setGraphic(pane);
|
||||
} else {
|
||||
setGraphic(null);
|
||||
removeButton.setOnAction(null);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
fiatCurrenciesComboBox = addLabelComboBox(root, ++gridRow).second;
|
||||
fiatCurrenciesComboBox.setPromptText("Add national currency");
|
||||
fiatCurrenciesComboBox.setConverter(new StringConverter<FiatCurrency>() {
|
||||
@Override
|
||||
public String toString(FiatCurrency tradeCurrency) {
|
||||
return tradeCurrency.getNameAndCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FiatCurrency fromString(String s) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
Tuple2<Label, ComboBox> labelComboBoxTuple2 = addLabelComboBox(root, gridRow);
|
||||
cryptoCurrenciesComboBox = labelComboBoxTuple2.second;
|
||||
GridPane.setColumnIndex(cryptoCurrenciesComboBox, 3);
|
||||
cryptoCurrenciesComboBox.setPromptText("Add crypto currency");
|
||||
cryptoCurrenciesComboBox.setConverter(new StringConverter<CryptoCurrency>() {
|
||||
@Override
|
||||
public String toString(CryptoCurrency tradeCurrency) {
|
||||
return tradeCurrency.getNameAndCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CryptoCurrency fromString(String s) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void initializeOtherOptions() {
|
||||
TitledGroupBg titledGroupBg = addTitledGroupBg(root, ++gridRow, 3, "Options", Layout.GROUP_DISTANCE);
|
||||
GridPane.setColumnSpan(titledGroupBg, 4);
|
||||
userLanguageComboBox = addLabelComboBox(root, gridRow, "Language:", Layout.FIRST_ROW_AND_GROUP_DISTANCE).second;
|
||||
// btcDenominationComboBox = addLabelComboBox(root, ++gridRow, "Bitcoin denomination:").second;
|
||||
blockChainExplorerComboBox = addLabelComboBox(root, ++gridRow, "Bitcoin block explorer:").second;
|
||||
autoSelectArbitratorsCheckBox = addLabelCheckBox(root, ++gridRow, "Auto select arbitrators:", "").second;
|
||||
|
||||
// TODO need a bit extra work to separate trade and non trade tx fees before it can be used
|
||||
/*transactionFeeInputTextField = addLabelInputTextField(root, ++gridRow, "Transaction fee (satoshi/byte):").second;
|
||||
transactionFeeFocusedListener = (o, oldValue, newValue) -> {
|
||||
onFocusOutTransactionFeeTextField(oldValue, newValue);
|
||||
};*/
|
||||
}
|
||||
|
||||
private void initializeDisplayOptions() {
|
||||
TitledGroupBg titledGroupBg = addTitledGroupBg(root, ++gridRow, 4, "Display options", Layout.GROUP_DISTANCE);
|
||||
GridPane.setColumnSpan(titledGroupBg, 4);
|
||||
useAnimationsCheckBox = addLabelCheckBox(root, gridRow, "Use animations:", "", Layout.FIRST_ROW_AND_GROUP_DISTANCE).second;
|
||||
Tuple2<Label, CheckBox> labelCheckBoxTuple2 = addLabelCheckBox(root, gridRow, "Show notifications:", "", Layout.FIRST_ROW_AND_GROUP_DISTANCE);
|
||||
showNotificationsCheckBox = labelCheckBoxTuple2.second;
|
||||
GridPane.setColumnIndex(labelCheckBoxTuple2.first, 2);
|
||||
GridPane.setColumnIndex(showNotificationsCheckBox, 3);
|
||||
|
||||
useEffectsCheckBox = addLabelCheckBox(root, ++gridRow, "Use effects:", "").second;
|
||||
labelCheckBoxTuple2 = addLabelCheckBox(root, gridRow, "Show instruction popups:", "");
|
||||
showInstructionsCheckBox = labelCheckBoxTuple2.second;
|
||||
GridPane.setColumnIndex(labelCheckBoxTuple2.first, 2);
|
||||
GridPane.setColumnIndex(showInstructionsCheckBox, 3);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Activate
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
private void activateDisplayCurrencies() {
|
||||
preferredTradeCurrencyComboBox.setItems(tradeCurrencies);
|
||||
preferredTradeCurrencyComboBox.getSelectionModel().select(preferences.getPreferredTradeCurrency());
|
||||
preferredTradeCurrencyComboBox.setOnAction(e -> {
|
||||
TradeCurrency selectedItem = preferredTradeCurrencyComboBox.getSelectionModel().getSelectedItem();
|
||||
if (selectedItem != null)
|
||||
preferences.setPreferredTradeCurrency(selectedItem);
|
||||
});
|
||||
|
||||
fiatCurrenciesComboBox.setItems(allFiatCurrencies);
|
||||
fiatCurrenciesListView.setItems(fiatCurrencies);
|
||||
fiatCurrenciesComboBox.setOnAction(e -> {
|
||||
FiatCurrency selectedItem = fiatCurrenciesComboBox.getSelectionModel().getSelectedItem();
|
||||
log.error("setOnAction " + selectedItem);
|
||||
if (selectedItem != null) {
|
||||
preferences.addFiatCurrency(selectedItem);
|
||||
if (allFiatCurrencies.contains(selectedItem)) {
|
||||
UserThread.execute(() -> {
|
||||
fiatCurrenciesComboBox.getSelectionModel().clearSelection();
|
||||
allFiatCurrencies.remove(selectedItem);
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
cryptoCurrenciesComboBox.setItems(allCryptoCurrencies);
|
||||
cryptoCurrenciesListView.setItems(cryptoCurrencies);
|
||||
cryptoCurrenciesComboBox.setOnAction(e -> {
|
||||
CryptoCurrency selectedItem = cryptoCurrenciesComboBox.getSelectionModel().getSelectedItem();
|
||||
if (selectedItem != null) {
|
||||
preferences.addCryptoCurrency(selectedItem);
|
||||
if (allCryptoCurrencies.contains(selectedItem)) {
|
||||
UserThread.execute(() -> {
|
||||
cryptoCurrenciesComboBox.getSelectionModel().clearSelection();
|
||||
allCryptoCurrencies.remove(selectedItem);
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void activateOtherOptions() {
|
||||
transactionFeePerByte.set(String.valueOf(preferences.getTxFeePerKB() / 1000));
|
||||
|
||||
/* btcDenominationComboBox.setDisable(true);
|
||||
btcDenominationComboBox.setItems(btcDenominations);
|
||||
btcDenominationComboBox.getSelectionModel().select(getBtcDenomination());
|
||||
btcDenominationComboBox.setOnAction(e -> onSelectBtcDenomination(btcDenominationComboBox.getSelectionModel().getSelectedItem()));*/
|
||||
|
||||
userLanguageComboBox.setItems(languageCodes);
|
||||
userLanguageComboBox.getSelectionModel().select(preferences.getPreferredLocale().getLanguage());
|
||||
userLanguageComboBox.setConverter(new StringConverter<String>() {
|
||||
@Override
|
||||
public String toString(String code) {
|
||||
return LanguageUtil.getDisplayName(code);
|
||||
@ -113,10 +373,13 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Preferenc
|
||||
return null;
|
||||
}
|
||||
});
|
||||
languageComboBox.setOnAction(e -> model.onSelectLanguageCode(languageComboBox.getSelectionModel().getSelectedItem()));
|
||||
userLanguageComboBox.setOnAction(e -> {
|
||||
String code = userLanguageComboBox.getSelectionModel().getSelectedItem();
|
||||
preferences.setPreferredLocale(new Locale(code, preferences.getPreferredLocale().getCountry()));
|
||||
});
|
||||
|
||||
|
||||
blockChainExplorerComboBox.setItems(model.blockExplorers);
|
||||
blockChainExplorerComboBox.setItems(blockExplorers);
|
||||
blockChainExplorerComboBox.getSelectionModel().select(preferences.getBlockChainExplorer());
|
||||
blockChainExplorerComboBox.setConverter(new StringConverter<BlockChainExplorer>() {
|
||||
@Override
|
||||
@ -131,9 +394,11 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Preferenc
|
||||
});
|
||||
blockChainExplorerComboBox.setOnAction(e -> preferences.setBlockChainExplorer(blockChainExplorerComboBox.getSelectionModel().getSelectedItem()));
|
||||
|
||||
// transactionFeeInputTextField.textProperty().bindBidirectional(model.transactionFeePerByte);
|
||||
// transactionFeeInputTextField.textProperty().bindBidirectional(transactionFeePerByte);
|
||||
// transactionFeeInputTextField.focusedProperty().addListener(transactionFeeFocusedListener);
|
||||
}
|
||||
|
||||
private void activateDisplayPreferences() {
|
||||
useAnimationsCheckBox.setSelected(preferences.getUseAnimations());
|
||||
useAnimationsCheckBox.setOnAction(e -> preferences.setUseAnimations(useAnimationsCheckBox.isSelected()));
|
||||
|
||||
@ -150,18 +415,30 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Preferenc
|
||||
autoSelectArbitratorsCheckBox.setOnAction(e -> preferences.setAutoSelectArbitrators(autoSelectArbitratorsCheckBox.isSelected()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void deactivate() {
|
||||
//btcDenominationComboBox.setOnAction(null);
|
||||
languageComboBox.setOnAction(null);
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Deactivate
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private void deactivateDisplayCurrencies() {
|
||||
preferredTradeCurrencyComboBox.setOnAction(null);
|
||||
}
|
||||
|
||||
private void deactivateOtherOptions() {
|
||||
//btcDenominationComboBox.setOnAction(null);
|
||||
userLanguageComboBox.setOnAction(null);
|
||||
blockChainExplorerComboBox.setOnAction(null);
|
||||
showNotificationsCheckBox.setOnAction(null);
|
||||
showInstructionsCheckBox.setOnAction(null);
|
||||
// transactionFeeInputTextField.textProperty().unbind();
|
||||
/// transactionFeeInputTextField.focusedProperty().removeListener(transactionFeeFocusedListener);
|
||||
}
|
||||
|
||||
|
||||
private void deactivateDisplayPreferences() {
|
||||
useAnimationsCheckBox.setOnAction(null);
|
||||
useEffectsCheckBox.setOnAction(null);
|
||||
autoSelectArbitratorsCheckBox.setOnAction(null);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,100 +0,0 @@
|
||||
/*
|
||||
* This file is part of Bitsquare.
|
||||
*
|
||||
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.gui.main.settings.preferences;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import io.bitsquare.common.UserThread;
|
||||
import io.bitsquare.gui.common.model.ActivatableViewModel;
|
||||
import io.bitsquare.gui.main.popups.Popup;
|
||||
import io.bitsquare.locale.LanguageUtil;
|
||||
import io.bitsquare.locale.TradeCurrency;
|
||||
import io.bitsquare.user.BlockChainExplorer;
|
||||
import io.bitsquare.user.Preferences;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
class PreferencesViewModel extends ActivatableViewModel {
|
||||
|
||||
private final Preferences preferences;
|
||||
final ObservableList<String> btcDenominations = FXCollections.observableArrayList(Preferences.getBtcDenominations());
|
||||
final ObservableList<BlockChainExplorer> blockExplorers;
|
||||
final ObservableList<TradeCurrency> tradeCurrencies;
|
||||
final ObservableList<String> languageCodes;
|
||||
final StringProperty transactionFeePerByte = new SimpleStringProperty();
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor, initialisation
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Inject
|
||||
public PreferencesViewModel(Preferences preferences) {
|
||||
this.preferences = preferences;
|
||||
|
||||
blockExplorers = FXCollections.observableArrayList(preferences.getBlockChainExplorers());
|
||||
tradeCurrencies = preferences.getTradeCurrenciesAsObservable();
|
||||
languageCodes = FXCollections.observableArrayList(LanguageUtil.getAllLanguageCodes());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void activate() {
|
||||
transactionFeePerByte.set(String.valueOf(preferences.getTxFeePerKB() / 1000));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void deactivate() {
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// UI actions
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void onSelectLanguageCode(String code) {
|
||||
preferences.setPreferredLocale(new Locale(code, preferences.getPreferredLocale().getCountry()));
|
||||
}
|
||||
|
||||
public void onFocusOutTransactionFeeTextField(Boolean oldValue, Boolean newValue) {
|
||||
if (oldValue && !newValue) {
|
||||
try {
|
||||
preferences.setTxFeePerKB(Long.parseLong(transactionFeePerByte.get()) * 1000);
|
||||
} catch (Exception e) {
|
||||
log.warn("Error at onFocusOutTransactionFeeTextField: " + e.getMessage());
|
||||
new Popup().warning(e.getMessage())
|
||||
.onClose(() -> UserThread.runAfter(
|
||||
() -> transactionFeePerByte.set(String.valueOf(preferences.getTxFeePerKB() / 1000)),
|
||||
100, TimeUnit.MILLISECONDS))
|
||||
.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Getters
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public String getLanguageCode() {
|
||||
return preferences.getPreferredLocale().getLanguage();
|
||||
}
|
||||
|
||||
}
|
@ -153,3 +153,16 @@ SWISH= Swish
|
||||
TRANSFER_WISE=TransferWise
|
||||
US_POSTAL_MONEY_ORDER=US Postal money order
|
||||
BLOCK_CHAINS=Crypto currencies
|
||||
|
||||
OK_PAY_SHORT=OKPay
|
||||
PERFECT_MONEY_SHORT=Perfect Money
|
||||
ALI_PAY_SHORT=AliPay
|
||||
SEPA_SHORT=SEPA
|
||||
NATIONAL_BANK_SHORT=National Banks
|
||||
SAME_BANK_SHORT=Same Bank
|
||||
SPECIFIC_BANKS_SHORT=Specific banks
|
||||
FED_WIRE_SHORT=Fed Wire
|
||||
SWISH_SHORT= Swish
|
||||
TRANSFER_WISE_SHORT=TransferWise
|
||||
US_POSTAL_MONEY_ORDER_SHORT=Money order
|
||||
BLOCK_CHAINS_SHORT=Crypto currencies
|
||||
|
@ -190,9 +190,6 @@ public class P2PDataStorage implements MessageListener, ConnectionListener {
|
||||
if (result) {
|
||||
map.put(hashOfPayload, protectedStorageEntry);
|
||||
|
||||
sequenceNumberMap.put(hashOfPayload, new MapValue(protectedStorageEntry.sequenceNumber, System.currentTimeMillis()));
|
||||
storage.queueUpForSave(sequenceNumberMap, 100);
|
||||
|
||||
StringBuilder sb = new StringBuilder("\n\n------------------------------------------------------------\n");
|
||||
sb.append("Data set after doAdd (truncated)");
|
||||
map.values().stream().forEach(e -> sb.append("\n").append(StringUtils.abbreviate(e.toString(), 100)));
|
||||
@ -200,8 +197,13 @@ public class P2PDataStorage implements MessageListener, ConnectionListener {
|
||||
log.trace(sb.toString());
|
||||
log.info("Data set after doAdd: size=" + map.values().size());
|
||||
|
||||
broadcast(new AddDataMessage(protectedStorageEntry), sender, listener, isDataOwner);
|
||||
if (hasSequenceNrIncreased(protectedStorageEntry.sequenceNumber, hashOfPayload)) {
|
||||
sequenceNumberMap.put(hashOfPayload, new MapValue(protectedStorageEntry.sequenceNumber, System.currentTimeMillis()));
|
||||
storage.queueUpForSave(sequenceNumberMap, 100);
|
||||
|
||||
broadcast(new AddDataMessage(protectedStorageEntry), sender, listener, isDataOwner);
|
||||
}
|
||||
|
||||
hashMapChangedListeners.stream().forEach(e -> e.onAdded(protectedStorageEntry));
|
||||
} else {
|
||||
log.trace("add failed");
|
||||
@ -226,7 +228,7 @@ public class P2PDataStorage implements MessageListener, ConnectionListener {
|
||||
} else {
|
||||
PublicKey ownerPubKey = storedData.getStoragePayload().getOwnerPubKey();
|
||||
boolean result = checkSignature(ownerPubKey, hashOfDataAndSeqNr, signature) &&
|
||||
isSequenceNrValid(sequenceNumber, hashOfPayload) &&
|
||||
hasSequenceNrIncreased(sequenceNumber, hashOfPayload) &&
|
||||
checkIfStoredDataPubKeyMatchesNewDataPubKey(ownerPubKey, hashOfPayload);
|
||||
|
||||
if (result) {
|
||||
@ -381,6 +383,22 @@ public class P2PDataStorage implements MessageListener, ConnectionListener {
|
||||
}
|
||||
|
||||
private boolean isSequenceNrValid(int newSequenceNumber, ByteArray hashOfData) {
|
||||
if (sequenceNumberMap.containsKey(hashOfData)) {
|
||||
Integer storedSequenceNumber = sequenceNumberMap.get(hashOfData).sequenceNr;
|
||||
if (newSequenceNumber >= storedSequenceNumber) {
|
||||
return true;
|
||||
} else {
|
||||
log.info("Sequence number is invalid. sequenceNumber = "
|
||||
+ newSequenceNumber + " / storedSequenceNumber=" + storedSequenceNumber + "\n" +
|
||||
"That can happen if the data owner gets an old delayed data storage message.");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasSequenceNrIncreased(int newSequenceNumber, ByteArray hashOfData) {
|
||||
if (sequenceNumberMap.containsKey(hashOfData)) {
|
||||
Integer storedSequenceNumber = sequenceNumberMap.get(hashOfData).sequenceNr;
|
||||
if (newSequenceNumber > storedSequenceNumber) {
|
||||
|
Loading…
Reference in New Issue
Block a user