mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-06-27 00:00:57 -04:00
Refactor fee handling, add user defined fee to settings, UI fixes
This commit is contained in:
parent
35d6612820
commit
f723bf5737
36 changed files with 255 additions and 143 deletions
|
@ -195,7 +195,7 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
|
|||
private Tuple2<TextField, VBox> getBalanceBox(String text) {
|
||||
TextField textField = new TextField();
|
||||
textField.setEditable(false);
|
||||
textField.setPrefWidth(100);
|
||||
textField.setPrefWidth(120);
|
||||
textField.setMouseTransparent(true);
|
||||
textField.setFocusTraversable(false);
|
||||
textField.setStyle("-fx-alignment: center; -fx-background-color: white;");
|
||||
|
|
|
@ -313,7 +313,6 @@ public class MainViewModel implements ViewModel {
|
|||
});
|
||||
pendingTradesChanged();
|
||||
addDisputeStateListeners(tradeManager.getTrades());
|
||||
tradeManager.onAllServicesInitialized();
|
||||
|
||||
|
||||
// arbitratorManager
|
||||
|
|
|
@ -406,7 +406,7 @@ public class DisputeSummaryPopup extends Popup {
|
|||
|
||||
private void calculatePayoutAmounts(DisputeResult.FeePaymentPolicy feePayment) {
|
||||
Contract contract = dispute.getContract();
|
||||
Coin refund = FeePolicy.SECURITY_DEPOSIT;
|
||||
Coin refund = FeePolicy.getSecurityDeposit();
|
||||
Coin winnerRefund;
|
||||
Coin loserRefund;
|
||||
switch (feePayment) {
|
||||
|
|
|
@ -105,28 +105,29 @@ public class ReservedListItem {
|
|||
switch (phase) {
|
||||
case PREPARATION:
|
||||
case TAKER_FEE_PAID:
|
||||
balanceLabel.setText(formatter.formatCoinWithCode(balance) + " locked in deposit");
|
||||
balanceLabel.setText(formatter.formatCoinWithCode(balance) + " (locally reserved)");
|
||||
break;
|
||||
case DEPOSIT_REQUESTED:
|
||||
case DEPOSIT_PAID:
|
||||
case FIAT_SENT:
|
||||
case FIAT_RECEIVED:
|
||||
// We ignore the tx fee as it will be paid by both (once deposit, once payout)
|
||||
Coin balanceInDeposit = FeePolicy.SECURITY_DEPOSIT;
|
||||
Coin balanceInDeposit = FeePolicy.getSecurityDeposit();
|
||||
// For the seller we add the trade amount
|
||||
if (trade.getContract().getSellerAddress().equals(getAddress()))
|
||||
balanceInDeposit.add(trade.getTradeAmount());
|
||||
balanceLabel.setText(formatter.formatCoinWithCode(balanceInDeposit) + " locked in deposit");
|
||||
|
||||
balanceLabel.setText(formatter.formatCoinWithCode(balance) + " (in MS escrow)");
|
||||
break;
|
||||
case PAYOUT_PAID:
|
||||
balanceLabel.setText(formatter.formatCoinWithCode(balance) + " in wallet");
|
||||
balanceLabel.setText(formatter.formatCoinWithCode(balance) + " (in local wallet)");
|
||||
break;
|
||||
case WITHDRAWN:
|
||||
log.error("Invalid state at updateBalance (WITHDRAWN)");
|
||||
balanceLabel.setText(formatter.formatCoinWithCode(balance) + " already withdrawn");
|
||||
break;
|
||||
case DISPUTE:
|
||||
balanceLabel.setText(formatter.formatCoinWithCode(balance) + " locked because of open ticket");
|
||||
balanceLabel.setText(formatter.formatCoinWithCode(balance) + " open dispute/ticket");
|
||||
break;
|
||||
default:
|
||||
log.warn("Not supported tradePhase: " + phase);
|
||||
|
|
|
@ -20,7 +20,6 @@ package io.bitsquare.gui.main.funds.withdrawal;
|
|||
import com.google.common.util.concurrent.FutureCallback;
|
||||
import io.bitsquare.app.BitsquareApp;
|
||||
import io.bitsquare.btc.AddressEntry;
|
||||
import io.bitsquare.btc.FeePolicy;
|
||||
import io.bitsquare.btc.Restrictions;
|
||||
import io.bitsquare.btc.WalletService;
|
||||
import io.bitsquare.btc.listeners.BalanceListener;
|
||||
|
@ -65,9 +64,12 @@ import java.util.stream.Stream;
|
|||
@FxmlView
|
||||
public class WithdrawalView extends ActivatableView<VBox, Void> {
|
||||
|
||||
@FXML Button withdrawButton;
|
||||
@FXML TableView<WithdrawalListItem> table;
|
||||
@FXML TextField withdrawFromTextField, withdrawToTextField, amountTextField;
|
||||
@FXML
|
||||
Button withdrawButton;
|
||||
@FXML
|
||||
TableView<WithdrawalListItem> table;
|
||||
@FXML
|
||||
TextField withdrawFromTextField, withdrawToTextField, amountTextField;
|
||||
@FXML
|
||||
TableColumn<WithdrawalListItem, WithdrawalListItem> labelColumn, addressColumn, balanceColumn, confidenceColumn;
|
||||
|
||||
|
@ -114,7 +116,7 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
|
|||
setConfidenceColumnCellFactory();
|
||||
|
||||
if (BitsquareApp.DEV_MODE)
|
||||
withdrawToTextField.setText("mwajQdfYnve1knXnmv7JdeiVpeogTsck6S");
|
||||
withdrawToTextField.setText("mxAkWWaQBqwqcYstKzqLku3kzR6pbu2zHq");
|
||||
}
|
||||
|
||||
private boolean areInputsValid() {
|
||||
|
@ -144,8 +146,7 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
|
|||
if (Coin.ZERO.compareTo(newValue.getBalance()) <= 0) {
|
||||
amountTextField.setText(newValue.getBalance().toPlainString());
|
||||
withdrawFromTextField.setText(newValue.getAddressEntry().getAddressString());
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
withdrawFromTextField.setText("");
|
||||
withdrawFromTextField.setPromptText("No fund to withdrawal on that address.");
|
||||
amountTextField.setText("");
|
||||
|
@ -173,15 +174,14 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
|
|||
|
||||
@FXML
|
||||
public void onWithdraw() {
|
||||
Coin amount = formatter.parseToCoin(amountTextField.getText());
|
||||
if (Restrictions.isMinSpendableAmount(amount)) {
|
||||
Coin senderAmount = formatter.parseToCoin(amountTextField.getText());
|
||||
if (Restrictions.isAboveDust(senderAmount)) {
|
||||
FutureCallback<Transaction> callback = new FutureCallback<Transaction>() {
|
||||
@Override
|
||||
public void onSuccess(@javax.annotation.Nullable Transaction transaction) {
|
||||
if (transaction != null) {
|
||||
log.info("onWithdraw onSuccess tx ID:" + transaction.getHashAsString());
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
log.error("onWithdraw transaction is null");
|
||||
}
|
||||
}
|
||||
|
@ -191,26 +191,29 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
|
|||
log.error("onWithdraw onFailure");
|
||||
}
|
||||
};
|
||||
try {
|
||||
Coin requiredFee = walletService.getRequiredFee(withdrawFromTextField.getText(),
|
||||
withdrawToTextField.getText(), senderAmount);
|
||||
Coin receiverAmount = senderAmount.subtract(requiredFee);
|
||||
if (BitsquareApp.DEV_MODE) {
|
||||
doWithdraw(receiverAmount, callback);
|
||||
} else {
|
||||
new Popup().headLine("Confirm your withdrawal request")
|
||||
.message("Sending: " + formatter.formatCoinWithCode(senderAmount) + "\n" +
|
||||
"From address: " + withdrawFromTextField.getText() + "\n" +
|
||||
"To receiving address: " + withdrawToTextField.getText() + ".\n\n" +
|
||||
"Required transaction fee is: " + formatter.formatCoinWithCode(requiredFee) + "\n" +
|
||||
"Recipient will receive: " + formatter.formatCoinWithCode(receiverAmount) + "\n\n" +
|
||||
"Are you sure you want to withdraw that amount?")
|
||||
.onAction(() -> doWithdraw(receiverAmount, callback))
|
||||
.show();
|
||||
|
||||
if (BitsquareApp.DEV_MODE) {
|
||||
doWithdraw(amount, callback);
|
||||
} else {
|
||||
new Popup().headLine("Confirm your withdrawal request").message("Amount: " + amountTextField.getText() + " " +
|
||||
"BTC\n" +
|
||||
"Sending" +
|
||||
" address: " + withdrawFromTextField.getText() + "\n" + "Receiving address: " +
|
||||
withdrawToTextField.getText() + "\n" + "Transaction fee: " +
|
||||
formatter.formatCoinWithCode(FeePolicy.TX_FEE) + "\n" +
|
||||
"Receivers amount: " +
|
||||
formatter.formatCoinWithCode(amount.subtract(FeePolicy.TX_FEE)) + " BTC\n\n" +
|
||||
"Are you sure you want to withdraw that amount?")
|
||||
.onAction(() -> {
|
||||
doWithdraw(amount, callback);
|
||||
})
|
||||
.show();
|
||||
}
|
||||
} catch (AddressFormatException | InsufficientMoneyException e) {
|
||||
e.printStackTrace();
|
||||
log.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
new Popup().warning("The amount to transfer is lower than the transaction fee and the min. possible tx value.").show();
|
||||
}
|
||||
}
|
||||
|
@ -284,8 +287,7 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
|
|||
hyperlink.setOnAction(event -> openDetails(item));
|
||||
}
|
||||
setGraphic(hyperlink);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
setGraphic(null);
|
||||
setId(null);
|
||||
}
|
||||
|
@ -363,8 +365,7 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
|
|||
|
||||
if (item != null && !empty) {
|
||||
setGraphic(item.getProgressIndicator());
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
setGraphic(null);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -117,9 +117,9 @@ class CreateOfferDataModel extends ActivatableDataModel {
|
|||
|
||||
offerId = UUID.randomUUID().toString();
|
||||
addressEntry = walletService.getAddressEntryByOfferId(offerId);
|
||||
offerFeeAsCoin = FeePolicy.CREATE_OFFER_FEE;
|
||||
networkFeeAsCoin = FeePolicy.TX_FEE;
|
||||
securityDepositAsCoin = FeePolicy.SECURITY_DEPOSIT;
|
||||
offerFeeAsCoin = FeePolicy.getCreateOfferFee();
|
||||
networkFeeAsCoin = FeePolicy.getFixedTxFeeForTrades();
|
||||
securityDepositAsCoin = FeePolicy.getSecurityDeposit();
|
||||
|
||||
balanceListener = new BalanceListener(getAddressEntry().getAddress()) {
|
||||
@Override
|
||||
|
|
|
@ -436,7 +436,7 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
|
|||
() -> {
|
||||
new Popup().headLine(BSResources.get("createOffer.success.headline"))
|
||||
.message(BSResources.get("createOffer.success.info"))
|
||||
.actionButtonText("Go to \"Open offers\"")
|
||||
.actionButtonText("Go to \"My offers\"")
|
||||
.onAction(() -> {
|
||||
close();
|
||||
FxTimer.runLater(Duration.ofMillis(100),
|
||||
|
|
|
@ -20,7 +20,10 @@ package io.bitsquare.gui.main.offer.takeoffer;
|
|||
import com.google.inject.Inject;
|
||||
import io.bitsquare.app.BitsquareApp;
|
||||
import io.bitsquare.arbitration.Arbitrator;
|
||||
import io.bitsquare.btc.*;
|
||||
import io.bitsquare.btc.AddressEntry;
|
||||
import io.bitsquare.btc.FeePolicy;
|
||||
import io.bitsquare.btc.TradeWalletService;
|
||||
import io.bitsquare.btc.WalletService;
|
||||
import io.bitsquare.btc.listeners.BalanceListener;
|
||||
import io.bitsquare.common.handlers.ResultHandler;
|
||||
import io.bitsquare.gui.common.model.ActivatableDataModel;
|
||||
|
@ -94,9 +97,9 @@ class TakeOfferDataModel extends ActivatableDataModel {
|
|||
this.walletPasswordPopup = walletPasswordPopup;
|
||||
this.preferences = preferences;
|
||||
|
||||
offerFeeAsCoin = FeePolicy.CREATE_OFFER_FEE;
|
||||
networkFeeAsCoin = FeePolicy.TX_FEE;
|
||||
securityDepositAsCoin = FeePolicy.SECURITY_DEPOSIT;
|
||||
offerFeeAsCoin = FeePolicy.getCreateOfferFee();
|
||||
networkFeeAsCoin = FeePolicy.getFixedTxFeeForTrades();
|
||||
securityDepositAsCoin = FeePolicy.getSecurityDeposit();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -127,7 +130,7 @@ class TakeOfferDataModel extends ActivatableDataModel {
|
|||
|
||||
addressEntry = walletService.getAddressEntryByOfferId(offer.getId());
|
||||
checkNotNull(addressEntry, "addressEntry must not be null");
|
||||
|
||||
|
||||
ObservableList<PaymentAccount> possiblePaymentAccounts = getPossiblePaymentAccounts();
|
||||
checkArgument(!possiblePaymentAccounts.isEmpty(), "possiblePaymentAccounts.isEmpty()");
|
||||
paymentAccount = possiblePaymentAccounts.get(0);
|
||||
|
@ -135,7 +138,7 @@ class TakeOfferDataModel extends ActivatableDataModel {
|
|||
amountAsCoin.set(offer.getAmount());
|
||||
|
||||
if (BitsquareApp.DEV_MODE)
|
||||
amountAsCoin.set(Restrictions.MIN_TRADE_AMOUNT);
|
||||
amountAsCoin.set(offer.getAmount());
|
||||
|
||||
calculateVolume();
|
||||
calculateTotalToPay();
|
||||
|
@ -274,7 +277,7 @@ class TakeOfferDataModel extends ActivatableDataModel {
|
|||
|
||||
boolean isMinAmountLessOrEqualAmount() {
|
||||
//noinspection SimplifiableIfStatement
|
||||
if (offer != null && offer.getMinAmount() != null && amountAsCoin.get() != null)
|
||||
if (offer != null && offer.getMinAmount() != null && amountAsCoin.get() != null)
|
||||
return !offer.getMinAmount().isGreaterThan(amountAsCoin.get());
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -196,7 +196,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
|||
model.isOfferAvailable,
|
||||
(a, b, c, d) -> a == null && b == null && !c && !d)
|
||||
.subscribe((observable, oldValue, newValue) -> {
|
||||
if (newValue) {
|
||||
if (!oldValue && newValue) {
|
||||
isOfferAvailablePopup = new Popup().information(BSResources.get("takeOffer.fundsBox.isOfferAvailable"))
|
||||
.show()
|
||||
.onClose(() -> {
|
||||
|
|
|
@ -17,14 +17,15 @@
|
|||
~ along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import javafx.scene.control.Tab?>
|
||||
<?import javafx.scene.control.TabPane?>
|
||||
<?import javafx.scene.layout.AnchorPane?>
|
||||
<TabPane fx:id="root" fx:controller="io.bitsquare.gui.main.portfolio.PortfolioView"
|
||||
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0"
|
||||
AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" tabClosingPolicy="UNAVAILABLE"
|
||||
xmlns:fx="http://javafx.com/fxml">
|
||||
|
||||
<Tab fx:id="openOffersTab" text="Open offers"/>
|
||||
<Tab fx:id="openOffersTab" text="My offers"/>
|
||||
<Tab fx:id="pendingTradesTab" text="Open trades"/>
|
||||
<Tab fx:id="closedTradesTab" text="History"/>
|
||||
|
||||
|
|
|
@ -295,7 +295,7 @@ public class PendingTradesDataModel extends ActivatableDataModel {
|
|||
}
|
||||
|
||||
Coin getTotalFees() {
|
||||
return FeePolicy.TX_FEE.add(isOfferer() ? FeePolicy.CREATE_OFFER_FEE : FeePolicy.TAKE_OFFER_FEE);
|
||||
return FeePolicy.getFixedTxFeeForTrades().add(isOfferer() ? FeePolicy.getCreateOfferFee() : FeePolicy.getTakeOfferFee());
|
||||
}
|
||||
|
||||
PendingTradesListItem getSelectedItem() {
|
||||
|
|
|
@ -324,7 +324,7 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
|
|||
}
|
||||
|
||||
public String getSecurityDeposit() {
|
||||
return formatter.formatCoinWithCode(FeePolicy.SECURITY_DEPOSIT);
|
||||
return formatter.formatCoinWithCode(FeePolicy.getSecurityDeposit());
|
||||
}
|
||||
|
||||
public boolean isBlockChainMethod() {
|
||||
|
|
|
@ -116,7 +116,7 @@ public class CompletedView extends TradeStepDetailsView {
|
|||
});
|
||||
|
||||
if (BitsquareApp.DEV_MODE)
|
||||
withdrawAddressTextField.setText("mwajQdfYnve1knXnmv7JdeiVpeogTsck6S");
|
||||
withdrawAddressTextField.setText("mxAkWWaQBqwqcYstKzqLku3kzR6pbu2zHq");
|
||||
}
|
||||
|
||||
public void setBtcTradeAmountLabelText(String text) {
|
||||
|
|
|
@ -19,10 +19,12 @@ package io.bitsquare.gui.main.settings.preferences;
|
|||
|
||||
import io.bitsquare.gui.common.view.ActivatableViewAndModel;
|
||||
import io.bitsquare.gui.common.view.FxmlView;
|
||||
import io.bitsquare.gui.components.InputTextField;
|
||||
import io.bitsquare.gui.util.Layout;
|
||||
import io.bitsquare.locale.LanguageUtil;
|
||||
import io.bitsquare.locale.TradeCurrency;
|
||||
import io.bitsquare.user.BlockChainExplorer;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.scene.control.CheckBox;
|
||||
import javafx.scene.control.ComboBox;
|
||||
import javafx.scene.layout.GridPane;
|
||||
|
@ -44,6 +46,8 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Preferenc
|
|||
private CheckBox useAnimationsCheckBox, useEffectsCheckBox, showPlaceOfferConfirmationCheckBox, showTakeOfferConfirmationCheckBox,
|
||||
autoSelectArbitratorsCheckBox;
|
||||
private int gridRow = 0;
|
||||
private InputTextField transactionFeeInputTextField;
|
||||
private ChangeListener<Boolean> transactionFeeFocusedListener;
|
||||
|
||||
@Inject
|
||||
public PreferencesView(PreferencesViewModel model) {
|
||||
|
@ -52,12 +56,16 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Preferenc
|
|||
|
||||
@Override
|
||||
public void initialize() {
|
||||
addTitledGroupBg(root, gridRow, 3, "Preferences");
|
||||
addTitledGroupBg(root, gridRow, 4, "Preferences");
|
||||
tradeCurrencyComboBox = addLabelComboBox(root, gridRow, "Preferred currency:", Layout.FIRST_ROW_DISTANCE).second;
|
||||
languageComboBox = addLabelComboBox(root, ++gridRow, "Language:").second;
|
||||
// btcDenominationComboBox = addLabelComboBox(root, ++gridRow, "Bitcoin denomination:").second;
|
||||
blockExplorerComboBox = addLabelComboBox(root, ++gridRow, "Bitcoin block explorer:").second;
|
||||
|
||||
transactionFeeInputTextField = addLabelInputTextField(root, ++gridRow, "Transaction fee (satoshi/byte):").second;
|
||||
transactionFeeFocusedListener = (o, oldValue, newValue) -> {
|
||||
model.onFocusOutTransactionFeeTextField(oldValue, newValue, transactionFeeInputTextField.getText());
|
||||
};
|
||||
|
||||
addTitledGroupBg(root, ++gridRow, 5, "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;
|
||||
|
@ -119,6 +127,8 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Preferenc
|
|||
});
|
||||
blockExplorerComboBox.setOnAction(e -> model.onSelectBlockExplorer(blockExplorerComboBox.getSelectionModel().getSelectedItem()));
|
||||
|
||||
transactionFeeInputTextField.textProperty().bindBidirectional(model.transactionFeePerByte);
|
||||
transactionFeeInputTextField.focusedProperty().addListener(transactionFeeFocusedListener);
|
||||
|
||||
useAnimationsCheckBox.setSelected(model.getUseAnimations());
|
||||
useAnimationsCheckBox.setOnAction(e -> model.onSelectUseAnimations(useAnimationsCheckBox.isSelected()));
|
||||
|
@ -142,6 +152,8 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Preferenc
|
|||
languageComboBox.setOnAction(null);
|
||||
tradeCurrencyComboBox.setOnAction(null);
|
||||
blockExplorerComboBox.setOnAction(null);
|
||||
transactionFeeInputTextField.textProperty().unbind();
|
||||
transactionFeeInputTextField.focusedProperty().removeListener(transactionFeeFocusedListener);
|
||||
useAnimationsCheckBox.setOnAction(null);
|
||||
useEffectsCheckBox.setOnAction(null);
|
||||
showPlaceOfferConfirmationCheckBox.setOnAction(null);
|
||||
|
|
|
@ -18,15 +18,20 @@
|
|||
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.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 {
|
||||
|
||||
|
@ -35,7 +40,8 @@ class PreferencesViewModel extends ActivatableViewModel {
|
|||
final ObservableList<BlockChainExplorer> blockExplorers;
|
||||
final ObservableList<TradeCurrency> tradeCurrencies;
|
||||
final ObservableList<String> languageCodes;
|
||||
|
||||
final StringProperty transactionFeePerByte = new SimpleStringProperty();
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor, initialisation
|
||||
|
@ -52,13 +58,13 @@ class PreferencesViewModel extends ActivatableViewModel {
|
|||
|
||||
@Override
|
||||
protected void activate() {
|
||||
transactionFeePerByte.set(String.valueOf(preferences.getTxFeePerKB() / 1000));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void deactivate() {
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// UI actions
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -99,6 +105,19 @@ class PreferencesViewModel extends ActivatableViewModel {
|
|||
preferences.setPreferredLocale(new Locale(code, preferences.getPreferredLocale().getCountry()));
|
||||
}
|
||||
|
||||
public void onFocusOutTransactionFeeTextField(Boolean oldValue, Boolean newValue, String text) {
|
||||
if (oldValue && !newValue) {
|
||||
try {
|
||||
preferences.setTxFeePerKB(Long.valueOf(transactionFeePerByte.get()) * 1000);
|
||||
} catch (Exception e) {
|
||||
new Popup().warning(e.getMessage())
|
||||
.onClose(() -> UserThread.runAfter(
|
||||
() -> transactionFeePerByte.set(String.valueOf(preferences.getTxFeePerKB() / 1000)),
|
||||
100, TimeUnit.MILLISECONDS))
|
||||
.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Getters
|
||||
|
@ -139,4 +158,5 @@ class PreferencesViewModel extends ActivatableViewModel {
|
|||
public TradeCurrency getTradeCurrency() {
|
||||
return preferences.getPreferredTradeCurrency();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -99,7 +99,7 @@ public class EmptyWalletPopup extends Popup {
|
|||
Tuple2<Label, InputTextField> tuple = addLabelInputTextField(gridPane, ++rowIndex, "Your destination address:");
|
||||
addressInputTextField = tuple.second;
|
||||
emptyWalletButton = new Button("Empty wallet");
|
||||
boolean isBalanceSufficient = Restrictions.isMinSpendableAmount(totalBalance);
|
||||
boolean isBalanceSufficient = Restrictions.isAboveDust(totalBalance);
|
||||
emptyWalletButton.setDefaultButton(isBalanceSufficient);
|
||||
closeButton.setDefaultButton(!isBalanceSufficient);
|
||||
emptyWalletButton.setDisable(!isBalanceSufficient && addressInputTextField.getText().length() > 0);
|
||||
|
|
|
@ -76,7 +76,7 @@ createOffer.advancedBox.county=Payments account country:
|
|||
createOffer.advancedBox.info=Your trading partners must fulfill your offer restrictions. You can edit the accepted countries, languages and arbitrators in the settings. The payments account details are used from your current selected payments account (if you have multiple payments accounts).
|
||||
|
||||
createOffer.success.headline=Your offer has been published to the P2P network.
|
||||
createOffer.success.info=You can manage your open offers in the \"Portfolio\" screen under \"Open offers\".
|
||||
createOffer.success.info=You can manage your open offers in the \"Portfolio\" screen under \"My offers\".
|
||||
|
||||
createOffer.error.message=An error occurred when placing the offer.\n\n{0}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue