Apply primary market based direction, add BTC if "buyer" or "seller" is used in info text, remove embedded app version in offerID,

This commit is contained in:
Manfred Karrer 2016-08-28 18:01:53 +02:00
parent ee90e40c54
commit 956843ca14
38 changed files with 320 additions and 214 deletions

View File

@ -3,6 +3,9 @@
<component name="ProjectCodeStyleSettingsManager">
<option name="PER_PROJECT_SETTINGS">
<value>
<MarkdownNavigatorCodeStyleSettings>
<option name="RIGHT_MARGIN" value="72" />
</MarkdownNavigatorCodeStyleSettings>
<XML>
<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
</XML>

View File

@ -348,17 +348,7 @@ public final class Offer implements StoragePayload, RequiresOwnerIsOnlinePayload
}
public String getId() {
String[] tokens = id.split("_");
return tokens[0];
}
@Nullable
public String getVersion() {
String[] tokens = id.split("_");
if (tokens.length > 1)
return tokens[1];
else
return null;
return id;
}
public String getShortId() {

View File

@ -361,40 +361,46 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
Optional<OpenOffer> openOfferOptional = findOpenOffer(message.offerId);
AvailabilityResult availabilityResult;
if (openOfferOptional.isPresent() && openOfferOptional.get().getState() == OpenOffer.State.AVAILABLE) {
final Offer offer = openOfferOptional.get().getOffer();
if (!preferences.getIgnoreTradersList().stream().filter(i -> i.equals(offer.getOffererNodeAddress().getHostNameWithoutPostFix())).findAny().isPresent()) {
availabilityResult = AvailabilityResult.AVAILABLE;
List<NodeAddress> acceptedArbitrators = user.getAcceptedArbitratorAddresses();
if (acceptedArbitrators != null && !acceptedArbitrators.isEmpty()) {
// We need to be backward compatible. takersTradePrice was not used before 0.4.9.
if (message.takersTradePrice > 0) {
// Check also tradePrice to avoid failures after taker fee is paid caused by a too big difference
// in trade price between the peers. Also here poor connectivity might cause market price API connection
// losses and therefore an outdated market price.
try {
offer.checkTradePriceTolerance(message.takersTradePrice);
} catch (TradePriceOutOfToleranceException e) {
log.warn("Trade price check failed because takers price is outside out tolerance.");
availabilityResult = AvailabilityResult.PRICE_OUT_OF_TOLERANCE;
} catch (MarketPriceNotAvailableException e) {
log.warn(e.getMessage());
availabilityResult = AvailabilityResult.MARKET_PRICE_NOT_AVAILABLE;
} catch (Throwable e) {
log.warn("Trade price check failed. " + e.getMessage());
availabilityResult = AvailabilityResult.UNKNOWN_FAILURE;
if (openOfferOptional.isPresent()) {
if (openOfferOptional.get().getState() == OpenOffer.State.AVAILABLE) {
final Offer offer = openOfferOptional.get().getOffer();
if (!preferences.getIgnoreTradersList().stream().filter(i -> i.equals(offer.getOffererNodeAddress().getHostNameWithoutPostFix())).findAny().isPresent()) {
availabilityResult = AvailabilityResult.AVAILABLE;
List<NodeAddress> acceptedArbitrators = user.getAcceptedArbitratorAddresses();
if (acceptedArbitrators != null && !acceptedArbitrators.isEmpty()) {
// We need to be backward compatible. takersTradePrice was not used before 0.4.9.
if (message.takersTradePrice > 0) {
// Check also tradePrice to avoid failures after taker fee is paid caused by a too big difference
// in trade price between the peers. Also here poor connectivity might cause market price API connection
// losses and therefore an outdated market price.
try {
offer.checkTradePriceTolerance(message.takersTradePrice);
} catch (TradePriceOutOfToleranceException e) {
log.warn("Trade price check failed because takers price is outside out tolerance.");
availabilityResult = AvailabilityResult.PRICE_OUT_OF_TOLERANCE;
} catch (MarketPriceNotAvailableException e) {
log.warn(e.getMessage());
availabilityResult = AvailabilityResult.MARKET_PRICE_NOT_AVAILABLE;
} catch (Throwable e) {
log.warn("Trade price check failed. " + e.getMessage());
availabilityResult = AvailabilityResult.UNKNOWN_FAILURE;
}
}
} else {
log.warn("acceptedArbitrators is null or empty: acceptedArbitrators=" + acceptedArbitrators);
availabilityResult = AvailabilityResult.NO_ARBITRATORS;
}
} else {
log.warn("acceptedArbitrators is null or empty: acceptedArbitrators=" + acceptedArbitrators);
availabilityResult = AvailabilityResult.NO_ARBITRATORS;
availabilityResult = AvailabilityResult.USER_IGNORED;
}
} else {
availabilityResult = AvailabilityResult.USER_IGNORED;
availabilityResult = AvailabilityResult.OFFER_TAKEN;
}
} else {
log.warn("handleOfferAvailabilityRequest: openOffer not found. That should never happen.");
availabilityResult = AvailabilityResult.OFFER_TAKEN;
}
try {
p2PService.sendEncryptedDirectMessage(sender,
message.getPubKeyRing(),

View File

@ -152,19 +152,28 @@ public class TraderDisputeView extends ActivatableView<VBox, Void> {
tableView.getSelectionModel().clearSelection();
tableView.getColumns().add(getSelectColumn());
TableColumn<Dispute, Dispute> tradeIdColumn = getTradeIdColumn();
tableView.getColumns().add(tradeIdColumn);
TableColumn<Dispute, Dispute> roleColumn = getRoleColumn();
tableView.getColumns().add(roleColumn);
TableColumn<Dispute, Dispute> dateColumn = getDateColumn();
tableView.getColumns().add(dateColumn);
TableColumn<Dispute, Dispute> contractColumn = getContractColumn();
tableView.getColumns().add(contractColumn);
TableColumn<Dispute, Dispute> dateColumn = getDateColumn();
tableView.getColumns().add(dateColumn);
TableColumn<Dispute, Dispute> tradeIdColumn = getTradeIdColumn();
tableView.getColumns().add(tradeIdColumn);
TableColumn<Dispute, Dispute> marketColumn = getMarketColumn();
tableView.getColumns().add(marketColumn);
TableColumn<Dispute, Dispute> roleColumn = getRoleColumn();
tableView.getColumns().add(roleColumn);
TableColumn<Dispute, Dispute> stateColumn = getStateColumn();
tableView.getColumns().add(stateColumn);
tradeIdColumn.setComparator((o1, o2) -> o1.getTradeId().compareTo(o2.getTradeId()));
dateColumn.setComparator((o1, o2) -> o1.getOpeningDate().compareTo(o2.getOpeningDate()));
marketColumn.setComparator((o1, o2) -> formatter.getCurrencyPair(o1.getContract().offer.getCurrencyCode()).compareTo(o2.getContract().offer.getCurrencyCode()));
dateColumn.setSortType(TableColumn.SortType.DESCENDING);
tableView.getSortOrder().add(dateColumn);
@ -859,6 +868,32 @@ public class TraderDisputeView extends ActivatableView<VBox, Void> {
return column;
}
private TableColumn<Dispute, Dispute> getMarketColumn() {
TableColumn<Dispute, Dispute> column = new TableColumn<Dispute, Dispute>("Market") {
{
setMinWidth(130);
}
};
column.setCellValueFactory((dispute) -> new ReadOnlyObjectWrapper<>(dispute.getValue()));
column.setCellFactory(
new Callback<TableColumn<Dispute, Dispute>, TableCell<Dispute, Dispute>>() {
@Override
public TableCell<Dispute, Dispute> call(TableColumn<Dispute, Dispute> column) {
return new TableCell<Dispute, Dispute>() {
@Override
public void updateItem(final Dispute item, boolean empty) {
super.updateItem(item, empty);
if (item != null && !empty)
setText(formatter.getCurrencyPair(item.getContract().offer.getCurrencyCode()));
else
setText("");
}
};
}
});
return column;
}
private TableColumn<Dispute, Dispute> getRoleColumn() {
TableColumn<Dispute, Dispute> column = new TableColumn<Dispute, Dispute>("Role") {
{
@ -876,9 +911,9 @@ public class TraderDisputeView extends ActivatableView<VBox, Void> {
super.updateItem(item, empty);
if (item != null && !empty) {
if (item.isDisputeOpenerIsOfferer())
setText(item.isDisputeOpenerIsBuyer() ? "Buyer/Offerer" : "Seller/Offerer");
setText(item.isDisputeOpenerIsBuyer() ? "BTC buyer/Offerer" : "BTC seller/Offerer");
else
setText(item.isDisputeOpenerIsBuyer() ? "Buyer/Taker" : "Seller/Taker");
setText(item.isDisputeOpenerIsBuyer() ? "BTC buyer/Taker" : "BTC seller/Taker");
} else {
setText("");
}

View File

@ -108,7 +108,6 @@ public class OfferBookChartView extends ActivatableViewAndModel<VBox, OfferBookC
currencyComboBox = new ComboBox<>();
currencyComboBox.setPromptText("Select currency");
currencyComboBox.setConverter(GUIUtil.getCurrencyListItemConverter("offers"));
currencyComboBox.setVisibleRowCount(25);
Label currencyLabel = new Label("Currency:");
HBox currencyHBox = new HBox();
@ -150,6 +149,7 @@ public class OfferBookChartView extends ActivatableViewAndModel<VBox, OfferBookC
tabPaneSelectionModel.selectedIndexProperty().addListener(selectedTabIndexListener);
currencyComboBox.setItems(model.getCurrencyListItems());
currencyComboBox.setVisibleRowCount(25);
if (model.getSelectedCurrencyListItem().isPresent())
currencyComboBox.getSelectionModel().select(model.getSelectedCurrencyListItem().get());

View File

@ -133,7 +133,7 @@ class OfferBookChartViewModel extends ActivatableViewModel {
.filter(e -> e != null)
.collect(Collectors.toList());
GUIUtil.fillCurrencyListItems(tradeCurrencyList, currencyListItems, preferences);
GUIUtil.fillCurrencyListItems(tradeCurrencyList, currencyListItems, null, preferences);
}
@Override

View File

@ -116,9 +116,9 @@ public class SpreadView extends ActivatableViewAndModel<GridPane, SpreadViewMode
}
private void updateHeaders() {
numberOfOffersColumn.setText("Total offers (" + sortedList.stream().mapToInt(item -> item.numberOfOffers).sum() + ")");
numberOfBuyOffersColumn.setText("Bid offers (" + sortedList.stream().mapToInt(item -> item.numberOfBuyOffers).sum() + ")");
numberOfSellOffersColumn.setText("Ask offers (" + sortedList.stream().mapToInt(item -> item.numberOfSellOffers).sum() + ")");
numberOfOffersColumn.setText("All offers (" + sortedList.stream().mapToInt(item -> item.numberOfOffers).sum() + ")");
numberOfBuyOffersColumn.setText("Buy BTC offers (" + sortedList.stream().mapToInt(item -> item.numberOfBuyOffers).sum() + ")");
numberOfSellOffersColumn.setText("Sell BTC offers (" + sortedList.stream().mapToInt(item -> item.numberOfSellOffers).sum() + ")");
totalAmountColumn.setText("Total amount in BTC (" + formatter.formatCoin(Coin.valueOf(sortedList.stream().mapToLong(item -> item.totalAmount.value).sum())) + ")");
}

View File

@ -140,6 +140,7 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
tabPaneSelectionModel.selectedIndexProperty().addListener(selectedTabIndexListener);
currencyComboBox.setItems(model.getCurrencyListItems());
currencyComboBox.setVisibleRowCount(25);
if (model.showAllTradeCurrenciesProperty.get())
currencyComboBox.getSelectionModel().select(0);
@ -379,7 +380,6 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
currencyComboBox = new ComboBox<>();
currencyComboBox.setPromptText("Select currency");
currencyComboBox.setConverter(GUIUtil.getCurrencyListItemConverter("trades, all time"));
currencyComboBox.setVisibleRowCount(25);
Pane spacer = new Pane();
HBox.setHgrow(spacer, Priority.ALWAYS);
@ -567,7 +567,7 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
public void updateItem(final TradeStatistics item, boolean empty) {
super.updateItem(item, empty);
if (item != null)
setText(formatter.getDirection(item.direction, item.currency));
setText(formatter.getDirectionWithCode(item.direction, item.currency));
else
setText("");
}

View File

@ -79,6 +79,7 @@ class TradesChartsViewModel extends ActivatableViewModel {
final ObjectProperty<TradeCurrency> selectedTradeCurrencyProperty = new SimpleObjectProperty<>();
final BooleanProperty showAllTradeCurrenciesProperty = new SimpleBooleanProperty(false);
private final ObservableList<CurrencyListItem> currencyListItems = FXCollections.observableArrayList();
private CurrencyListItem showAllCurrencyListItem = new CurrencyListItem(new CryptoCurrency(GUIUtil.SHOW_ALL_FLAG, GUIUtil.SHOW_ALL_FLAG), -1);
final ObservableList<TradeStatistics> tradeStatisticsByCurrency = FXCollections.observableArrayList();
ObservableList<XYChart.Data<Number, Number>> priceItems = FXCollections.observableArrayList();
ObservableList<XYChart.Data<Number, Number>> volumeItems = FXCollections.observableArrayList();
@ -128,8 +129,7 @@ class TradesChartsViewModel extends ActivatableViewModel {
.filter(e -> e != null)
.collect(Collectors.toList());
GUIUtil.fillCurrencyListItems(tradeCurrencyList, currencyListItems, preferences);
currencyListItems.add(0, new CurrencyListItem(new CryptoCurrency(GUIUtil.SHOW_ALL_FLAG, GUIUtil.SHOW_ALL_FLAG), -1));
GUIUtil.fillCurrencyListItems(tradeCurrencyList, currencyListItems, showAllCurrencyListItem, preferences);
}
@VisibleForTesting

View File

@ -19,7 +19,6 @@ package io.bitsquare.gui.main.offer.createoffer;
import com.google.inject.Inject;
import io.bitsquare.app.DevFlags;
import io.bitsquare.app.Version;
import io.bitsquare.arbitration.Arbitrator;
import io.bitsquare.btc.AddressEntry;
import io.bitsquare.btc.FeePolicy;
@ -296,10 +295,7 @@ class CreateOfferDataModel extends ActivatableDataModel {
checkNotNull(p2PService.getAddress(), "Address must not be null");
// We encode the version into the id to be able to distinguish in future versions offers
// Once we have a hard fork we can remove that hack and add the version as a field
String idWithExtra = offerId + "_" + Version.VERSION;
return new Offer(idWithExtra,
return new Offer(offerId,
p2PService.getAddress(),
keyRing.getPubKeyRing(),
direction,

View File

@ -622,7 +622,7 @@ class CreateOfferViewModel extends ActivatableWithDataModel<CreateOfferDataModel
///////////////////////////////////////////////////////////////////////////////////////////
public boolean isPriceInRange() {
if (marketPriceMargin.get() != null) {
if (marketPriceMargin.get() != null && !marketPriceMargin.get().isEmpty()) {
if (formatter.parsePercentStringToDouble(marketPriceMargin.get()) > preferences.getMaxPriceDistanceInPercent()) {
displayPriceOutOfRangePopup();
return false;

View File

@ -18,6 +18,7 @@
package io.bitsquare.gui.main.offer.offerbook;
import io.bitsquare.alert.PrivateNotificationManager;
import io.bitsquare.common.UserThread;
import io.bitsquare.gui.Navigation;
import io.bitsquare.gui.common.view.ActivatableViewAndModel;
import io.bitsquare.gui.common.view.FxmlView;
@ -64,6 +65,7 @@ import org.fxmisc.easybind.Subscription;
import org.fxmisc.easybind.monadic.MonadicBinding;
import javax.inject.Inject;
import java.util.Optional;
import static io.bitsquare.gui.util.FormBuilder.*;
@ -114,7 +116,6 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi
currencyComboBox = addLabelComboBox(root, gridRow, "Filter by currency:", Layout.FIRST_ROW_DISTANCE).second;
currencyComboBox.setPromptText("Select currency");
currencyComboBox.setConverter(GUIUtil.getCurrencyListItemConverter("offers"));
currencyComboBox.setVisibleRowCount(25);
paymentMethodComboBox = addLabelComboBox(root, ++gridRow, "Filter by payment method:").second;
paymentMethodComboBox.setPromptText("Select payment method");
@ -205,12 +206,15 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi
@Override
protected void activate() {
currencyComboBox.setItems(model.getCurrencyListItems());
currencyComboBox.setVisibleRowCount(25);
model.currencyListItems.addListener(currencyListItemsListener);
applyCurrencyComboBoxSelection();
currencyComboBox.setOnAction(e -> {
CurrencyListItem selectedItem = currencyComboBox.getSelectionModel().getSelectedItem();
if (selectedItem != null)
model.onSetTradeCurrency(selectedItem.tradeCurrency);
});
@ -275,10 +279,13 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi
}
private void applyCurrencyComboBoxSelection() {
if (model.showAllTradeCurrenciesProperty.get())
currencyComboBox.getSelectionModel().select(0);
else if (model.getSelectedCurrencyListItem().isPresent())
currencyComboBox.getSelectionModel().select(model.getSelectedCurrencyListItem().get());
Optional<CurrencyListItem> selectedCurrencyListItem = model.getSelectedCurrencyListItem();
UserThread.execute(() -> {
if (model.showAllTradeCurrenciesProperty.get() || !selectedCurrencyListItem.isPresent())
currencyComboBox.getSelectionModel().select(model.getShowAllCurrencyListItem());
else
currencyComboBox.getSelectionModel().select(selectedCurrencyListItem.get());
});
}
@ -604,7 +611,7 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi
private TableColumn<OfferBookListItem, OfferBookListItem> getPaymentMethodColumn() {
TableColumn<OfferBookListItem, OfferBookListItem> column = new TableColumn<OfferBookListItem, OfferBookListItem>("Payment method") {
{
setMinWidth(130);
setMinWidth(120);
}
};
column.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue()));
@ -717,6 +724,7 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi
button.setId(isSellOffer ? "buy-button" : "sell-button");
button.setStyle("-fx-text-fill: white;"); // does not take the font colors sometimes from the style
title = model.getDirectionLabel(offer);
button.setTooltip(new Tooltip("Take offer for " + model.getDirectionLabelTooltip(offer)));
button.setOnAction(e -> onTakeOffer(offer));
}

View File

@ -83,8 +83,7 @@ class OfferBookViewModel extends ActivatableViewModel {
private TradeCurrency selectedTradeCurrency;
private final ListChangeListener<OfferBookListItem> offerBookListItemsListener;
final ObservableList<CurrencyListItem> currencyListItems = FXCollections.observableArrayList();
private final ObservableList<TradeCurrency> allTradeCurrencies = FXCollections.observableArrayList();
private CurrencyListItem showAllCurrencyListItem = new CurrencyListItem(new CryptoCurrency(GUIUtil.SHOW_ALL_FLAG, GUIUtil.SHOW_ALL_FLAG), -1);
private Offer.Direction direction;
private final StringProperty btcCode = new SimpleStringProperty();
@ -135,7 +134,7 @@ class OfferBookViewModel extends ActivatableViewModel {
offerBookListItems.addListener(offerBookListItemsListener);
String code = direction == Offer.Direction.BUY ? preferences.getBuyScreenCurrencyCode() : preferences.getSellScreenCurrencyCode();
if (code != null && !code.isEmpty() && CurrencyUtil.getTradeCurrency(code).isPresent()) {
if (code != null && !code.equals("SHOW_ALL_FLAG") && !code.isEmpty() && CurrencyUtil.getTradeCurrency(code).isPresent()) {
showAllTradeCurrenciesProperty.set(false);
selectedTradeCurrency = CurrencyUtil.getTradeCurrency(code).get();
} else {
@ -143,6 +142,7 @@ class OfferBookViewModel extends ActivatableViewModel {
selectedTradeCurrency = CurrencyUtil.getDefaultTradeCurrency();
}
tradeCurrencyCode.set(selectedTradeCurrency.getCode());
setPriceFeedType();
btcCode.bind(preferences.btcDenominationProperty());
@ -249,6 +249,10 @@ class OfferBookViewModel extends ActivatableViewModel {
return currencyListItems.stream().filter(e -> tradeCurrencyCode.get() != null && e.tradeCurrency.getCode().equals(tradeCurrencyCode.get())).findAny();
}
CurrencyListItem getShowAllCurrencyListItem() {
return showAllCurrencyListItem;
}
String getAmount(OfferBookListItem item) {
Offer offer = item.getOffer();
@ -349,7 +353,11 @@ class OfferBookViewModel extends ActivatableViewModel {
}
String getDirectionLabel(Offer offer) {
return formatter.getDirection(offer.getMirroredDirection(), offer.getCurrencyCode());
return formatter.getDirectionWithCode(offer.getMirroredDirection(), offer.getCurrencyCode());
}
String getDirectionLabelTooltip(Offer offer) {
return formatter.getDirectionWithCodeDetailed(offer.getMirroredDirection(), offer.getCurrencyCode());
}
@ -389,8 +397,7 @@ class OfferBookViewModel extends ActivatableViewModel {
.filter(e -> e != null)
.collect(Collectors.toList());
GUIUtil.fillCurrencyListItems(tradeCurrencyList, currencyListItems, preferences);
currencyListItems.add(0, new CurrencyListItem(new CryptoCurrency(GUIUtil.SHOW_ALL_FLAG, GUIUtil.SHOW_ALL_FLAG), -1));
GUIUtil.fillCurrencyListItems(tradeCurrencyList, currencyListItems, showAllCurrencyListItem, preferences);
tradeCurrencyCodes = currencyListItems.stream().map(e -> e.tradeCurrency.getCode()).collect(Collectors.toSet());
}

View File

@ -880,7 +880,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
priceAsPercentageLabel = priceAsPercentageTuple.third;
Tuple2<Label, VBox> priceAsPercentageInputBoxTuple = getTradeInputBox(priceAsPercentageValueCurrencyBox, "Distance in % from market price");
priceAsPercentageInputBoxTuple.first.setPrefWidth(200);
priceAsPercentageInputBoxTuple.first.setPrefWidth(220);
priceAsPercentageInputBox = priceAsPercentageInputBoxTuple.second;
priceAsPercentageTextField.setPromptText("Enter % value");
@ -920,7 +920,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
private Tuple2<Label, VBox> getTradeInputBox(HBox amountValueBox, String promptText) {
Label descriptionLabel = new Label(promptText);
descriptionLabel.setId("input-description-label");
descriptionLabel.setPrefWidth(170);
descriptionLabel.setPrefWidth(190);
VBox box = new VBox();
box.setSpacing(4);
@ -930,7 +930,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
private Tuple3<HBox, InputTextField, Label> getAmountCurrencyBox(String promptText) {
InputTextField input = new InputTextField();
input.setPrefWidth(170);
input.setPrefWidth(190);
input.setAlignment(Pos.CENTER_RIGHT);
input.setId("text-input-with-currency-text-field");
input.setPromptText(promptText);
@ -945,7 +945,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
private Tuple3<HBox, TextField, Label> getValueCurrencyBox() {
TextField textField = new InputTextField();
textField.setPrefWidth(170);
textField.setPrefWidth(190);
textField.setAlignment(Pos.CENTER_RIGHT);
textField.setId("text-input-with-currency-text-field");
textField.setMouseTransparent(true);

View File

@ -154,7 +154,7 @@ public class NotificationCenter {
if (tradeManager.isBuyer(trade.getOffer())) {
switch (tradeState) {
case OFFERER_RECEIVED_DEPOSIT_TX_PUBLISHED_MSG:
message = "Your offer has been accepted by a seller.";
message = "Your offer has been accepted by a BTC seller.";
break;
case DEPOSIT_CONFIRMED_IN_BLOCK_CHAIN:
message = "Your trade has at least one blockchain confirmation.\n" +
@ -164,10 +164,10 @@ public class NotificationCenter {
} else {
switch (tradeState) {
case OFFERER_RECEIVED_DEPOSIT_TX_PUBLISHED_MSG:
message = "Your offer has been accepted by a buyer.";
message = "Your offer has been accepted by a BTC buyer.";
break;
case SELLER_RECEIVED_FIAT_PAYMENT_INITIATED_MSG:
message = "The bitcoin buyer has started the payment.";
message = "The BTC buyer has started the payment.";
break;
}
}

View File

@ -116,23 +116,24 @@ public class ContractWindow extends Overlay<ContractWindow> {
Layout.FIRST_ROW_DISTANCE).second.setMouseTransparent(false);
addLabelTextField(gridPane, ++rowIndex, "Offer date:", formatter.formatDateTime(offer.getDate()));
addLabelTextField(gridPane, ++rowIndex, "Trade date:", formatter.formatDateTime(dispute.getTradeDate()));
addLabelTextField(gridPane, ++rowIndex, "Trade type:", formatter.getDirectionBothSides(offer.getDirection()));
String currencyCode = offer.getCurrencyCode();
addLabelTextField(gridPane, ++rowIndex, "Trade type:", formatter.getDirectionBothSides(offer.getDirection(), currencyCode));
addLabelTextField(gridPane, ++rowIndex, "Trade price:", formatter.formatPrice(contract.getTradePrice()));
addLabelTextField(gridPane, ++rowIndex, "Trade amount:", formatter.formatCoinWithCode(contract.getTradeAmount()));
addLabelTextField(gridPane, ++rowIndex, formatter.formatVolumeLabel(offer.getCurrencyCode(), ":"),
addLabelTextField(gridPane, ++rowIndex, formatter.formatVolumeLabel(currencyCode, ":"),
formatter.formatVolumeWithCode(new ExchangeRate(contract.getTradePrice()).coinToFiat(contract.getTradeAmount())));
addLabelTextFieldWithCopyIcon(gridPane, ++rowIndex, "Buyer bitcoin address:",
addLabelTextFieldWithCopyIcon(gridPane, ++rowIndex, "BTC buyer bitcoin address:",
contract.getBuyerPayoutAddressString()).second.setMouseTransparent(false);
addLabelTextFieldWithCopyIcon(gridPane, ++rowIndex, "Seller bitcoin address:",
addLabelTextFieldWithCopyIcon(gridPane, ++rowIndex, "BTC seller bitcoin address:",
contract.getSellerPayoutAddressString()).second.setMouseTransparent(false);
addLabelTextFieldWithCopyIcon(gridPane, ++rowIndex, "Contract hash:",
Utils.HEX.encode(dispute.getContractHash())).second.setMouseTransparent(false);
addLabelTextFieldWithCopyIcon(gridPane, ++rowIndex, "Buyer address:", contract.getBuyerNodeAddress().getFullAddress());
addLabelTextFieldWithCopyIcon(gridPane, ++rowIndex, "Seller address:", contract.getSellerNodeAddress().getFullAddress());
addLabelTextFieldWithCopyIcon(gridPane, ++rowIndex, "BTC buyer address:", contract.getBuyerNodeAddress().getFullAddress());
addLabelTextFieldWithCopyIcon(gridPane, ++rowIndex, "BTC seller address:", contract.getSellerNodeAddress().getFullAddress());
addLabelTextFieldWithCopyIcon(gridPane, ++rowIndex, "Selected arbitrator:", contract.arbitratorNodeAddress.getFullAddress());
addLabelTextFieldWithCopyIcon(gridPane, ++rowIndex, "Buyer payment details:",
addLabelTextFieldWithCopyIcon(gridPane, ++rowIndex, "BTC buyer payment details:",
BSResources.get(contract.getBuyerPaymentAccountContractData().getPaymentDetails())).second.setMouseTransparent(false);
addLabelTextFieldWithCopyIcon(gridPane, ++rowIndex, "Seller payment details:",
addLabelTextFieldWithCopyIcon(gridPane, ++rowIndex, "BTC seller payment details:",
BSResources.get(sellerPaymentAccountContractData.getPaymentDetails())).second.setMouseTransparent(false);
if (showAcceptedCountryCodes) {

View File

@ -232,14 +232,14 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
addLabelTextField(gridPane, ++rowIndex, "Ticket opening date:", formatter.formatDateTime(dispute.getOpeningDate()));
if (dispute.isDisputeOpenerIsOfferer()) {
if (dispute.isDisputeOpenerIsBuyer())
role = "Buyer/offerer";
role = "BTC Buyer/offerer";
else
role = "Seller/offerer";
role = "BTC Seller/offerer";
} else {
if (dispute.isDisputeOpenerIsBuyer())
role = "Buyer/taker";
role = "BTC Buyer/taker";
else
role = "Seller/taker";
role = "BTC Seller/taker";
}
addLabelTextField(gridPane, ++rowIndex, "Traders role:", role);
addLabelTextField(gridPane, ++rowIndex, "Trade amount:", formatter.formatCoinWithCode(contract.getTradeAmount()));
@ -272,8 +272,8 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
Label distributionLabel = addLabel(gridPane, ++rowIndex, "Trade amount payout:", 10);
GridPane.setValignment(distributionLabel, VPos.TOP);
buyerIsWinnerRadioButton = new RadioButton("Buyer gets trade amount payout");
sellerIsWinnerRadioButton = new RadioButton("Seller gets trade amount payout");
buyerIsWinnerRadioButton = new RadioButton("BTC buyer gets trade amount payout");
sellerIsWinnerRadioButton = new RadioButton("BTC seller gets trade amount payout");
shareRadioButton = new RadioButton("Both gets half trade amount payout");
VBox radioButtonPane = new VBox();
radioButtonPane.setSpacing(20);
@ -475,8 +475,8 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
"\n" + role + " delivered tamper proof evidence: " + formatter.booleanToYesNo(disputeResult.tamperProofEvidenceProperty().get()) +
"\n" + role + " did ID verification: " + formatter.booleanToYesNo(disputeResult.idVerificationProperty().get()) +
"\n" + role + " did screencast or video: " + formatter.booleanToYesNo(disputeResult.screenCastProperty().get()) +
"\nPayout amount for buyer: " + formatter.formatCoinWithCode(disputeResult.getBuyerPayoutAmount()) +
"\nPayout amount for seller: " + formatter.formatCoinWithCode(disputeResult.getSellerPayoutAmount()) +
"\nPayout amount for BTC buyer: " + formatter.formatCoinWithCode(disputeResult.getBuyerPayoutAmount()) +
"\nPayout amount for BTC seller: " + formatter.formatCoinWithCode(disputeResult.getSellerPayoutAmount()) +
"\nArbitrators dispute fee: " + formatter.formatCoinWithCode(disputeResult.getArbitratorPayoutAmount()) +
"\n\nSummary notes:\n" + disputeResult.summaryNotesProperty().get();

View File

@ -160,20 +160,21 @@ public class OfferDetailsWindow extends Overlay<OfferDetailsWindow> {
String fiatDirectionInfo = ":";
String btcDirectionInfo = ":";
Offer.Direction direction = offer.getDirection();
String currencyCode = offer.getCurrencyCode();
if (takeOfferHandlerOptional.isPresent()) {
addLabelTextField(gridPane, rowIndex, "Offer type:", formatter.getDirectionForTakeOffer(direction), Layout.FIRST_ROW_DISTANCE);
addLabelTextField(gridPane, rowIndex, "Offer type:", formatter.getDirectionForTakeOffer(direction, currencyCode), Layout.FIRST_ROW_DISTANCE);
fiatDirectionInfo = direction == Offer.Direction.BUY ? " to receive:" : " to spend:";
btcDirectionInfo = direction == Offer.Direction.SELL ? " to receive:" : " to spend:";
} else if (placeOfferHandlerOptional.isPresent()) {
addLabelTextField(gridPane, rowIndex, "Offer type:", formatter.getOfferDirectionForCreateOffer(direction), Layout.FIRST_ROW_DISTANCE);
addLabelTextField(gridPane, rowIndex, "Offer type:", formatter.getOfferDirectionForCreateOffer(direction, currencyCode), Layout.FIRST_ROW_DISTANCE);
fiatDirectionInfo = direction == Offer.Direction.SELL ? " to receive:" : " to spend:";
btcDirectionInfo = direction == Offer.Direction.BUY ? " to receive:" : " to spend:";
} else {
addLabelTextField(gridPane, rowIndex, "Offer type:", formatter.getDirectionBothSides(direction), Layout.FIRST_ROW_DISTANCE);
addLabelTextField(gridPane, rowIndex, "Offer type:", formatter.getDirectionBothSides(direction, currencyCode), Layout.FIRST_ROW_DISTANCE);
}
if (takeOfferHandlerOptional.isPresent()) {
addLabelTextField(gridPane, ++rowIndex, "Bitcoin amount" + btcDirectionInfo, formatter.formatCoinWithCode(tradeAmount));
addLabelTextField(gridPane, ++rowIndex, formatter.formatVolumeLabel(offer.getCurrencyCode()) + fiatDirectionInfo,
addLabelTextField(gridPane, ++rowIndex, formatter.formatVolumeLabel(currencyCode) + fiatDirectionInfo,
formatter.formatVolumeWithCode(offer.getVolumeByAmount(tradeAmount)));
} else {
addLabelTextField(gridPane, ++rowIndex, "Bitcoin amount" + btcDirectionInfo, formatter.formatCoinWithCode(offer.getAmount()));
@ -182,7 +183,7 @@ public class OfferDetailsWindow extends Overlay<OfferDetailsWindow> {
String minVolume = "";
if (!offer.getAmount().equals(offer.getMinAmount()))
minVolume = " (min. " + formatter.formatVolumeWithCode(offer.getMinOfferVolume()) + ")";
addLabelTextField(gridPane, ++rowIndex, formatter.formatVolumeLabel(offer.getCurrencyCode()) + fiatDirectionInfo, volume + minVolume);
addLabelTextField(gridPane, ++rowIndex, formatter.formatVolumeLabel(currencyCode) + fiatDirectionInfo, volume + minVolume);
}
if (takeOfferHandlerOptional.isPresent()) {

View File

@ -35,7 +35,7 @@ public class TacWindow extends Overlay<TacWindow> {
"4. The user confirms that he has read and agreed to the rules regarding the dispute process:\n" +
" - You must finalize trades within the maximum duration specified for each payment method.\n" +
" - You must enter the trade ID in the \"reason for payment\" text field when doing the fiat payment transfer.\n" +
" - If the bank of the fiat sender charges fees the sender (bitcoin buyer) has to cover the fees.\n" +
" - If the bank of the fiat sender charges fees the sender (BTC buyer) has to cover the fees.\n" +
" - You must cooperate with the arbitrator during the arbitration process.\n" +
" - You must reply within 48 hours to each arbitrator inquiry.\n" +
" - Failure to follow the above requirements may result in loss of your security deposit.\n\n" +

View File

@ -116,11 +116,11 @@ public class TradeDetailsWindow extends Overlay<TradeDetailsWindow> {
String fiatDirectionInfo;
String btcDirectionInfo;
if (tradeManager.isBuyer(offer)) {
addLabelTextField(gridPane, rowIndex, "Trade type:", formatter.getDirectionForBuyer(myOffer), Layout.FIRST_ROW_DISTANCE);
addLabelTextField(gridPane, rowIndex, "Trade type:", formatter.getDirectionForBuyer(myOffer, offer.getCurrencyCode()), Layout.FIRST_ROW_DISTANCE);
fiatDirectionInfo = " to spend:";
btcDirectionInfo = " to receive:";
} else {
addLabelTextField(gridPane, rowIndex, "Trade type:", formatter.getDirectionForSeller(myOffer), Layout.FIRST_ROW_DISTANCE);
addLabelTextField(gridPane, rowIndex, "Trade type:", formatter.getDirectionForSeller(myOffer, offer.getCurrencyCode()), Layout.FIRST_ROW_DISTANCE);
fiatDirectionInfo = " to receive:";
btcDirectionInfo = " to spend:";
}
@ -180,11 +180,11 @@ public class TradeDetailsWindow extends Overlay<TradeDetailsWindow> {
if (contract != null) {
if (buyerPaymentAccountContractData != null) {
TextFieldWithCopyIcon tf = addLabelTextFieldWithCopyIcon(gridPane, ++rowIndex, "Buyer payment details:", BSResources.get(buyerPaymentAccountContractData.getPaymentDetails())).second;
TextFieldWithCopyIcon tf = addLabelTextFieldWithCopyIcon(gridPane, ++rowIndex, "BTC buyer payment details:", BSResources.get(buyerPaymentAccountContractData.getPaymentDetails())).second;
tf.setTooltip(new Tooltip(tf.getText()));
}
if (sellerPaymentAccountContractData != null) {
TextFieldWithCopyIcon tf = addLabelTextFieldWithCopyIcon(gridPane, ++rowIndex, "Seller payment details:", BSResources.get(sellerPaymentAccountContractData.getPaymentDetails())).second;
TextFieldWithCopyIcon tf = addLabelTextFieldWithCopyIcon(gridPane, ++rowIndex, "BTC seller payment details:", BSResources.get(sellerPaymentAccountContractData.getPaymentDetails())).second;
tf.setTooltip(new Tooltip(tf.getText()));
}
if (buyerPaymentAccountContractData == null && sellerPaymentAccountContractData == null)

View File

@ -76,7 +76,7 @@ class ClosedTradesViewModel extends ActivatableWithDataModel<ClosedTradesDataMod
}
String getDirectionLabel(ClosedTradableListItem item) {
return (item != null) ? formatter.getDirection(dataModel.getDirection(item.getTradable().getOffer()), item.getTradable().getOffer().getCurrencyCode()) : "";
return (item != null) ? formatter.getDirectionWithCode(dataModel.getDirection(item.getTradable().getOffer()), item.getTradable().getOffer().getCurrencyCode()) : "";
}
String getDate(ClosedTradableListItem item) {

View File

@ -64,8 +64,20 @@ public class FailedTradesView extends ActivatableViewAndModel<VBox, FailedTrades
tradeIdColumn.setComparator((o1, o2) -> o1.getTrade().getId().compareTo(o2.getTrade().getId()));
dateColumn.setComparator((o1, o2) -> o1.getTrade().getDate().compareTo(o2.getTrade().getDate()));
priceColumn.setComparator((o1, o2) -> o1.getTrade().getTradePrice().compareTo(o2.getTrade().getTradePrice()));
volumeColumn.setComparator((o1, o2) -> o1.getTrade().getTradeVolume().compareTo(o2.getTrade().getTradeVolume()));
amountColumn.setComparator((o1, o2) -> o1.getTrade().getTradeAmount().compareTo(o2.getTrade().getTradeAmount()));
volumeColumn.setComparator((o1, o2) -> {
if (o1.getTrade().getTradeVolume() != null && o2.getTrade().getTradeVolume() != null)
return o1.getTrade().getTradeVolume().compareTo(o2.getTrade().getTradeVolume());
else
return 0;
});
amountColumn.setComparator((o1, o2) -> {
if (o1.getTrade().getTradeAmount() != null && o2.getTrade().getTradeAmount() != null)
return o1.getTrade().getTradeAmount().compareTo(o2.getTrade().getTradeAmount());
else
return 0;
});
stateColumn.setComparator((o1, o2) -> model.getState(o1).compareTo(model.getState(o2)));
marketColumn.setComparator((o1, o2) -> model.getMarketLabel(o1).compareTo(model.getMarketLabel(o2)));

View File

@ -62,7 +62,7 @@ class FailedTradesViewModel extends ActivatableWithDataModel<FailedTradesDataMod
}
String getDirectionLabel(FailedTradesListItem item) {
return (item != null) ? formatter.getDirection(dataModel.getDirection(item.getTrade().getOffer()), item.getTrade().getOffer().getCurrencyCode()) : "";
return (item != null) ? formatter.getDirectionWithCode(dataModel.getDirection(item.getTrade().getOffer()), item.getTrade().getOffer().getCurrencyCode()) : "";
}
String getMarketLabel(FailedTradesListItem item) {

View File

@ -34,7 +34,7 @@
<TableColumn text="Price" fx:id="priceColumn" minWidth="160"/>
<TableColumn text="Amount in BTC (Min.)" fx:id="amountColumn" minWidth="180" maxWidth="190"/>
<TableColumn text="Amount (Min.)" fx:id="volumeColumn" minWidth="200"/>
<TableColumn text="Trade type" fx:id="directionColumn" minWidth="100" maxWidth="100"/>
<TableColumn text="Trade type" fx:id="directionColumn" minWidth="100"/>
<TableColumn text="" fx:id="removeItemColumn" minWidth="120" maxWidth="120" sortable="false"/>
</columns>
</TableView>

View File

@ -83,7 +83,7 @@ class OpenOffersViewModel extends ActivatableWithDataModel<OpenOffersDataModel>
if ((item == null))
return "";
return formatter.getDirection(dataModel.getDirection(item.getOffer()), item.getOffer().getCurrencyCode());
return formatter.getDirectionWithCode(dataModel.getDirection(item.getOffer()), item.getOffer().getCurrencyCode());
}
String getMarketLabel(OpenOfferListItem item) {

View File

@ -28,15 +28,14 @@
<TableView fx:id="tableView" VBox.vgrow="SOMETIMES">
<columns>
<TableColumn text="Select" fx:id="selectColumn" minWidth="70" maxWidth="70" sortable="false"/>
<TableColumn text="Trade ID" fx:id="idColumn" minWidth="100"/>
<TableColumn text="Date/Time" fx:id="dateColumn" minWidth="130"/>
<TableColumn text="Market" fx:id="marketColumn" minWidth="90"/>
<TableColumn text="Price" fx:id="priceColumn" minWidth="100"/>
<TableColumn text="Amount in BTC" fx:id="tradeAmountColumn" minWidth="150"/>
<TableColumn text="Amount" fx:id="tradeVolumeColumn" minWidth="130"/>
<TableColumn text="Payment method" fx:id="paymentMethodColumn" minWidth="120"/>
<TableColumn text="My role" fx:id="roleColumn" minWidth="110" maxWidth="120"/>
<TableColumn text="Payment method" fx:id="paymentMethodColumn" minWidth="130"/>
<TableColumn text="My role" fx:id="roleColumn" minWidth="130"/>
<TableColumn text="" fx:id="avatarColumn" minWidth="40" maxWidth="40"/>
</columns>
</TableView>

View File

@ -55,7 +55,7 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
@FXML
TableView<PendingTradesListItem> tableView;
@FXML
TableColumn<PendingTradesListItem, PendingTradesListItem> selectColumn, priceColumn, tradeVolumeColumn, tradeAmountColumn, avatarColumn, marketColumn, roleColumn, paymentMethodColumn, idColumn, dateColumn;
TableColumn<PendingTradesListItem, PendingTradesListItem> priceColumn, tradeVolumeColumn, tradeAmountColumn, avatarColumn, marketColumn, roleColumn, paymentMethodColumn, idColumn, dateColumn;
@FXML
private SortedList<PendingTradesListItem> sortedList;
@ -81,7 +81,6 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
@Override
public void initialize() {
setSelectColumnCellFactory();
setTradeIdColumnCellFactory();
setDateColumnCellFactory();
setAmountColumnCellFactory();
@ -98,11 +97,26 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
idColumn.setComparator((o1, o2) -> o1.getTrade().getId().compareTo(o2.getTrade().getId()));
dateColumn.setComparator((o1, o2) -> o1.getTrade().getDate().compareTo(o2.getTrade().getDate()));
tradeVolumeColumn.setComparator((o1, o2) -> o1.getTrade().getTradeVolume().compareTo(o2.getTrade().getTradeVolume()));
tradeAmountColumn.setComparator((o1, o2) -> o1.getTrade().getTradeAmount().compareTo(o2.getTrade().getTradeAmount()));
tradeVolumeColumn.setComparator((o1, o2) -> {
if (o1.getTrade().getTradeVolume() != null && o2.getTrade().getTradeVolume() != null)
return o1.getTrade().getTradeVolume().compareTo(o2.getTrade().getTradeVolume());
else
return 0;
});
tradeAmountColumn.setComparator((o1, o2) -> {
if (o1.getTrade().getTradeAmount() != null && o2.getTrade().getTradeAmount() != null)
return o1.getTrade().getTradeAmount().compareTo(o2.getTrade().getTradeAmount());
else
return 0;
});
priceColumn.setComparator((o1, o2) -> o1.getPrice().compareTo(o2.getPrice()));
paymentMethodColumn.setComparator((o1, o2) -> o1.getTrade().getOffer().getPaymentMethod().getId().compareTo(o2.getTrade().getOffer().getPaymentMethod().getId()));
avatarColumn.setComparator((o1, o2) -> o1.getTrade().getTradingPeerNodeAddress().hostName.compareTo(o2.getTrade().getTradingPeerNodeAddress().hostName));
avatarColumn.setComparator((o1, o2) -> {
if (o1.getTrade().getTradingPeerNodeAddress() != null && o2.getTrade().getTradingPeerNodeAddress() != null)
return o1.getTrade().getTradingPeerNodeAddress().hostName.compareTo(o2.getTrade().getTradingPeerNodeAddress().hostName);
else
return 0;
});
roleColumn.setComparator((o1, o2) -> model.getMyRole(o1).compareTo(model.getMyRole(o2)));
marketColumn.setComparator((o1, o2) -> model.getMarketLabel(o1).compareTo(model.getMarketLabel(o2)));
@ -235,39 +249,6 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
// CellFactories
///////////////////////////////////////////////////////////////////////////////////////////
private void setSelectColumnCellFactory() {
selectColumn.setCellValueFactory((pendingTradesListItem) -> new ReadOnlyObjectWrapper<>(pendingTradesListItem.getValue()));
selectColumn.setCellFactory(
new Callback<TableColumn<PendingTradesListItem, PendingTradesListItem>, TableCell<PendingTradesListItem, PendingTradesListItem>>() {
@Override
public TableCell<PendingTradesListItem, PendingTradesListItem> call(TableColumn<PendingTradesListItem,
PendingTradesListItem> column) {
return new TableCell<PendingTradesListItem, PendingTradesListItem>() {
Button button;
@Override
public void updateItem(final PendingTradesListItem item, boolean empty) {
super.updateItem(item, empty);
if (item != null && !empty) {
if (button == null) {
button = new Button("Select");
button.setOnAction(e -> tableView.getSelectionModel().select(item));
setGraphic(button);
}
} else {
setGraphic(null);
if (button != null) {
button.setOnAction(null);
button = null;
}
}
}
};
}
});
}
private void setTradeIdColumnCellFactory() {
idColumn.setCellValueFactory((pendingTradesListItem) -> new ReadOnlyObjectWrapper<>(pendingTradesListItem.getValue()));
idColumn.setCellFactory(

View File

@ -212,10 +212,12 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
String getMyRole(PendingTradesListItem item) {
Trade trade = item.getTrade();
Contract contract = trade.getContract();
if (contract != null)
return formatter.getRole(contract.isBuyerOffererAndSellerTaker(), dataModel.isOfferer(trade.getOffer()));
else
if (contract != null) {
Offer offer = trade.getOffer();
return formatter.getRole(contract.isBuyerOffererAndSellerTaker(), dataModel.isOfferer(offer), offer.getCurrencyCode());
} else {
return "";
}
}
String getPaymentMethod(PendingTradesListItem item) {

View File

@ -73,7 +73,7 @@ public class BuyerStep2View extends TradeStepView {
"(You can wait for more confirmations if you want - 6 confirmations are considered as very secure.)\n\n" +
"Please transfer from your external " +
CurrencyUtil.getNameByCode(trade.getOffer().getCurrencyCode()) + " wallet\n" +
model.formatter.formatVolumeWithCode(trade.getTradeVolume()) + " to the bitcoin seller.\n\n" +
model.formatter.formatVolumeWithCode(trade.getTradeVolume()) + " to the BTC seller.\n\n" +
"Here are the payment account details of the bitcoin seller:\n" +
"" + paymentAccountContractData.getPaymentDetailsForTradePopup() + ".\n\n" +
"(You can copy & paste the values from the main screen after closing that popup.)";
@ -82,8 +82,8 @@ public class BuyerStep2View extends TradeStepView {
message = "Your trade has reached at least one blockchain confirmation.\n" +
"(You can wait for more confirmations if you want - 6 confirmations are considered as very secure.)\n\n" +
"Please go to a bank and pay " +
model.formatter.formatVolumeWithCode(trade.getTradeVolume()) + " to the bitcoin seller.\n\n" +
"Here are the payment account details of the bitcoin seller:\n" +
model.formatter.formatVolumeWithCode(trade.getTradeVolume()) + " to the BTC seller.\n\n" +
"Here are the payment account details of the BTC seller:\n" +
"" + paymentAccountContractData.getPaymentDetailsForTradePopup() + ".\n" +
"(You can copy & paste the values from the main screen after closing that popup.)\n\n" +
"Please don't forget to add the trade ID \"" + trade.getShortId() +
@ -92,13 +92,13 @@ public class BuyerStep2View extends TradeStepView {
"Bitcoin, Btc or Bitsquare.\n\n" +
"If your bank charges fees you have to cover those fees.\n\n" +
"After you have done the payment write on the paper receipt: NO REFUNDS.\n" +
"Then tear it in 2 parts, make a photo and send it to the seller's email address.";
"Then tear it in 2 parts, make a photo and send it to the BTC seller's email address.";
else
message = "Your trade has reached at least one blockchain confirmation.\n" +
"(You can wait for more confirmations if you want - 6 confirmations are considered as very secure.)\n\n" +
"Please go to your online banking web page and pay " +
model.formatter.formatVolumeWithCode(trade.getTradeVolume()) + " to the bitcoin seller.\n\n" +
"Here are the payment account details of the bitcoin seller:\n" +
model.formatter.formatVolumeWithCode(trade.getTradeVolume()) + " to the BTC seller.\n\n" +
"Here are the payment account details of the BTC seller:\n" +
"" + paymentAccountContractData.getPaymentDetailsForTradePopup() + ".\n" +
"(You can copy & paste the values from the main screen after closing that popup.)\n\n" +
"Please don't forget to add the trade ID \"" + trade.getShortId() +

View File

@ -37,12 +37,12 @@ public class BuyerStep3View extends TradeStepView {
@Override
protected String getInfoBlockTitle() {
return "Wait for seller's payment confirmation";
return "Wait for BTC seller's payment confirmation";
}
@Override
protected String getInfoText() {
return "Waiting for the bitcoin seller's confirmation " +
return "Waiting for the BTC seller's confirmation " +
"for the receipt of the " + model.dataModel.getCurrencyCode() + " payment.";
}
@ -57,9 +57,9 @@ public class BuyerStep3View extends TradeStepView {
String substitute = model.isBlockChainMethod() ?
"on the " + model.dataModel.getCurrencyCode() + "blockchain" :
"at your payment provider (e.g. bank)";
return "The seller still has not confirmed your payment!\n" +
return "The BTC seller still has not confirmed your payment!\n" +
"Please check " + substitute + " if the payment sending was successful.\n" +
"If the seller does not confirm the receipt of your payment until " +
"If the BTC seller does not confirm the receipt of your payment until " +
model.getDateForOpenDispute() +
" the trade will be investigated by the arbitrator.";
}
@ -71,7 +71,7 @@ public class BuyerStep3View extends TradeStepView {
@Override
protected String getOpenForDisputeText() {
return "The seller has not confirmed your payment!\n" +
return "The BTC seller has not confirmed your payment!\n" +
"The max. period for the trade has elapsed.\n" +
"Please contact the arbitrator for opening a dispute.";
}

View File

@ -43,7 +43,7 @@ public class SellerStep1View extends TradeStepView {
@Override
protected String getInfoText() {
return "Deposit transaction has been published.\n" +
"The bitcoin buyer needs to wait for at least one blockchain confirmation before " +
"The BTC buyer needs to wait for at least one blockchain confirmation before " +
"starting the payment.";
}

View File

@ -43,7 +43,7 @@ public class SellerStep2View extends TradeStepView {
@Override
protected String getInfoText() {
return "The deposit transaction has at least one blockchain confirmation.\n" +
"You need to wait until the bitcoin buyer starts the " + model.dataModel.getCurrencyCode() + " payment.";
"You need to wait until the BTC buyer starts the " + model.dataModel.getCurrencyCode() + " payment.";
}
@ -54,7 +54,7 @@ public class SellerStep2View extends TradeStepView {
@Override
protected String getWarningText() {
setInformationHeadline();
return "The buyer still has not done the " + model.dataModel.getCurrencyCode() + " payment.\n" +
return "The BTC buyer still has not done the " + model.dataModel.getCurrencyCode() + " payment.\n" +
"You need to wait until he starts the payment.\n" +
"If the trade has not been completed on " +
model.getDateForOpenDispute() +
@ -67,7 +67,7 @@ public class SellerStep2View extends TradeStepView {
@Override
protected String getOpenForDisputeText() {
return "The buyer has not started his payment!\n" +
return "The BTC buyer has not started his payment!\n" +
"The max. allowed period for the trade has elapsed.\n" +
"Please contact the arbitrator for opening a dispute.";
}

View File

@ -82,11 +82,11 @@ public class SellerStep3View extends TradeStepView {
} else {
message = "Your trading partner has confirmed that he initiated the " + currencyName + " payment.\n\n" +
"Please go to your online banking web page and check if you have received " +
tradeVolumeWithCode + " from the bitcoin buyer.\n\n" +
tradeVolumeWithCode + " from the BTC buyer.\n\n" +
"The trade ID (\"reason for payment\" text) of the transaction is: \"" + trade.getShortId() + "\"";
if (paymentAccountContractData instanceof CashDepositAccountContractData)
message += "\n\nBecause the payment is done via Cash Deposit the buyer has to write \"NO REFUND\" " +
message += "\n\nBecause the payment is done via Cash Deposit the BTC buyer has to write \"NO REFUND\" " +
"on the paper receipt, tear it in 2 parts and send you a photo by email.\n\n" +
"To avoid chargeback risk, only confirm if you received the email and if you are " +
"sure the paper receipt is valid.\n" +
@ -200,11 +200,11 @@ public class SellerStep3View extends TradeStepView {
@Override
protected String getInfoText() {
if (model.isBlockChainMethod()) {
return "The bitcoin buyer has started the " + model.dataModel.getCurrencyCode() + " payment.\n" +
return "The BTC buyer has started the " + model.dataModel.getCurrencyCode() + " payment.\n" +
"Check for blockchain confirmations at your altcoin wallet or block explorer and " +
"confirm the payment when you have sufficient blockchain confirmations.";
} else {
return "The bitcoin buyer has started the " + model.dataModel.getCurrencyCode() + " payment.\n" +
return "The BTC buyer has started the " + model.dataModel.getCurrencyCode() + " payment.\n" +
"Check at your payment account (e.g. bank account) and confirm when you have " +
"received the payment.";
}
@ -271,7 +271,7 @@ public class SellerStep3View extends TradeStepView {
}
}
message += "Please note, that as soon you have confirmed the receipt, the locked trade amount will be released " +
"to the bitcoin buyer and the security deposit will be refunded.";
"to the BTC buyer and the security deposit will be refunded.";
new Popup()
.headLine("Confirm that you have received the payment")
.confirmation(message)

View File

@ -355,7 +355,7 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Activatab
private void activateDisplayCurrencies() {
preferredTradeCurrencyComboBox.setItems(tradeCurrencies);
preferredTradeCurrencyComboBox.getSelectionModel().select(preferences.getPreferredTradeCurrency());
preferredTradeCurrencyComboBox.setVisibleRowCount(Math.min(preferredTradeCurrencyComboBox.getItems().size(), 25));
preferredTradeCurrencyComboBox.setVisibleRowCount(25);
preferredTradeCurrencyComboBox.setOnAction(e -> {
TradeCurrency selectedItem = preferredTradeCurrencyComboBox.getSelectionModel().getSelectedItem();
if (selectedItem != null)

View File

@ -334,13 +334,20 @@ public class BSFormatter {
return decimalFormat.format(MathUtils.roundDouble(value, precision)).replace(",", ".");
}
public String getDirection(Offer.Direction direction, String currencyCode) {
public String getDirectionWithCode(Offer.Direction direction, String currencyCode) {
if (CurrencyUtil.isFiatCurrency(currencyCode))
return (direction == Offer.Direction.BUY) ? "Buy BTC" : "Sell BTC";
else
return (direction == Offer.Direction.SELL) ? "Buy " + currencyCode : "Sell " + currencyCode;
}
public String getDirectionWithCodeDetailed(Offer.Direction direction, String currencyCode) {
if (CurrencyUtil.isFiatCurrency(currencyCode))
return (direction == Offer.Direction.BUY) ? "buying BTC for " + currencyCode : "selling BTC for " + currencyCode;
else
return (direction == Offer.Direction.SELL) ? "buying " + currencyCode + " (selling BTC)" : "selling " + currencyCode + " (buying BTC)";
}
public String formatAmount(Offer offer) {
return formatCoin(offer.getAmount());
}
@ -512,36 +519,64 @@ public class BSFormatter {
}
}
public String getDirectionBothSides(Offer.Direction direction) {
return direction == Offer.Direction.BUY ? "Offerer as bitcoin buyer / Taker as bitcoin seller" :
"Offerer as bitcoin seller / Taker as bitcoin buyer";
}
public String getDirectionForBuyer(boolean isMyOffer) {
return isMyOffer ? "You are buying bitcoin as offerer / Taker is selling bitcoin" :
"You are buying bitcoin as taker / Offerer is selling bitcoin";
}
public String getDirectionForSeller(boolean isMyOffer) {
return isMyOffer ? "You are selling bitcoin as offerer / Taker is buying bitcoin" :
"You are selling bitcoin as taker / Offerer is buying bitcoin";
}
public String getDirectionForTakeOffer(Offer.Direction direction) {
return direction == Offer.Direction.BUY ? "You are selling bitcoin (by taking an offer from someone who wants to buy bitcoin)" :
"You are buying bitcoin (by taking an offer from someone who wants to sell bitcoin)";
}
public String getOfferDirectionForCreateOffer(Offer.Direction direction) {
return direction == Offer.Direction.BUY ? "You are creating an offer for buying bitcoin" :
"You are creating an offer for selling bitcoin";
}
public String getRole(boolean isBuyerOffererAndSellerTaker, boolean isOfferer) {
if (isBuyerOffererAndSellerTaker)
return isOfferer ? "Buyer (offerer)" : "Seller (taker)";
public String getDirectionBothSides(Offer.Direction direction, String currencyCode) {
if (CurrencyUtil.isFiatCurrency(currencyCode))
return direction == Offer.Direction.BUY ? "Offerer as BTC buyer / Taker as BTC seller" :
"Offerer as BTC seller / Taker as BTC buyer";
else
return isOfferer ? "Seller (offerer)" : "Buyer (taker)";
return direction == Offer.Direction.SELL ? "Offerer as " + currencyCode + " buyer / Taker as " + currencyCode + " seller" :
"Offerer as " + currencyCode + " seller / Taker as " + currencyCode + " buyer";
}
public String getDirectionForBuyer(boolean isMyOffer, String currencyCode) {
if (CurrencyUtil.isFiatCurrency(currencyCode))
return isMyOffer ? "You are buying BTC as offerer / Taker is selling BTC" :
"You are buying BTC as taker / Offerer is selling BTC";
else
return isMyOffer ? "You are selling " + currencyCode + " as offerer / Taker is buying " + currencyCode + "" :
"You are selling " + currencyCode + " as taker / Offerer is buying " + currencyCode + "";
}
public String getDirectionForSeller(boolean isMyOffer, String currencyCode) {
if (CurrencyUtil.isFiatCurrency(currencyCode))
return isMyOffer ? "You are selling BTC as offerer / Taker is buying BTC" :
"You are selling BTC as taker / Offerer is buying BTC";
else
return isMyOffer ? "You are buying " + currencyCode + " as offerer / Taker is selling " + currencyCode + "" :
"You are buying " + currencyCode + " as taker / Offerer is selling " + currencyCode + "";
}
public String getDirectionForTakeOffer(Offer.Direction direction, String currencyCode) {
if (CurrencyUtil.isFiatCurrency(currencyCode))
return direction == Offer.Direction.BUY ? "You are selling BTC (buying " + currencyCode + ")" :
"You are buying BTC (selling " + currencyCode + ")";
else
return direction == Offer.Direction.SELL ? "You are selling " + currencyCode + " (buying BTC)" :
"You are buying " + currencyCode + " (selling BTC)";
}
public String getOfferDirectionForCreateOffer(Offer.Direction direction, String currencyCode) {
if (CurrencyUtil.isFiatCurrency(currencyCode))
return direction == Offer.Direction.BUY ? "You are creating an offer for buying BTC" :
"You are creating an offer for selling BTC";
else
return direction == Offer.Direction.SELL ? "You are creating an offer for buying " + currencyCode + " (selling BTC)" :
"You are creating an offer for selling " + currencyCode + " (buying BTC)";
}
public String getRole(boolean isBuyerOffererAndSellerTaker, boolean isOfferer, String currencyCode) {
if (CurrencyUtil.isFiatCurrency(currencyCode)) {
if (isBuyerOffererAndSellerTaker)
return isOfferer ? "BTC buyer as offerer" : "BTC seller as taker";
else
return isOfferer ? "BTC seller as offerer" : "BTC buyer as taker";
} else {
if (isBuyerOffererAndSellerTaker)
return isOfferer ? currencyCode + " seller as offerer" : currencyCode + " buyer as taker";
else
return isOfferer ? currencyCode + " buyer as offerer" : currencyCode + " seller as taker";
}
}
public String formatBytes(long bytes) {

View File

@ -28,5 +28,30 @@ public class CurrencyListItem {
this.numTrades = numTrades;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CurrencyListItem that = (CurrencyListItem) o;
if (numTrades != that.numTrades) return false;
return !(tradeCurrency != null ? !tradeCurrency.equals(that.tradeCurrency) : that.tradeCurrency != null);
}
@Override
public int hashCode() {
int result = tradeCurrency != null ? tradeCurrency.hashCode() : 0;
result = 31 * result + numTrades;
return result;
}
@Override
public String toString() {
return "CurrencyListItem{" +
"tradeCurrency=" + tradeCurrency +
", numTrades=" + numTrades +
'}';
}
}

View File

@ -44,6 +44,7 @@ import javafx.util.StringConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nullable;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
@ -232,7 +233,7 @@ public class GUIUtil {
};
}
public static void fillCurrencyListItems(List<TradeCurrency> tradeCurrencyList, ObservableList<CurrencyListItem> currencyListItems, Preferences preferences) {
public static void fillCurrencyListItems(List<TradeCurrency> tradeCurrencyList, ObservableList<CurrencyListItem> currencyListItems, @Nullable CurrencyListItem showAllCurrencyListItem, Preferences preferences) {
Set<TradeCurrency> tradeCurrencySet = new HashSet<>();
Map<String, Integer> tradesPerCurrencyMap = new HashMap<>();
tradeCurrencyList.stream().forEach(tradeCurrency -> {
@ -244,7 +245,7 @@ public class GUIUtil {
tradesPerCurrencyMap.put(code, 1);
});
List<CurrencyListItem> fiatList = tradeCurrencySet.stream()
List<CurrencyListItem> list = tradeCurrencySet.stream()
.filter(e -> CurrencyUtil.isFiatCurrency(e.getCode()))
.map(e -> new CurrencyListItem(e, tradesPerCurrencyMap.get(e.getCode())))
.collect(Collectors.toList());
@ -254,15 +255,19 @@ public class GUIUtil {
.collect(Collectors.toList());
if (preferences.getSortMarketCurrenciesNumerically()) {
fiatList.sort((o1, o2) -> new Integer(o2.numTrades).compareTo(o1.numTrades));
list.sort((o1, o2) -> new Integer(o2.numTrades).compareTo(o1.numTrades));
cryptoList.sort((o1, o2) -> new Integer(o2.numTrades).compareTo(o1.numTrades));
} else {
fiatList.sort((o1, o2) -> o1.tradeCurrency.compareTo(o2.tradeCurrency));
list.sort((o1, o2) -> o1.tradeCurrency.compareTo(o2.tradeCurrency));
cryptoList.sort((o1, o2) -> o1.tradeCurrency.compareTo(o2.tradeCurrency));
}
fiatList.addAll(cryptoList);
currencyListItems.setAll(fiatList);
list.addAll(cryptoList);
if (showAllCurrencyListItem != null)
list.add(0, showAllCurrencyListItem);
currencyListItems.setAll(list);
}
public static void openWebPage(String target) {

View File

@ -107,7 +107,7 @@ takeOffer.amountPriceBox.next=Next step
takeOffer.amountPriceBox.warning.invalidBtcDecimalPlaces=The amount you have entered exceeds the number of allowed decimal places.\nThe amount has been adjusted to 4 decimal places.
takeOffer.validation.amountSmallerThanMinAmount=Amount cannot be smaller than minimum amount defined in the offer.
takeOffer.validation.amountLargerThanOfferAmount=Input amount cannot be higher than the amount defined in the offer.
takeOffer.validation.amountLargerThanOfferAmountMinusFee=That input amount would create a dust change for the seller.
takeOffer.validation.amountLargerThanOfferAmountMinusFee=That input amount would create a dust change for the BTC seller.
takeOffer.fundsBox.title=Fund your trade
takeOffer.fundsBox.isOfferAvailable=Check if offer is available...
@ -117,7 +117,7 @@ takeOffer.fundsBox.address=Trade wallet address:
takeOffer.fundsBox.balance=Trade wallet balance:
takeOffer.fundsBox.buy.info=For every offer there is a dedicated trade wallet. You need to fund that trade wallet with the necessary bitcoin amount. Those \
funds will be paid in to a locked deposit address. At the end of a successful trade you will get back your security deposit and the bitcoin amount you sold will be transferred to the \
buyer.
BTC buyer.
takeOffer.fundsBox.sell.info=For every offer there is a dedicated trade wallet. You need to fund that trade wallet with the necessary bitcoin amount. Those \
funds will be paid in to a locked deposit address. At the end of a successful trade you will get back your security deposit.
takeOffer.fundsBox.tradeAmount=Amount to sell: