mirror of
https://github.com/bisq-network/bisq.git
synced 2024-11-19 09:52:23 +01:00
Add popups
This commit is contained in:
parent
8bf207b656
commit
cb8761b74e
@ -21,7 +21,9 @@ public class PopupId {
|
|||||||
|
|
||||||
// We don't use an enum because it would break updates if we add a new item in a new version
|
// We don't use an enum because it would break updates if we add a new item in a new version
|
||||||
|
|
||||||
public static String SEC_DEPOSIT = "SEC_DEPOSIT";
|
public static String TRADE_WALLET = "tradeWallet";
|
||||||
public static String TRADE_WALLET = "TRADE_WALLET";
|
public static String SEND_PAYMENT_INFO = "sendPaymentInfo";
|
||||||
|
public static String PAYMENT_SENT = "paymentSent";
|
||||||
|
public static String PAYMENT_RECEIVED = "paymentReceived";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -143,8 +143,10 @@ public class Preferences implements Serializable {
|
|||||||
showTakeOfferConfirmation = true;
|
showTakeOfferConfirmation = true;
|
||||||
|
|
||||||
showAgainMap = new HashMap<>();
|
showAgainMap = new HashMap<>();
|
||||||
showAgainMap.put(PopupId.SEC_DEPOSIT, true);
|
|
||||||
showAgainMap.put(PopupId.TRADE_WALLET, true);
|
showAgainMap.put(PopupId.TRADE_WALLET, true);
|
||||||
|
showAgainMap.put(PopupId.SEND_PAYMENT_INFO, true);
|
||||||
|
showAgainMap.put(PopupId.PAYMENT_SENT, true);
|
||||||
|
showAgainMap.put(PopupId.PAYMENT_RECEIVED, true);
|
||||||
|
|
||||||
storage.queueUpForSave();
|
storage.queueUpForSave();
|
||||||
}
|
}
|
||||||
@ -345,6 +347,10 @@ public class Preferences implements Serializable {
|
|||||||
return showAgainMap;
|
return showAgainMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean showAgain(String key) {
|
||||||
|
return getShowAgainMap().containsKey(key) && getShowAgainMap().get(key);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean getTacAccepted() {
|
public boolean getTacAccepted() {
|
||||||
return tacAccepted;
|
return tacAccepted;
|
||||||
}
|
}
|
||||||
|
@ -269,7 +269,11 @@ public class User implements Serializable {
|
|||||||
}*/
|
}*/
|
||||||
|
|
||||||
public Arbitrator getAcceptedArbitratorByAddress(Address address) {
|
public Arbitrator getAcceptedArbitratorByAddress(Address address) {
|
||||||
return acceptedArbitrators.stream().filter(e -> e.getArbitratorAddress().equals(address)).findFirst().get();
|
Optional<Arbitrator> arbitratorOptional = acceptedArbitrators.stream().filter(e -> e.getArbitratorAddress().equals(address)).findFirst();
|
||||||
|
if (arbitratorOptional.isPresent())
|
||||||
|
return arbitratorOptional.get();
|
||||||
|
else
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ import static io.bitsquare.app.BitsquareEnvironment.APP_NAME_KEY;
|
|||||||
public class BitsquareApp extends Application {
|
public class BitsquareApp extends Application {
|
||||||
private static final Logger log = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(BitsquareApp.class);
|
private static final Logger log = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(BitsquareApp.class);
|
||||||
|
|
||||||
public static final boolean DEV_MODE = true;
|
public static final boolean DEV_MODE = false;
|
||||||
|
|
||||||
private static Environment env;
|
private static Environment env;
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@ import javafx.geometry.Insets;
|
|||||||
import javafx.geometry.VPos;
|
import javafx.geometry.VPos;
|
||||||
import javafx.scene.control.CheckBox;
|
import javafx.scene.control.CheckBox;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
|
import javafx.scene.control.Tooltip;
|
||||||
import javafx.scene.layout.FlowPane;
|
import javafx.scene.layout.FlowPane;
|
||||||
import javafx.scene.layout.GridPane;
|
import javafx.scene.layout.GridPane;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@ -94,6 +95,7 @@ public class OKPayForm extends PaymentMethodForm {
|
|||||||
checkBox.setSelected(okPayAccount.getTradeCurrencies().contains(e));
|
checkBox.setSelected(okPayAccount.getTradeCurrencies().contains(e));
|
||||||
checkBox.setMinWidth(60);
|
checkBox.setMinWidth(60);
|
||||||
checkBox.setMaxWidth(checkBox.getMinWidth());
|
checkBox.setMaxWidth(checkBox.getMinWidth());
|
||||||
|
checkBox.setTooltip(new Tooltip(e.getName()));
|
||||||
checkBox.setOnAction(event -> {
|
checkBox.setOnAction(event -> {
|
||||||
if (checkBox.isSelected())
|
if (checkBox.isSelected())
|
||||||
okPayAccount.addCurrency(e);
|
okPayAccount.addCurrency(e);
|
||||||
|
@ -34,6 +34,7 @@ import javafx.geometry.VPos;
|
|||||||
import javafx.scene.control.*;
|
import javafx.scene.control.*;
|
||||||
import javafx.scene.layout.FlowPane;
|
import javafx.scene.layout.FlowPane;
|
||||||
import javafx.scene.layout.GridPane;
|
import javafx.scene.layout.GridPane;
|
||||||
|
import javafx.scene.text.TextAlignment;
|
||||||
import javafx.util.StringConverter;
|
import javafx.util.StringConverter;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -98,9 +99,9 @@ public class SepaForm extends PaymentMethodForm {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Tuple2<Label, ComboBox> tuple2 = addLabelComboBox(gridPane, ++gridRow, "Country of Bank:");
|
Tuple2<Label, ComboBox> tuple2 = addLabelComboBox(gridPane, ++gridRow, "Country of your Bank:");
|
||||||
ComboBox<Country> countryComboBox = tuple2.second;
|
ComboBox<Country> countryComboBox = tuple2.second;
|
||||||
countryComboBox.setPromptText("Select country of Bank");
|
countryComboBox.setPromptText("Select country of your Bank");
|
||||||
countryComboBox.setConverter(new StringConverter<Country>() {
|
countryComboBox.setConverter(new StringConverter<Country>() {
|
||||||
@Override
|
@Override
|
||||||
public String toString(Country country) {
|
public String toString(Country country) {
|
||||||
@ -141,15 +142,18 @@ public class SepaForm extends PaymentMethodForm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void addEuroCountriesGrid(boolean isEditable) {
|
private void addEuroCountriesGrid(boolean isEditable) {
|
||||||
addCountriesGrid(isEditable, "Accept taker countries (Euro):", euroCountryCheckBoxes, CountryUtil.getAllSepaEuroCountries());
|
addCountriesGrid(isEditable, "Accept trades from those Euro countries:", euroCountryCheckBoxes, CountryUtil.getAllSepaEuroCountries());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addNonEuroCountriesGrid(boolean isEditable) {
|
private void addNonEuroCountriesGrid(boolean isEditable) {
|
||||||
addCountriesGrid(isEditable, "Accepted taker countries (non-Euro):", nonEuroCountryCheckBoxes, CountryUtil.getAllSepaNonEuroCountries());
|
addCountriesGrid(isEditable, "Accept trades from those non-Euro countries:", nonEuroCountryCheckBoxes, CountryUtil.getAllSepaNonEuroCountries());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addCountriesGrid(boolean isEditable, String title, List<CheckBox> checkBoxList, List<Country> dataProvider) {
|
private void addCountriesGrid(boolean isEditable, String title, List<CheckBox> checkBoxList, List<Country> dataProvider) {
|
||||||
Label label = addLabel(gridPane, ++gridRow, title, 0);
|
Label label = addLabel(gridPane, ++gridRow, title, 0);
|
||||||
|
label.setWrapText(true);
|
||||||
|
label.setPrefWidth(200);
|
||||||
|
label.setTextAlignment(TextAlignment.RIGHT);
|
||||||
GridPane.setValignment(label, VPos.TOP);
|
GridPane.setValignment(label, VPos.TOP);
|
||||||
FlowPane flowPane = new FlowPane();
|
FlowPane flowPane = new FlowPane();
|
||||||
flowPane.setPadding(new Insets(10, 10, 10, 10));
|
flowPane.setPadding(new Insets(10, 10, 10, 10));
|
||||||
@ -169,7 +173,6 @@ public class SepaForm extends PaymentMethodForm {
|
|||||||
checkBoxList.add(checkBox);
|
checkBoxList.add(checkBox);
|
||||||
checkBox.setMouseTransparent(!isEditable);
|
checkBox.setMouseTransparent(!isEditable);
|
||||||
checkBox.setMinWidth(45);
|
checkBox.setMinWidth(45);
|
||||||
checkBox.setMaxWidth(checkBox.getMinWidth());
|
|
||||||
checkBox.setTooltip(new Tooltip(country.name));
|
checkBox.setTooltip(new Tooltip(country.name));
|
||||||
checkBox.setOnAction(event -> {
|
checkBox.setOnAction(event -> {
|
||||||
if (checkBox.isSelected())
|
if (checkBox.isSelected())
|
||||||
|
@ -338,7 +338,7 @@ class MainViewModel implements ViewModel {
|
|||||||
|
|
||||||
// tac
|
// tac
|
||||||
if (!preferences.getTacAccepted() && !BitsquareApp.DEV_MODE)
|
if (!preferences.getTacAccepted() && !BitsquareApp.DEV_MODE)
|
||||||
new TacPopup().url(WebViewPopup.getLocalUrl("tac.html")).onAgree(() -> preferences.setTacAccepted(true)).show();
|
new TacPopup().url(WebViewPopup.getLocalUrl("tac")).onAgree(() -> preferences.setTacAccepted(true)).show();
|
||||||
|
|
||||||
|
|
||||||
// update nr of peers in footer
|
// update nr of peers in footer
|
||||||
|
@ -196,8 +196,8 @@ public class ArbitratorRegistrationView extends ActivatableViewAndModel<VBox, Ar
|
|||||||
addTitledGroupBg(gridPane, ++gridRow, 2, "Information", Layout.GROUP_DISTANCE);
|
addTitledGroupBg(gridPane, ++gridRow, 2, "Information", Layout.GROUP_DISTANCE);
|
||||||
Label infoLabel = addMultilineLabel(gridPane, gridRow);
|
Label infoLabel = addMultilineLabel(gridPane, gridRow);
|
||||||
GridPane.setMargin(infoLabel, new Insets(Layout.FIRST_ROW_AND_GROUP_DISTANCE, 0, 0, 0));
|
GridPane.setMargin(infoLabel, new Insets(Layout.FIRST_ROW_AND_GROUP_DISTANCE, 0, 0, 0));
|
||||||
infoLabel.setText("Please not that you need to stay available for 15 days after revoking as there might be trades which are using you as " +
|
infoLabel.setText("Please note that you need to stay available for 15 days after revoking as there might be trades which are using you as " +
|
||||||
"arbitrator. The max. allowed trader period is 8 days and the dispute process might take up to 7 days.");
|
"arbitrator. The max. allowed trade period is 8 days and the dispute process might take up to 7 days.");
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -28,7 +28,6 @@ import io.bitsquare.gui.util.Layout;
|
|||||||
import io.bitsquare.locale.LanguageUtil;
|
import io.bitsquare.locale.LanguageUtil;
|
||||||
import javafx.beans.property.ReadOnlyObjectWrapper;
|
import javafx.beans.property.ReadOnlyObjectWrapper;
|
||||||
import javafx.collections.ListChangeListener;
|
import javafx.collections.ListChangeListener;
|
||||||
import javafx.geometry.HPos;
|
|
||||||
import javafx.geometry.Insets;
|
import javafx.geometry.Insets;
|
||||||
import javafx.geometry.VPos;
|
import javafx.geometry.VPos;
|
||||||
import javafx.scene.control.*;
|
import javafx.scene.control.*;
|
||||||
@ -192,12 +191,6 @@ public class ArbitratorSelectionView extends ActivatableViewAndModel<GridPane, A
|
|||||||
GridPane.setMargin(autoSelectAllMatchingCheckBox, new Insets(0, -10, 0, -10));
|
GridPane.setMargin(autoSelectAllMatchingCheckBox, new Insets(0, -10, 0, -10));
|
||||||
autoSelectAllMatchingCheckBox.setOnAction(event -> model.setAutoSelectArbitrators(autoSelectAllMatchingCheckBox.isSelected()));
|
autoSelectAllMatchingCheckBox.setOnAction(event -> model.setAutoSelectArbitrators(autoSelectAllMatchingCheckBox.isSelected()));
|
||||||
|
|
||||||
Button reloadButton = addButton(root, gridRow, "Reload");
|
|
||||||
GridPane.setColumnIndex(reloadButton, 1);
|
|
||||||
GridPane.setHalignment(reloadButton, HPos.RIGHT);
|
|
||||||
GridPane.setMargin(reloadButton, new Insets(0, -10, 0, -10));
|
|
||||||
reloadButton.setOnAction(event -> model.reload());
|
|
||||||
|
|
||||||
TableColumn<ArbitratorListItem, String> dateColumn = new TableColumn("Registration date");
|
TableColumn<ArbitratorListItem, String> dateColumn = new TableColumn("Registration date");
|
||||||
dateColumn.setCellValueFactory(param -> new ReadOnlyObjectWrapper(param.getValue().getRegistrationDate()));
|
dateColumn.setCellValueFactory(param -> new ReadOnlyObjectWrapper(param.getValue().getRegistrationDate()));
|
||||||
dateColumn.setMinWidth(130);
|
dateColumn.setMinWidth(130);
|
||||||
|
@ -130,10 +130,6 @@ class ArbitratorSelectionViewModel extends ActivatableDataModel {
|
|||||||
return user.isMyOwnRegisteredArbitrator(arbitrator);
|
return user.isMyOwnRegisteredArbitrator(arbitrator);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reload() {
|
|
||||||
arbitratorManager.applyArbitrators();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateAutoSelectArbitrators() {
|
private void updateAutoSelectArbitrators() {
|
||||||
if (preferences.getAutoSelectArbitrators()) {
|
if (preferences.getAutoSelectArbitrators()) {
|
||||||
arbitratorListItems.stream().forEach(item -> {
|
arbitratorListItems.stream().forEach(item -> {
|
||||||
|
@ -25,7 +25,7 @@ import io.bitsquare.gui.main.MainView;
|
|||||||
import io.bitsquare.gui.main.funds.reserved.ReservedView;
|
import io.bitsquare.gui.main.funds.reserved.ReservedView;
|
||||||
import io.bitsquare.gui.main.funds.transactions.TransactionsView;
|
import io.bitsquare.gui.main.funds.transactions.TransactionsView;
|
||||||
import io.bitsquare.gui.main.funds.withdrawal.WithdrawalView;
|
import io.bitsquare.gui.main.funds.withdrawal.WithdrawalView;
|
||||||
import io.bitsquare.gui.popups.FirstTimePopup;
|
import io.bitsquare.gui.popups.FirstTimeWebViewPopup;
|
||||||
import io.bitsquare.gui.popups.WebViewPopup;
|
import io.bitsquare.gui.popups.WebViewPopup;
|
||||||
import io.bitsquare.user.PopupId;
|
import io.bitsquare.user.PopupId;
|
||||||
import io.bitsquare.user.Preferences;
|
import io.bitsquare.user.Preferences;
|
||||||
@ -85,8 +85,9 @@ public class FundsView extends ActivatableViewAndModel<TabPane, Activatable> {
|
|||||||
else if (root.getSelectionModel().getSelectedItem() == transactionsTab)
|
else if (root.getSelectionModel().getSelectedItem() == transactionsTab)
|
||||||
navigation.navigateTo(MainView.class, FundsView.class, TransactionsView.class);
|
navigation.navigateTo(MainView.class, FundsView.class, TransactionsView.class);
|
||||||
|
|
||||||
if (preferences.getShowAgainMap().get(PopupId.TRADE_WALLET) && !BitsquareApp.DEV_MODE)
|
String key = PopupId.TRADE_WALLET;
|
||||||
new FirstTimePopup(preferences).url(WebViewPopup.getLocalUrl("tradeWallet.html")).show();
|
if (preferences.showAgain(key) && !BitsquareApp.DEV_MODE)
|
||||||
|
new FirstTimeWebViewPopup(preferences).id(key).url(WebViewPopup.getLocalUrl(key)).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -21,19 +21,14 @@ import io.bitsquare.btc.WalletService;
|
|||||||
import io.bitsquare.btc.listeners.AddressConfidenceListener;
|
import io.bitsquare.btc.listeners.AddressConfidenceListener;
|
||||||
import io.bitsquare.gui.components.confidence.ConfidenceProgressIndicator;
|
import io.bitsquare.gui.components.confidence.ConfidenceProgressIndicator;
|
||||||
import io.bitsquare.gui.util.BSFormatter;
|
import io.bitsquare.gui.util.BSFormatter;
|
||||||
|
|
||||||
import org.bitcoinj.core.Address;
|
|
||||||
import org.bitcoinj.core.Coin;
|
|
||||||
import org.bitcoinj.core.Transaction;
|
|
||||||
import org.bitcoinj.core.TransactionConfidence;
|
|
||||||
import org.bitcoinj.core.TransactionOutput;
|
|
||||||
|
|
||||||
import javafx.beans.property.SimpleStringProperty;
|
import javafx.beans.property.SimpleStringProperty;
|
||||||
import javafx.beans.property.StringProperty;
|
import javafx.beans.property.StringProperty;
|
||||||
import javafx.scene.control.*;
|
import javafx.scene.control.Tooltip;
|
||||||
|
import org.bitcoinj.core.*;
|
||||||
|
|
||||||
public class TransactionsListItem {
|
public class TransactionsListItem {
|
||||||
|
|
||||||
|
|
||||||
private final StringProperty date = new SimpleStringProperty();
|
private final StringProperty date = new SimpleStringProperty();
|
||||||
private final StringProperty amount = new SimpleStringProperty();
|
private final StringProperty amount = new SimpleStringProperty();
|
||||||
private final StringProperty type = new SimpleStringProperty();
|
private final StringProperty type = new SimpleStringProperty();
|
||||||
@ -44,6 +39,7 @@ public class TransactionsListItem {
|
|||||||
|
|
||||||
private final Tooltip tooltip;
|
private final Tooltip tooltip;
|
||||||
private String addressString;
|
private String addressString;
|
||||||
|
private boolean notAnAddress;
|
||||||
private AddressConfidenceListener confidenceListener;
|
private AddressConfidenceListener confidenceListener;
|
||||||
|
|
||||||
public TransactionsListItem(Transaction transaction, WalletService walletService, BSFormatter formatter) {
|
public TransactionsListItem(Transaction transaction, WalletService walletService, BSFormatter formatter) {
|
||||||
@ -64,14 +60,13 @@ public class TransactionsListItem {
|
|||||||
address =
|
address =
|
||||||
transactionOutput.getScriptPubKey().getToAddress(walletService.getWallet().getParams());
|
transactionOutput.getScriptPubKey().getToAddress(walletService.getWallet().getParams());
|
||||||
addressString = address.toString();
|
addressString = address.toString();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
addressString = "No sent to address script used.";
|
addressString = "No sent to address script used.";
|
||||||
|
notAnAddress = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else if (valueSentFromMe.isZero()) {
|
||||||
else if (valueSentFromMe.isZero()) {
|
|
||||||
amount.set(formatter.formatCoin(valueSentToMe));
|
amount.set(formatter.formatCoin(valueSentToMe));
|
||||||
type.set("Received with");
|
type.set("Received with");
|
||||||
|
|
||||||
@ -82,14 +77,13 @@ public class TransactionsListItem {
|
|||||||
address =
|
address =
|
||||||
transactionOutput.getScriptPubKey().getToAddress(walletService.getWallet().getParams());
|
transactionOutput.getScriptPubKey().getToAddress(walletService.getWallet().getParams());
|
||||||
addressString = address.toString();
|
addressString = address.toString();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
addressString = "No sent to address script used.";
|
addressString = "No sent to address script used.";
|
||||||
|
notAnAddress = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
amount.set(formatter.formatCoin(valueSentToMe.subtract(valueSentFromMe)));
|
amount.set(formatter.formatCoin(valueSentToMe.subtract(valueSentFromMe)));
|
||||||
boolean outgoing = false;
|
boolean outgoing = false;
|
||||||
for (TransactionOutput transactionOutput : transaction.getOutputs()) {
|
for (TransactionOutput transactionOutput : transaction.getOutputs()) {
|
||||||
@ -100,19 +94,19 @@ public class TransactionsListItem {
|
|||||||
address = transactionOutput.getScriptPubKey().getToAddress(walletService.getWallet().getParams
|
address = transactionOutput.getScriptPubKey().getToAddress(walletService.getWallet().getParams
|
||||||
());
|
());
|
||||||
addressString = address.toString();
|
addressString = address.toString();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
addressString = "No sent to address script used.";
|
addressString = "No sent to address script used.";
|
||||||
|
notAnAddress = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (outgoing) {
|
if (outgoing) {
|
||||||
type.set("Sent to");
|
type.set("Sent to");
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
type.set("Internal (TX Fee)");
|
type.set("Internal (TX Fee)");
|
||||||
addressString = "Internal swap between addresses.";
|
addressString = "Internal swap between addresses.";
|
||||||
|
notAnAddress = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,5 +188,9 @@ public class TransactionsListItem {
|
|||||||
public String getAddressString() {
|
public String getAddressString() {
|
||||||
return addressString;
|
return addressString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isNotAnAddress() {
|
||||||
|
return notAnAddress;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,8 +40,10 @@ import java.util.stream.Collectors;
|
|||||||
@FxmlView
|
@FxmlView
|
||||||
public class TransactionsView extends ActivatableView<VBox, Void> {
|
public class TransactionsView extends ActivatableView<VBox, Void> {
|
||||||
|
|
||||||
@FXML TableView<TransactionsListItem> table;
|
@FXML
|
||||||
@FXML TableColumn<TransactionsListItem, TransactionsListItem> dateColumn, addressColumn, amountColumn, typeColumn,
|
TableView<TransactionsListItem> table;
|
||||||
|
@FXML
|
||||||
|
TableColumn<TransactionsListItem, TransactionsListItem> dateColumn, addressColumn, amountColumn, typeColumn,
|
||||||
confidenceColumn;
|
confidenceColumn;
|
||||||
|
|
||||||
private ObservableList<TransactionsListItem> transactionsListItems;
|
private ObservableList<TransactionsListItem> transactionsListItems;
|
||||||
@ -85,12 +87,14 @@ public class TransactionsView extends ActivatableView<VBox, Void> {
|
|||||||
// TODO Open popup with details view
|
// TODO Open popup with details view
|
||||||
log.debug("openTxDetails " + item);
|
log.debug("openTxDetails " + item);
|
||||||
|
|
||||||
try {
|
if (!item.isNotAnAddress()) {
|
||||||
Utilities.openWebPage(preferences.getBlockChainExplorer().addressUrl + item.getAddressString());
|
try {
|
||||||
} catch (Exception e) {
|
Utilities.openWebPage(preferences.getBlockChainExplorer().addressUrl + item.getAddressString());
|
||||||
log.error(e.getMessage());
|
} catch (Exception e) {
|
||||||
new Popup().warning("Opening browser failed. Please check your internet " +
|
log.error(e.getMessage());
|
||||||
"connection.").show();
|
new Popup().warning("Opening browser failed. Please check your internet " +
|
||||||
|
"connection.").show();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,8 +118,7 @@ public class TransactionsView extends ActivatableView<VBox, Void> {
|
|||||||
hyperlink = new Hyperlink(item.getAddressString());
|
hyperlink = new Hyperlink(item.getAddressString());
|
||||||
hyperlink.setOnAction(event -> openTxDetails(item));
|
hyperlink.setOnAction(event -> openTxDetails(item));
|
||||||
setGraphic(hyperlink);
|
setGraphic(hyperlink);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
setGraphic(null);
|
setGraphic(null);
|
||||||
setId(null);
|
setId(null);
|
||||||
}
|
}
|
||||||
@ -143,8 +146,7 @@ public class TransactionsView extends ActivatableView<VBox, Void> {
|
|||||||
|
|
||||||
if (item != null && !empty) {
|
if (item != null && !empty) {
|
||||||
setGraphic(item.getProgressIndicator());
|
setGraphic(item.getProgressIndicator());
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
setGraphic(null);
|
setGraphic(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -203,7 +203,7 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
|
|||||||
formatter.formatCoinWithCode(FeePolicy.TX_FEE) + "\n" +
|
formatter.formatCoinWithCode(FeePolicy.TX_FEE) + "\n" +
|
||||||
"Receivers amount: " +
|
"Receivers amount: " +
|
||||||
formatter.formatCoinWithCode(amount.subtract(FeePolicy.TX_FEE)) + " BTC\n\n" +
|
formatter.formatCoinWithCode(amount.subtract(FeePolicy.TX_FEE)) + " BTC\n\n" +
|
||||||
"Are you sure you withdraw that amount?")
|
"Are you sure you want to withdraw that amount?")
|
||||||
.onAction(() -> {
|
.onAction(() -> {
|
||||||
doWithdraw(amount, callback);
|
doWithdraw(amount, callback);
|
||||||
})
|
})
|
||||||
|
@ -56,8 +56,8 @@ public class BuyerSubView extends TradeSubView {
|
|||||||
@Override
|
@Override
|
||||||
protected void addWizards() {
|
protected void addWizards() {
|
||||||
waitTxInBlockchain = new TradeWizardItem(WaitTxInBlockchainView.class, "Wait for blockchain confirmation");
|
waitTxInBlockchain = new TradeWizardItem(WaitTxInBlockchainView.class, "Wait for blockchain confirmation");
|
||||||
startPayment = new TradeWizardItem(StartPaymentView.class, "Start EUR payment");
|
startPayment = new TradeWizardItem(StartPaymentView.class, "Start payment");
|
||||||
waitPaymentReceived = new TradeWizardItem(WaitPaymentReceivedView.class, "Wait until EUR payment arrived");
|
waitPaymentReceived = new TradeWizardItem(WaitPaymentReceivedView.class, "Wait until payment arrived");
|
||||||
waitPayoutUnlock = new TradeWizardItem(WaitPayoutLockTimeView.class, "Wait for payout unlock");
|
waitPayoutUnlock = new TradeWizardItem(WaitPayoutLockTimeView.class, "Wait for payout unlock");
|
||||||
completed = new TradeWizardItem(CompletedView.class, "Completed");
|
completed = new TradeWizardItem(CompletedView.class, "Completed");
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@ import io.bitsquare.gui.popups.WalletPasswordPopup;
|
|||||||
import io.bitsquare.payment.PaymentAccountContractData;
|
import io.bitsquare.payment.PaymentAccountContractData;
|
||||||
import io.bitsquare.trade.*;
|
import io.bitsquare.trade.*;
|
||||||
import io.bitsquare.trade.offer.Offer;
|
import io.bitsquare.trade.offer.Offer;
|
||||||
|
import io.bitsquare.user.Preferences;
|
||||||
import io.bitsquare.user.User;
|
import io.bitsquare.user.User;
|
||||||
import javafx.beans.property.*;
|
import javafx.beans.property.*;
|
||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
@ -69,6 +70,7 @@ public class PendingTradesDataModel extends ActivatableDataModel {
|
|||||||
private final ObjectProperty<Trade> tradeProperty = new SimpleObjectProperty<>();
|
private final ObjectProperty<Trade> tradeProperty = new SimpleObjectProperty<>();
|
||||||
private final StringProperty txId = new SimpleStringProperty();
|
private final StringProperty txId = new SimpleStringProperty();
|
||||||
private Trade trade;
|
private Trade trade;
|
||||||
|
private Preferences preferences;
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -77,7 +79,7 @@ public class PendingTradesDataModel extends ActivatableDataModel {
|
|||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public PendingTradesDataModel(TradeManager tradeManager, WalletService walletService, TradeWalletService tradeWalletService,
|
public PendingTradesDataModel(TradeManager tradeManager, WalletService walletService, TradeWalletService tradeWalletService,
|
||||||
User user, KeyRing keyRing, DisputeManager disputeManager,
|
User user, KeyRing keyRing, DisputeManager disputeManager, Preferences preferences,
|
||||||
Navigation navigation, WalletPasswordPopup walletPasswordPopup) {
|
Navigation navigation, WalletPasswordPopup walletPasswordPopup) {
|
||||||
this.tradeManager = tradeManager;
|
this.tradeManager = tradeManager;
|
||||||
this.walletService = walletService;
|
this.walletService = walletService;
|
||||||
@ -85,6 +87,7 @@ public class PendingTradesDataModel extends ActivatableDataModel {
|
|||||||
this.user = user;
|
this.user = user;
|
||||||
this.keyRing = keyRing;
|
this.keyRing = keyRing;
|
||||||
this.disputeManager = disputeManager;
|
this.disputeManager = disputeManager;
|
||||||
|
this.preferences = preferences;
|
||||||
this.navigation = navigation;
|
this.navigation = navigation;
|
||||||
this.walletPasswordPopup = walletPasswordPopup;
|
this.walletPasswordPopup = walletPasswordPopup;
|
||||||
|
|
||||||
@ -323,6 +326,10 @@ public class PendingTradesDataModel extends ActivatableDataModel {
|
|||||||
return disputeManager;
|
return disputeManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Preferences getPreferences() {
|
||||||
|
return preferences;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Utils
|
// Utils
|
||||||
|
@ -56,8 +56,8 @@ public class SellerSubView extends TradeSubView {
|
|||||||
@Override
|
@Override
|
||||||
protected void addWizards() {
|
protected void addWizards() {
|
||||||
waitTxInBlockchain = new TradeWizardItem(WaitTxInBlockchainView.class, "Wait for blockchain confirmation");
|
waitTxInBlockchain = new TradeWizardItem(WaitTxInBlockchainView.class, "Wait for blockchain confirmation");
|
||||||
waitPaymentStarted = new TradeWizardItem(WaitPaymentStartedView.class, "Wait until EUR payment has started");
|
waitPaymentStarted = new TradeWizardItem(WaitPaymentStartedView.class, "Wait until payment has started");
|
||||||
confirmPaymentReceived = new TradeWizardItem(ConfirmPaymentReceivedView.class, "Confirm EUR payment received");
|
confirmPaymentReceived = new TradeWizardItem(ConfirmPaymentReceivedView.class, "Confirm payment received");
|
||||||
waitPayoutUnlock = new TradeWizardItem(WaitPayoutLockTimeView.class, "Wait for payout unlock");
|
waitPayoutUnlock = new TradeWizardItem(WaitPayoutLockTimeView.class, "Wait for payout unlock");
|
||||||
completed = new TradeWizardItem(CompletedView.class, "Completed");
|
completed = new TradeWizardItem(CompletedView.class, "Completed");
|
||||||
|
|
||||||
@ -110,11 +110,11 @@ public class SellerSubView extends TradeSubView {
|
|||||||
showItem(confirmPaymentReceived);
|
showItem(confirmPaymentReceived);
|
||||||
|
|
||||||
if (model.isBlockChainMethod()) {
|
if (model.isBlockChainMethod()) {
|
||||||
((ConfirmPaymentReceivedView) tradeStepDetailsView).setInfoLabelText(BSResources.get("The Bitcoin buyer has started the {0} payment." +
|
((ConfirmPaymentReceivedView) tradeStepDetailsView).setInfoLabelText(BSResources.get("The Bitcoin buyer has started the {0} payment. " +
|
||||||
"Check your Altcoin wallet or Block explorer and confirm when you have received the payment.",
|
"Check your Altcoin wallet or Block explorer and confirm when you have received the payment.",
|
||||||
model.getCurrencyCode()));
|
model.getCurrencyCode()));
|
||||||
} else {
|
} else {
|
||||||
((ConfirmPaymentReceivedView) tradeStepDetailsView).setInfoLabelText(BSResources.get("The Bitcoin buyer has started the {0} payment." +
|
((ConfirmPaymentReceivedView) tradeStepDetailsView).setInfoLabelText(BSResources.get("The Bitcoin buyer has started the {0} payment. " +
|
||||||
"Check your payment account and confirm when you have received the payment.",
|
"Check your payment account and confirm when you have received the payment.",
|
||||||
model.getCurrencyCode()));
|
model.getCurrencyCode()));
|
||||||
}
|
}
|
||||||
|
@ -17,10 +17,13 @@
|
|||||||
|
|
||||||
package io.bitsquare.gui.main.portfolio.pendingtrades.steps;
|
package io.bitsquare.gui.main.portfolio.pendingtrades.steps;
|
||||||
|
|
||||||
|
import io.bitsquare.app.BitsquareApp;
|
||||||
import io.bitsquare.gui.components.TxIdTextField;
|
import io.bitsquare.gui.components.TxIdTextField;
|
||||||
import io.bitsquare.gui.main.portfolio.pendingtrades.PendingTradesViewModel;
|
import io.bitsquare.gui.main.portfolio.pendingtrades.PendingTradesViewModel;
|
||||||
import io.bitsquare.gui.popups.Popup;
|
import io.bitsquare.gui.popups.Popup;
|
||||||
import io.bitsquare.gui.util.Layout;
|
import io.bitsquare.gui.util.Layout;
|
||||||
|
import io.bitsquare.user.PopupId;
|
||||||
|
import io.bitsquare.user.Preferences;
|
||||||
import javafx.beans.value.ChangeListener;
|
import javafx.beans.value.ChangeListener;
|
||||||
import javafx.event.ActionEvent;
|
import javafx.event.ActionEvent;
|
||||||
import javafx.geometry.HPos;
|
import javafx.geometry.HPos;
|
||||||
@ -105,13 +108,23 @@ public class ConfirmPaymentReceivedView extends TradeStepDetailsView {
|
|||||||
private void onPaymentReceived(ActionEvent actionEvent) {
|
private void onPaymentReceived(ActionEvent actionEvent) {
|
||||||
log.debug("onPaymentReceived");
|
log.debug("onPaymentReceived");
|
||||||
if (model.isAuthenticated()) {
|
if (model.isAuthenticated()) {
|
||||||
confirmFiatReceivedButton.setDisable(true);
|
Preferences preferences = model.dataModel.getPreferences();
|
||||||
|
String key = PopupId.PAYMENT_RECEIVED;
|
||||||
|
if (preferences.showAgain(key) && !BitsquareApp.DEV_MODE) {
|
||||||
|
new Popup().information("Please note that as soon you have confirmed that you have received the " +
|
||||||
|
"payment the locked Bitcoin will be released.\n" +
|
||||||
|
"There is no way to reverse a Bitcoin payment. Confirm only if you are sure.")
|
||||||
|
.onClose(() -> preferences.dontShowAgain(key))
|
||||||
|
.show();
|
||||||
|
} else {
|
||||||
|
confirmFiatReceivedButton.setDisable(true);
|
||||||
|
|
||||||
statusProgressIndicator.setVisible(true);
|
statusProgressIndicator.setVisible(true);
|
||||||
statusProgressIndicator.setProgress(-1);
|
statusProgressIndicator.setProgress(-1);
|
||||||
statusLabel.setText("Sending message to trading partner...");
|
statusLabel.setText("Sending message to trading partner...");
|
||||||
|
|
||||||
model.fiatPaymentReceived();
|
model.fiatPaymentReceived();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
new Popup().warning("You need to wait until your client is authenticated in the network.\n" +
|
new Popup().warning("You need to wait until your client is authenticated in the network.\n" +
|
||||||
"That might take up to about 2 minutes at startup.").show();
|
"That might take up to about 2 minutes at startup.").show();
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
package io.bitsquare.gui.main.portfolio.pendingtrades.steps;
|
package io.bitsquare.gui.main.portfolio.pendingtrades.steps;
|
||||||
|
|
||||||
|
import io.bitsquare.app.BitsquareApp;
|
||||||
import io.bitsquare.common.util.Tuple3;
|
import io.bitsquare.common.util.Tuple3;
|
||||||
import io.bitsquare.gui.components.TitledGroupBg;
|
import io.bitsquare.gui.components.TitledGroupBg;
|
||||||
import io.bitsquare.gui.components.TxIdTextField;
|
import io.bitsquare.gui.components.TxIdTextField;
|
||||||
@ -26,6 +27,8 @@ import io.bitsquare.gui.popups.Popup;
|
|||||||
import io.bitsquare.gui.util.Layout;
|
import io.bitsquare.gui.util.Layout;
|
||||||
import io.bitsquare.payment.PaymentAccountContractData;
|
import io.bitsquare.payment.PaymentAccountContractData;
|
||||||
import io.bitsquare.payment.PaymentMethod;
|
import io.bitsquare.payment.PaymentMethod;
|
||||||
|
import io.bitsquare.user.PopupId;
|
||||||
|
import io.bitsquare.user.Preferences;
|
||||||
import javafx.beans.value.ChangeListener;
|
import javafx.beans.value.ChangeListener;
|
||||||
import javafx.event.ActionEvent;
|
import javafx.event.ActionEvent;
|
||||||
import javafx.geometry.Insets;
|
import javafx.geometry.Insets;
|
||||||
@ -37,6 +40,7 @@ import javafx.scene.layout.GridPane;
|
|||||||
import static io.bitsquare.gui.util.FormBuilder.*;
|
import static io.bitsquare.gui.util.FormBuilder.*;
|
||||||
|
|
||||||
public class StartPaymentView extends TradeStepDetailsView {
|
public class StartPaymentView extends TradeStepDetailsView {
|
||||||
|
private final Preferences preferences;
|
||||||
private TxIdTextField txIdTextField;
|
private TxIdTextField txIdTextField;
|
||||||
|
|
||||||
private Button paymentStartedButton;
|
private Button paymentStartedButton;
|
||||||
@ -55,6 +59,7 @@ public class StartPaymentView extends TradeStepDetailsView {
|
|||||||
public StartPaymentView(PendingTradesViewModel model) {
|
public StartPaymentView(PendingTradesViewModel model) {
|
||||||
super(model);
|
super(model);
|
||||||
txIdChangeListener = (ov, oldValue, newValue) -> txIdTextField.setup(newValue);
|
txIdChangeListener = (ov, oldValue, newValue) -> txIdTextField.setup(newValue);
|
||||||
|
preferences = model.dataModel.getPreferences();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -63,6 +68,16 @@ public class StartPaymentView extends TradeStepDetailsView {
|
|||||||
|
|
||||||
model.getTxId().addListener(txIdChangeListener);
|
model.getTxId().addListener(txIdChangeListener);
|
||||||
txIdTextField.setup(model.getTxId().get());
|
txIdTextField.setup(model.getTxId().get());
|
||||||
|
|
||||||
|
String key = PopupId.SEND_PAYMENT_INFO;
|
||||||
|
if (preferences.showAgain(key) && !BitsquareApp.DEV_MODE) {
|
||||||
|
new Popup().information("You need to transfer now the agreed amount to your trading partner.\n" +
|
||||||
|
"Please take care that you use the exact data presented here, including the reference text\n" +
|
||||||
|
"Please do not click the \"Payment started\" button if you have before you have completed the transfer.\n" +
|
||||||
|
"Take care that you make the transfer soon to not miss the exceed trading period.")
|
||||||
|
.onClose(() -> preferences.dontShowAgain(key))
|
||||||
|
.show();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -126,13 +141,21 @@ public class StartPaymentView extends TradeStepDetailsView {
|
|||||||
private void onPaymentStarted(ActionEvent actionEvent) {
|
private void onPaymentStarted(ActionEvent actionEvent) {
|
||||||
log.debug("onPaymentStarted");
|
log.debug("onPaymentStarted");
|
||||||
if (model.isAuthenticated()) {
|
if (model.isAuthenticated()) {
|
||||||
paymentStartedButton.setDisable(true);
|
String key = PopupId.PAYMENT_SENT;
|
||||||
|
if (preferences.showAgain(key) && !BitsquareApp.DEV_MODE) {
|
||||||
|
new Popup().information("You are confirming that you have transferred the payment to your trading partner.\n" +
|
||||||
|
"Please click the \"Payment started\" button only if you have completed the transfer.")
|
||||||
|
.onClose(() -> preferences.dontShowAgain(key))
|
||||||
|
.show();
|
||||||
|
} else {
|
||||||
|
paymentStartedButton.setDisable(true);
|
||||||
|
|
||||||
statusProgressIndicator.setVisible(true);
|
statusProgressIndicator.setVisible(true);
|
||||||
statusProgressIndicator.setProgress(-1);
|
statusProgressIndicator.setProgress(-1);
|
||||||
statusLabel.setText("Sending message to trading partner...");
|
statusLabel.setText("Sending message to trading partner...");
|
||||||
|
|
||||||
model.fiatPaymentStarted();
|
model.fiatPaymentStarted();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
new Popup().warning("You need to wait until your client is authenticated in the network.\n" +
|
new Popup().warning("You need to wait until your client is authenticated in the network.\n" +
|
||||||
"That might take up to about 2 minutes at startup.").show();
|
"That might take up to about 2 minutes at startup.").show();
|
||||||
|
@ -29,8 +29,8 @@ import java.util.Optional;
|
|||||||
|
|
||||||
import static io.bitsquare.gui.util.FormBuilder.addCheckBox;
|
import static io.bitsquare.gui.util.FormBuilder.addCheckBox;
|
||||||
|
|
||||||
public class FirstTimePopup extends WebViewPopup {
|
public class FirstTimeWebViewPopup extends WebViewPopup {
|
||||||
private static final Logger log = LoggerFactory.getLogger(FirstTimePopup.class);
|
private static final Logger log = LoggerFactory.getLogger(FirstTimeWebViewPopup.class);
|
||||||
private Preferences preferences;
|
private Preferences preferences;
|
||||||
private String id;
|
private String id;
|
||||||
|
|
||||||
@ -39,22 +39,22 @@ public class FirstTimePopup extends WebViewPopup {
|
|||||||
// Public API
|
// Public API
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
public FirstTimePopup(Preferences preferences) {
|
public FirstTimeWebViewPopup(Preferences preferences) {
|
||||||
this.preferences = preferences;
|
this.preferences = preferences;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FirstTimePopup url(String url) {
|
public FirstTimeWebViewPopup url(String url) {
|
||||||
super.url(url);
|
super.url(url);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FirstTimePopup onClose(Runnable closeHandler) {
|
public FirstTimeWebViewPopup onClose(Runnable closeHandler) {
|
||||||
this.closeHandlerOptional = Optional.of(closeHandler);
|
this.closeHandlerOptional = Optional.of(closeHandler);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FirstTimePopup id(String id) {
|
public FirstTimeWebViewPopup id(String id) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
@ -110,7 +110,7 @@ public class OfferDetailsPopup extends Popup {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void addContent() {
|
private void addContent() {
|
||||||
int rows = 9;
|
int rows = 11;
|
||||||
if (offer.getPaymentMethodCountryCode() != null)
|
if (offer.getPaymentMethodCountryCode() != null)
|
||||||
rows++;
|
rows++;
|
||||||
if (offer.getOfferFeePaymentTxID() != null)
|
if (offer.getOfferFeePaymentTxID() != null)
|
||||||
@ -124,7 +124,8 @@ public class OfferDetailsPopup extends Popup {
|
|||||||
addLabelTextField(gridPane, rowIndex, "Offer ID:", offer.getId(), Layout.FIRST_ROW_DISTANCE);
|
addLabelTextField(gridPane, rowIndex, "Offer ID:", offer.getId(), Layout.FIRST_ROW_DISTANCE);
|
||||||
addLabelTextField(gridPane, ++rowIndex, "Creation date:", formatter.formatDateTime(offer.getDate()));
|
addLabelTextField(gridPane, ++rowIndex, "Creation date:", formatter.formatDateTime(offer.getDate()));
|
||||||
addLabelTextField(gridPane, ++rowIndex, "Offer direction:", Offer.Direction.BUY.name());
|
addLabelTextField(gridPane, ++rowIndex, "Offer direction:", Offer.Direction.BUY.name());
|
||||||
addLabelTextField(gridPane, ++rowIndex, "Price:", formatter.formatFiat(offer.getPrice()) + " " + offer.getCurrencyCode());
|
addLabelTextField(gridPane, ++rowIndex, "Currency:", offer.getCurrencyCode());
|
||||||
|
addLabelTextField(gridPane, ++rowIndex, "Price:", formatter.formatFiat(offer.getPrice()) + " " + offer.getCurrencyCode() + "/" + "BTC");
|
||||||
addLabelTextField(gridPane, ++rowIndex, "Amount:", formatter.formatCoinWithCode(offer.getAmount()));
|
addLabelTextField(gridPane, ++rowIndex, "Amount:", formatter.formatCoinWithCode(offer.getAmount()));
|
||||||
addLabelTextField(gridPane, ++rowIndex, "Min. amount:", formatter.formatCoinWithCode(offer.getMinAmount()));
|
addLabelTextField(gridPane, ++rowIndex, "Min. amount:", formatter.formatCoinWithCode(offer.getMinAmount()));
|
||||||
addLabelTextField(gridPane, ++rowIndex, "Payment method:", BSResources.get(offer.getPaymentMethod().getId()));
|
addLabelTextField(gridPane, ++rowIndex, "Payment method:", BSResources.get(offer.getPaymentMethod().getId()));
|
||||||
@ -192,6 +193,7 @@ public class OfferDetailsPopup extends Popup {
|
|||||||
});
|
});
|
||||||
|
|
||||||
CheckBox checkBox = addCheckBox(gridPane, ++rowIndex, "Don't show again", 5);
|
CheckBox checkBox = addCheckBox(gridPane, ++rowIndex, "Don't show again", 5);
|
||||||
|
checkBox.setPadding(new Insets(10, 0, 15, 0));
|
||||||
checkBox.setSelected(!preferences.getShowTakeOfferConfirmation());
|
checkBox.setSelected(!preferences.getShowTakeOfferConfirmation());
|
||||||
checkBox.setOnAction(e -> preferences.setShowTakeOfferConfirmation(!checkBox.isSelected()));
|
checkBox.setOnAction(e -> preferences.setShowTakeOfferConfirmation(!checkBox.isSelected()));
|
||||||
} else {
|
} else {
|
||||||
|
@ -30,6 +30,7 @@ import javafx.geometry.Insets;
|
|||||||
import javafx.scene.control.Button;
|
import javafx.scene.control.Button;
|
||||||
import javafx.scene.control.TextArea;
|
import javafx.scene.control.TextArea;
|
||||||
import javafx.scene.control.TextField;
|
import javafx.scene.control.TextField;
|
||||||
|
import javafx.scene.control.Tooltip;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@ -126,15 +127,19 @@ public class TradeDetailsPopup extends Popup {
|
|||||||
addLabelTextField(gridPane, ++rowIndex, "Offer direction:", direction);
|
addLabelTextField(gridPane, ++rowIndex, "Offer direction:", direction);
|
||||||
addLabelTextField(gridPane, ++rowIndex, "Price:", formatter.formatFiat(offer.getPrice()) + " " + offer.getCurrencyCode());
|
addLabelTextField(gridPane, ++rowIndex, "Price:", formatter.formatFiat(offer.getPrice()) + " " + offer.getCurrencyCode());
|
||||||
addLabelTextField(gridPane, ++rowIndex, "Trade amount:", formatter.formatCoinWithCode(trade.getTradeAmount()));
|
addLabelTextField(gridPane, ++rowIndex, "Trade amount:", formatter.formatCoinWithCode(trade.getTradeAmount()));
|
||||||
addLabelTextField(gridPane, ++rowIndex, "Selected arbitrator:", formatter.arbitratorAddressToShortAddress(trade.getArbitratorAddress()));
|
addLabelTextField(gridPane, ++rowIndex, "Selected arbitrator:", trade.getArbitratorAddress().getFullAddress());
|
||||||
|
|
||||||
if (contract != null) {
|
if (contract != null) {
|
||||||
if (buyerPaymentAccountContractData != null)
|
if (buyerPaymentAccountContractData != null) {
|
||||||
addLabelTextField(gridPane, ++rowIndex, "Buyer payment details:", BSResources.get(buyerPaymentAccountContractData.getPaymentDetails()));
|
TextField tf = addLabelTextField(gridPane, ++rowIndex, "Buyer payment details:", BSResources.get(buyerPaymentAccountContractData.getPaymentDetails())).second;
|
||||||
|
tf.setTooltip(new Tooltip(tf.getText()));
|
||||||
if (sellerPaymentAccountContractData != null)
|
tf.setMouseTransparent(false);
|
||||||
addLabelTextField(gridPane, ++rowIndex, "Seller payment details:", BSResources.get(sellerPaymentAccountContractData.getPaymentDetails()));
|
}
|
||||||
|
if (sellerPaymentAccountContractData != null) {
|
||||||
|
TextField tf = addLabelTextField(gridPane, ++rowIndex, "Seller payment details:", BSResources.get(sellerPaymentAccountContractData.getPaymentDetails())).second;
|
||||||
|
tf.setTooltip(new Tooltip(tf.getText()));
|
||||||
|
tf.setMouseTransparent(false);
|
||||||
|
}
|
||||||
if (buyerPaymentAccountContractData == null && sellerPaymentAccountContractData == null)
|
if (buyerPaymentAccountContractData == null && sellerPaymentAccountContractData == null)
|
||||||
addLabelTextField(gridPane, ++rowIndex, "Payment method:", BSResources.get(contract.getPaymentMethodName()));
|
addLabelTextField(gridPane, ++rowIndex, "Payment method:", BSResources.get(contract.getPaymentMethodName()));
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ public class WebViewPopup extends Popup {
|
|||||||
protected String url;
|
protected String url;
|
||||||
|
|
||||||
public static String getLocalUrl(String htmlFile) {
|
public static String getLocalUrl(String htmlFile) {
|
||||||
return WebViewPopup.class.getResource("/html/" + htmlFile).toExternalForm();
|
return WebViewPopup.class.getResource("/html/" + htmlFile + ".html").toExternalForm();
|
||||||
}
|
}
|
||||||
|
|
||||||
public WebViewPopup() {
|
public WebViewPopup() {
|
||||||
|
@ -308,14 +308,9 @@ public class BSFormatter {
|
|||||||
|
|
||||||
|
|
||||||
public String arbitratorAddressesToString(List<Address> addresses) {
|
public String arbitratorAddressesToString(List<Address> addresses) {
|
||||||
//return addresses.stream().map(e -> e.getFullAddress().substring(0, 8)).collect(Collectors.joining(", "));
|
|
||||||
return addresses.stream().map(e -> e.getFullAddress()).collect(Collectors.joining(", "));
|
return addresses.stream().map(e -> e.getFullAddress()).collect(Collectors.joining(", "));
|
||||||
}
|
}
|
||||||
|
|
||||||
public String arbitratorAddressToShortAddress(Address address) {
|
|
||||||
return address.getFullAddress().substring(0, 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String languageCodesToString(List<String> languageLocales) {
|
public String languageCodesToString(List<String> languageLocales) {
|
||||||
return languageLocales.stream().map(LanguageUtil::getDisplayName).collect(Collectors.joining(", "));
|
return languageLocales.stream().map(LanguageUtil::getDisplayName).collect(Collectors.joining(", "));
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,8 @@
|
|||||||
body {
|
body {
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
color: #333;
|
color: #333;
|
||||||
font-size: 13px;
|
font-size: 14px;
|
||||||
|
line-height: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
|
@ -75,7 +75,7 @@ createOffer.advancedBox.currency=Currency:
|
|||||||
createOffer.advancedBox.county=Payments account country:
|
createOffer.advancedBox.county=Payments account country:
|
||||||
createOffer.advancedBox.info=Your trading partners must fulfill your offer restrictions. You can edit the accepted countries, languages and arbitrators in the settings. The payments account details are used from your current selected payments account (if you have multiple payments accounts).
|
createOffer.advancedBox.info=Your trading partners must fulfill your offer restrictions. You can edit the accepted countries, languages and arbitrators in the settings. The payments account details are used from your current selected payments account (if you have multiple payments accounts).
|
||||||
|
|
||||||
createOffer.success.headline=Your offer has been successfully published to the distributed offerbook.
|
createOffer.success.headline=Your offer has been published to the offerbook.
|
||||||
createOffer.success.info=In the portfolio screen you can manage your open offers.
|
createOffer.success.info=In the portfolio screen you can manage your open offers.
|
||||||
|
|
||||||
createOffer.error.message=An error occurred when placing the offer.\n\n{0}
|
createOffer.error.message=An error occurred when placing the offer.\n\n{0}
|
||||||
|
@ -80,7 +80,7 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
|
|||||||
private MonadicBinding<Boolean> readyForAuthentication;
|
private MonadicBinding<Boolean> readyForAuthentication;
|
||||||
private final Storage<Address> dbStorage;
|
private final Storage<Address> dbStorage;
|
||||||
private Address myOnionAddress;
|
private Address myOnionAddress;
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Constructor
|
// Constructor
|
||||||
@ -186,7 +186,7 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
|
|||||||
// We set connectionType to that connection to avoid that is get closed when
|
// We set connectionType to that connection to avoid that is get closed when
|
||||||
// we get too many connection attempts.
|
// we get too many connection attempts.
|
||||||
// That is used as protection against eclipse attacks.
|
// That is used as protection against eclipse attacks.
|
||||||
connection.setConnectionType(ConnectionType.DIRECT_MSG);
|
connection.setConnectionType(ConnectionMode.DIRECT_MSG);
|
||||||
|
|
||||||
log.info("Received SealedAndSignedMessage and decrypted it: " + decryptedMsgWithPubKey);
|
log.info("Received SealedAndSignedMessage and decrypted it: " + decryptedMsgWithPubKey);
|
||||||
decryptedMailListeners.stream().forEach(
|
decryptedMailListeners.stream().forEach(
|
||||||
@ -305,7 +305,8 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
|
|||||||
Log.traceCall();
|
Log.traceCall();
|
||||||
checkArgument(networkNode.getAddress() != null, "Address must be set when we have the hidden service ready");
|
checkArgument(networkNode.getAddress() != null, "Address must be set when we have the hidden service ready");
|
||||||
if (myOnionAddress != null)
|
if (myOnionAddress != null)
|
||||||
checkArgument(networkNode.getAddress() == myOnionAddress, "networkNode.getAddress() must be same as myOnionAddress");
|
checkArgument(networkNode.getAddress().equals(myOnionAddress),
|
||||||
|
"networkNode.getAddress() must be same as myOnionAddress.");
|
||||||
|
|
||||||
myOnionAddress = networkNode.getAddress();
|
myOnionAddress = networkNode.getAddress();
|
||||||
dbStorage.queueUpForSave(myOnionAddress);
|
dbStorage.queueUpForSave(myOnionAddress);
|
||||||
@ -709,7 +710,7 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
|
|||||||
return blurredAddressHash != null &&
|
return blurredAddressHash != null &&
|
||||||
Arrays.equals(blurredAddressHash, sealedAndSignedMessage.addressPrefixHash);
|
Arrays.equals(blurredAddressHash, sealedAndSignedMessage.addressPrefixHash);
|
||||||
} else {
|
} else {
|
||||||
log.warn("myOnionAddress must not be null at verifyAddressPrefixHash");
|
log.debug("myOnionAddress is null at verifyAddressPrefixHash. That is expected at startup.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ public class Connection implements MessageListener {
|
|||||||
private static final Logger log = LoggerFactory.getLogger(Connection.class);
|
private static final Logger log = LoggerFactory.getLogger(Connection.class);
|
||||||
private static final int MAX_MSG_SIZE = 5 * 1024 * 1024; // 5 MB of compressed data
|
private static final int MAX_MSG_SIZE = 5 * 1024 * 1024; // 5 MB of compressed data
|
||||||
private static final int SOCKET_TIMEOUT = 30 * 60 * 1000; // 30 min.
|
private static final int SOCKET_TIMEOUT = 30 * 60 * 1000; // 30 min.
|
||||||
private ConnectionType connectionType;
|
private ConnectionMode connectionType;
|
||||||
|
|
||||||
public static int getMaxMsgSize() {
|
public static int getMaxMsgSize() {
|
||||||
return MAX_MSG_SIZE;
|
return MAX_MSG_SIZE;
|
||||||
@ -123,7 +123,7 @@ public class Connection implements MessageListener {
|
|||||||
connectionListener.onPeerAddressAuthenticated(peerAddress, connection);
|
connectionListener.onPeerAddressAuthenticated(peerAddress, connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setConnectionType(ConnectionType connectionType) {
|
public void setConnectionType(ConnectionMode connectionType) {
|
||||||
this.connectionType = connectionType;
|
this.connectionType = connectionType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,7 +210,7 @@ public class Connection implements MessageListener {
|
|||||||
return stopped;
|
return stopped;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConnectionType getConnectionType() {
|
public ConnectionMode getConnectionType() {
|
||||||
return connectionType;
|
return connectionType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
package io.bitsquare.p2p.network;
|
||||||
|
|
||||||
|
public enum ConnectionMode {
|
||||||
|
PASSIVE, // for connections initiated by other peer
|
||||||
|
ACTIVE, // for connections initiated by us
|
||||||
|
DIRECT_MSG, // for connections used for direct messaging
|
||||||
|
AUTH_REQUEST // for connections used for starting the authentication
|
||||||
|
}
|
@ -8,7 +8,7 @@ import io.bitsquare.common.UserThread;
|
|||||||
import io.bitsquare.p2p.Address;
|
import io.bitsquare.p2p.Address;
|
||||||
import io.bitsquare.p2p.Message;
|
import io.bitsquare.p2p.Message;
|
||||||
import io.bitsquare.p2p.network.Connection;
|
import io.bitsquare.p2p.network.Connection;
|
||||||
import io.bitsquare.p2p.network.ConnectionType;
|
import io.bitsquare.p2p.network.ConnectionMode;
|
||||||
import io.bitsquare.p2p.network.MessageListener;
|
import io.bitsquare.p2p.network.MessageListener;
|
||||||
import io.bitsquare.p2p.network.NetworkNode;
|
import io.bitsquare.p2p.network.NetworkNode;
|
||||||
import io.bitsquare.p2p.peers.messages.auth.*;
|
import io.bitsquare.p2p.peers.messages.auth.*;
|
||||||
@ -72,7 +72,7 @@ public class AuthenticationHandshake implements MessageListener {
|
|||||||
|
|
||||||
// We use the active connectionType if we started the authentication request to another peer
|
// We use the active connectionType if we started the authentication request to another peer
|
||||||
// That is used for protecting eclipse attacks
|
// That is used for protecting eclipse attacks
|
||||||
connection.setConnectionType(ConnectionType.ACTIVE);
|
connection.setConnectionType(ConnectionMode.ACTIVE);
|
||||||
|
|
||||||
AuthenticationResponse authenticationResponse = (AuthenticationResponse) message;
|
AuthenticationResponse authenticationResponse = (AuthenticationResponse) message;
|
||||||
Address peerAddress = authenticationResponse.address;
|
Address peerAddress = authenticationResponse.address;
|
||||||
@ -180,7 +180,7 @@ public class AuthenticationHandshake implements MessageListener {
|
|||||||
log.trace("send AuthenticationRequest to " + peerAddress + " succeeded.");
|
log.trace("send AuthenticationRequest to " + peerAddress + " succeeded.");
|
||||||
connection.setPeerAddress(peerAddress);
|
connection.setPeerAddress(peerAddress);
|
||||||
// We protect that connection from getting closed by maintenance cleanup...
|
// We protect that connection from getting closed by maintenance cleanup...
|
||||||
connection.setConnectionType(ConnectionType.AUTH_REQUEST);
|
connection.setConnectionType(ConnectionMode.AUTH_REQUEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -228,7 +228,7 @@ public class AuthenticationHandshake implements MessageListener {
|
|||||||
connection.setPeerAddress(peerAddress);
|
connection.setPeerAddress(peerAddress);
|
||||||
// We use passive connectionType for connections created from received authentication requests from other peers
|
// We use passive connectionType for connections created from received authentication requests from other peers
|
||||||
// That is used for protecting eclipse attacks
|
// That is used for protecting eclipse attacks
|
||||||
connection.setConnectionType(ConnectionType.PASSIVE);
|
connection.setConnectionType(ConnectionMode.PASSIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -168,7 +168,7 @@ public class PeerGroup implements MessageListener, ConnectionListener {
|
|||||||
Address peerAddress = message.address;
|
Address peerAddress = message.address;
|
||||||
if (!authenticationHandshakes.containsKey(peerAddress)) {
|
if (!authenticationHandshakes.containsKey(peerAddress)) {
|
||||||
// We protect that connection from getting closed by maintenance cleanup...
|
// We protect that connection from getting closed by maintenance cleanup...
|
||||||
connection.setConnectionType(ConnectionType.AUTH_REQUEST);
|
connection.setConnectionType(ConnectionMode.AUTH_REQUEST);
|
||||||
AuthenticationHandshake authenticationHandshake = new AuthenticationHandshake(networkNode, PeerGroup.this, getMyAddress());
|
AuthenticationHandshake authenticationHandshake = new AuthenticationHandshake(networkNode, PeerGroup.this, getMyAddress());
|
||||||
authenticationHandshakes.put(peerAddress, authenticationHandshake);
|
authenticationHandshakes.put(peerAddress, authenticationHandshake);
|
||||||
SettableFuture<Connection> future = authenticationHandshake.respondToAuthenticationRequest(message, connection);
|
SettableFuture<Connection> future = authenticationHandshake.respondToAuthenticationRequest(message, connection);
|
||||||
@ -186,8 +186,7 @@ public class PeerGroup implements MessageListener, ConnectionListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(@NotNull Throwable throwable) {
|
public void onFailure(@NotNull Throwable throwable) {
|
||||||
log.error("AuthenticationHandshake failed. " + throwable.getMessage());
|
log.info("AuthenticationHandshake failed. That is expected if peer went offline. " + throwable.getMessage());
|
||||||
throwable.printStackTrace();
|
|
||||||
removePeer(connection.getPeerAddress());
|
removePeer(connection.getPeerAddress());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -468,7 +467,7 @@ public class PeerGroup implements MessageListener, ConnectionListener {
|
|||||||
|
|
||||||
List<Connection> authenticatedConnections = allConnections.stream()
|
List<Connection> authenticatedConnections = allConnections.stream()
|
||||||
.filter(e -> e.isAuthenticated())
|
.filter(e -> e.isAuthenticated())
|
||||||
.filter(e -> e.getConnectionType() == ConnectionType.PASSIVE)
|
.filter(e -> e.getConnectionType() == ConnectionMode.PASSIVE)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
if (authenticatedConnections.size() == 0) {
|
if (authenticatedConnections.size() == 0) {
|
||||||
@ -477,7 +476,7 @@ public class PeerGroup implements MessageListener, ConnectionListener {
|
|||||||
if (size > MAX_CONNECTIONS_NORMAL_PRIO) {
|
if (size > MAX_CONNECTIONS_NORMAL_PRIO) {
|
||||||
authenticatedConnections = allConnections.stream()
|
authenticatedConnections = allConnections.stream()
|
||||||
.filter(e -> e.isAuthenticated())
|
.filter(e -> e.isAuthenticated())
|
||||||
.filter(e -> e.getConnectionType() == ConnectionType.PASSIVE || e.getConnectionType() == ConnectionType.ACTIVE)
|
.filter(e -> e.getConnectionType() == ConnectionMode.PASSIVE || e.getConnectionType() == ConnectionMode.ACTIVE)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
if (authenticatedConnections.size() == 0) {
|
if (authenticatedConnections.size() == 0) {
|
||||||
|
@ -285,7 +285,7 @@ public class ProtectedExpirableDataStorage implements MessageListener {
|
|||||||
Log.traceCall();
|
Log.traceCall();
|
||||||
int newSequenceNumber = data.sequenceNumber;
|
int newSequenceNumber = data.sequenceNumber;
|
||||||
Integer storedSequenceNumber = sequenceNumberMap.get(hashOfData);
|
Integer storedSequenceNumber = sequenceNumberMap.get(hashOfData);
|
||||||
if (sequenceNumberMap.containsKey(hashOfData) && newSequenceNumber <= storedSequenceNumber) {
|
if (sequenceNumberMap.containsKey(hashOfData) && newSequenceNumber < storedSequenceNumber) {
|
||||||
log.trace("Sequence number is invalid. newSequenceNumber="
|
log.trace("Sequence number is invalid. newSequenceNumber="
|
||||||
+ newSequenceNumber + " / storedSequenceNumber=" + storedSequenceNumber);
|
+ newSequenceNumber + " / storedSequenceNumber=" + storedSequenceNumber);
|
||||||
return false;
|
return false;
|
||||||
|
Loading…
Reference in New Issue
Block a user