wallet update notifications

This commit is contained in:
Craig Raw 2020-08-06 17:52:18 +02:00
parent 32d25286a6
commit 10a684cf41
8 changed files with 118 additions and 1 deletions

2
drongo

@ -1 +1 @@
Subproject commit eb07a7ffa3c46cda83ac951d3b1ebd529460554c Subproject commit 1f7be6c7d5f1cdfda58617b212630575066e5496

View file

@ -34,14 +34,18 @@ import javafx.event.ActionEvent;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader; import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable; import javafx.fxml.Initializable;
import javafx.geometry.Pos;
import javafx.scene.Node; import javafx.scene.Node;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.Dragboard; import javafx.scene.input.Dragboard;
import javafx.scene.input.TransferMode; import javafx.scene.input.TransferMode;
import javafx.scene.layout.StackPane; import javafx.scene.layout.StackPane;
import javafx.stage.FileChooser; import javafx.stage.FileChooser;
import javafx.stage.Stage; import javafx.stage.Stage;
import javafx.util.Duration; import javafx.util.Duration;
import org.controlsfx.control.Notifications;
import org.controlsfx.control.StatusBar; import org.controlsfx.control.StatusBar;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -51,6 +55,7 @@ import java.net.URL;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.text.ParseException; import java.text.ParseException;
import java.util.*; import java.util.*;
import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class AppController implements Initializable { public class AppController implements Initializable {
@ -154,6 +159,9 @@ public class AppController implements Initializable {
rootStack.getStyleClass().removeAll(DRAG_OVER_CLASS); rootStack.getStyleClass().removeAll(DRAG_OVER_CLASS);
}); });
Stage tabStage = (Stage)tabs.getScene().getWindow();
tabStage.getScene().getStylesheets().add(AppController.class.getResource("notificationpopup.css").toExternalForm());
tabs.getSelectionModel().selectedItemProperty().addListener((observable, old_val, selectedTab) -> { tabs.getSelectionModel().selectedItemProperty().addListener((observable, old_val, selectedTab) -> {
if(selectedTab != null) { if(selectedTab != null) {
TabData tabData = (TabData)selectedTab.getUserData(); TabData tabData = (TabData)selectedTab.getUserData();
@ -526,6 +534,18 @@ public class AppController implements Initializable {
alert.showAndWait(); alert.showAndWait();
} }
public void selectTab(Wallet wallet) {
for(Tab tab : tabs.getTabs()) {
TabData tabData = (TabData) tab.getUserData();
if(tabData.getType() == TabData.TabType.WALLET) {
WalletTabData walletTabData = (WalletTabData) tabData;
if(walletTabData.getWallet() == wallet) {
tabs.getSelectionModel().select(tab);
}
}
}
}
public void closeTab(ActionEvent event) { public void closeTab(ActionEvent event) {
tabs.getTabs().remove(tabs.getSelectionModel().getSelectedItem()); tabs.getTabs().remove(tabs.getSelectionModel().getSelectedItem());
} }
@ -904,6 +924,35 @@ public class AppController implements Initializable {
exportWallet.setDisable(!event.getWallet().isValid()); exportWallet.setDisable(!event.getWallet().isValid());
} }
@Subscribe
public void newWalletTransactions(NewWalletTransactionsEvent event) {
String text = "New " + (event.getBlockTransactions().size() > 1 ? "transactions: " : "transaction: ");
BitcoinUnit unit = Config.get().getBitcoinUnit();
if(unit == null || unit.equals(BitcoinUnit.AUTO)) {
unit = (event.getTotalValue() >= BitcoinUnit.getAutoThreshold() ? BitcoinUnit.BTC : BitcoinUnit.SATOSHIS);
}
if(unit == BitcoinUnit.BTC) {
text += CoinLabel.getBTCFormat().format((double)event.getTotalValue() / Transaction.SATOSHIS_PER_BITCOIN) + " BTC";
} else {
text += String.format(Locale.ENGLISH, "%,d", event.getTotalValue()) + " sats";
}
Image image = new Image("image/sparrow-small.png", 50, 50, false, false);
Notifications notificationBuilder = Notifications.create()
.title("Sparrow - " + event.getWallet().getName())
.text(text)
.graphic(new ImageView(image))
.hideAfter(Duration.seconds(180))
.position(Pos.TOP_RIGHT)
.hideCloseButton()
.threshold(5, Notifications.create().title("Sparrow").text("Multiple new transactions").graphic(new ImageView(image)))
.onAction(e -> selectTab(event.getWallet()));
notificationBuilder.show();
}
@Subscribe @Subscribe
public void statusUpdated(StatusEvent event) { public void statusUpdated(StatusEvent event) {
statusBar.setText(event.getStatus()); statusBar.setText(event.getStatus());

View file

@ -0,0 +1,30 @@
package com.sparrowwallet.sparrow.event;
import com.sparrowwallet.drongo.wallet.BlockTransaction;
import com.sparrowwallet.drongo.wallet.Wallet;
import java.util.List;
public class NewWalletTransactionsEvent {
private final Wallet wallet;
private final List<BlockTransaction> blockTransactions;
private final long totalValue;
public NewWalletTransactionsEvent(Wallet wallet, List<BlockTransaction> blockTransactions, long totalValue) {
this.wallet = wallet;
this.blockTransactions = blockTransactions;
this.totalValue = totalValue;
}
public Wallet getWallet() {
return wallet;
}
public List<BlockTransaction> getBlockTransactions() {
return blockTransactions;
}
public long getTotalValue() {
return totalValue;
}
}

View file

@ -17,6 +17,7 @@ public class FontAwesome5 extends GlyphFont {
public static enum Glyph implements INamedCharacter { public static enum Glyph implements INamedCharacter {
ARROW_DOWN('\uf063'), ARROW_DOWN('\uf063'),
ARROW_UP('\uf062'), ARROW_UP('\uf062'),
BTC('\uf15a'),
CAMERA('\uf030'), CAMERA('\uf030'),
CHECK_CIRCLE('\uf058'), CHECK_CIRCLE('\uf058'),
CIRCLE('\uf111'), CIRCLE('\uf111'),

View file

@ -5,6 +5,8 @@ import com.sparrowwallet.drongo.wallet.BlockTransaction;
import com.sparrowwallet.drongo.wallet.BlockTransactionHashIndex; import com.sparrowwallet.drongo.wallet.BlockTransactionHashIndex;
import com.sparrowwallet.drongo.wallet.Wallet; import com.sparrowwallet.drongo.wallet.Wallet;
import com.sparrowwallet.drongo.wallet.WalletNode; import com.sparrowwallet.drongo.wallet.WalletNode;
import com.sparrowwallet.sparrow.EventManager;
import com.sparrowwallet.sparrow.event.NewWalletTransactionsEvent;
import javafx.beans.property.LongProperty; import javafx.beans.property.LongProperty;
import javafx.beans.property.LongPropertyBase; import javafx.beans.property.LongPropertyBase;
@ -64,6 +66,12 @@ public class WalletTransactionsEntry extends Entry {
getChildren().removeAll(entriesRemoved); getChildren().removeAll(entriesRemoved);
calculateBalances(); calculateBalances();
if(!entriesAdded.isEmpty()) {
List<BlockTransaction> blockTransactions = entriesAdded.stream().map(txEntry -> ((TransactionEntry)txEntry).getBlockTransaction()).collect(Collectors.toList());
long totalValue = entriesAdded.stream().mapToLong(Entry::getValue).sum();
EventManager.get().post(new NewWalletTransactionsEvent(wallet, blockTransactions, totalValue));
}
} }
private static Collection<WalletTransaction> getWalletTransactions(Wallet wallet) { private static Collection<WalletTransaction> getWalletTransactions(Wallet wallet) {

View file

@ -0,0 +1,29 @@
.notification-bar > .pane {
-fx-padding: 0 7 7 7;
}
.notification-bar > .close-button {
-fx-min-height: 27;
-fx-padding: 10 0 0 0;
-fx-translate-y: 10;
}
.notification-bar > .pane .label.title {
-fx-font-size: 15px;
-fx-text-fill: #292929;
-fx-padding: 5 0 0 68;
-fx-translate-y: 10;
}
.notification-bar > .pane .label {
-fx-font-size: 1em;
-fx-text-fill: #292929;
-fx-alignment: top-left;
-fx-padding: 0 0 0 10;
-fx-graphic-text-gap: 8;
}
.notification-bar > .pane .label .text {
-fx-translate-y: 12;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB