diff --git a/src/main/java/com/sparrowwallet/sparrow/AppController.java b/src/main/java/com/sparrowwallet/sparrow/AppController.java index 6e33523f..d8eb6e5a 100644 --- a/src/main/java/com/sparrowwallet/sparrow/AppController.java +++ b/src/main/java/com/sparrowwallet/sparrow/AppController.java @@ -144,10 +144,6 @@ public class AppController implements Initializable { private CheckMenuItem showLoadingLog; private static final BooleanProperty showLoadingLogProperty = new SimpleBooleanProperty(); - @FXML - private CheckMenuItem showUtxosChart; - private static final BooleanProperty showUtxosChartProperty = new SimpleBooleanProperty(); - @FXML private CheckMenuItem showTxHex; private static final BooleanProperty showTxHexProperty = new SimpleBooleanProperty(); @@ -320,8 +316,6 @@ public class AppController implements Initializable { showTxHex.selectedProperty().bindBidirectional(showTxHexProperty); showLoadingLogProperty.set(Config.get().isShowLoadingLog()); showLoadingLog.selectedProperty().bindBidirectional(showLoadingLogProperty); - showUtxosChartProperty.set(Config.get().isShowUtxosChart()); - showUtxosChart.selectedProperty().bindBidirectional(showUtxosChartProperty); preventSleepProperty.set(Config.get().isPreventSleep()); preventSleep.selectedProperty().bindBidirectional(preventSleepProperty); @@ -802,12 +796,6 @@ public class AppController implements Initializable { EventManager.get().post(new LoadingLogChangedEvent(item.isSelected())); } - public void showUtxosChart(ActionEvent event) { - CheckMenuItem item = (CheckMenuItem)event.getSource(); - Config.get().setShowUtxosChart(item.isSelected()); - EventManager.get().post(new UtxosChartChangedEvent(item.isSelected())); - } - public void showTxHex(ActionEvent event) { CheckMenuItem item = (CheckMenuItem)event.getSource(); Config.get().setShowTransactionHex(item.isSelected()); @@ -1869,7 +1857,6 @@ public class AppController implements Initializable { lockWallet.setDisable(true); exportWallet.setDisable(true); showLoadingLog.setDisable(true); - showUtxosChart.setDisable(true); showTxHex.setDisable(false); findMixingPartner.setDisable(true); } else if(event instanceof WalletTabSelectedEvent) { @@ -1880,7 +1867,6 @@ public class AppController implements Initializable { lockWallet.setDisable(walletTabData.getWalletForm().lockedProperty().get()); exportWallet.setDisable(walletTabData.getWallet() == null || !walletTabData.getWallet().isValid()); showLoadingLog.setDisable(false); - showUtxosChart.setDisable(false); showTxHex.setDisable(true); findMixingPartner.setDisable(exportWallet.isDisable() || !SorobanServices.canWalletMix(walletTabData.getWallet()) || !AppServices.onlineProperty().get()); } diff --git a/src/main/java/com/sparrowwallet/sparrow/control/UtxosChart.java b/src/main/java/com/sparrowwallet/sparrow/control/UtxosChart.java index 10d60016..58dab11d 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/UtxosChart.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/UtxosChart.java @@ -9,14 +9,18 @@ import com.sparrowwallet.sparrow.wallet.WalletUtxosEntry; import javafx.beans.NamedArg; import javafx.scene.Node; import javafx.scene.chart.*; +import javafx.scene.control.Tooltip; +import javafx.util.Duration; import java.util.List; +import java.util.Locale; import java.util.Set; import java.util.stream.Collectors; public class UtxosChart extends BarChart { private static final int MAX_BARS = 8; private static final String OTHER_CATEGORY = "Other"; + private static final int TOOLTIP_SHOW_DELAY = 50; private List selectedEntries; private int totalUtxos; @@ -57,9 +61,11 @@ public class UtxosChart extends BarChart { XYChart.Data existingData = utxoSeries.getData().get(i); if(!newData.getXValue().equals(existingData.getXValue()) || !newData.getYValue().equals(existingData.getYValue()) || (newData.getExtraValue() instanceof Entry && !newData.getExtraValue().equals(existingData.getExtraValue()))) { utxoSeries.getData().set(i, newData); + installTooltip(newData); } } else { utxoSeries.getData().add(newData); + installTooltip(newData); } } @@ -74,12 +80,21 @@ public class UtxosChart extends BarChart { private String getCategoryName(Entry entry) { if(entry.getLabel() != null && !entry.getLabel().isEmpty()) { - return entry.getLabel().length() > 15 ? entry.getLabel().substring(0, 15) + "..." + "\n" + ((UtxoEntry)entry).getDescription() : entry.getLabel() + "\n" + ((UtxoEntry)entry).getDescription(); + return entry.getLabel() + "\n" + ((UtxoEntry)entry).getDescription(); } return ((UtxoEntry)entry).getDescription(); } + private void installTooltip(XYChart.Data item) { + Tooltip.uninstall(item.getNode(), null); + + String satsValue = String.format(Locale.ENGLISH, "%,d", item.getYValue()); + Tooltip tooltip = new Tooltip(item.getXValue() + "\n" + satsValue + " sats"); + tooltip.setShowDelay(Duration.millis(TOOLTIP_SHOW_DELAY)); + Tooltip.install(item.getNode(), tooltip); + } + public void select(List entries) { Set selectedBars = lookupAll(".chart-bar.selected"); for(Node selectedBar : selectedBars) { diff --git a/src/main/java/com/sparrowwallet/sparrow/io/Config.java b/src/main/java/com/sparrowwallet/sparrow/io/Config.java index 60693f4b..3112e677 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/Config.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/Config.java @@ -40,7 +40,6 @@ public class Config { private boolean hideEmptyUsedAddresses = false; private boolean showTransactionHex = true; private boolean showLoadingLog = true; - private boolean showUtxosChart = true; private boolean preventSleep = false; private List recentWalletFiles; private Integer keyDerivationPeriod; @@ -273,15 +272,6 @@ public class Config { flush(); } - public boolean isShowUtxosChart() { - return showUtxosChart; - } - - public void setShowUtxosChart(boolean showUtxosChart) { - this.showUtxosChart = showUtxosChart; - flush(); - } - public boolean isPreventSleep() { return preventSleep; } @@ -388,7 +378,9 @@ public class Config { public void changePublicServer() { List otherServers = PublicElectrumServer.getServers().stream().map(PublicElectrumServer::getUrl).filter(url -> !url.equals(getPublicElectrumServer())).collect(Collectors.toList()); - setPublicElectrumServer(otherServers.get(new Random().nextInt(otherServers.size()))); + if(!otherServers.isEmpty()) { + setPublicElectrumServer(otherServers.get(new Random().nextInt(otherServers.size()))); + } } public String getCoreServer() { diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/TransactionsController.java b/src/main/java/com/sparrowwallet/sparrow/wallet/TransactionsController.java index c89df25b..095e4ef2 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/TransactionsController.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/TransactionsController.java @@ -106,15 +106,6 @@ public class TransactionsController extends WalletFormController implements Init loadingLog.setEditable(false); } - private void setFiatBalance(FiatLabel fiatLabel, CurrencyRate currencyRate, long balance) { - if(currencyRate != null && currencyRate.isAvailable() && balance > 0) { - fiatLabel.set(currencyRate, balance); - } else { - fiatLabel.setCurrency(null); - fiatLabel.setBtcRate(0.0); - } - } - private void setTransactionCount(WalletTransactionsEntry walletTransactionsEntry) { transactionCount.setText(walletTransactionsEntry.getChildren() != null ? Integer.toString(walletTransactionsEntry.getChildren().size()) : "0"); } diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/UtxosController.java b/src/main/java/com/sparrowwallet/sparrow/wallet/UtxosController.java index f0858c54..bc2914c0 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/UtxosController.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/UtxosController.java @@ -52,6 +52,21 @@ import static com.sparrowwallet.sparrow.AppServices.showErrorDialog; public class UtxosController extends WalletFormController implements Initializable { private static final Logger log = LoggerFactory.getLogger(UtxosController.class); + @FXML + private CoinLabel balance; + + @FXML + private FiatLabel fiatBalance; + + @FXML + private CoinLabel mempoolBalance; + + @FXML + private FiatLabel fiatMempoolBalance; + + @FXML + private CopyableLabel utxoCount; + @FXML private UtxosTreeTable utxosTable; @@ -115,8 +130,17 @@ public class UtxosController extends WalletFormController implements Initializab @Override public void initializeView() { - utxosTable.initialize(getWalletForm().getWalletUtxosEntry()); - utxosChart.initialize(getWalletForm().getWalletUtxosEntry()); + balance.valueProperty().addListener((observable, oldValue, newValue) -> { + setFiatBalance(fiatBalance, AppServices.getFiatCurrencyExchangeRate(), newValue.longValue()); + }); + mempoolBalance.valueProperty().addListener((observable, oldValue, newValue) -> { + setFiatBalance(fiatMempoolBalance, AppServices.getFiatCurrencyExchangeRate(), newValue.longValue()); + }); + + WalletUtxosEntry walletUtxosEntry = getWalletForm().getWalletUtxosEntry(); + updateFields(walletUtxosEntry); + utxosTable.initialize(walletUtxosEntry); + utxosChart.initialize(walletUtxosEntry); mixButtonsBox.managedProperty().bind(mixButtonsBox.visibleProperty()); mixButtonsBox.setVisible(getWalletForm().getWallet().isWhirlpoolMixWallet()); @@ -159,9 +183,12 @@ public class UtxosController extends WalletFormController implements Initializab utxosChart.select(selectedEntries); updateButtons(Config.get().getBitcoinUnit()); }); + } - utxosChart.managedProperty().bind(utxosChart.visibleProperty()); - utxosChart.setVisible(Config.get().isShowUtxosChart() && !getWalletForm().getWallet().isWhirlpoolMixWallet()); + private void updateFields(WalletUtxosEntry walletUtxosEntry) { + balance.setValue(walletUtxosEntry.getChildren().stream().mapToLong(Entry::getValue).sum()); + mempoolBalance.setValue(walletUtxosEntry.getChildren().stream().filter(entry -> ((UtxoEntry)entry).getHashIndex().getHeight() <= 0).mapToLong(Entry::getValue).sum()); + utxoCount.setText(walletUtxosEntry.getChildren() != null ? Integer.toString(walletUtxosEntry.getChildren().size()) : "0"); } private boolean canWalletMix() { @@ -458,6 +485,7 @@ public class UtxosController extends WalletFormController implements Initializab public void walletNodesChanged(WalletNodesChangedEvent event) { if(event.getWallet().equals(walletForm.getWallet())) { WalletUtxosEntry walletUtxosEntry = getWalletForm().getWalletUtxosEntry(); + updateFields(walletUtxosEntry); utxosTable.updateAll(walletUtxosEntry); utxosChart.update(walletUtxosEntry); mixSelected.setVisible(canWalletMix()); @@ -478,6 +506,7 @@ public class UtxosController extends WalletFormController implements Initializab utxosTable.getSelectionModel().clearSelection(); } + updateFields(walletUtxosEntry); utxosTable.updateHistory(event.getHistoryChangedNodes()); utxosChart.update(walletUtxosEntry); } @@ -497,6 +526,8 @@ public class UtxosController extends WalletFormController implements Initializab public void bitcoinUnitChanged(BitcoinUnitChangedEvent event) { utxosTable.setBitcoinUnit(getWalletForm().getWallet(), event.getBitcoinUnit()); utxosChart.setBitcoinUnit(getWalletForm().getWallet(), event.getBitcoinUnit()); + balance.refresh(event.getBitcoinUnit()); + mempoolBalance.refresh(event.getBitcoinUnit()); updateButtons(event.getBitcoinUnit()); } diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/WalletFormController.java b/src/main/java/com/sparrowwallet/sparrow/wallet/WalletFormController.java index 4321b7d8..cd924723 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/WalletFormController.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/WalletFormController.java @@ -5,8 +5,10 @@ import com.sparrowwallet.drongo.KeyDerivation; import com.sparrowwallet.drongo.wallet.Keystore; import com.sparrowwallet.drongo.wallet.WalletNode; import com.sparrowwallet.sparrow.BaseController; +import com.sparrowwallet.sparrow.CurrencyRate; import com.sparrowwallet.sparrow.EventManager; import com.sparrowwallet.sparrow.WalletTabData; +import com.sparrowwallet.sparrow.control.FiatLabel; import com.sparrowwallet.sparrow.event.WalletTabsClosedEvent; public abstract class WalletFormController extends BaseController { @@ -53,4 +55,13 @@ public abstract class WalletFormController extends BaseController { return node.getDerivationPath().replace("m", "multi"); } + + protected void setFiatBalance(FiatLabel fiatLabel, CurrencyRate currencyRate, long balance) { + if(currencyRate != null && currencyRate.isAvailable() && balance > 0) { + fiatLabel.set(currencyRate, balance); + } else { + fiatLabel.setCurrency(null); + fiatLabel.setBtcRate(0.0); + } + } } diff --git a/src/main/resources/com/sparrowwallet/sparrow/app.fxml b/src/main/resources/com/sparrowwallet/sparrow/app.fxml index 01d20e52..cdd3df63 100644 --- a/src/main/resources/com/sparrowwallet/sparrow/app.fxml +++ b/src/main/resources/com/sparrowwallet/sparrow/app.fxml @@ -98,7 +98,6 @@ - diff --git a/src/main/resources/com/sparrowwallet/sparrow/wallet/utxos.fxml b/src/main/resources/com/sparrowwallet/sparrow/wallet/utxos.fxml index af752dae..3c6b5258 100644 --- a/src/main/resources/com/sparrowwallet/sparrow/wallet/utxos.fxml +++ b/src/main/resources/com/sparrowwallet/sparrow/wallet/utxos.fxml @@ -5,35 +5,64 @@ - - + + + + + + - - -
+ + + + + + + + + + + +
+
+ + + + + + + + + + +
+
+ + + + + + + + +
- - - -
@@ -69,14 +98,6 @@
- - - - - - - -