Fix Number of open trades not updating #286

This commit is contained in:
Manfred Karrer 2014-11-27 02:42:47 +01:00
parent 635f839f78
commit ac95325e5c
3 changed files with 94 additions and 83 deletions

View file

@ -39,8 +39,8 @@ import javax.inject.Named;
import viewfx.view.FxmlView; import viewfx.view.FxmlView;
import viewfx.view.View; import viewfx.view.View;
import viewfx.view.ViewLoader; import viewfx.view.ViewLoader;
import viewfx.view.support.ActivatableView;
import viewfx.view.support.CachingViewLoader; import viewfx.view.support.CachingViewLoader;
import viewfx.view.support.InitializableView;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.geometry.Insets; import javafx.geometry.Insets;
@ -56,7 +56,7 @@ import javafx.scene.text.*;
import static javafx.scene.layout.AnchorPane.*; import static javafx.scene.layout.AnchorPane.*;
@FxmlView @FxmlView
public class MainView extends ActivatableView<StackPane, MainViewModel> { public class MainView extends InitializableView<StackPane, MainViewModel> {
public static final String TITLE_KEY = "view.title"; public static final String TITLE_KEY = "view.title";
@ -78,17 +78,10 @@ public class MainView extends ActivatableView<StackPane, MainViewModel> {
this.overlayManager = overlayManager; this.overlayManager = overlayManager;
this.transitions = transitions; this.transitions = transitions;
this.title = title; this.title = title;
model.getTradeManager().featureNotImplementedWarningProperty().addListener((ov, oldValue, newValue) -> {
if (oldValue == null && newValue != null) {
Popups.openWarningPopup(newValue);
model.getTradeManager().setFeatureNotImplementedWarning(null);
}
});
} }
@Override @Override
protected void activate() { protected void initialize() {
ToggleButton homeButton = new NavButton(HomeView.class, "Overview") {{ ToggleButton homeButton = new NavButton(HomeView.class, "Overview") {{
setDisable(true); // during irc demo setDisable(true); // during irc demo
}}; }};
@ -133,6 +126,8 @@ public class MainView extends ActivatableView<StackPane, MainViewModel> {
setId("base-content-container"); setId("base-content-container");
}}; }};
setupNotificationIcon(portfolioButtonHolder);
navigation.addListener(viewPath -> { navigation.addListener(viewPath -> {
if (viewPath.size() != 2 || viewPath.indexOf(MainView.class) != 0) if (viewPath.size() != 2 || viewPath.indexOf(MainView.class) != 0)
return; return;
@ -155,26 +150,49 @@ public class MainView extends ActivatableView<StackPane, MainViewModel> {
root.getChildren().addAll(baseApplicationContainer, splashScreen); root.getChildren().addAll(baseApplicationContainer, splashScreen);
Platform.runLater( model.isReadyForMainScreen.addListener((ov, oldValue, newValue) -> {
() -> model.initBackend().subscribe( if (newValue) {
next -> { bankAccountComboBoxHolder.getChildren().setAll(createBankAccountComboBox());
},
error -> {
},
() -> Platform.runLater(() -> {
bankAccountComboBoxHolder.getChildren().setAll(createBankAccountComboBox());
applyPendingTradesInfoIcon(model.numPendingTrades.get(), portfolioButtonHolder); navigation.navigateToLastOpenView();
model.numPendingTrades.addListener((ov2, prev2, numPendingTrades) ->
applyPendingTradesInfoIcon((int) numPendingTrades, portfolioButtonHolder));
navigation.navigateToLastOpenView(); transitions.fadeOutAndRemove(splashScreen, 1500);
}
});
transitions.fadeOutAndRemove(splashScreen, 1500); model.featureNotImplementedWarning.addListener((ov, oldValue, newValue) -> {
} if (oldValue == null && newValue != null)
) Popups.openWarningPopup(newValue);
) });
);
// Delay a bit to give time for rendering the splash screen
Platform.runLater(() -> model.initBackend());
}
private void setupNotificationIcon(Pane portfolioButtonHolder) {
Label numPendingTradesLabel = new Label();
numPendingTradesLabel.textProperty().bind(model.numPendingTradesAsString);
numPendingTradesLabel.relocate(5, 1);
numPendingTradesLabel.setId("nav-alert-label");
ImageView icon = new ImageView();
icon.setLayoutX(0.5);
icon.setId("image-alert-round");
Pane notification = new Pane();
notification.relocate(30, 9);
notification.setMouseTransparent(true);
notification.setVisible(model.numPendingTrades.get() > 0);
notification.setEffect(new DropShadow(4, 1, 2, Color.GREY));
notification.getChildren().addAll(icon, numPendingTradesLabel);
portfolioButtonHolder.getChildren().add(notification);
model.numPendingTrades.addListener((ov, oldValue, newValue) -> {
notification.setVisible((int) newValue > 0);
if ((int) newValue > 0)
SystemNotification.openInfoNotification(title, "You got a new trade message.");
});
} }
private VBox createSplashScreen() { private VBox createSplashScreen() {
@ -212,7 +230,7 @@ public class MainView extends ActivatableView<StackPane, MainViewModel> {
}); });
Label bitcoinNetworkLabel = new Label(); Label bitcoinNetworkLabel = new Label();
bitcoinNetworkLabel.setText(model.getBitcoinNetwork().toString()); bitcoinNetworkLabel.setText(model.bitcoinNetworkAsString);
bitcoinNetworkLabel.setId("splash-bitcoin-network-label"); bitcoinNetworkLabel.setId("splash-bitcoin-network-label");
HBox blockchainSyncBox = new HBox(); HBox blockchainSyncBox = new HBox();
@ -268,21 +286,19 @@ public class MainView extends ActivatableView<StackPane, MainViewModel> {
} }
private VBox createBankAccountComboBox() { private VBox createBankAccountComboBox() {
final ComboBox<BankAccount> comboBox = new ComboBox<>(model.getUser().getBankAccounts()); final ComboBox<BankAccount> comboBox = new ComboBox<>(model.getBankAccounts());
comboBox.setLayoutY(12); comboBox.setLayoutY(12);
comboBox.setVisibleRowCount(5); comboBox.setVisibleRowCount(5);
comboBox.setConverter(model.getBankAccountsConverter()); comboBox.setConverter(model.getBankAccountsConverter());
comboBox.valueProperty().addListener((ov, oldValue, newValue) ->
model.getUser().setCurrentBankAccount(newValue));
comboBox.disableProperty().bind(model.bankAccountsComboBoxDisable); comboBox.disableProperty().bind(model.bankAccountsComboBoxDisable);
comboBox.promptTextProperty().bind(model.bankAccountsComboBoxPrompt); comboBox.promptTextProperty().bind(model.bankAccountsComboBoxPrompt);
model.getUser().currentBankAccountProperty().addListener((ov, oldValue, newValue) -> comboBox.getSelectionModel().selectedItemProperty().addListener((ov, oldValue, newValue) ->
comboBox.getSelectionModel().select(newValue)); model.setCurrentBankAccount(newValue));
comboBox.getSelectionModel().select(model.getUser().currentBankAccountProperty().get()); model.currentBankAccount.addListener((ov, oldValue, newValue) ->
comboBox.getSelectionModel().select(newValue));
comboBox.getSelectionModel().select(model.currentBankAccount.get());
final Label titleLabel = new Label("Bank account"); final Label titleLabel = new Label("Bank account");
titleLabel.setMouseTransparent(true); titleLabel.setMouseTransparent(true);
@ -299,33 +315,6 @@ public class MainView extends ActivatableView<StackPane, MainViewModel> {
return vBox; return vBox;
} }
private void applyPendingTradesInfoIcon(int numPendingTrades, Pane targetPane) {
if (numPendingTrades <= 0) {
if (targetPane.getChildren().size() > 1) {
targetPane.getChildren().remove(1);
}
return;
}
Label numPendingTradesLabel = new Label(String.valueOf(numPendingTrades));
if (targetPane.getChildren().size() == 1) {
ImageView icon = new ImageView();
icon.setLayoutX(0.5);
icon.setId("image-alert-round");
numPendingTradesLabel.relocate(5, 1);
numPendingTradesLabel.setId("nav-alert-label");
Pane alert = new Pane();
alert.relocate(30, 9);
alert.setMouseTransparent(true);
alert.setEffect(new DropShadow(4, 1, 2, Color.GREY));
alert.getChildren().addAll(icon, numPendingTradesLabel);
targetPane.getChildren().add(alert);
}
SystemNotification.openInfoNotification(title, "You got a new trade message.");
}
private void configureBlurring(Node node) { private void configureBlurring(Node node) {
Popups.setOverlayManager(overlayManager); Popups.setOverlayManager(overlayManager);

View file

@ -20,6 +20,7 @@ package io.bitsquare.gui.main;
import io.bitsquare.bank.BankAccount; import io.bitsquare.bank.BankAccount;
import io.bitsquare.btc.BitcoinNetwork; import io.bitsquare.btc.BitcoinNetwork;
import io.bitsquare.btc.WalletService; import io.bitsquare.btc.WalletService;
import io.bitsquare.gui.components.Popups;
import io.bitsquare.gui.util.BSFormatter; import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.msg.MessageService; import io.bitsquare.msg.MessageService;
import io.bitsquare.network.BootstrapState; import io.bitsquare.network.BootstrapState;
@ -45,6 +46,7 @@ import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty; import javafx.beans.property.StringProperty;
import javafx.collections.ListChangeListener; import javafx.collections.ListChangeListener;
import javafx.collections.MapChangeListener; import javafx.collections.MapChangeListener;
import javafx.collections.ObservableList;
import javafx.util.StringConverter; import javafx.util.StringConverter;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -57,6 +59,7 @@ class MainViewModel implements ViewModel {
final DoubleProperty networkSyncProgress = new SimpleDoubleProperty(-1); final DoubleProperty networkSyncProgress = new SimpleDoubleProperty(-1);
final IntegerProperty numPendingTrades = new SimpleIntegerProperty(0); final IntegerProperty numPendingTrades = new SimpleIntegerProperty(0);
final StringProperty numPendingTradesAsString = new SimpleStringProperty();
final ObjectProperty<BootstrapState> bootstrapState = new SimpleObjectProperty<>(); final ObjectProperty<BootstrapState> bootstrapState = new SimpleObjectProperty<>();
final StringProperty bootstrapStateText = new SimpleStringProperty(); final StringProperty bootstrapStateText = new SimpleStringProperty();
final ObjectProperty walletServiceException = new SimpleObjectProperty<Throwable>(); final ObjectProperty walletServiceException = new SimpleObjectProperty<Throwable>();
@ -69,17 +72,22 @@ class MainViewModel implements ViewModel {
final BooleanProperty blockchainSyncIndicatorVisible = new SimpleBooleanProperty(true); final BooleanProperty blockchainSyncIndicatorVisible = new SimpleBooleanProperty(true);
final StringProperty blockchainSyncIconId = new SimpleStringProperty(); final StringProperty blockchainSyncIconId = new SimpleStringProperty();
final StringProperty walletServiceErrorMsg = new SimpleStringProperty(); final StringProperty walletServiceErrorMsg = new SimpleStringProperty();
final BooleanProperty isReadyForMainScreen = new SimpleBooleanProperty();
final DoubleProperty bootstrapProgress = new SimpleDoubleProperty(-1); final DoubleProperty bootstrapProgress = new SimpleDoubleProperty(-1);
final BooleanProperty bootstrapFailed = new SimpleBooleanProperty(); final BooleanProperty bootstrapFailed = new SimpleBooleanProperty();
final StringProperty bootstrapErrorMsg = new SimpleStringProperty(); final StringProperty bootstrapErrorMsg = new SimpleStringProperty();
final StringProperty bootstrapIconId = new SimpleStringProperty(); final StringProperty bootstrapIconId = new SimpleStringProperty();
final StringProperty featureNotImplementedWarning = new SimpleStringProperty();
final ObjectProperty<BankAccount> currentBankAccount = new SimpleObjectProperty<>();
final String bitcoinNetworkAsString;
private final User user; private final User user;
private final WalletService walletService; private final WalletService walletService;
private final MessageService messageService; private final MessageService messageService;
private final TradeManager tradeManager; private final TradeManager tradeManager;
private final BitcoinNetwork bitcoinNetwork;
private final BSFormatter formatter; private final BSFormatter formatter;
@ -92,10 +100,13 @@ class MainViewModel implements ViewModel {
this.messageService = messageService; this.messageService = messageService;
this.tradeManager = tradeManager; this.tradeManager = tradeManager;
this.formatter = formatter; this.formatter = formatter;
this.bitcoinNetwork = bitcoinNetwork;
bitcoinNetworkAsString = bitcoinNetwork.toString();
user.getCurrentBankAccount().addListener((observable, oldValue, newValue) -> persistence.write(user)); user.getCurrentBankAccount().addListener((observable, oldValue, newValue) -> persistence.write(user));
currentBankAccount.bind(user.currentBankAccountProperty());
bootstrapState.addListener((ov, oldValue, newValue) -> { bootstrapState.addListener((ov, oldValue, newValue) -> {
if (newValue == BootstrapState.DISCOVERY_DIRECT_SUCCEEDED || if (newValue == BootstrapState.DISCOVERY_DIRECT_SUCCEEDED ||
newValue == BootstrapState.DISCOVERY_AUTO_PORT_FORWARDING_SUCCEEDED || newValue == BootstrapState.DISCOVERY_AUTO_PORT_FORWARDING_SUCCEEDED ||
@ -148,21 +159,29 @@ class MainViewModel implements ViewModel {
}); });
bankAccountsComboBoxDisable.set(user.getBankAccounts().isEmpty()); bankAccountsComboBoxDisable.set(user.getBankAccounts().isEmpty());
bankAccountsComboBoxPrompt.set(user.getBankAccounts().isEmpty() ? "No accounts" : ""); bankAccountsComboBoxPrompt.set(user.getBankAccounts().isEmpty() ? "No accounts" : "");
tradeManager.featureNotImplementedWarningProperty().addListener((ov, oldValue, newValue) -> {
if (oldValue == null && newValue != null) {
featureNotImplementedWarning.set(newValue);
Popups.openWarningPopup(newValue);
tradeManager.setFeatureNotImplementedWarning(null);
}
});
} }
public Observable<?> initBackend() { public void initBackend() {
walletService.getDownloadProgress().subscribe( walletService.getDownloadProgress().subscribe(
percentage -> Platform.runLater(() -> networkSyncProgress.set(percentage / 100.0)), percentage -> Platform.runLater(() -> networkSyncProgress.set(percentage / 100.0)),
error -> Platform.runLater(() -> System.out.println("error = " + error)), error -> log.error(error.toString()),
() -> Platform.runLater(() -> networkSyncProgress.set(1.0))); () -> Platform.runLater(() -> networkSyncProgress.set(1.0)));
Observable<BootstrapState> message = messageService.init(); Observable<BootstrapState> message = messageService.init();
message.publish(); message.publish();
message.subscribe( message.subscribe(
state -> state -> Platform.runLater(() -> bootstrapState.set(state)),
Platform.runLater(() -> bootstrapState.set(state)),
error -> log.error(error.toString()), error -> log.error(error.toString()),
() -> log.trace("message completed")); () -> log.trace("message completed"));
@ -180,23 +199,19 @@ class MainViewModel implements ViewModel {
error -> log.error(error.toString()), error -> log.error(error.toString()),
() -> Platform.runLater(() -> { () -> Platform.runLater(() -> {
log.trace("backend completed"); log.trace("backend completed");
tradeManager.getPendingTrades().addListener( backEndCompleted();
(MapChangeListener<String, Trade>) change -> updateNumPendingTrades());
updateNumPendingTrades();
}) })
); );
return backend;
} }
private void backEndCompleted() {
public User getUser() { tradeManager.getPendingTrades().addListener(
return user; (MapChangeListener<String, Trade>) change -> updateNumPendingTrades());
updateNumPendingTrades();
isReadyForMainScreen.set(true);
} }
public TradeManager getTradeManager() {
return tradeManager;
}
public StringConverter<BankAccount> getBankAccountsConverter() { public StringConverter<BankAccount> getBankAccountsConverter() {
return new StringConverter<BankAccount>() { return new StringConverter<BankAccount>() {
@ -214,8 +229,9 @@ class MainViewModel implements ViewModel {
private void updateNumPendingTrades() { private void updateNumPendingTrades() {
log.debug("updateNumPendingTrades " + tradeManager.getPendingTrades().size());
numPendingTrades.set(tradeManager.getPendingTrades().size()); numPendingTrades.set(tradeManager.getPendingTrades().size());
if (numPendingTrades.get() > 0)
numPendingTradesAsString.set(String.valueOf(numPendingTrades.get()));
} }
private void setNetworkSyncProgress(double value) { private void setNetworkSyncProgress(double value) {
@ -230,7 +246,12 @@ class MainViewModel implements ViewModel {
blockchainSyncIndicatorVisible.set(value < 1); blockchainSyncIndicatorVisible.set(value < 1);
} }
public BitcoinNetwork getBitcoinNetwork() { public ObservableList<BankAccount> getBankAccounts() {
return bitcoinNetwork; return user.getBankAccounts();
} }
public void setCurrentBankAccount(BankAccount currentBankAccount) {
user.setCurrentBankAccount(currentBankAccount);
}
} }

View file

@ -152,7 +152,8 @@ public class IrcAccountView extends ActivatableViewAndModel<GridPane, IrcAccount
@FXML @FXML
void onSave() { void onSave() {
if (wizard != null && model.requestSaveBankAccount().isValid) boolean isValid = model.requestSaveBankAccount().isValid;
if (wizard != null && isValid)
wizard.nextStep(this); wizard.nextStep(this);
} }