mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-06-25 07:10:48 -04:00
Use PopupManager for queuing popups, improve version handling, deactivate focus requests, add popup when getting disconnection because of version conflict
This commit is contained in:
parent
ba4a228fed
commit
a264fa4e0b
94 changed files with 421 additions and 288 deletions
|
@ -128,18 +128,24 @@ public class BitsquareApp extends Application {
|
|||
injector = Guice.createInjector(bitsquareAppModule);
|
||||
injector.getInstance(InjectorViewFactory.class).setInjector(injector);
|
||||
|
||||
Version.setNetworkId(injector.getInstance(BitsquareEnvironment.class).getBitcoinNetwork().ordinal());
|
||||
|
||||
// load the main view and create the main scene
|
||||
CachingViewLoader viewLoader = injector.getInstance(CachingViewLoader.class);
|
||||
mainView = (MainView) viewLoader.load(MainView.class);
|
||||
mainView.setPersistedFilesCorrupted(corruptedDatabaseFiles);
|
||||
Version.setBtcNetworkId(injector.getInstance(BitsquareEnvironment.class).getBitcoinNetwork().ordinal());
|
||||
|
||||
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);
|
||||
|
||||
/* Storage.setDatabaseCorruptionHandler((String fileName) -> {
|
||||
corruptedDatabaseFiles.add(fileName);
|
||||
if (mainView != null)
|
||||
mainView.setPersistedFilesCorrupted(corruptedDatabaseFiles);
|
||||
});*/
|
||||
|
||||
scene = new Scene(mainView.getRoot(), 1000, 740);
|
||||
scene.getStylesheets().setAll(
|
||||
|
|
|
@ -73,7 +73,8 @@ public class AddressTextField extends AnchorPane {
|
|||
}
|
||||
});
|
||||
textField.focusTraversableProperty().set(focusTraversableProperty().get());
|
||||
focusedProperty().addListener((ov, oldValue, newValue) -> textField.requestFocus());
|
||||
//TODO app wide focus
|
||||
//focusedProperty().addListener((ov, oldValue, newValue) -> textField.requestFocus());
|
||||
|
||||
Label copyIcon = new Label();
|
||||
copyIcon.setLayoutY(3);
|
||||
|
|
|
@ -67,7 +67,8 @@ public class TextFieldWithCopyIcon extends AnchorPane {
|
|||
AnchorPane.setRightAnchor(textField, 30.0);
|
||||
AnchorPane.setLeftAnchor(textField, 0.0);
|
||||
textField.focusTraversableProperty().set(focusTraversableProperty().get());
|
||||
focusedProperty().addListener((ov, oldValue, newValue) -> textField.requestFocus());
|
||||
//TODO app wide focus
|
||||
//focusedProperty().addListener((ov, oldValue, newValue) -> textField.requestFocus());
|
||||
|
||||
getChildren().addAll(textField, copyIcon);
|
||||
}
|
||||
|
|
|
@ -85,7 +85,8 @@ public class TxIdTextField extends AnchorPane {
|
|||
AnchorPane.setRightAnchor(textField, 55.0);
|
||||
AnchorPane.setLeftAnchor(textField, 0.0);
|
||||
textField.focusTraversableProperty().set(focusTraversableProperty().get());
|
||||
focusedProperty().addListener((ov, oldValue, newValue) -> textField.requestFocus());
|
||||
//TODO app wide focus
|
||||
//focusedProperty().addListener((ov, oldValue, newValue) -> textField.requestFocus());
|
||||
|
||||
getChildren().addAll(textField, copyIcon, progressIndicator);
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
package io.bitsquare.gui.main;
|
||||
|
||||
import io.bitsquare.BitsquareException;
|
||||
import io.bitsquare.app.BitsquareApp;
|
||||
import io.bitsquare.common.UserThread;
|
||||
import io.bitsquare.common.util.Tuple2;
|
||||
import io.bitsquare.gui.Navigation;
|
||||
|
@ -184,11 +185,18 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
|
|||
|
||||
if (!persistedFilesCorrupted.isEmpty()) {
|
||||
// show warning that some files has been corrupted
|
||||
new Popup().warning("Those data base file(s) are not compatible with our current code base." +
|
||||
"\n" + persistedFilesCorrupted.toString() +
|
||||
"\n\nWe made a backup of the corrupted file(s) and applied the default values." +
|
||||
"\n\nThe backup is located at: [data directory]/db/corrupted"
|
||||
).show();
|
||||
new Popup().warning("We detected incompatible data base files!\n\n" +
|
||||
"Those database file(s) are not compatible with our current code base:" +
|
||||
"\n" + persistedFilesCorrupted.toString() +
|
||||
"\n\nWe made a backup of the corrupted file(s) and applied the default values to a new " +
|
||||
"database version." +
|
||||
"\n\nThe backup is located at:\n[you local app data directory]/db/backup_of_corrupted_data.\n\n" +
|
||||
"Please check if you have the latest version of Bitsquare installed.\n" +
|
||||
"You can download it at:\nhttps://github.com/bitsquare/bitsquare/releases\n\n" +
|
||||
"Please restart the application.")
|
||||
.closeButtonText("Shut down")
|
||||
.onClose(BitsquareApp.shutDownHandler::run)
|
||||
.show();
|
||||
}
|
||||
|
||||
transitions.fadeOutAndRemove(splashScreen, 1500, actionEvent -> disposeSplashScreen());
|
||||
|
@ -358,7 +366,8 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
|
|||
model.walletServiceErrorMsg.addListener((ov, oldValue, newValue) -> {
|
||||
if (newValue != null) {
|
||||
btcInfoLabel.setId("splash-error-state-msg");
|
||||
btcNetworkWarnMsgPopup = new Popup().warning(newValue).show();
|
||||
btcNetworkWarnMsgPopup = new Popup().warning(newValue);
|
||||
btcNetworkWarnMsgPopup.show();
|
||||
} else {
|
||||
btcInfoLabel.setId("footer-pane");
|
||||
if (btcNetworkWarnMsgPopup != null)
|
||||
|
@ -407,7 +416,8 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
|
|||
p2PNetworkLabel.idProperty().bind(model.p2PNetworkLabelId);
|
||||
model.p2PNetworkWarnMsg.addListener((ov, oldValue, newValue) -> {
|
||||
if (newValue != null) {
|
||||
p2PNetworkWarnMsgPopup = new Popup().warning(newValue).show();
|
||||
p2PNetworkWarnMsgPopup = new Popup().warning(newValue);
|
||||
p2PNetworkWarnMsgPopup.show();
|
||||
} else if (p2PNetworkWarnMsgPopup != null) {
|
||||
p2PNetworkWarnMsgPopup.hide();
|
||||
}
|
||||
|
|
|
@ -41,6 +41,9 @@ import io.bitsquare.locale.CountryUtil;
|
|||
import io.bitsquare.locale.CurrencyUtil;
|
||||
import io.bitsquare.p2p.P2PService;
|
||||
import io.bitsquare.p2p.P2PServiceListener;
|
||||
import io.bitsquare.p2p.network.CloseConnectionReason;
|
||||
import io.bitsquare.p2p.network.Connection;
|
||||
import io.bitsquare.p2p.network.ConnectionListener;
|
||||
import io.bitsquare.payment.OKPayAccount;
|
||||
import io.bitsquare.trade.Trade;
|
||||
import io.bitsquare.trade.TradeManager;
|
||||
|
@ -187,7 +190,7 @@ public class MainViewModel implements ViewModel {
|
|||
"There might be some network connection problems.\n\n" +
|
||||
"Please restart and try again.")
|
||||
.closeButtonText("Shut down")
|
||||
.onClose(() -> BitsquareApp.shutDownHandler.run())
|
||||
.onClose(BitsquareApp.shutDownHandler::run)
|
||||
.show();
|
||||
});
|
||||
}
|
||||
|
@ -211,6 +214,34 @@ public class MainViewModel implements ViewModel {
|
|||
private BooleanProperty initP2PNetwork() {
|
||||
final BooleanProperty p2pNetworkInitialized = new SimpleBooleanProperty();
|
||||
p2PNetworkInfo.set("Connecting to Tor network...");
|
||||
p2PService.getNetworkNode().addConnectionListener(new ConnectionListener() {
|
||||
@Override
|
||||
public void onConnection(Connection connection) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisconnect(CloseConnectionReason closeConnectionReason, Connection connection) {
|
||||
// We only check at seed nodes as they are running the latest version
|
||||
// Other disconnects might be caused by peers running an older version
|
||||
if (connection.getPeerType() == Connection.PeerType.SEED_NODE &&
|
||||
closeConnectionReason == CloseConnectionReason.RULE_VIOLATION) {
|
||||
new Popup()
|
||||
.warning("You got disconnected from a seed node.\n\n" +
|
||||
"Reason for getting disconnected: " + connection.getRuleViolation().name() + "\n\n" +
|
||||
"It might be that your installed version is not compatible with " +
|
||||
"the network.\n\n" +
|
||||
"Please check if you run the latest software version.\n" +
|
||||
"You can download the latest version of Bitsquare at:\n" +
|
||||
"https://github.com/bitsquare/bitsquare/releases/\n\n" +
|
||||
"")
|
||||
.show();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Throwable throwable) {
|
||||
}
|
||||
});
|
||||
p2PService.start(new P2PServiceListener() {
|
||||
@Override
|
||||
public void onTorNodeReady() {
|
||||
|
@ -348,8 +379,9 @@ public class MainViewModel implements ViewModel {
|
|||
if (walletService.getWallet().isEncrypted() &&
|
||||
(openOfferManager.getOpenOffers().size() > 0
|
||||
|| tradeManager.getTrades().size() > 0
|
||||
|| disputeManager.getDisputesAsObservableList().size() > 0))
|
||||
walletPasswordPopup.show().onAesKey(aesKey -> tradeWalletService.setAesKey(aesKey));
|
||||
|| disputeManager.getDisputesAsObservableList().size() > 0)) {
|
||||
walletPasswordPopup.onAesKey(aesKey -> tradeWalletService.setAesKey(aesKey)).show();
|
||||
}
|
||||
|
||||
if (tradeManager.pendingTradesInitializedProperty().get() && isSplashScreenRemoved.get())
|
||||
applyTradePeriodState();
|
||||
|
|
|
@ -24,6 +24,7 @@ import io.bitsquare.common.UserThread;
|
|||
import io.bitsquare.common.util.Tuple2;
|
||||
import io.bitsquare.gui.common.view.ActivatableViewAndModel;
|
||||
import io.bitsquare.gui.common.view.FxmlView;
|
||||
import io.bitsquare.gui.popups.EnterPrivKeyPopup;
|
||||
import io.bitsquare.gui.popups.Popup;
|
||||
import io.bitsquare.gui.util.FormBuilder;
|
||||
import io.bitsquare.gui.util.ImageUtil;
|
||||
|
|
|
@ -114,13 +114,13 @@ public class SeedWordsView extends ActivatableView<GridPane, Void> {
|
|||
|
||||
|
||||
private void askForPassword() {
|
||||
walletPasswordPopup.show().onAesKey(aesKey -> {
|
||||
walletPasswordPopup.onAesKey(aesKey -> {
|
||||
Wallet wallet = walletService.getWallet();
|
||||
KeyCrypter keyCrypter = wallet.getKeyCrypter();
|
||||
keyChainSeed = wallet.getKeyChainSeed();
|
||||
DeterministicSeed decryptedSeed = keyChainSeed.decrypt(keyCrypter, "", aesKey);
|
||||
showSeedScreen(decryptedSeed);
|
||||
});
|
||||
}).show();
|
||||
}
|
||||
|
||||
private void showSeedScreen(DeterministicSeed seed) {
|
||||
|
|
|
@ -21,9 +21,9 @@ import io.bitsquare.arbitration.Dispute;
|
|||
import io.bitsquare.arbitration.DisputeManager;
|
||||
import io.bitsquare.common.crypto.KeyRing;
|
||||
import io.bitsquare.gui.common.view.FxmlView;
|
||||
import io.bitsquare.gui.main.disputes.DisputeSummaryPopup;
|
||||
import io.bitsquare.gui.main.disputes.trader.TraderDisputeView;
|
||||
import io.bitsquare.gui.popups.ContractPopup;
|
||||
import io.bitsquare.gui.popups.DisputeSummaryPopup;
|
||||
import io.bitsquare.gui.popups.TradeDetailsPopup;
|
||||
import io.bitsquare.gui.util.BSFormatter;
|
||||
import io.bitsquare.trade.TradeManager;
|
||||
|
|
|
@ -29,8 +29,8 @@ import io.bitsquare.gui.common.view.ActivatableView;
|
|||
import io.bitsquare.gui.common.view.FxmlView;
|
||||
import io.bitsquare.gui.components.HyperlinkWithIcon;
|
||||
import io.bitsquare.gui.components.TableGroupHeadline;
|
||||
import io.bitsquare.gui.main.disputes.DisputeSummaryPopup;
|
||||
import io.bitsquare.gui.popups.ContractPopup;
|
||||
import io.bitsquare.gui.popups.DisputeSummaryPopup;
|
||||
import io.bitsquare.gui.popups.Popup;
|
||||
import io.bitsquare.gui.popups.TradeDetailsPopup;
|
||||
import io.bitsquare.gui.util.BSFormatter;
|
||||
|
|
|
@ -310,10 +310,11 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
|
|||
}
|
||||
|
||||
private void doWithdraw(Coin amount, FutureCallback<Transaction> callback) {
|
||||
if (walletService.getWallet().isEncrypted())
|
||||
walletPasswordPopup.show().onAesKey(aesKey -> sendFunds(amount, aesKey, callback));
|
||||
else
|
||||
if (walletService.getWallet().isEncrypted()) {
|
||||
walletPasswordPopup.onAesKey(aesKey -> sendFunds(amount, aesKey, callback)).show();
|
||||
} else {
|
||||
sendFunds(amount, null, callback);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendFunds(Coin amount, KeyParameter aesKey, FutureCallback<Transaction> callback) {
|
||||
|
|
|
@ -253,10 +253,10 @@ class CreateOfferDataModel extends ActivatableDataModel {
|
|||
|
||||
void onPlaceOffer(Offer offer, TransactionResultHandler resultHandler) {
|
||||
if (walletService.getWallet().isEncrypted() && tradeWalletService.getAesKey() == null) {
|
||||
walletPasswordPopup.show().onAesKey(aesKey -> {
|
||||
walletPasswordPopup.onAesKey(aesKey -> {
|
||||
tradeWalletService.setAesKey(aesKey);
|
||||
doPlaceOffer(offer, resultHandler);
|
||||
});
|
||||
}).show();
|
||||
} else {
|
||||
doPlaceOffer(offer, resultHandler);
|
||||
}
|
||||
|
|
|
@ -220,7 +220,7 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi
|
|||
}
|
||||
}
|
||||
|
||||
private void onShowInfo(boolean isPaymentAccountValidForOffer, boolean hasMatchingArbitrator) {
|
||||
private void onShowInfo(boolean isPaymentAccountValidForOffer, boolean hasMatchingArbitrator, boolean hasSameProtocolVersion) {
|
||||
if (!hasMatchingArbitrator) {
|
||||
showWarning("You don't have an arbitrator selected.",
|
||||
"You need to setup at least one arbitrator to be able to trade.\n" +
|
||||
|
@ -229,6 +229,13 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi
|
|||
showWarning("You don't have a payment account with the payment method required for that offer.",
|
||||
"You need to setup a payment account with that payment method if you want to take that offer.\n" +
|
||||
"Do you want to do this now?", PaymentAccountView.class);
|
||||
} else if (!hasSameProtocolVersion) {
|
||||
new Popup().information("That offer requires a different protocol version as the one used in your " +
|
||||
"version of the software." +
|
||||
"\n\n" + "Please check if you have the latest version installed, otherwise the user " +
|
||||
"who created the offer has used an older version.\n" +
|
||||
"You cannot trade with an incompatible protocol version.")
|
||||
.show();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -418,39 +425,42 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi
|
|||
boolean isTradable;
|
||||
boolean isPaymentAccountValidForOffer;
|
||||
boolean hasMatchingArbitrator;
|
||||
boolean hasSameProtocolVersion;
|
||||
|
||||
{
|
||||
button.setGraphic(iconView);
|
||||
button.setMinWidth(70);
|
||||
}
|
||||
|
||||
private void verifyIfTradable(final Offer offer) {
|
||||
TableRow tableRow = getTableRow();
|
||||
if (tableRow != null) {
|
||||
isPaymentAccountValidForOffer = model.isPaymentAccountValidForOffer(offer);
|
||||
hasMatchingArbitrator = model.hasMatchingArbitrator(offer);
|
||||
isTradable = isPaymentAccountValidForOffer && hasMatchingArbitrator;
|
||||
|
||||
tableRow.setOpacity(isTradable ? 1 : 0.4);
|
||||
|
||||
if (isTradable) {
|
||||
// set first row button as default
|
||||
button.setDefaultButton(getIndex() == 0);
|
||||
tableRow.setOnMouseClicked(null);
|
||||
} else {
|
||||
button.setDefaultButton(false);
|
||||
tableRow.setOnMouseClicked(e -> onShowInfo(isPaymentAccountValidForOffer, hasMatchingArbitrator));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateItem(final OfferBookListItem newItem, boolean empty) {
|
||||
super.updateItem(newItem, empty);
|
||||
|
||||
if (newItem != null && !empty) {
|
||||
final Offer offer = newItem.getOffer();
|
||||
verifyIfTradable(offer);
|
||||
|
||||
TableRow tableRow = getTableRow();
|
||||
if (tableRow != null) {
|
||||
isPaymentAccountValidForOffer = model.isPaymentAccountValidForOffer(offer);
|
||||
hasMatchingArbitrator = model.hasMatchingArbitrator(offer);
|
||||
hasSameProtocolVersion = model.hasSameProtocolVersion(offer);
|
||||
isTradable = isPaymentAccountValidForOffer && hasMatchingArbitrator &&
|
||||
hasSameProtocolVersion;
|
||||
|
||||
tableRow.setOpacity(isTradable ? 1 : 0.4);
|
||||
|
||||
if (isTradable) {
|
||||
// set first row button as default
|
||||
button.setDefaultButton(getIndex() == 0);
|
||||
tableRow.setOnMouseClicked(null);
|
||||
} else {
|
||||
button.setDefaultButton(false);
|
||||
tableRow.setOnMouseClicked(e ->
|
||||
onShowInfo(isPaymentAccountValidForOffer, hasMatchingArbitrator,
|
||||
hasSameProtocolVersion));
|
||||
}
|
||||
}
|
||||
|
||||
String title;
|
||||
if (isTradable) {
|
||||
if (model.isMyOffer(offer)) {
|
||||
|
@ -465,7 +475,7 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi
|
|||
} else {
|
||||
title = "Not matching";
|
||||
iconView.setId(null);
|
||||
button.setOnAction(e -> onShowInfo(isPaymentAccountValidForOffer, hasMatchingArbitrator));
|
||||
button.setOnAction(e -> onShowInfo(isPaymentAccountValidForOffer, hasMatchingArbitrator, hasSameProtocolVersion));
|
||||
}
|
||||
|
||||
button.setText(title);
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
package io.bitsquare.gui.main.offer.offerbook;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import io.bitsquare.app.Version;
|
||||
import io.bitsquare.common.handlers.ErrorMessageHandler;
|
||||
import io.bitsquare.common.handlers.ResultHandler;
|
||||
import io.bitsquare.gui.common.model.ActivatableViewModel;
|
||||
|
@ -281,7 +282,6 @@ class OfferBookViewModel extends ActivatableViewModel {
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
public boolean hasMatchingArbitrator(Offer offer) {
|
||||
for (NodeAddress offerArbitratorNodeAddress : offer.getArbitratorNodeAddresses()) {
|
||||
for (NodeAddress acceptedArbitratorNodeAddress : user.getAcceptedArbitratorAddresses()) {
|
||||
|
@ -291,4 +291,8 @@ class OfferBookViewModel extends ActivatableViewModel {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean hasSameProtocolVersion(Offer offer) {
|
||||
return offer.getProtocolVersion() == Version.TRADE_PROTOCOL_VERSION;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -167,10 +167,10 @@ class TakeOfferDataModel extends ActivatableDataModel {
|
|||
// have it persisted as well.
|
||||
void onTakeOffer(TradeResultHandler tradeResultHandler) {
|
||||
if (walletService.getWallet().isEncrypted() && tradeWalletService.getAesKey() == null) {
|
||||
walletPasswordPopup.show().onAesKey(aesKey -> {
|
||||
walletPasswordPopup.onAesKey(aesKey -> {
|
||||
tradeWalletService.setAesKey(aesKey);
|
||||
doTakeOffer(tradeResultHandler);
|
||||
});
|
||||
}).show();
|
||||
} else {
|
||||
doTakeOffer(tradeResultHandler);
|
||||
}
|
||||
|
|
|
@ -182,11 +182,11 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
|||
.subscribe((observable, oldValue, newValue) -> {
|
||||
if (!oldValue && newValue) {
|
||||
isOfferAvailablePopup = new Popup().information(BSResources.get("takeOffer.fundsBox.isOfferAvailable"))
|
||||
.show()
|
||||
.onClose(() -> {
|
||||
model.resetErrorMessage();
|
||||
close();
|
||||
}).show();
|
||||
});
|
||||
isOfferAvailablePopup.show();
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -170,9 +170,9 @@ public class PendingTradesDataModel extends ActivatableDataModel {
|
|||
|
||||
void onWithdrawRequest(String toAddress) {
|
||||
checkNotNull(trade, "trade must not be null");
|
||||
if (walletService.getWallet().isEncrypted())
|
||||
walletPasswordPopup.show().onAesKey(aesKey -> doWithdrawRequest(toAddress, aesKey));
|
||||
else
|
||||
if (walletService.getWallet().isEncrypted()) {
|
||||
walletPasswordPopup.onAesKey(aesKey -> doWithdrawRequest(toAddress, aesKey)).show();
|
||||
} else
|
||||
doWithdrawRequest(toAddress, null);
|
||||
}
|
||||
|
||||
|
|
|
@ -110,8 +110,9 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
|
|||
// Focus selectedItem from model
|
||||
int index = table.getItems().indexOf(model.getSelectedItem());
|
||||
UserThread.execute(() -> {
|
||||
table.requestFocus();
|
||||
UserThread.execute(() -> table.getFocusModel().focus(index));
|
||||
//TODO app wide focus
|
||||
//table.requestFocus();
|
||||
//UserThread.execute(() -> table.getFocusModel().focus(index));
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@ -151,9 +152,10 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
|
|||
// Select and focus selectedItem from model
|
||||
int index = table.getItems().indexOf(selectedItem);
|
||||
UserThread.execute(() -> {
|
||||
//TODO app wide focus
|
||||
table.getSelectionModel().select(index);
|
||||
table.requestFocus();
|
||||
UserThread.execute(() -> table.getFocusModel().focus(index));
|
||||
//table.requestFocus();
|
||||
//UserThread.execute(() -> table.getFocusModel().focus(index));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,11 +69,12 @@ public class CompletedView extends TradeStepDetailsView {
|
|||
// We need to handle both cases: Address not set and address already set (when returning from other view)
|
||||
// We get address validation after focus out, so first make sure we loose focus and then set it again as hint for user to put address in
|
||||
UserThread.execute(() -> {
|
||||
withdrawAddressTextField.requestFocus();
|
||||
UserThread.execute(() -> {
|
||||
//TODO app wide focus
|
||||
// withdrawAddressTextField.requestFocus();
|
||||
/* UserThread.execute(() -> {
|
||||
this.requestFocus();
|
||||
UserThread.execute(() -> withdrawAddressTextField.requestFocus());
|
||||
});
|
||||
});*/
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ public class ContractPopup extends Popup {
|
|||
width = 850;
|
||||
createGridPane();
|
||||
addContent();
|
||||
createPopup();
|
||||
display();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -152,7 +152,8 @@ public class ContractPopup extends Popup {
|
|||
addLabelTxIdTextField(gridPane, ++rowIndex, "Payout transaction ID:", dispute.getPayoutTxId());
|
||||
|
||||
Button cancelButton = addButtonAfterGroup(gridPane, ++rowIndex, "Close");
|
||||
cancelButton.requestFocus();
|
||||
//TODO app wide focus
|
||||
//cancelButton.requestFocus();
|
||||
cancelButton.setOnAction(e -> {
|
||||
closeHandlerOptional.ifPresent(closeHandler -> closeHandler.run());
|
||||
hide();
|
||||
|
|
|
@ -46,15 +46,14 @@ public class DisplayAlertMessagePopup extends Popup {
|
|||
public DisplayAlertMessagePopup() {
|
||||
}
|
||||
|
||||
public DisplayAlertMessagePopup show() {
|
||||
public void show() {
|
||||
width = 700;
|
||||
// need to set headLine, otherwise the fields will not be created in addHeadLine
|
||||
headLine = "Important information!";
|
||||
createGridPane();
|
||||
addHeadLine();
|
||||
addContent();
|
||||
createPopup();
|
||||
return this;
|
||||
PopupManager.queueForDisplay(this);
|
||||
}
|
||||
|
||||
public DisplayAlertMessagePopup alertMessage(Alert alert) {
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.gui.main.disputes;
|
||||
package io.bitsquare.gui.popups;
|
||||
|
||||
import io.bitsquare.arbitration.Dispute;
|
||||
import io.bitsquare.arbitration.DisputeManager;
|
||||
|
@ -26,7 +26,6 @@ import io.bitsquare.btc.TradeWalletService;
|
|||
import io.bitsquare.btc.WalletService;
|
||||
import io.bitsquare.btc.exceptions.TransactionVerificationException;
|
||||
import io.bitsquare.common.util.Tuple2;
|
||||
import io.bitsquare.gui.popups.Popup;
|
||||
import io.bitsquare.gui.util.BSFormatter;
|
||||
import io.bitsquare.gui.util.Layout;
|
||||
import io.bitsquare.gui.util.Transitions;
|
||||
|
@ -89,7 +88,7 @@ public class DisputeSummaryPopup extends Popup {
|
|||
width = 850;
|
||||
createGridPane();
|
||||
addContent();
|
||||
createPopup();
|
||||
PopupManager.queueForDisplay(this);
|
||||
}
|
||||
|
||||
public DisputeSummaryPopup onClose(Runnable closeHandler) {
|
|
@ -64,7 +64,7 @@ public class EmptyWalletPopup extends Popup {
|
|||
this.formatter = formatter;
|
||||
}
|
||||
|
||||
public EmptyWalletPopup show() {
|
||||
public void show() {
|
||||
if (headLine == null)
|
||||
headLine = "Empty wallet";
|
||||
|
||||
|
@ -72,8 +72,7 @@ public class EmptyWalletPopup extends Popup {
|
|||
createGridPane();
|
||||
addHeadLine();
|
||||
addContent();
|
||||
createPopup();
|
||||
return this;
|
||||
PopupManager.queueForDisplay(this);
|
||||
}
|
||||
|
||||
public EmptyWalletPopup onClose(Runnable closeHandler) {
|
||||
|
|
|
@ -15,11 +15,10 @@
|
|||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.gui.main.account.arbitratorregistration;
|
||||
package io.bitsquare.gui.popups;
|
||||
|
||||
import io.bitsquare.app.BitsquareApp;
|
||||
import io.bitsquare.gui.components.InputTextField;
|
||||
import io.bitsquare.gui.popups.Popup;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
|
@ -50,7 +49,7 @@ public class EnterPrivKeyPopup extends Popup {
|
|||
public EnterPrivKeyPopup() {
|
||||
}
|
||||
|
||||
public EnterPrivKeyPopup show() {
|
||||
public void show() {
|
||||
if (gridPane != null) {
|
||||
rowIndex = -1;
|
||||
gridPane.getChildren().clear();
|
||||
|
@ -63,9 +62,7 @@ public class EnterPrivKeyPopup extends Popup {
|
|||
addHeadLine();
|
||||
addInputFields();
|
||||
addButtons();
|
||||
createPopup();
|
||||
|
||||
return this;
|
||||
PopupManager.queueForDisplay(this);
|
||||
}
|
||||
|
||||
public EnterPrivKeyPopup onClose(Runnable closeHandler) {
|
|
@ -79,7 +79,7 @@ public class OfferDetailsPopup extends Popup {
|
|||
width = 850;
|
||||
createGridPane();
|
||||
addContent();
|
||||
createPopup();
|
||||
display();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -90,7 +90,7 @@ public class OfferDetailsPopup extends Popup {
|
|||
width = 850;
|
||||
createGridPane();
|
||||
addContent();
|
||||
createPopup();
|
||||
display();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ public class OpenEmergencyTicketPopup extends Popup {
|
|||
public OpenEmergencyTicketPopup() {
|
||||
}
|
||||
|
||||
public OpenEmergencyTicketPopup show() {
|
||||
public void show() {
|
||||
if (headLine == null)
|
||||
headLine = "Open support ticket";
|
||||
|
||||
|
@ -50,8 +50,7 @@ public class OpenEmergencyTicketPopup extends Popup {
|
|||
createGridPane();
|
||||
addHeadLine();
|
||||
addContent();
|
||||
createPopup();
|
||||
return this;
|
||||
PopupManager.queueForDisplay(this);
|
||||
}
|
||||
|
||||
public OpenEmergencyTicketPopup onOpenTicket(ResultHandler openTicketHandler) {
|
||||
|
|
|
@ -78,7 +78,7 @@ public class Popup {
|
|||
public Popup() {
|
||||
}
|
||||
|
||||
public Popup show() {
|
||||
public void show() {
|
||||
createGridPane();
|
||||
addHeadLine();
|
||||
|
||||
|
@ -91,13 +91,16 @@ public class Popup {
|
|||
|
||||
addCloseButton();
|
||||
addDontShowAgainCheckBox();
|
||||
createPopup();
|
||||
return this;
|
||||
PopupManager.queueForDisplay(this);
|
||||
}
|
||||
|
||||
public void hide() {
|
||||
MainView.removeBlur();
|
||||
stage.hide();
|
||||
if (stage != null)
|
||||
stage.hide();
|
||||
else
|
||||
log.warn("Stage is null");
|
||||
PopupManager.isHidden(this);
|
||||
}
|
||||
|
||||
public Popup onClose(Runnable closeHandler) {
|
||||
|
@ -207,7 +210,7 @@ public class Popup {
|
|||
FxTimer.runLater(Duration.ofMillis(Transitions.DEFAULT_DURATION), () -> MainView.blurLight());
|
||||
}
|
||||
|
||||
protected void createPopup() {
|
||||
public void display() {
|
||||
if (owner == null)
|
||||
owner = MainView.getRootContainer();
|
||||
|
||||
|
@ -333,7 +336,8 @@ public class Popup {
|
|||
if (actionHandlerOptional.isPresent() || actionButtonText != null) {
|
||||
actionButton = new Button(actionButtonText == null ? "Ok" : actionButtonText);
|
||||
actionButton.setDefaultButton(true);
|
||||
actionButton.requestFocus();
|
||||
//TODO app wide focus
|
||||
//actionButton.requestFocus();
|
||||
actionButton.setOnAction(event -> {
|
||||
hide();
|
||||
actionHandlerOptional.ifPresent(actionHandler -> actionHandler.run());
|
||||
|
@ -367,4 +371,12 @@ public class Popup {
|
|||
else
|
||||
truncatedMessage = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Popup{" +
|
||||
"headLine='" + headLine + '\'' +
|
||||
", message='" + message + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
|
40
gui/src/main/java/io/bitsquare/gui/popups/PopupManager.java
Normal file
40
gui/src/main/java/io/bitsquare/gui/popups/PopupManager.java
Normal file
|
@ -0,0 +1,40 @@
|
|||
package io.bitsquare.gui.popups;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
class PopupManager {
|
||||
private static final Logger log = LoggerFactory.getLogger(PopupManager.class);
|
||||
private static Queue<Popup> popups = new LinkedBlockingQueue<>(3);
|
||||
private static Popup displayedPopup;
|
||||
|
||||
static void queueForDisplay(Popup popup) {
|
||||
boolean result = popups.offer(popup);
|
||||
if (!result)
|
||||
log.warn("The capacity is full with popups in the queue.\n\t" +
|
||||
"Not added new popup=" + popup);
|
||||
displayNext();
|
||||
}
|
||||
|
||||
static void isHidden(Popup popup) {
|
||||
if (displayedPopup == null || displayedPopup == popup) {
|
||||
displayedPopup = null;
|
||||
displayNext();
|
||||
} else {
|
||||
log.warn("We got a isHidden called with a wrong popup.\n\t" +
|
||||
"popup (argument)=" + popup + "\n\tdisplayedPopup=" + displayedPopup);
|
||||
}
|
||||
}
|
||||
|
||||
private static void displayNext() {
|
||||
if (displayedPopup == null) {
|
||||
if (!popups.isEmpty()) {
|
||||
displayedPopup = popups.poll();
|
||||
displayedPopup.display();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -51,7 +51,7 @@ public class SelectDepositTxPopup extends Popup {
|
|||
public SelectDepositTxPopup() {
|
||||
}
|
||||
|
||||
public SelectDepositTxPopup show() {
|
||||
public void show() {
|
||||
if (headLine == null)
|
||||
headLine = "Select deposit transaction for dispute";
|
||||
|
||||
|
@ -60,8 +60,7 @@ public class SelectDepositTxPopup extends Popup {
|
|||
addHeadLine();
|
||||
addContent();
|
||||
addCloseButton();
|
||||
createPopup();
|
||||
return this;
|
||||
PopupManager.queueForDisplay(this);
|
||||
}
|
||||
|
||||
public SelectDepositTxPopup onSelect(Consumer<Transaction> selectHandler) {
|
||||
|
|
|
@ -59,7 +59,7 @@ public class SendAlertMessagePopup extends Popup {
|
|||
public SendAlertMessagePopup() {
|
||||
}
|
||||
|
||||
public SendAlertMessagePopup show() {
|
||||
public void show() {
|
||||
if (headLine == null)
|
||||
headLine = "Send global notification";
|
||||
|
||||
|
@ -67,8 +67,7 @@ public class SendAlertMessagePopup extends Popup {
|
|||
createGridPane();
|
||||
addHeadLine();
|
||||
addContent();
|
||||
createPopup();
|
||||
return this;
|
||||
PopupManager.queueForDisplay(this);
|
||||
}
|
||||
|
||||
public SendAlertMessagePopup onAddAlertMessage(SendAlertMessageHandler sendAlertMessageHandler) {
|
||||
|
|
|
@ -65,7 +65,7 @@ public class TradeDetailsPopup extends Popup {
|
|||
width = 850;
|
||||
createGridPane();
|
||||
addContent();
|
||||
createPopup();
|
||||
display();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -191,7 +191,8 @@ public class TradeDetailsPopup extends Popup {
|
|||
}
|
||||
|
||||
Button cancelButton = addButtonAfterGroup(gridPane, ++rowIndex, "Close");
|
||||
cancelButton.requestFocus();
|
||||
//TODO app wide focus
|
||||
//cancelButton.requestFocus();
|
||||
cancelButton.setOnAction(e -> {
|
||||
closeHandlerOptional.ifPresent(closeHandler -> closeHandler.run());
|
||||
hide();
|
||||
|
|
|
@ -64,7 +64,7 @@ public class WalletPasswordPopup extends Popup {
|
|||
this.walletService = walletService;
|
||||
}
|
||||
|
||||
public WalletPasswordPopup show() {
|
||||
public void show() {
|
||||
if (gridPane != null) {
|
||||
rowIndex = -1;
|
||||
gridPane.getChildren().clear();
|
||||
|
@ -77,9 +77,7 @@ public class WalletPasswordPopup extends Popup {
|
|||
addHeadLine();
|
||||
addInputFields();
|
||||
addButtons();
|
||||
createPopup();
|
||||
|
||||
return this;
|
||||
PopupManager.queueForDisplay(this);
|
||||
}
|
||||
|
||||
public WalletPasswordPopup onClose(Runnable closeHandler) {
|
||||
|
|
|
@ -10,7 +10,12 @@
|
|||
<appender-ref ref="CONSOLE_APPENDER"/>
|
||||
</root>
|
||||
|
||||
|
||||
<!-- <logger name="io.bitsquare.p2p.peers.PeerGroup" level="TRACE"/>
|
||||
|
||||
<logger name="io.bitsquare.storage.Storage" level="WARN"/>
|
||||
<logger name="io.bitsquare.storage.FileManager" level="WARN"/>
|
||||
|
||||
<logger name="io.bitsquare.p2p.P2PService" level="TRACE"/>
|
||||
<logger name="io.bitsquare.p2p.storage.ProtectedExpirableDataStorage" level="TRACE"/>
|
||||
<logger name="io.bitsquare.p2p.network.LocalhostNetworkNode" level="TRACE"/>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue