use of bisq.desktop.main.overlays.popups.Popup in project bisq-desktop by bisq-network.
the class BisqApp method showErrorPopup.
private void showErrorPopup(Throwable throwable, boolean doShutDown) {
if (!shutDownRequested) {
if (scene == null) {
log.warn("Scene not available yet, we create a new scene. The bug might be caused by an exception in a constructor or by a circular dependency in guice. throwable=" + throwable.toString());
scene = new Scene(new StackPane(), 1000, 650);
scene.getStylesheets().setAll("/bisq/desktop/bisq.css", "/bisq/desktop/images.css");
primaryStage.setScene(scene);
primaryStage.show();
}
try {
try {
if (!popupOpened) {
String message = throwable.getMessage();
popupOpened = true;
if (message != null)
new Popup<>().error(message).onClose(() -> popupOpened = false).show();
else
new Popup<>().error(throwable.toString()).onClose(() -> popupOpened = false).show();
}
} catch (Throwable throwable3) {
log.error("Error at displaying Throwable.");
throwable3.printStackTrace();
}
if (doShutDown)
stop();
} catch (Throwable throwable2) {
// If printStackTrace cause a further exception we don't pass the throwable to the Popup.
log.error(throwable2.toString());
if (doShutDown)
stop();
}
}
}
use of bisq.desktop.main.overlays.popups.Popup in project bisq-desktop by bisq-network.
the class BisqApp method start.
@SuppressWarnings("PointlessBooleanExpression")
@Override
public void start(Stage stage) throws IOException {
BisqApp.primaryStage = stage;
try {
// Guice
bisqAppModule = new BisqAppModule(bisqEnvironment, primaryStage);
injector = Guice.createInjector(bisqAppModule);
injector.getInstance(InjectorViewFactory.class).setInjector(injector);
// All classes which are persisting objects need to be added here
// Maintain order!
ArrayList<PersistedDataHost> persistedDataHosts = new ArrayList<>();
final Preferences preferences = injector.getInstance(Preferences.class);
persistedDataHosts.add(preferences);
persistedDataHosts.add(injector.getInstance(User.class));
persistedDataHosts.add(injector.getInstance(Navigation.class));
persistedDataHosts.add(injector.getInstance(AddressEntryList.class));
persistedDataHosts.add(injector.getInstance(OpenOfferManager.class));
persistedDataHosts.add(injector.getInstance(TradeManager.class));
persistedDataHosts.add(injector.getInstance(ClosedTradableManager.class));
persistedDataHosts.add(injector.getInstance(FailedTradesManager.class));
persistedDataHosts.add(injector.getInstance(DisputeManager.class));
persistedDataHosts.add(injector.getInstance(P2PService.class));
persistedDataHosts.add(injector.getInstance(ProposalCollectionsService.class));
persistedDataHosts.add(injector.getInstance(VoteService.class));
// we apply at startup the reading of persisted data but don't want to get it triggered in the constructor
persistedDataHosts.forEach(e -> {
try {
log.debug("call readPersisted at " + e.getClass().getSimpleName());
e.readPersisted();
} catch (Throwable e1) {
log.error("readPersisted error", e1);
}
});
boolean useDevMode = injector.getInstance(Key.get(Boolean.class, Names.named(AppOptionKeys.USE_DEV_MODE)));
DevEnv.setDevMode(useDevMode);
Version.setBaseCryptoNetworkId(BisqEnvironment.getBaseCurrencyNetwork().ordinal());
Version.printVersion();
if (Utilities.isLinux())
System.setProperty("prism.lcdtext", "false");
Storage.setDatabaseCorruptionHandler((String fileName) -> {
corruptedDatabaseFiles.add(fileName);
if (mainView != null)
mainView.setPersistedFilesCorrupted(corruptedDatabaseFiles);
});
// load the main view and create the main scene
CachingViewLoader viewLoader = injector.getInstance(CachingViewLoader.class);
mainView = (MainView) viewLoader.load(MainView.class);
mainView.setPersistedFilesCorrupted(corruptedDatabaseFiles);
scene = new Scene(mainView.getRoot(), INITIAL_SCENE_WIDTH, INITIAL_SCENE_HEIGHT);
scene.getStylesheets().setAll("/bisq/desktop/bisq.css", "/bisq/desktop/images.css", "/bisq/desktop/CandleStickChart.css");
// configure the system tray
SystemTray.create(primaryStage, shutDownHandler);
primaryStage.setOnCloseRequest(event -> {
event.consume();
stop();
});
scene.addEventHandler(KeyEvent.KEY_RELEASED, keyEvent -> {
Utilities.isAltOrCtrlPressed(KeyCode.W, keyEvent);
if (Utilities.isCtrlPressed(KeyCode.W, keyEvent) || Utilities.isCtrlPressed(KeyCode.Q, keyEvent)) {
stop();
} else {
if (Utilities.isAltOrCtrlPressed(KeyCode.E, keyEvent)) {
showEmptyWalletPopup(injector.getInstance(BtcWalletService.class));
} else if (Utilities.isAltOrCtrlPressed(KeyCode.M, keyEvent)) {
showSendAlertMessagePopup();
} else if (Utilities.isAltOrCtrlPressed(KeyCode.F, keyEvent)) {
showFilterPopup();
} else if (Utilities.isAltOrCtrlPressed(KeyCode.J, keyEvent)) {
WalletsManager walletsManager = injector.getInstance(WalletsManager.class);
if (walletsManager.areWalletsAvailable())
new ShowWalletDataWindow(walletsManager).show();
else
new Popup<>().warning(Res.get("popup.warning.walletNotInitialized")).show();
} else if (Utilities.isAltOrCtrlPressed(KeyCode.G, keyEvent)) {
if (injector.getInstance(BtcWalletService.class).isWalletReady())
injector.getInstance(ManualPayoutTxWindow.class).show();
else
new Popup<>().warning(Res.get("popup.warning.walletNotInitialized")).show();
} else if (DevEnv.isDevMode()) {
// dev ode only
if (Utilities.isAltOrCtrlPressed(KeyCode.B, keyEvent)) {
// BSQ empty wallet not public yet
showEmptyWalletPopup(injector.getInstance(BsqWalletService.class));
} else if (Utilities.isAltOrCtrlPressed(KeyCode.P, keyEvent)) {
showFPSWindow();
} else if (Utilities.isAltOrCtrlPressed(KeyCode.Z, keyEvent)) {
showDebugWindow();
}
}
}
});
// configure the primary stage
primaryStage.setTitle(bisqEnvironment.getRequiredProperty(AppOptionKeys.APP_NAME_KEY));
primaryStage.setScene(scene);
primaryStage.setMinWidth(1020);
primaryStage.setMinHeight(620);
// on windows the title icon is also used as task bar icon in a larger size
// on Linux no title icon is supported but also a large task bar icon is derived from that title icon
String iconPath;
if (Utilities.isOSX())
iconPath = ImageUtil.isRetina() ? "/images/window_icon@2x.png" : "/images/window_icon.png";
else if (Utilities.isWindows())
iconPath = "/images/task_bar_icon_windows.png";
else
iconPath = "/images/task_bar_icon_linux.png";
primaryStage.getIcons().add(new Image(getClass().getResourceAsStream(iconPath)));
// make the UI visible
primaryStage.show();
if (!Utilities.isCorrectOSArchitecture()) {
String osArchitecture = Utilities.getOSArchitecture();
// We don't force a shutdown as the osArchitecture might in strange cases return a wrong value.
// Needs at least more testing on different machines...
new Popup<>().warning(Res.get("popup.warning.wrongVersion", osArchitecture, Utilities.getJVMArchitecture(), osArchitecture)).show();
}
UserThread.runPeriodically(() -> Profiler.printSystemLoad(log), LOG_MEMORY_PERIOD_MIN, TimeUnit.MINUTES);
} catch (Throwable throwable) {
log.error("Error during app init", throwable);
showErrorPopup(throwable, false);
}
}
use of bisq.desktop.main.overlays.popups.Popup in project bisq-desktop by bisq-network.
the class MainView method initialize.
@Override
protected void initialize() {
MainView.rootContainer = root;
ToggleButton marketButton = new NavButton(MarketView.class, Res.get("mainView.menu.market"));
ToggleButton buyButton = new NavButton(BuyOfferView.class, Res.get("mainView.menu.buyBtc"));
ToggleButton sellButton = new NavButton(SellOfferView.class, Res.get("mainView.menu.sellBtc"));
ToggleButton portfolioButton = new NavButton(PortfolioView.class, Res.get("mainView.menu.portfolio"));
ToggleButton fundsButton = new NavButton(FundsView.class, Res.get("mainView.menu.funds"));
ToggleButton disputesButton = new NavButton(DisputesView.class, Res.get("mainView.menu.support"));
ToggleButton settingsButton = new NavButton(SettingsView.class, Res.get("mainView.menu.settings"));
ToggleButton accountButton = new NavButton(AccountView.class, Res.get("mainView.menu.account"));
ToggleButton daoButton = new NavButton(DaoView.class, Res.get("mainView.menu.dao"));
Pane portfolioButtonHolder = new Pane(portfolioButton);
Pane disputesButtonHolder = new Pane(disputesButton);
if (!BisqEnvironment.isDAOActivatedAndBaseCurrencySupportingBsq()) {
daoButton.setVisible(false);
daoButton.setManaged(false);
}
root.sceneProperty().addListener((observable, oldValue, newValue) -> {
if (newValue != null) {
newValue.addEventHandler(KeyEvent.KEY_RELEASED, keyEvent -> {
// TODO can be removed once DAO is released
if (Utilities.isAltOrCtrlPressed(KeyCode.D, keyEvent)) {
if (BisqEnvironment.getBaseCurrencyNetwork().isBitcoin()) {
daoButton.setVisible(true);
daoButton.setManaged(true);
}
} else if (Utilities.isAltOrCtrlPressed(KeyCode.DIGIT1, keyEvent)) {
marketButton.fire();
} else if (Utilities.isAltOrCtrlPressed(KeyCode.DIGIT2, keyEvent)) {
buyButton.fire();
} else if (Utilities.isAltOrCtrlPressed(KeyCode.DIGIT3, keyEvent)) {
sellButton.fire();
} else if (Utilities.isAltOrCtrlPressed(KeyCode.DIGIT4, keyEvent)) {
portfolioButton.fire();
} else if (Utilities.isAltOrCtrlPressed(KeyCode.DIGIT5, keyEvent)) {
fundsButton.fire();
} else if (Utilities.isAltOrCtrlPressed(KeyCode.DIGIT6, keyEvent)) {
disputesButton.fire();
} else if (Utilities.isAltOrCtrlPressed(KeyCode.DIGIT7, keyEvent)) {
settingsButton.fire();
} else if (Utilities.isAltOrCtrlPressed(KeyCode.DIGIT8, keyEvent)) {
accountButton.fire();
} else if (Utilities.isAltOrCtrlPressed(KeyCode.DIGIT9, keyEvent)) {
if (daoButton.isVisible())
daoButton.fire();
}
});
}
});
HBox leftNavPane = new HBox(marketButton, buyButton, sellButton, portfolioButtonHolder, fundsButton, disputesButtonHolder) {
{
setLeftAnchor(this, 10d);
setTopAnchor(this, 0d);
}
};
Tuple2<ComboBox<PriceFeedComboBoxItem>, VBox> marketPriceBox = getMarketPriceBox();
ComboBox<PriceFeedComboBoxItem> priceComboBox = marketPriceBox.first;
priceComboBox.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
model.setPriceFeedComboBoxItem(newValue);
});
ChangeListener<PriceFeedComboBoxItem> selectedPriceFeedItemListener = (observable, oldValue, newValue) -> {
if (newValue != null)
priceComboBox.getSelectionModel().select(newValue);
};
model.selectedPriceFeedComboBoxItemProperty.addListener(selectedPriceFeedItemListener);
priceComboBox.setItems(model.priceFeedComboBoxItems);
HBox.setMargin(marketPriceBox.second, new Insets(0, 0, 0, 0));
Tuple2<TextField, VBox> availableBalanceBox = getBalanceBox(Res.get("mainView.balance.available"));
availableBalanceBox.first.textProperty().bind(model.availableBalance);
Tuple2<TextField, VBox> reservedBalanceBox = getBalanceBox(Res.get("mainView.balance.reserved"));
reservedBalanceBox.first.textProperty().bind(model.reservedBalance);
Tuple2<TextField, VBox> lockedBalanceBox = getBalanceBox(Res.get("mainView.balance.locked"));
lockedBalanceBox.first.textProperty().bind(model.lockedBalance);
HBox rightNavPane = new HBox(marketPriceBox.second, availableBalanceBox.second, reservedBalanceBox.second, lockedBalanceBox.second, settingsButton, accountButton, daoButton) {
{
setRightAnchor(this, 10d);
setTopAnchor(this, 0d);
}
};
root.widthProperty().addListener((observable, oldValue, newValue) -> {
double w = (double) newValue;
if (w > 0) {
leftNavPane.setSpacing(w >= 1080 ? 12 : 6);
rightNavPane.setSpacing(w >= 1080 ? 12 : 6);
}
});
AnchorPane contentContainer = new AnchorPane() {
{
setId("content-pane");
setLeftAnchor(this, 0d);
setRightAnchor(this, 0d);
setTopAnchor(this, 60d);
setBottomAnchor(this, 10d);
}
};
AnchorPane applicationContainer = new AnchorPane(leftNavPane, rightNavPane, contentContainer) {
{
setId("content-pane");
}
};
BorderPane baseApplicationContainer = new BorderPane(applicationContainer) {
{
setId("base-content-container");
}
};
baseApplicationContainer.setBottom(createFooter());
setupNotificationIcon(portfolioButtonHolder);
setupDisputesIcon(disputesButtonHolder);
navigation.addListener(viewPath -> {
if (viewPath.size() != 2 || viewPath.indexOf(MainView.class) != 0)
return;
Class<? extends View> viewClass = viewPath.tip();
View view = viewLoader.load(viewClass);
contentContainer.getChildren().setAll(view.getRoot());
navButtons.getToggles().stream().filter(toggle -> toggle instanceof NavButton).filter(button -> viewClass == ((NavButton) button).viewClass).findFirst().orElseThrow(() -> new BisqException("No button matching %s found", viewClass)).setSelected(true);
});
VBox splashScreen = createSplashScreen();
root.getChildren().addAll(baseApplicationContainer, splashScreen);
model.showAppScreen.addListener((ov, oldValue, newValue) -> {
if (newValue) {
navigation.navigateToPreviousVisitedView();
if (!persistedFilesCorrupted.isEmpty()) {
if (persistedFilesCorrupted.size() > 1 || !persistedFilesCorrupted.get(0).equals("ViewPathAsString")) {
// show warning that some files has been corrupted
new Popup<>().warning(Res.get("popup.warning.incompatibleDB", persistedFilesCorrupted.toString(), model.getAppDateDir())).useShutDownButton().show();
} else {
log.debug("We detected incompatible data base file for Navigation. That is a minor issue happening with refactoring of UI classes " + "and we don't display a warning popup to the user.");
}
}
transitions.fadeOutAndRemove(splashScreen, 1500, actionEvent -> disposeSplashScreen());
}
});
// Delay a bit to give time for rendering the splash screen
UserThread.execute(model::start);
}
use of bisq.desktop.main.overlays.popups.Popup in project bisq-desktop by bisq-network.
the class MainViewModel method checkCryptoSetup.
private void checkCryptoSetup() {
BooleanProperty result = new SimpleBooleanProperty();
// We want to test if the client is compiled with the correct crypto provider (BountyCastle)
// and if the unlimited Strength for cryptographic keys is set.
// If users compile themselves they might miss that step and then would get an exception in the trade.
// To avoid that we add here at startup a sample encryption and signing to see if it don't causes an exception.
// See: https://github.com/bisq-network/exchange/blob/master/doc/build.md#7-enable-unlimited-strength-for-cryptographic-keys
Thread checkCryptoThread = new Thread() {
@Override
public void run() {
try {
Thread.currentThread().setName("checkCryptoThread");
log.trace("Run crypto test");
// just use any simple dummy msg
Ping payload = new Ping(1, 1);
SealedAndSigned sealedAndSigned = EncryptionService.encryptHybridWithSignature(payload, keyRing.getSignatureKeyPair(), keyRing.getPubKeyRing().getEncryptionPubKey());
DecryptedDataTuple tuple = encryptionService.decryptHybridWithSignature(sealedAndSigned, keyRing.getEncryptionKeyPair().getPrivate());
if (tuple.getNetworkEnvelope() instanceof Ping && ((Ping) tuple.getNetworkEnvelope()).getNonce() == payload.getNonce() && ((Ping) tuple.getNetworkEnvelope()).getLastRoundTripTime() == payload.getLastRoundTripTime()) {
log.debug("Crypto test succeeded");
if (Security.getProvider("BC") != null) {
UserThread.execute(() -> result.set(true));
} else {
throw new CryptoException("Security provider BountyCastle is not available.");
}
} else {
throw new CryptoException("Payload not correct after decryption");
}
} catch (CryptoException e) {
e.printStackTrace();
String msg = Res.get("popup.warning.cryptoTestFailed", e.getMessage());
log.error(msg);
UserThread.execute(() -> new Popup<>().warning(msg).useShutDownButton().useReportBugButton().show());
}
}
};
checkCryptoThread.start();
}
use of bisq.desktop.main.overlays.popups.Popup in project bisq-desktop by bisq-network.
the class MainViewModel method checkForLockedUpFunds.
private void checkForLockedUpFunds() {
Set<String> tradesIdSet = tradeManager.getLockedTradesStream().filter(Trade::hasFailed).map(Trade::getId).collect(Collectors.toSet());
tradesIdSet.addAll(failedTradesManager.getLockedTradesStream().map(Trade::getId).collect(Collectors.toSet()));
tradesIdSet.addAll(closedTradableManager.getLockedTradesStream().map(e -> {
log.warn("We found a closed trade with locked up funds. " + "That should never happen. trade ID=" + e.getId());
return e.getId();
}).collect(Collectors.toSet()));
btcWalletService.getAddressEntriesForTrade().stream().filter(e -> tradesIdSet.contains(e.getOfferId()) && e.getContext() == AddressEntry.Context.MULTI_SIG).forEach(e -> {
final Coin balance = e.getCoinLockedInMultiSig();
final String message = Res.get("popup.warning.lockedUpFunds", formatter.formatCoinWithCode(balance), e.getAddressString(), e.getOfferId());
log.warn(message);
new Popup<>().warning(message).show();
});
}
Aggregations