From fe33a80de52884c471e94eeaedf321c91a2e6044 Mon Sep 17 00:00:00 2001 From: Justin Carter Date: Wed, 11 Sep 2019 07:44:31 +0200 Subject: [PATCH 1/2] Extract DisplayUtils from BSFormatter All methods that are only used in the desktop project are removed from BSFormatter to DisplayUtils. This reduces the entanglement between the desktop and core project by reducing the surface area of the coupling. --- .../alerts/market/MarketAlerts.java | 2 +- .../main/java/bisq/core/offer/OfferUtil.java | 11 - .../main/java/bisq/core/util/BSFormatter.java | 249 +-------------- .../bisq/desktop/components/PeerInfoIcon.java | 5 +- .../paymentmethods/PaymentMethodForm.java | 3 +- .../java/bisq/desktop/main/Chat/Chat.java | 3 +- .../main/java/bisq/desktop/main/MainView.java | 5 +- .../java/bisq/desktop/main/MainViewModel.java | 5 +- .../main/dao/bonding/bonds/BondListItem.java | 5 +- .../reputation/MyReputationListItem.java | 5 +- .../dao/bonding/roles/RoleDetailsWindow.java | 4 +- .../proofofburn/MyProofOfBurnListItem.java | 5 +- .../proofofburn/ProofOfBurnListItem.java | 5 +- .../economy/dashboard/BsqDashboardView.java | 2 +- .../governance/proposals/ProposalsView.java | 3 +- .../dao/governance/result/VoteResultView.java | 4 +- .../desktop/main/dao/wallet/tx/BsqTxView.java | 8 +- .../arbitrator/ArbitratorDisputeView.java | 3 +- .../disputes/trader/TraderDisputeView.java | 9 +- .../desktop/main/funds/locked/LockedView.java | 3 +- .../main/funds/reserved/ReservedView.java | 3 +- .../transactions/TransactionsListItem.java | 3 +- .../bisq/desktop/main/market/MarketView.java | 11 +- .../offerbook/OfferBookChartViewModel.java | 5 +- .../main/market/trades/TradesChartsView.java | 19 +- .../market/trades/TradesChartsViewModel.java | 7 +- .../main/offer/MutableOfferDataModel.java | 4 +- .../main/offer/MutableOfferViewModel.java | 24 +- .../main/offer/offerbook/OfferBookView.java | 3 +- .../offer/offerbook/OfferBookViewModel.java | 7 +- .../offer/takeoffer/TakeOfferViewModel.java | 15 +- .../main/overlays/windows/ContractWindow.java | 13 +- .../windows/DisputeSummaryWindow.java | 15 +- .../overlays/windows/OfferDetailsWindow.java | 25 +- .../windows/ProposalResultsWindow.java | 4 +- .../overlays/windows/TradeDetailsWindow.java | 17 +- .../closedtrades/ClosedTradesView.java | 5 +- .../closedtrades/ClosedTradesViewModel.java | 11 +- .../editoffer/EditOfferViewModel.java | 4 +- .../failedtrades/FailedTradesViewModel.java | 9 +- .../openoffer/OpenOffersViewModel.java | 11 +- .../pendingtrades/PendingTradesView.java | 7 +- .../pendingtrades/PendingTradesViewModel.java | 5 +- .../steps/buyer/BuyerStep2View.java | 3 +- .../steps/seller/SellerStep3View.java | 3 +- .../settings/network/P2pNetworkListItem.java | 4 +- .../java/bisq/desktop/util/DisplayUtils.java | 291 ++++++++++++++++++ .../bisq/desktop/util/BSFormatterTest.java | 101 +----- .../bisq/desktop/util/DisplayUtilsTest.java | 132 ++++++++ 49 files changed, 610 insertions(+), 490 deletions(-) create mode 100644 desktop/src/main/java/bisq/desktop/util/DisplayUtils.java create mode 100644 desktop/src/test/java/bisq/desktop/util/DisplayUtilsTest.java diff --git a/core/src/main/java/bisq/core/notifications/alerts/market/MarketAlerts.java b/core/src/main/java/bisq/core/notifications/alerts/market/MarketAlerts.java index dd984789359..664ad169294 100644 --- a/core/src/main/java/bisq/core/notifications/alerts/market/MarketAlerts.java +++ b/core/src/main/java/bisq/core/notifications/alerts/market/MarketAlerts.java @@ -181,7 +181,7 @@ else if (!isFiatCurrency && !isSellOffer) String msg = Res.get("account.notifications.marketAlert.message.msg", direction, BSFormatter.getCurrencyPair(currencyCode), - formatter.formatPrice(offerPrice), + BSFormatter.formatPrice(offerPrice), BSFormatter.formatToPercentWithSymbol(ratio / 10000d), marketDir, Res.get(offer.getPaymentMethod().getId()), diff --git a/core/src/main/java/bisq/core/offer/OfferUtil.java b/core/src/main/java/bisq/core/offer/OfferUtil.java index 7d26b6cad39..96aca43bcef 100644 --- a/core/src/main/java/bisq/core/offer/OfferUtil.java +++ b/core/src/main/java/bisq/core/offer/OfferUtil.java @@ -306,17 +306,6 @@ public static Optional getFeeInUserFiatCurrency(Coin makerFee, boolean i } } - public static String getFeeWithFiatAmount(Coin makerFeeAsCoin, Optional optionalFeeInFiat, BSFormatter formatter) { - String fee = makerFeeAsCoin != null ? formatter.formatCoinWithCode(makerFeeAsCoin) : Res.get("shared.na"); - String feeInFiatAsString; - if (optionalFeeInFiat != null && optionalFeeInFiat.isPresent()) { - feeInFiatAsString = formatter.formatVolumeWithCode(optionalFeeInFiat.get()); - } else { - feeInFiatAsString = Res.get("shared.na"); - } - return Res.get("feeOptionWindow.fee", fee, feeInFiatAsString); - } - public static Map getExtraDataMap(AccountAgeWitnessService accountAgeWitnessService, ReferralIdService referralIdService, diff --git a/core/src/main/java/bisq/core/util/BSFormatter.java b/core/src/main/java/bisq/core/util/BSFormatter.java index 24a39b40e1d..866b09eb630 100644 --- a/core/src/main/java/bisq/core/util/BSFormatter.java +++ b/core/src/main/java/bisq/core/util/BSFormatter.java @@ -23,8 +23,6 @@ import bisq.core.locale.Res; import bisq.core.monetary.Altcoin; import bisq.core.monetary.Price; -import bisq.core.monetary.Volume; -import bisq.core.offer.Offer; import bisq.core.offer.OfferPayload; import bisq.network.p2p.NodeAddress; @@ -63,8 +61,6 @@ public class BSFormatter { public final static String RANGE_SEPARATOR = " - "; - protected final static int scale = 3; - // We don't support localized formatting. Format is always using "." as decimal mark and no grouping separator. // Input of "," as decimal mark (like in german locale) will be replaced with ".". // Input of a group separator (1,123,45) lead to an validation error. @@ -74,8 +70,7 @@ public class BSFormatter { // protected String currencyCode = CurrencyUtil.getDefaultFiatCurrencyAsCode(); - protected static final MonetaryFormat fiatPriceFormat = new MonetaryFormat().shift(0).minDecimals(4).repeatOptionalDecimals(0, 0); - protected static final MonetaryFormat fiatVolumeFormat = new MonetaryFormat().shift(0).minDecimals(2).repeatOptionalDecimals(0, 0); + public static final MonetaryFormat fiatPriceFormat = new MonetaryFormat().shift(0).minDecimals(4).repeatOptionalDecimals(0, 0); protected static final MonetaryFormat altcoinFormat = new MonetaryFormat().shift(0).minDecimals(8).repeatOptionalDecimals(0, 0); protected static final DecimalFormat decimalFormat = new DecimalFormat("#.#"); @@ -177,45 +172,12 @@ public Coin parseToCoin(String input, MonetaryFormat coinFormat) { } } - /** - * Converts to a coin with max. 4 decimal places. Last place gets rounded. - * 0.01234 -> 0.0123 - * 0.01235 -> 0.0124 - * - * @param input - * @return - */ - public Coin parseToCoinWith4Decimals(String input) { - try { - return Coin.valueOf(new BigDecimal(parseToCoin(cleanDoubleInput(input)).value).setScale(-scale - 1, - BigDecimal.ROUND_HALF_UP).setScale(scale + 1, BigDecimal.ROUND_HALF_UP).toBigInteger().longValue()); - } catch (Throwable t) { - if (input != null && input.length() > 0) - log.warn("Exception at parseToCoinWith4Decimals: " + t.toString()); - return Coin.ZERO; - } - } - - public boolean hasBtcValidDecimals(String input) { - return parseToCoin(input).equals(parseToCoinWith4Decimals(input)); - } - - /** - * Transform a coin with the properties defined in the format (used to reduce decimal places) - * - * @param coin The coin which should be transformed - * @return The transformed coin - */ - public Coin reduceTo4Decimals(Coin coin) { - return parseToCoin(formatCoin(coin)); - } - /////////////////////////////////////////////////////////////////////////////////////////// // FIAT /////////////////////////////////////////////////////////////////////////////////////////// - private static String formatFiat(Fiat fiat, MonetaryFormat format, boolean appendCurrencyCode) { + public static String formatFiat(Fiat fiat, MonetaryFormat format, boolean appendCurrencyCode) { if (fiat != null) { try { final String res = format.noCode().format(fiat).toString(); @@ -296,19 +258,6 @@ private static String formatAltcoin(Altcoin altcoin, boolean appendCurrencyCode) // Volume /////////////////////////////////////////////////////////////////////////////////////////// - public String formatVolume(Offer offer, Boolean decimalAligned, int maxNumberOfDigits) { - return formatVolume(offer, decimalAligned, maxNumberOfDigits, true); - } - - public String formatVolume(Offer offer, Boolean decimalAligned, int maxNumberOfDigits, boolean showRange) { - String formattedVolume = offer.isRange() && showRange ? formatVolume(offer.getMinVolume()) + RANGE_SEPARATOR + formatVolume(offer.getVolume()) : formatVolume(offer.getVolume()); - - if (decimalAligned) { - formattedVolume = fillUpPlacesWithEmptyStrings(formattedVolume, maxNumberOfDigits); - } - return formattedVolume; - } - @NotNull public static String fillUpPlacesWithEmptyStrings(String formattedNumber, int maxNumberOfDigits) { //FIXME: temporary deactivate adding spaces in front of numbers as we don't use a monospace font right now. @@ -319,27 +268,7 @@ public static String fillUpPlacesWithEmptyStrings(String formattedNumber, int ma return formattedNumber; } - public String formatVolume(Volume volume) { - return formatVolume(volume, fiatVolumeFormat, false); - } - - public String formatVolumeWithCode(Volume volume) { - return formatVolume(volume, fiatVolumeFormat, true); - } - - private static String formatVolume(Volume volume, MonetaryFormat fiatVolumeFormat, boolean appendCurrencyCode) { - if (volume != null) { - Monetary monetary = volume.getMonetary(); - if (monetary instanceof Fiat) - return formatFiat((Fiat) monetary, fiatVolumeFormat, appendCurrencyCode); - else - return formatAltcoinVolume((Altcoin) monetary, appendCurrencyCode); - } else { - return ""; - } - } - - private static String formatAltcoinVolume(Altcoin altcoin, boolean appendCurrencyCode) { + public static String formatAltcoinVolume(Altcoin altcoin, boolean appendCurrencyCode) { if (altcoin != null) { try { // TODO quick hack... @@ -361,40 +290,6 @@ private static String formatAltcoinVolume(Altcoin altcoin, boolean appendCurrenc } } - public static String formatVolumeLabel(String currencyCode) { - return formatVolumeLabel(currencyCode, ""); - } - - public static String formatVolumeLabel(String currencyCode, String postFix) { - return Res.get("formatter.formatVolumeLabel", - currencyCode, postFix); - } - - /////////////////////////////////////////////////////////////////////////////////////////// - // Amount - /////////////////////////////////////////////////////////////////////////////////////////// - - public String formatAmount(Offer offer) { - return formatAmount(offer, false); - } - - public String formatAmount(Offer offer, boolean decimalAligned) { - String formattedAmount = offer.isRange() ? formatCoin(offer.getMinAmount()) + RANGE_SEPARATOR + formatCoin(offer.getAmount()) : formatCoin(offer.getAmount()); - if (decimalAligned) { - formattedAmount = fillUpPlacesWithEmptyStrings(formattedAmount, 15); - } - return formattedAmount; - } - - public String formatAmount(Offer offer, int decimalPlaces, boolean decimalAligned, int maxPlaces) { - String formattedAmount = offer.isRange() ? formatCoin(offer.getMinAmount(), decimalPlaces) + RANGE_SEPARATOR + formatCoin(offer.getAmount(), decimalPlaces) : formatCoin(offer.getAmount(), decimalPlaces); - - if (decimalAligned) { - formattedAmount = fillUpPlacesWithEmptyStrings(formattedAmount, maxPlaces); - } - return formattedAmount; - } - /////////////////////////////////////////////////////////////////////////////////////////// // Price @@ -413,23 +308,14 @@ public static String formatPrice(Price price, MonetaryFormat fiatPriceFormat, bo } } - public String formatPrice(Price price, boolean appendCurrencyCode) { + public static String formatPrice(Price price, boolean appendCurrencyCode) { return formatPrice(price, fiatPriceFormat, true); } - public String formatPrice(Price price) { + public static String formatPrice(Price price) { return formatPrice(price, fiatPriceFormat, false); } - public String formatPrice(Price price, Boolean decimalAligned, int maxPlaces) { - String formattedPrice = formatPrice(price); - - if (decimalAligned) { - formattedPrice = fillUpPlacesWithEmptyStrings(formattedPrice, maxPlaces); - } - return formattedPrice; - } - /////////////////////////////////////////////////////////////////////////////////////////// // Market price /////////////////////////////////////////////////////////////////////////////////////////// @@ -456,13 +342,6 @@ public static String formatRoundedDoubleWithPrecision(double value, int precisio return decimalFormat.format(MathUtils.roundDouble(value, precision)).replace(",", "."); } - public static String getDirectionWithCode(OfferPayload.Direction direction, String currencyCode) { - if (CurrencyUtil.isFiatCurrency(currencyCode)) - return (direction == OfferPayload.Direction.BUY) ? Res.get("shared.buyCurrency", Res.getBaseCurrencyCode()) : Res.get("shared.sellCurrency", Res.getBaseCurrencyCode()); - else - return (direction == OfferPayload.Direction.SELL) ? Res.get("shared.buyCurrency", currencyCode) : Res.get("shared.sellCurrency", currencyCode); - } - public static String getDirectionWithCodeDetailed(OfferPayload.Direction direction, String currencyCode) { if (CurrencyUtil.isFiatCurrency(currencyCode)) return (direction == OfferPayload.Direction.BUY) ? Res.get("shared.buyingBTCWith", currencyCode) : Res.get("shared.sellingBTCFor", currencyCode); @@ -474,12 +353,8 @@ public static String arbitratorAddressesToString(List nodeAddresses return nodeAddresses.stream().map(NodeAddress::getFullAddress).collect(Collectors.joining(", ")); } - public static String formatDateTime(Date date) { - return formatDateTime(date, true); - } - public static String formatDateTime(Date date, boolean useLocaleAndLocalTimezone) { - Locale locale = useLocaleAndLocalTimezone ? getLocale() : Locale.US; + Locale locale = useLocaleAndLocalTimezone ? GlobalSettings.getLocale() : Locale.US; DateFormat dateInstance = DateFormat.getDateInstance(DateFormat.DEFAULT, locale); DateFormat timeInstance = DateFormat.getTimeInstance(DateFormat.DEFAULT, locale); if (!useLocaleAndLocalTimezone) { @@ -497,34 +372,6 @@ public static String formatDateTime(Date date, DateFormat dateFormatter, DateFor } } - public static String formatDateTimeSpan(Date dateFrom, Date dateTo) { - if (dateFrom != null && dateTo != null) { - DateFormat dateFormatter = DateFormat.getDateInstance(DateFormat.DEFAULT, getLocale()); - DateFormat timeFormatter = DateFormat.getTimeInstance(DateFormat.DEFAULT, getLocale()); - return dateFormatter.format(dateFrom) + " " + timeFormatter.format(dateFrom) + RANGE_SEPARATOR + timeFormatter.format(dateTo); - } else { - return ""; - } - } - - public static String formatTime(Date date) { - if (date != null) { - DateFormat timeFormatter = DateFormat.getTimeInstance(DateFormat.DEFAULT, getLocale()); - return timeFormatter.format(date); - } else { - return ""; - } - } - - public static String formatDate(Date date) { - if (date != null) { - DateFormat dateFormatter = DateFormat.getDateInstance(DateFormat.DEFAULT, getLocale()); - return dateFormatter.format(date); - } else { - return ""; - } - } - public static String formatToPercentWithSymbol(double value) { return formatToPercent(value) + "%"; } @@ -579,7 +426,7 @@ public static String convertCharsForNumber(String input) { return input.replace(",", "."); } - protected static String cleanDoubleInput(String input) { + public static String cleanDoubleInput(String input) { input = convertCharsForNumber(input); if (input.equals(".")) input = input.replace(".", "0."); @@ -594,14 +441,6 @@ protected static String cleanDoubleInput(String input) { return input; } - public static String formatAccountAge(long durationMillis) { - durationMillis = Math.max(0, durationMillis); - String day = Res.get("time.day").toLowerCase(); - String days = Res.get("time.days"); - String format = "d\' " + days + "\'"; - return StringUtils.replaceOnce(DurationFormatUtils.formatDuration(durationMillis, format), "1 " + days, "1 " + day); - } - public static String formatDurationAsWords(long durationMillis) { return formatDurationAsWords(durationMillis, false, true); } @@ -646,76 +485,6 @@ public static String formatDurationAsWords(long durationMillis, boolean showSeco return duration.trim(); } - public static String booleanToYesNo(boolean value) { - return value ? Res.get("shared.yes") : Res.get("shared.no"); - } - - public static String getDirectionBothSides(OfferPayload.Direction direction, String currencyCode) { - if (CurrencyUtil.isFiatCurrency(currencyCode)) { - currencyCode = Res.getBaseCurrencyCode(); - return direction == OfferPayload.Direction.BUY ? - Res.get("formatter.makerTaker", currencyCode, Res.get("shared.buyer"), currencyCode, Res.get("shared.seller")) : - Res.get("formatter.makerTaker", currencyCode, Res.get("shared.seller"), currencyCode, Res.get("shared.buyer")); - } else { - return direction == OfferPayload.Direction.SELL ? - Res.get("formatter.makerTaker", currencyCode, Res.get("shared.buyer"), currencyCode, Res.get("shared.seller")) : - Res.get("formatter.makerTaker", currencyCode, Res.get("shared.seller"), currencyCode, Res.get("shared.buyer")); - } - } - - public static String getDirectionForBuyer(boolean isMyOffer, String currencyCode) { - if (CurrencyUtil.isFiatCurrency(currencyCode)) { - String code = Res.getBaseCurrencyCode(); - return isMyOffer ? - Res.get("formatter.youAreAsMaker", Res.get("shared.buying"), code, Res.get("shared.selling"), code) : - Res.get("formatter.youAreAsTaker", Res.get("shared.buying"), code, Res.get("shared.selling"), code); - } else { - return isMyOffer ? - Res.get("formatter.youAreAsMaker", Res.get("shared.selling"), currencyCode, Res.get("shared.buying"), currencyCode) : - Res.get("formatter.youAreAsTaker", Res.get("shared.selling"), currencyCode, Res.get("shared.buying"), currencyCode); - } - } - - public static String getDirectionForSeller(boolean isMyOffer, String currencyCode) { - if (CurrencyUtil.isFiatCurrency(currencyCode)) { - String code = Res.getBaseCurrencyCode(); - return isMyOffer ? - Res.get("formatter.youAreAsMaker", Res.get("shared.selling"), code, Res.get("shared.buying"), code) : - Res.get("formatter.youAreAsTaker", Res.get("shared.selling"), code, Res.get("shared.buying"), code); - } else { - return isMyOffer ? - Res.get("formatter.youAreAsMaker", Res.get("shared.buying"), currencyCode, Res.get("shared.selling"), currencyCode) : - Res.get("formatter.youAreAsTaker", Res.get("shared.buying"), currencyCode, Res.get("shared.selling"), currencyCode); - } - } - - public static String getDirectionForTakeOffer(OfferPayload.Direction direction, String currencyCode) { - String baseCurrencyCode = Res.getBaseCurrencyCode(); - if (CurrencyUtil.isFiatCurrency(currencyCode)) { - return direction == OfferPayload.Direction.BUY ? - Res.get("formatter.youAre", Res.get("shared.selling"), baseCurrencyCode, Res.get("shared.buying"), currencyCode) : - Res.get("formatter.youAre", Res.get("shared.buying"), baseCurrencyCode, Res.get("shared.selling"), currencyCode); - } else { - - return direction == OfferPayload.Direction.SELL ? - Res.get("formatter.youAre", Res.get("shared.selling"), currencyCode, Res.get("shared.buying"), baseCurrencyCode) : - Res.get("formatter.youAre", Res.get("shared.buying"), currencyCode, Res.get("shared.selling"), baseCurrencyCode); - } - } - - public static String getOfferDirectionForCreateOffer(OfferPayload.Direction direction, String currencyCode) { - String baseCurrencyCode = Res.getBaseCurrencyCode(); - if (CurrencyUtil.isFiatCurrency(currencyCode)) { - return direction == OfferPayload.Direction.BUY ? - Res.get("formatter.youAreCreatingAnOffer.fiat", Res.get("shared.buy"), baseCurrencyCode) : - Res.get("formatter.youAreCreatingAnOffer.fiat", Res.get("shared.sell"), baseCurrencyCode); - } else { - return direction == OfferPayload.Direction.SELL ? - Res.get("formatter.youAreCreatingAnOffer.altcoin", Res.get("shared.buy"), currencyCode, Res.get("shared.selling"), baseCurrencyCode) : - Res.get("formatter.youAreCreatingAnOffer.altcoin", Res.get("shared.sell"), currencyCode, Res.get("shared.buying"), baseCurrencyCode); - } - } - public static String getRole(boolean isBuyerMakerAndSellerTaker, boolean isMaker, String currencyCode) { if (CurrencyUtil.isFiatCurrency(currencyCode)) { String baseCurrencyCode = Res.getBaseCurrencyCode(); @@ -776,8 +545,4 @@ public static String getPriceWithCurrencyCode(String currencyCode, String transl else return Res.get(translationKey, currencyCode, Res.getBaseCurrencyCode()); } - - private static Locale getLocale() { - return GlobalSettings.getLocale(); - } } diff --git a/desktop/src/main/java/bisq/desktop/components/PeerInfoIcon.java b/desktop/src/main/java/bisq/desktop/components/PeerInfoIcon.java index 327a14e5d81..54d3725e618 100644 --- a/desktop/src/main/java/bisq/desktop/components/PeerInfoIcon.java +++ b/desktop/src/main/java/bisq/desktop/components/PeerInfoIcon.java @@ -18,6 +18,7 @@ package bisq.desktop.components; import bisq.desktop.main.overlays.editor.PeerInfoWithTagEditor; +import bisq.desktop.util.DisplayUtils; import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.alert.PrivateNotificationManager; @@ -141,7 +142,7 @@ private PeerInfoIcon(NodeAddress nodeAddress, boolean isFiatCurrency = CurrencyUtil.isFiatCurrency(offer.getCurrencyCode()); String accountAge = isFiatCurrency ? - peersAccountAge > -1 ? Res.get("peerInfoIcon.tooltip.age", BSFormatter.formatAccountAge(peersAccountAge)) : + peersAccountAge > -1 ? Res.get("peerInfoIcon.tooltip.age", DisplayUtils.formatAccountAge(peersAccountAge)) : Res.get("peerInfoIcon.tooltip.unknownAge") : ""; tooltipText = hasTraded ? @@ -268,7 +269,7 @@ protected void addMouseListener(int numTrades, long makersAccountAge) { final String accountAgeTagEditor = isFiatCurrency ? makersAccountAge > -1 ? - BSFormatter.formatAccountAge(makersAccountAge) : + DisplayUtils.formatAccountAge(makersAccountAge) : Res.get("peerInfo.unknownAge") : null; setOnMouseClicked(e -> new PeerInfoWithTagEditor(privateNotificationManager, offer, preferences, useDevPrivilegeKeys) diff --git a/desktop/src/main/java/bisq/desktop/components/paymentmethods/PaymentMethodForm.java b/desktop/src/main/java/bisq/desktop/components/paymentmethods/PaymentMethodForm.java index 5ee83479218..3830ed53378 100644 --- a/desktop/src/main/java/bisq/desktop/components/paymentmethods/PaymentMethodForm.java +++ b/desktop/src/main/java/bisq/desktop/components/paymentmethods/PaymentMethodForm.java @@ -21,6 +21,7 @@ import bisq.desktop.components.InfoTextField; import bisq.desktop.components.InputTextField; import bisq.desktop.main.overlays.popups.Popup; +import bisq.desktop.util.DisplayUtils; import bisq.desktop.util.FormBuilder; import bisq.desktop.util.Layout; @@ -182,7 +183,7 @@ else if (!paymentAccount.getTradeCurrencies().isEmpty()) Res.get("payment.maxPeriodAndLimit", getTimeText(hours), formatter.formatCoinWithCode(Coin.valueOf(accountAgeWitnessService.getMyTradeLimit(paymentAccount, tradeCurrency.getCode()))), - BSFormatter.formatAccountAge(accountAge)); + DisplayUtils.formatAccountAge(accountAge)); if (isDisplayForm) addCompactTopLabelTextField(gridPane, ++gridRow, Res.get("payment.limitations"), limitationsText); diff --git a/desktop/src/main/java/bisq/desktop/main/Chat/Chat.java b/desktop/src/main/java/bisq/desktop/main/Chat/Chat.java index b27e7f7dd7c..7ebdbe5983f 100644 --- a/desktop/src/main/java/bisq/desktop/main/Chat/Chat.java +++ b/desktop/src/main/java/bisq/desktop/main/Chat/Chat.java @@ -24,6 +24,7 @@ import bisq.desktop.components.TableGroupHeadline; import bisq.desktop.components.TextFieldWithIcon; import bisq.desktop.main.overlays.popups.Popup; +import bisq.desktop.util.DisplayUtils; import bisq.desktop.util.GUIUtil; import bisq.core.arbitration.Attachment; @@ -404,7 +405,7 @@ public void updateItem(final DisputeCommunicationMessage message, boolean empty) AnchorPane.setLeftAnchor(statusHBox, padding); } AnchorPane.setBottomAnchor(statusHBox, 7d); - headerLabel.setText(BSFormatter.formatDateTime(new Date(message.getDate()))); + headerLabel.setText(DisplayUtils.formatDateTime(new Date(message.getDate()))); messageLabel.setText(message.getMessage()); attachmentsBox.getChildren().clear(); if (allowAttachments && diff --git a/desktop/src/main/java/bisq/desktop/main/MainView.java b/desktop/src/main/java/bisq/desktop/main/MainView.java index d578150e99b..c01df5b11f8 100644 --- a/desktop/src/main/java/bisq/desktop/main/MainView.java +++ b/desktop/src/main/java/bisq/desktop/main/MainView.java @@ -37,6 +37,7 @@ import bisq.desktop.main.overlays.popups.Popup; import bisq.desktop.main.portfolio.PortfolioView; import bisq.desktop.main.settings.SettingsView; +import bisq.desktop.util.DisplayUtils; import bisq.desktop.util.Transitions; import bisq.core.dao.monitoring.DaoStateMonitoringService; @@ -522,14 +523,14 @@ private String getPriceProviderTooltipString() { res = Res.get("mainView.marketPrice.tooltip", "https://bitcoinaverage.com", "", - formatter.formatTime(model.getPriceFeedService().getLastRequestTimeStampBtcAverage()), + DisplayUtils.formatTime(model.getPriceFeedService().getLastRequestTimeStampBtcAverage()), model.getPriceFeedService().getProviderNodeAddress()); } else { String altcoinExtra = "\n" + Res.get("mainView.marketPrice.tooltip.altcoinExtra"); res = Res.get("mainView.marketPrice.tooltip", "https://poloniex.com", altcoinExtra, - formatter.formatTime(model.getPriceFeedService().getLastRequestTimeStampPoloniex()), + DisplayUtils.formatTime(model.getPriceFeedService().getLastRequestTimeStampPoloniex()), model.getPriceFeedService().getProviderNodeAddress()); } return res; diff --git a/desktop/src/main/java/bisq/desktop/main/MainViewModel.java b/desktop/src/main/java/bisq/desktop/main/MainViewModel.java index 00f7b1e6274..8fb0bf46eab 100644 --- a/desktop/src/main/java/bisq/desktop/main/MainViewModel.java +++ b/desktop/src/main/java/bisq/desktop/main/MainViewModel.java @@ -32,6 +32,7 @@ import bisq.desktop.main.overlays.windows.downloadupdate.DisplayUpdateDownloadWindow; import bisq.desktop.main.presentation.DaoPresentation; import bisq.desktop.main.presentation.MarketPricePresentation; +import bisq.desktop.util.DisplayUtils; import bisq.desktop.util.GUIUtil; import bisq.core.account.witness.AccountAgeWitnessService; @@ -218,7 +219,7 @@ public void onSetupComplete() { DontShowAgainLookup.dontShowAgain(key, true); new Popup<>().warning(Res.get("popup.warning.tradePeriod.halfReached", trade.getShortId(), - BSFormatter.formatDateTime(maxTradePeriodDate))) + DisplayUtils.formatDateTime(maxTradePeriodDate))) .show(); } break; @@ -228,7 +229,7 @@ public void onSetupComplete() { DontShowAgainLookup.dontShowAgain(key, true); new Popup<>().warning(Res.get("popup.warning.tradePeriod.ended", trade.getShortId(), - BSFormatter.formatDateTime(maxTradePeriodDate))) + DisplayUtils.formatDateTime(maxTradePeriodDate))) .show(); } break; diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondListItem.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondListItem.java index 12116585d93..edcbfb46827 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondListItem.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondListItem.java @@ -17,11 +17,12 @@ package bisq.desktop.main.dao.bonding.bonds; +import bisq.desktop.util.DisplayUtils; + import bisq.core.dao.governance.bond.Bond; import bisq.core.dao.governance.bond.BondState; import bisq.core.dao.governance.bond.role.BondedRole; import bisq.core.locale.Res; -import bisq.core.util.BSFormatter; import bisq.core.util.BsqFormatter; import bisq.common.util.Utilities; @@ -59,7 +60,7 @@ class BondListItem { bondDetails = Utilities.bytesAsHexString(bond.getBondedAsset().getHash()); } lockupTxId = bond.getLockupTxId(); - lockupDateString = bond.getLockupDate() > 0 ? BSFormatter.formatDateTime(new Date(bond.getLockupDate())) : "-"; + lockupDateString = bond.getLockupDate() > 0 ? DisplayUtils.formatDateTime(new Date(bond.getLockupDate())) : "-"; bondState = bond.getBondState(); bondStateString = Res.get("dao.bond.bondState." + bond.getBondState().name()); } diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyReputationListItem.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyReputationListItem.java index b143de62455..fe5536794a6 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyReputationListItem.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyReputationListItem.java @@ -17,11 +17,12 @@ package bisq.desktop.main.dao.bonding.reputation; +import bisq.desktop.util.DisplayUtils; + import bisq.core.dao.governance.bond.BondState; import bisq.core.dao.governance.bond.reputation.MyBondedReputation; import bisq.core.dao.governance.bond.reputation.MyReputation; import bisq.core.locale.Res; -import bisq.core.util.BSFormatter; import bisq.core.util.BsqFormatter; import bisq.common.util.Utilities; @@ -58,7 +59,7 @@ class MyReputationListItem { txId = myBondedReputation.getLockupTxId(); amount = bsqFormatter.formatCoin(Coin.valueOf(myBondedReputation.getAmount())); lockupDate = new Date(myBondedReputation.getLockupDate()); - lockupDateString = BSFormatter.formatDateTime(lockupDate); + lockupDateString = DisplayUtils.formatDateTime(lockupDate); lockTime = Integer.toString(myBondedReputation.getLockTime()); lockupTxId = myBondedReputation.getLockupTxId(); bondState = myBondedReputation.getBondState(); diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/RoleDetailsWindow.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/RoleDetailsWindow.java index c5e97bb9c93..89b50b977a1 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/RoleDetailsWindow.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/RoleDetailsWindow.java @@ -18,13 +18,13 @@ package bisq.desktop.main.dao.bonding.roles; import bisq.desktop.main.overlays.Overlay; +import bisq.desktop.util.DisplayUtils; import bisq.desktop.util.FormBuilder; import bisq.core.dao.DaoFacade; import bisq.core.dao.state.model.governance.BondedRoleType; import bisq.core.dao.state.model.governance.RoleProposal; import bisq.core.locale.Res; -import bisq.core.util.BSFormatter; import bisq.core.util.BsqFormatter; import org.bitcoinj.core.Coin; @@ -98,6 +98,6 @@ private void addContent() { bondedRoleType.getLink(), bondedRoleType.getLink(), 0); FormBuilder.addTopLabelTextField(gridPane, ++rowIndex, Res.get("dao.bond.details.isSingleton"), - BSFormatter.booleanToYesNo(bondedRoleType.isAllowMultipleHolders())); + DisplayUtils.booleanToYesNo(bondedRoleType.isAllowMultipleHolders())); } } diff --git a/desktop/src/main/java/bisq/desktop/main/dao/burnbsq/proofofburn/MyProofOfBurnListItem.java b/desktop/src/main/java/bisq/desktop/main/dao/burnbsq/proofofburn/MyProofOfBurnListItem.java index f8ed06ecdf4..fe2e11e1bd2 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/burnbsq/proofofburn/MyProofOfBurnListItem.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/burnbsq/proofofburn/MyProofOfBurnListItem.java @@ -17,11 +17,12 @@ package bisq.desktop.main.dao.burnbsq.proofofburn; +import bisq.desktop.util.DisplayUtils; + import bisq.core.dao.governance.proofofburn.MyProofOfBurn; import bisq.core.dao.governance.proofofburn.ProofOfBurnService; import bisq.core.dao.state.model.blockchain.Tx; import bisq.core.locale.Res; -import bisq.core.util.BSFormatter; import bisq.core.util.BsqFormatter; import bisq.common.util.Utilities; @@ -53,7 +54,7 @@ class MyProofOfBurnListItem { if (optionalTx.isPresent()) { Tx tx = optionalTx.get(); date = new Date(tx.getTime()); - dateAsString = BSFormatter.formatDateTime(date); + dateAsString = DisplayUtils.formatDateTime(date); amount = proofOfBurnService.getAmount(tx); amountAsString = bsqFormatter.formatCoinWithCode(Coin.valueOf(amount)); txId = tx.getId(); diff --git a/desktop/src/main/java/bisq/desktop/main/dao/burnbsq/proofofburn/ProofOfBurnListItem.java b/desktop/src/main/java/bisq/desktop/main/dao/burnbsq/proofofburn/ProofOfBurnListItem.java index 4c595c50430..912ff42c7df 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/burnbsq/proofofburn/ProofOfBurnListItem.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/burnbsq/proofofburn/ProofOfBurnListItem.java @@ -17,9 +17,10 @@ package bisq.desktop.main.dao.burnbsq.proofofburn; +import bisq.desktop.util.DisplayUtils; + import bisq.core.dao.governance.proofofburn.ProofOfBurnService; import bisq.core.dao.state.model.blockchain.Tx; -import bisq.core.util.BSFormatter; import bisq.core.util.BsqFormatter; import bisq.common.util.Utilities; @@ -47,6 +48,6 @@ class ProofOfBurnListItem { hashAsHex = Utilities.bytesAsHexString(proofOfBurnService.getHashFromOpReturnData(tx)); pubKey = Utilities.bytesAsHexString(proofOfBurnService.getPubKey(txId)); date = new Date(tx.getTime()); - dateAsString = BSFormatter.formatDateTime(date); + dateAsString = DisplayUtils.formatDateTime(date); } } diff --git a/desktop/src/main/java/bisq/desktop/main/dao/economy/dashboard/BsqDashboardView.java b/desktop/src/main/java/bisq/desktop/main/dao/economy/dashboard/BsqDashboardView.java index 0de2e7e6252..01701758d8b 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/economy/dashboard/BsqDashboardView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/economy/dashboard/BsqDashboardView.java @@ -308,7 +308,7 @@ private void updatePrice() { Optional optionalBsqPrice = priceFeedService.getBsqPrice(); if (optionalBsqPrice.isPresent()) { Price bsqPrice = optionalBsqPrice.get(); - marketPriceLabel.setText(bsqFormatter.formatPrice(bsqPrice) + " BSQ/BTC"); + marketPriceLabel.setText(BSFormatter.formatPrice(bsqPrice) + " BSQ/BTC"); marketCapTextField.setText(bsqFormatter.formatMarketCap(priceFeedService.getMarketPrice("BSQ"), priceFeedService.getMarketPrice(preferences.getPreferredTradeCurrency().getCode()), diff --git a/desktop/src/main/java/bisq/desktop/main/dao/governance/proposals/ProposalsView.java b/desktop/src/main/java/bisq/desktop/main/dao/governance/proposals/ProposalsView.java index 0f55a554460..d5d28609e59 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/governance/proposals/ProposalsView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/governance/proposals/ProposalsView.java @@ -30,6 +30,7 @@ import bisq.desktop.main.dao.governance.PhasesView; import bisq.desktop.main.overlays.popups.Popup; import bisq.desktop.main.overlays.windows.SelectProposalWindow; +import bisq.desktop.util.DisplayUtils; import bisq.desktop.util.GUIUtil; import bisq.desktop.util.Layout; import bisq.desktop.util.validation.BsqValidator; @@ -718,7 +719,7 @@ public TableCell call( public void updateItem(final ProposalsListItem item, boolean empty) { super.updateItem(item, empty); if (item != null) - setText(BSFormatter.formatDateTime(item.getProposal().getCreationDateAsDate())); + setText(DisplayUtils.formatDateTime(item.getProposal().getCreationDateAsDate())); else setText(""); } diff --git a/desktop/src/main/java/bisq/desktop/main/dao/governance/result/VoteResultView.java b/desktop/src/main/java/bisq/desktop/main/dao/governance/result/VoteResultView.java index 5ee98a0b8f0..ee3f1ad6ad5 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/governance/result/VoteResultView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/governance/result/VoteResultView.java @@ -26,6 +26,7 @@ import bisq.desktop.main.dao.governance.PhasesView; import bisq.desktop.main.overlays.popups.Popup; import bisq.desktop.main.overlays.windows.ProposalResultsWindow; +import bisq.desktop.util.DisplayUtils; import bisq.desktop.util.FormBuilder; import bisq.desktop.util.GUIUtil; import bisq.desktop.util.Layout; @@ -57,7 +58,6 @@ import bisq.core.dao.state.model.governance.RoleProposal; import bisq.core.dao.state.model.governance.Vote; import bisq.core.locale.Res; -import bisq.core.util.BSFormatter; import bisq.core.util.BsqFormatter; import bisq.common.UserThread; @@ -638,7 +638,7 @@ public TableCell call( public void updateItem(final ProposalListItem item, boolean empty) { super.updateItem(item, empty); if (item != null) - setText(BSFormatter.formatDateTime(item.getProposal().getCreationDateAsDate())); + setText(DisplayUtils.formatDateTime(item.getProposal().getCreationDateAsDate())); else setText(""); } diff --git a/desktop/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java b/desktop/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java index f1fe1ca7f50..75583d3b05f 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java @@ -24,6 +24,7 @@ import bisq.desktop.components.AutoTooltipTableColumn; import bisq.desktop.components.HyperlinkWithIcon; import bisq.desktop.main.dao.wallet.BsqBalanceUtil; +import bisq.desktop.util.DisplayUtils; import bisq.desktop.util.FormBuilder; import bisq.desktop.util.GUIUtil; @@ -38,7 +39,6 @@ import bisq.core.dao.state.model.governance.IssuanceType; import bisq.core.locale.Res; import bisq.core.user.Preferences; -import bisq.core.util.BSFormatter; import bisq.core.util.BsqFormatter; import bisq.common.Timer; @@ -368,7 +368,7 @@ public void updateItem(final BsqTxListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { - setText(BSFormatter.formatDateTime(item.getDate())); + setText(DisplayUtils.formatDateTime(item.getDate())); } else { setText(""); } @@ -631,7 +631,7 @@ public void updateItem(final BsqTxListItem item, boolean empty) { style = "dao-tx-type-issuance-icon"; int issuanceBlockHeight = daoFacade.getIssuanceBlockHeight(txId); long blockTime = daoFacade.getBlockTime(issuanceBlockHeight); - String formattedDate = BSFormatter.formatDateTime(new Date(blockTime)); + String formattedDate = DisplayUtils.formatDateTime(new Date(blockTime)); toolTipText = Res.get("dao.tx.issuanceFromCompReq.tooltip", formattedDate); } else { awesomeIcon = AwesomeIcon.FILE_TEXT; @@ -645,7 +645,7 @@ public void updateItem(final BsqTxListItem item, boolean empty) { style = "dao-tx-type-issuance-icon"; int issuanceBlockHeight = daoFacade.getIssuanceBlockHeight(txId); long blockTime = daoFacade.getBlockTime(issuanceBlockHeight); - String formattedDate = BSFormatter.formatDateTime(new Date(blockTime)); + String formattedDate = DisplayUtils.formatDateTime(new Date(blockTime)); toolTipText = Res.get("dao.tx.issuanceFromReimbursement.tooltip", formattedDate); } else { awesomeIcon = AwesomeIcon.FILE_TEXT; diff --git a/desktop/src/main/java/bisq/desktop/main/disputes/arbitrator/ArbitratorDisputeView.java b/desktop/src/main/java/bisq/desktop/main/disputes/arbitrator/ArbitratorDisputeView.java index f21f53fa395..e8a0e2d0f6d 100644 --- a/desktop/src/main/java/bisq/desktop/main/disputes/arbitrator/ArbitratorDisputeView.java +++ b/desktop/src/main/java/bisq/desktop/main/disputes/arbitrator/ArbitratorDisputeView.java @@ -22,6 +22,7 @@ import bisq.desktop.main.overlays.windows.ContractWindow; import bisq.desktop.main.overlays.windows.DisputeSummaryWindow; import bisq.desktop.main.overlays.windows.TradeDetailsWindow; +import bisq.desktop.util.DisplayUtils; import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.alert.PrivateNotificationManager; @@ -79,7 +80,7 @@ protected void applyFilteredListPredicate(String filterString) { // If in arbitrator view we must only display disputes where we are selected as arbitrator (must not receive others anyway) filteredList.setPredicate(dispute -> { boolean matchesTradeId = dispute.getTradeId().contains(filterString); - boolean matchesDate = formatter.formatDate(dispute.getOpeningDate()).contains(filterString); + boolean matchesDate = DisplayUtils.formatDate(dispute.getOpeningDate()).contains(filterString); boolean isBuyerOnion = dispute.getContract().getBuyerNodeAddress().getFullAddress().contains(filterString); boolean isSellerOnion = dispute.getContract().getSellerNodeAddress().getFullAddress().contains(filterString); boolean matchesBuyersPaymentAccountData = dispute.getContract().getBuyerPaymentAccountPayload().getPaymentDetails().contains(filterString); diff --git a/desktop/src/main/java/bisq/desktop/main/disputes/trader/TraderDisputeView.java b/desktop/src/main/java/bisq/desktop/main/disputes/trader/TraderDisputeView.java index d9e55005d19..8ee118bafd0 100644 --- a/desktop/src/main/java/bisq/desktop/main/disputes/trader/TraderDisputeView.java +++ b/desktop/src/main/java/bisq/desktop/main/disputes/trader/TraderDisputeView.java @@ -30,6 +30,7 @@ import bisq.desktop.main.overlays.windows.DisputeSummaryWindow; import bisq.desktop.main.overlays.windows.SendPrivateNotificationWindow; import bisq.desktop.main.overlays.windows.TradeDetailsWindow; +import bisq.desktop.util.DisplayUtils; import bisq.desktop.util.GUIUtil; import bisq.core.account.witness.AccountAgeWitnessService; @@ -257,7 +258,7 @@ public void initialize() { .append(dispute0.getTradeId()) .append("\n") .append("## Date: ") - .append(BSFormatter.formatDateTime(dispute0.getOpeningDate())) + .append(DisplayUtils.formatDateTime(dispute0.getOpeningDate())) .append("\n") .append("## Is support ticket: ") .append(dispute0.isSupportTicket()) @@ -582,7 +583,7 @@ public TableCell call(TableColumn column) { public void updateItem(final Dispute item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) - setText(BSFormatter.formatDateTime(item.getOpeningDate())); + setText(DisplayUtils.formatDateTime(item.getOpeningDate())); else setText(""); } @@ -693,7 +694,7 @@ private String getBuyerOnionAddressColumnLabel(Dispute item) { if (buyerNodeAddress != null) { String nrOfDisputes = disputeManager.getNrOfDisputes(true, contract); long accountAge = accountAgeWitnessService.getAccountAge(contract.getBuyerPaymentAccountPayload(), contract.getBuyerPubKeyRing()); - String age = BSFormatter.formatAccountAge(accountAge); + String age = DisplayUtils.formatAccountAge(accountAge); String postFix = CurrencyUtil.isFiatCurrency(item.getContract().getOfferPayload().getCurrencyCode()) ? " / " + age : ""; return buyerNodeAddress.getHostNameWithoutPostFix() + " (" + nrOfDisputes + postFix + ")"; } else @@ -710,7 +711,7 @@ private String getSellerOnionAddressColumnLabel(Dispute item) { if (sellerNodeAddress != null) { String nrOfDisputes = disputeManager.getNrOfDisputes(false, contract); long accountAge = accountAgeWitnessService.getAccountAge(contract.getSellerPaymentAccountPayload(), contract.getSellerPubKeyRing()); - String age = BSFormatter.formatAccountAge(accountAge); + String age = DisplayUtils.formatAccountAge(accountAge); String postFix = CurrencyUtil.isFiatCurrency(item.getContract().getOfferPayload().getCurrencyCode()) ? " / " + age : ""; return sellerNodeAddress.getHostNameWithoutPostFix() + " (" + nrOfDisputes + postFix + ")"; } else diff --git a/desktop/src/main/java/bisq/desktop/main/funds/locked/LockedView.java b/desktop/src/main/java/bisq/desktop/main/funds/locked/LockedView.java index d01e5fe698c..fd39c35b85e 100644 --- a/desktop/src/main/java/bisq/desktop/main/funds/locked/LockedView.java +++ b/desktop/src/main/java/bisq/desktop/main/funds/locked/LockedView.java @@ -23,6 +23,7 @@ import bisq.desktop.components.HyperlinkWithIcon; import bisq.desktop.main.overlays.windows.OfferDetailsWindow; import bisq.desktop.main.overlays.windows.TradeDetailsWindow; +import bisq.desktop.util.DisplayUtils; import bisq.desktop.util.GUIUtil; import bisq.core.btc.listeners.BalanceListener; @@ -228,7 +229,7 @@ public void updateItem(final LockedListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { if (getTradable(item).isPresent()) - setGraphic(new AutoTooltipLabel(BSFormatter.formatDateTime(getTradable(item).get().getDate()))); + setGraphic(new AutoTooltipLabel(DisplayUtils.formatDateTime(getTradable(item).get().getDate()))); else setGraphic(new AutoTooltipLabel(Res.get("shared.noDateAvailable"))); } else { diff --git a/desktop/src/main/java/bisq/desktop/main/funds/reserved/ReservedView.java b/desktop/src/main/java/bisq/desktop/main/funds/reserved/ReservedView.java index eea40021bdd..c9056efa510 100644 --- a/desktop/src/main/java/bisq/desktop/main/funds/reserved/ReservedView.java +++ b/desktop/src/main/java/bisq/desktop/main/funds/reserved/ReservedView.java @@ -23,6 +23,7 @@ import bisq.desktop.components.HyperlinkWithIcon; import bisq.desktop.main.overlays.windows.OfferDetailsWindow; import bisq.desktop.main.overlays.windows.TradeDetailsWindow; +import bisq.desktop.util.DisplayUtils; import bisq.desktop.util.GUIUtil; import bisq.core.btc.listeners.BalanceListener; @@ -228,7 +229,7 @@ public void updateItem(final ReservedListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { if (getTradable(item).isPresent()) - setGraphic(new AutoTooltipLabel(BSFormatter.formatDateTime(getTradable(item).get().getDate()))); + setGraphic(new AutoTooltipLabel(DisplayUtils.formatDateTime(getTradable(item).get().getDate()))); else setGraphic(new AutoTooltipLabel(Res.get("shared.noDateAvailable"))); } else { diff --git a/desktop/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java b/desktop/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java index 4e20da06d0c..6b255d5d79f 100644 --- a/desktop/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java +++ b/desktop/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java @@ -18,6 +18,7 @@ package bisq.desktop.main.funds.transactions; import bisq.desktop.components.indicator.TxConfidenceIndicator; +import bisq.desktop.util.DisplayUtils; import bisq.desktop.util.GUIUtil; import bisq.core.btc.listeners.TxConfidenceListener; @@ -239,7 +240,7 @@ else if (details.isEmpty()) } // Use tx.getIncludedInBestChainAt() when available, otherwise use tx.getUpdateTime() date = transaction.getIncludedInBestChainAt() != null ? transaction.getIncludedInBestChainAt() : transaction.getUpdateTime(); - dateString = BSFormatter.formatDateTime(date); + dateString = DisplayUtils.formatDateTime(date); isDustAttackTx = received && valueSentToMe.value < ignoreDustThreshold; if (isDustAttackTx) { diff --git a/desktop/src/main/java/bisq/desktop/main/market/MarketView.java b/desktop/src/main/java/bisq/desktop/main/market/MarketView.java index ea3d9a9faed..e928d6334b8 100644 --- a/desktop/src/main/java/bisq/desktop/main/market/MarketView.java +++ b/desktop/src/main/java/bisq/desktop/main/market/MarketView.java @@ -31,6 +31,7 @@ import bisq.desktop.main.offer.offerbook.OfferBook; import bisq.desktop.main.offer.offerbook.OfferBookListItem; import bisq.desktop.main.overlays.popups.Popup; +import bisq.desktop.util.DisplayUtils; import bisq.core.locale.Res; import bisq.core.offer.OfferPayload; @@ -183,11 +184,11 @@ private String getAllTradesWithReferralId() { .map(trade -> { StringBuilder sb = new StringBuilder(); sb.append("Trade ID: ").append(trade.getOfferId()).append("\n") - .append("Date: ").append(BSFormatter.formatDateTime(trade.getTradeDate())).append("\n") + .append("Date: ").append(DisplayUtils.formatDateTime(trade.getTradeDate())).append("\n") .append("Market: ").append(BSFormatter.getCurrencyPair(trade.getCurrencyCode())).append("\n") - .append("Price: ").append(formatter.formatPrice(trade.getTradePrice())).append("\n") + .append("Price: ").append(BSFormatter.formatPrice(trade.getTradePrice())).append("\n") .append("Amount: ").append(formatter.formatCoin(trade.getTradeAmount())).append("\n") - .append("Volume: ").append(formatter.formatVolume(trade.getTradeVolume())).append("\n") + .append("Volume: ").append(DisplayUtils.formatVolume(trade.getTradeVolume())).append("\n") .append("Payment method: ").append(Res.get(trade.getOfferPaymentMethod())).append("\n") .append("ReferralID: ").append(trade.getExtraDataMap().get(OfferPayload.REFERRAL_ID)); return sb.toString(); @@ -206,8 +207,8 @@ private String getAllOffersWithReferralId() { sb.append("Offer ID: ").append(offer.getId()).append("\n") .append("Type: ").append(offer.getDirection().name()).append("\n") .append("Market: ").append(BSFormatter.getCurrencyPair(offer.getCurrencyCode())).append("\n") - .append("Price: ").append(formatter.formatPrice(offer.getPrice())).append("\n") - .append("Amount: ").append(formatter.formatAmount(offer)).append(" BTC\n") + .append("Price: ").append(BSFormatter.formatPrice(offer.getPrice())).append("\n") + .append("Amount: ").append(DisplayUtils.formatAmount(offer, formatter)).append(" BTC\n") .append("Payment method: ").append(Res.get(offer.getPaymentMethod().getId())).append("\n") .append("ReferralID: ").append(offer.getOfferPayload().getExtraDataMap().get(OfferPayload.REFERRAL_ID)); return sb.toString(); diff --git a/desktop/src/main/java/bisq/desktop/main/market/offerbook/OfferBookChartViewModel.java b/desktop/src/main/java/bisq/desktop/main/market/offerbook/OfferBookChartViewModel.java index 74220d84f4a..a600e6779df 100644 --- a/desktop/src/main/java/bisq/desktop/main/market/offerbook/OfferBookChartViewModel.java +++ b/desktop/src/main/java/bisq/desktop/main/market/offerbook/OfferBookChartViewModel.java @@ -26,6 +26,7 @@ import bisq.desktop.main.settings.preferences.PreferencesView; import bisq.desktop.util.CurrencyList; import bisq.desktop.util.CurrencyListItem; +import bisq.desktop.util.DisplayUtils; import bisq.desktop.util.GUIUtil; import bisq.core.account.witness.AccountAgeWitnessService; @@ -254,7 +255,7 @@ public String getPrice(Offer offer) { } private String formatPrice(Offer offer, boolean decimalAligned) { - return formatter.formatPrice(offer.getPrice(), decimalAligned, offer.isBuyOffer() ? maxPlacesForBuyPrice.get() : maxPlacesForSellPrice.get()); + return DisplayUtils.formatPrice(offer.getPrice(), decimalAligned, offer.isBuyOffer() ? maxPlacesForBuyPrice.get() : maxPlacesForSellPrice.get()); } public String getVolume(Offer offer) { @@ -262,7 +263,7 @@ public String getVolume(Offer offer) { } private String formatVolume(Offer offer, boolean decimalAligned) { - return formatter.formatVolume(offer, decimalAligned, offer.isBuyOffer() ? maxPlacesForBuyVolume.get() : maxPlacesForSellVolume.get(), false); + return DisplayUtils.formatVolume(offer, decimalAligned, offer.isBuyOffer() ? maxPlacesForBuyVolume.get() : maxPlacesForSellVolume.get(), false); } /////////////////////////////////////////////////////////////////////////////////////////// diff --git a/desktop/src/main/java/bisq/desktop/main/market/trades/TradesChartsView.java b/desktop/src/main/java/bisq/desktop/main/market/trades/TradesChartsView.java index 5d0327da43d..bc8760f4f34 100644 --- a/desktop/src/main/java/bisq/desktop/main/market/trades/TradesChartsView.java +++ b/desktop/src/main/java/bisq/desktop/main/market/trades/TradesChartsView.java @@ -27,6 +27,7 @@ import bisq.desktop.main.market.trades.charts.price.CandleStickChart; import bisq.desktop.main.market.trades.charts.volume.VolumeChart; import bisq.desktop.util.CurrencyListItem; +import bisq.desktop.util.DisplayUtils; import bisq.desktop.util.GUIUtil; import bisq.core.locale.CurrencyUtil; @@ -347,7 +348,7 @@ public String toString(Number object) { final double value = MathUtils.scaleDownByPowerOf10(doubleValue, 8); return BSFormatter.formatRoundedDoubleWithPrecision(value, 8); } else { - return formatter.formatPrice(Price.valueOf(currencyCode, MathUtils.doubleToLong(doubleValue))); + return BSFormatter.formatPrice(Price.valueOf(currencyCode, MathUtils.doubleToLong(doubleValue))); } } @@ -364,7 +365,7 @@ public String toString(Number object) { final double value = MathUtils.scaleDownByPowerOf10((long) object, 8); return BSFormatter.formatRoundedDoubleWithPrecision(value, 8); } else { - return formatter.formatPrice(Price.valueOf(model.getCurrencyCode(), (long) object)); + return BSFormatter.formatPrice(Price.valueOf(model.getCurrencyCode(), (long) object)); } } @@ -480,9 +481,9 @@ public String toString(Number object) { long index = MathUtils.doubleToLong((double) object); long time = model.getTimeFromTickIndex(index); if (model.tickUnit.ordinal() <= TradesChartsViewModel.TickUnit.DAY.ordinal()) - return index % 4 == 0 ? formatter.formatDate(new Date(time)) : ""; + return index % 4 == 0 ? DisplayUtils.formatDate(new Date(time)) : ""; else - return index % 3 == 0 ? formatter.formatTime(new Date(time)) : ""; + return index % 3 == 0 ? DisplayUtils.formatTime(new Date(time)) : ""; } @Override @@ -568,7 +569,7 @@ public TableCell call( public void updateItem(final TradeStatistics2 item, boolean empty) { super.updateItem(item, empty); if (item != null) - setText(BSFormatter.formatDateTime(item.getTradeDate())); + setText(DisplayUtils.formatDateTime(item.getTradeDate())); else setText(""); } @@ -621,7 +622,7 @@ public TableCell call( public void updateItem(final TradeStatistics2 item, boolean empty) { super.updateItem(item, empty); if (item != null) - setText(formatter.formatPrice(item.getTradePrice())); + setText(BSFormatter.formatPrice(item.getTradePrice())); else setText(""); } @@ -671,8 +672,8 @@ public void updateItem(final TradeStatistics2 item, boolean empty) { super.updateItem(item, empty); if (item != null) setText(model.showAllTradeCurrenciesProperty.get() ? - formatter.formatVolumeWithCode(item.getTradeVolume()) : - formatter.formatVolume(item.getTradeVolume())); + DisplayUtils.formatVolumeWithCode(item.getTradeVolume()) : + DisplayUtils.formatVolume(item.getTradeVolume())); else setText(""); } @@ -744,7 +745,7 @@ public void updateItem(final TradeStatistics2 item, boolean empty) { @NotNull private String getDirectionLabel(TradeStatistics2 item) { - return BSFormatter.getDirectionWithCode(OfferPayload.Direction.valueOf(item.getDirection().name()), item.getCurrencyCode()); + return DisplayUtils.getDirectionWithCode(OfferPayload.Direction.valueOf(item.getDirection().name()), item.getCurrencyCode()); } @NotNull diff --git a/desktop/src/main/java/bisq/desktop/main/market/trades/TradesChartsViewModel.java b/desktop/src/main/java/bisq/desktop/main/market/trades/TradesChartsViewModel.java index c9da02597ec..721e1fd1a27 100644 --- a/desktop/src/main/java/bisq/desktop/main/market/trades/TradesChartsViewModel.java +++ b/desktop/src/main/java/bisq/desktop/main/market/trades/TradesChartsViewModel.java @@ -25,6 +25,7 @@ import bisq.desktop.main.settings.preferences.PreferencesView; import bisq.desktop.util.CurrencyList; import bisq.desktop.util.CurrencyListItem; +import bisq.desktop.util.DisplayUtils; import bisq.desktop.util.GUIUtil; import bisq.core.locale.CryptoCurrency; @@ -345,12 +346,12 @@ CandleData getCandleData(long tick, Set set) { final Date dateFrom = new Date(getTimeFromTickIndex(tick)); final Date dateTo = new Date(getTimeFromTickIndex(tick + 1)); String dateString = tickUnit.ordinal() > TickUnit.DAY.ordinal() ? - formatter.formatDateTimeSpan(dateFrom, dateTo) : - formatter.formatDate(dateFrom) + " - " + formatter.formatDate(dateTo); + DisplayUtils.formatDateTimeSpan(dateFrom, dateTo) : + DisplayUtils.formatDate(dateFrom) + " - " + DisplayUtils.formatDate(dateTo); return new CandleData(tick, open, close, high, low, averagePrice, medianPrice, accumulatedAmount, accumulatedVolume, numTrades, isBullish, dateString); } - + Long findMedian(Long[] prices) { int middle = prices.length / 2; long median; diff --git a/desktop/src/main/java/bisq/desktop/main/offer/MutableOfferDataModel.java b/desktop/src/main/java/bisq/desktop/main/offer/MutableOfferDataModel.java index ab9a0f10f17..1490057fd48 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/MutableOfferDataModel.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/MutableOfferDataModel.java @@ -17,6 +17,8 @@ package bisq.desktop.main.offer; +import bisq.desktop.util.DisplayUtils; + import bisq.core.account.witness.AccountAgeRestrictions; import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.arbitration.Arbitrator; @@ -646,7 +648,7 @@ void calculateAmount() { !price.get().isZero() && allowAmountUpdate) { try { - Coin value = btcFormatter.reduceTo4Decimals(price.get().getAmountByVolume(volume.get())); + Coin value = DisplayUtils.reduceTo4Decimals(price.get().getAmountByVolume(volume.get()), btcFormatter); if (isHalCashAccount()) value = OfferUtil.getAdjustedAmountForHalCash(value, price.get(), getMaxTradeLimit()); else if (CurrencyUtil.isFiatCurrency(tradeCurrencyCode.get())) diff --git a/desktop/src/main/java/bisq/desktop/main/offer/MutableOfferViewModel.java b/desktop/src/main/java/bisq/desktop/main/offer/MutableOfferViewModel.java index b90f9b3a9ac..660220ea35d 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/MutableOfferViewModel.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/MutableOfferViewModel.java @@ -25,6 +25,7 @@ import bisq.desktop.main.overlays.popups.Popup; import bisq.desktop.main.settings.SettingsView; import bisq.desktop.main.settings.preferences.PreferencesView; +import bisq.desktop.util.DisplayUtils; import bisq.desktop.util.GUIUtil; import bisq.desktop.util.validation.AltcoinValidator; import bisq.desktop.util.validation.BsqValidator; @@ -441,7 +442,7 @@ private void createListeners() { priceListener = (ov, oldValue, newValue) -> { ignorePriceStringListener = true; if (newValue != null) - price.set(btcFormatter.formatPrice(newValue)); + price.set(BSFormatter.formatPrice(newValue)); else price.set(""); @@ -451,7 +452,7 @@ private void createListeners() { volumeListener = (ov, oldValue, newValue) -> { ignoreVolumeStringListener = true; if (newValue != null) - volume.set(btcFormatter.formatVolume(newValue)); + volume.set(DisplayUtils.formatVolume(newValue)); else volume.set(""); @@ -492,7 +493,7 @@ private void applyMakerFee() { Coin makerFeeInBtc = dataModel.getMakerFeeInBtc(); Optional optionalBtcFeeInFiat = OfferUtil.getFeeInUserFiatCurrency(makerFeeInBtc, true, preferences, priceFeedService, bsqFormatter); - String btcFeeWithFiatAmount = OfferUtil.getFeeWithFiatAmount(makerFeeInBtc, optionalBtcFeeInFiat, btcFormatter); + String btcFeeWithFiatAmount = DisplayUtils.getFeeWithFiatAmount(makerFeeInBtc, optionalBtcFeeInFiat, btcFormatter); if (DevEnv.isDaoActivated()) { tradeFeeInBtcWithFiat.set(btcFeeWithFiatAmount); } else { @@ -502,14 +503,14 @@ private void applyMakerFee() { Coin makerFeeInBsq = dataModel.getMakerFeeInBsq(); Optional optionalBsqFeeInFiat = OfferUtil.getFeeInUserFiatCurrency(makerFeeInBsq, false, preferences, priceFeedService, bsqFormatter); - String bsqFeeWithFiatAmount = OfferUtil.getFeeWithFiatAmount(makerFeeInBsq, optionalBsqFeeInFiat, bsqFormatter); + String bsqFeeWithFiatAmount = DisplayUtils.getFeeWithFiatAmount(makerFeeInBsq, optionalBsqFeeInFiat, bsqFormatter); if (DevEnv.isDaoActivated()) { tradeFeeInBsqWithFiat.set(bsqFeeWithFiatAmount); } else { // Before DAO is enabled we show fee as fiat and % in second line String feeInFiatAsString; if (optionalBtcFeeInFiat != null && optionalBtcFeeInFiat.isPresent()) { - feeInFiatAsString = btcFormatter.formatVolumeWithCode(optionalBtcFeeInFiat.get()); + feeInFiatAsString = DisplayUtils.formatVolumeWithCode(optionalBtcFeeInFiat.get()); } else { feeInFiatAsString = Res.get("shared.na"); } @@ -757,7 +758,7 @@ public void onFocusOutMinAmountTextField(boolean oldValue, boolean newValue) { if (dataModel.getMinVolume().get() != null) { InputValidator.ValidationResult minVolumeResult = isVolumeInputValid( - btcFormatter.formatVolume(dataModel.getMinVolume().get())); + DisplayUtils.formatVolume(dataModel.getMinVolume().get())); volumeValidationResult.set(minVolumeResult); @@ -788,7 +789,7 @@ void onFocusOutPriceTextField(boolean oldValue, boolean newValue) { setPriceToModel(); ignorePriceStringListener = true; if (dataModel.getPrice().get() != null) - price.set(btcFormatter.formatPrice(dataModel.getPrice().get())); + price.set(BSFormatter.formatPrice(dataModel.getPrice().get())); ignorePriceStringListener = false; dataModel.calculateVolume(); dataModel.calculateAmount(); @@ -836,7 +837,7 @@ void onFocusOutVolumeTextField(boolean oldValue, boolean newValue) { else if (CurrencyUtil.isFiatCurrency(tradeCurrencyCode.get())) volume = OfferUtil.getRoundedFiatVolume(volume); - this.volume.set(btcFormatter.formatVolume(volume)); + this.volume.set(DisplayUtils.formatVolume(volume)); } ignoreVolumeStringListener = false; @@ -1062,7 +1063,7 @@ public M getDataModel() { private void setAmountToModel() { if (amount.get() != null && !amount.get().isEmpty()) { - Coin amount = btcFormatter.parseToCoinWith4Decimals(this.amount.get()); + Coin amount = DisplayUtils.parseToCoinWith4Decimals(this.amount.get(), btcFormatter); long maxTradeLimit = dataModel.getMaxTradeLimit(); Price price = dataModel.getPrice().get(); @@ -1086,7 +1087,7 @@ else if (CurrencyUtil.isFiatCurrency(tradeCurrencyCode.get())) private void setMinAmountToModel() { if (minAmount.get() != null && !minAmount.get().isEmpty()) { - Coin minAmount = btcFormatter.parseToCoinWith4Decimals(this.minAmount.get()); + Coin minAmount = DisplayUtils.parseToCoinWith4Decimals(this.minAmount.get(), btcFormatter); Price price = dataModel.getPrice().get(); long maxTradeLimit = dataModel.getMaxTradeLimit(); @@ -1188,7 +1189,7 @@ private void updateButtonDisableState() { dataModel.getPrice().get() != null && dataModel.getPrice().get().getValue() != 0 && isVolumeInputValid(volume.get()).isValid && - isVolumeInputValid(btcFormatter.formatVolume(dataModel.getMinVolume().get())).isValid && + isVolumeInputValid(DisplayUtils.formatVolume(dataModel.getMinVolume().get())).isValid && dataModel.isMinAmountLessOrEqualAmount(); isNextButtonDisabled.set(!inputDataValid); @@ -1207,4 +1208,5 @@ private void stopTimeoutTimer() { private BSFormatter getFormatterForMakerFee() { return dataModel.isCurrencyForMakerFeeBtc() ? btcFormatter : bsqFormatter; } + } diff --git a/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookView.java b/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookView.java index 50cf3e829a3..4341a69c6f0 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookView.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookView.java @@ -37,6 +37,7 @@ import bisq.desktop.main.offer.OfferView; import bisq.desktop.main.overlays.popups.Popup; import bisq.desktop.main.overlays.windows.OfferDetailsWindow; +import bisq.desktop.util.DisplayUtils; import bisq.desktop.util.FormBuilder; import bisq.desktop.util.GUIUtil; import bisq.desktop.util.Layout; @@ -573,7 +574,7 @@ private void onShowInfo(Offer offer, final long tradeLimit = model.accountAgeWitnessService.getMyTradeLimit(account.get(), offer.getCurrencyCode()); new Popup<>() .warning(Res.get("offerbook.warning.tradeLimitNotMatching", - BSFormatter.formatAccountAge(model.accountAgeWitnessService.getMyAccountAge(account.get().getPaymentAccountPayload())), + DisplayUtils.formatAccountAge(model.accountAgeWitnessService.getMyAccountAge(account.get().getPaymentAccountPayload())), formatter.formatCoinWithCode(Coin.valueOf(tradeLimit)), formatter.formatCoinWithCode(offer.getMinAmount()))) .show(); diff --git a/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookViewModel.java b/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookViewModel.java index 02b9ed3a024..6c955937cb5 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookViewModel.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/offerbook/OfferBookViewModel.java @@ -22,6 +22,7 @@ import bisq.desktop.main.MainView; import bisq.desktop.main.settings.SettingsView; import bisq.desktop.main.settings.preferences.PreferencesView; +import bisq.desktop.util.DisplayUtils; import bisq.desktop.util.GUIUtil; import bisq.core.account.witness.AccountAgeWitnessService; @@ -341,7 +342,7 @@ String getAmount(OfferBookListItem item) { } private String formatAmount(Offer offer, boolean decimalAligned) { - return formatter.formatAmount(offer, GUIUtil.AMOUNT_DECIMALS, decimalAligned, maxPlacesForAmount.get()); + return DisplayUtils.formatAmount(offer, GUIUtil.AMOUNT_DECIMALS, decimalAligned, maxPlacesForAmount.get(), formatter); } @@ -363,7 +364,7 @@ String getAbsolutePriceMargin(Offer offer) { } private String formatPrice(Offer offer, boolean decimalAligned) { - return formatter.formatPrice(offer.getPrice(), decimalAligned, maxPlacesForPrice.get()); + return DisplayUtils.formatPrice(offer.getPrice(), decimalAligned, maxPlacesForPrice.get()); } private String formatMarketPriceMargin(Offer offer, boolean decimalAligned) { @@ -390,7 +391,7 @@ private String formatVolume(Offer offer, boolean decimalAligned) { if (offerVolume != null && minOfferVolume != null) { String postFix = showAllTradeCurrenciesProperty.get() ? " " + offer.getCurrencyCode() : ""; decimalAligned = decimalAligned && !showAllTradeCurrenciesProperty.get(); - return formatter.formatVolume(offer, decimalAligned, maxPlacesForVolume.get()) + postFix; + return DisplayUtils.formatVolume(offer, decimalAligned, maxPlacesForVolume.get()) + postFix; } else { return Res.get("shared.na"); } diff --git a/desktop/src/main/java/bisq/desktop/main/offer/takeoffer/TakeOfferViewModel.java b/desktop/src/main/java/bisq/desktop/main/offer/takeoffer/TakeOfferViewModel.java index e538c59bf33..37f9fe77c8f 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/takeoffer/TakeOfferViewModel.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/takeoffer/TakeOfferViewModel.java @@ -24,6 +24,7 @@ import bisq.desktop.main.funds.FundsView; import bisq.desktop.main.funds.deposit.DepositView; import bisq.desktop.main.overlays.popups.Popup; +import bisq.desktop.util.DisplayUtils; import bisq.desktop.util.GUIUtil; import bisq.desktop.util.validation.BtcValidator; @@ -205,7 +206,7 @@ void initWithData(Offer offer) { } amountRange = btcFormatter.formatCoin(offer.getMinAmount()) + " - " + btcFormatter.formatCoin(offer.getAmount()); - price = btcFormatter.formatPrice(dataModel.tradePrice); + price = BSFormatter.formatPrice(dataModel.tradePrice); marketPriceMargin = BSFormatter.formatToPercent(offer.getMarketPriceMargin()); paymentLabel = Res.get("takeOffer.fundsBox.paymentLabel", offer.getShortId()); @@ -288,7 +289,7 @@ private void applyTakerFee() { Coin makerFeeInBtc = dataModel.getTakerFeeInBtc(); Optional optionalBtcFeeInFiat = OfferUtil.getFeeInUserFiatCurrency(makerFeeInBtc, true, preferences, priceFeedService, bsqFormatter); - String btcFeeWithFiatAmount = OfferUtil.getFeeWithFiatAmount(makerFeeInBtc, optionalBtcFeeInFiat, btcFormatter); + String btcFeeWithFiatAmount = DisplayUtils.getFeeWithFiatAmount(makerFeeInBtc, optionalBtcFeeInFiat, btcFormatter); if (DevEnv.isDaoActivated()) { tradeFeeInBtcWithFiat.set(btcFeeWithFiatAmount); } else { @@ -298,14 +299,14 @@ private void applyTakerFee() { Coin makerFeeInBsq = dataModel.getTakerFeeInBsq(); Optional optionalBsqFeeInFiat = OfferUtil.getFeeInUserFiatCurrency(makerFeeInBsq, false, preferences, priceFeedService, bsqFormatter); - String bsqFeeWithFiatAmount = OfferUtil.getFeeWithFiatAmount(makerFeeInBsq, optionalBsqFeeInFiat, bsqFormatter); + String bsqFeeWithFiatAmount = DisplayUtils.getFeeWithFiatAmount(makerFeeInBsq, optionalBsqFeeInFiat, bsqFormatter); if (DevEnv.isDaoActivated()) { tradeFeeInBsqWithFiat.set(bsqFeeWithFiatAmount); } else { // Before DAO is enabled we show fee as fiat and % in second line String feeInFiatAsString; if (optionalBtcFeeInFiat != null && optionalBtcFeeInFiat.isPresent()) { - feeInFiatAsString = btcFormatter.formatVolumeWithCode(optionalBtcFeeInFiat.get()); + feeInFiatAsString = DisplayUtils.formatVolumeWithCode(optionalBtcFeeInFiat.get()); } else { feeInFiatAsString = Res.get("shared.na"); } @@ -334,7 +335,7 @@ void onFocusOutAmountTextField(boolean oldValue, boolean newValue, String userIn InputValidator.ValidationResult result = isBtcInputValid(amount.get()); amountValidationResult.set(result); if (result.isValid) { - showWarningInvalidBtcDecimalPlaces.set(!btcFormatter.hasBtcValidDecimals(userInput)); + showWarningInvalidBtcDecimalPlaces.set(!DisplayUtils.hasBtcValidDecimals(userInput, btcFormatter)); // only allow max 4 decimal places for btc values setAmountToModel(); // reformat input @@ -503,7 +504,7 @@ private void updateButtonDisableState() { /////////////////////////////////////////////////////////////////////////////////////////// private void addBindings() { - volume.bind(createStringBinding(() -> btcFormatter.formatVolume(dataModel.volume.get()), dataModel.volume)); + volume.bind(createStringBinding(() -> DisplayUtils.formatVolume(dataModel.volume.get()), dataModel.volume)); if (dataModel.getDirection() == OfferPayload.Direction.SELL) { volumeDescriptionLabel.set(Res.get("createOffer.amountPriceBox.buy.volumeDescription", dataModel.getCurrencyCode())); @@ -626,7 +627,7 @@ private void calculateVolume() { private void setAmountToModel() { if (amount.get() != null && !amount.get().isEmpty()) { - Coin amount = btcFormatter.parseToCoinWith4Decimals(this.amount.get()); + Coin amount = DisplayUtils.parseToCoinWith4Decimals(this.amount.get(), btcFormatter); long maxTradeLimit = dataModel.getMaxTradeLimit(); Price price = dataModel.tradePrice; if (price != null) { diff --git a/desktop/src/main/java/bisq/desktop/main/overlays/windows/ContractWindow.java b/desktop/src/main/java/bisq/desktop/main/overlays/windows/ContractWindow.java index 29f67bd6641..55889cd0f9f 100644 --- a/desktop/src/main/java/bisq/desktop/main/overlays/windows/ContractWindow.java +++ b/desktop/src/main/java/bisq/desktop/main/overlays/windows/ContractWindow.java @@ -20,6 +20,7 @@ import bisq.desktop.components.BisqTextArea; import bisq.desktop.main.MainView; import bisq.desktop.main.overlays.Overlay; +import bisq.desktop.util.DisplayUtils; import bisq.desktop.util.Layout; import bisq.core.account.witness.AccountAgeWitnessService; @@ -133,16 +134,16 @@ private void addContent() { addConfirmationLabelTextFieldWithCopyIcon(gridPane, rowIndex, Res.get("shared.offerId"), offer.getId(), Layout.TWICE_FIRST_ROW_DISTANCE).second.setMouseTransparent(false); addConfirmationLabelLabel(gridPane, ++rowIndex, Res.get("contractWindow.dates"), - BSFormatter.formatDateTime(offer.getDate()) + " / " + BSFormatter.formatDateTime(dispute.getTradeDate())); + DisplayUtils.formatDateTime(offer.getDate()) + " / " + DisplayUtils.formatDateTime(dispute.getTradeDate())); String currencyCode = offer.getCurrencyCode(); addConfirmationLabelLabel(gridPane, ++rowIndex, Res.get("shared.offerType"), - BSFormatter.getDirectionBothSides(offer.getDirection(), currencyCode)); + DisplayUtils.getDirectionBothSides(offer.getDirection(), currencyCode)); addConfirmationLabelLabel(gridPane, ++rowIndex, Res.get("shared.tradePrice"), - formatter.formatPrice(contract.getTradePrice())); + BSFormatter.formatPrice(contract.getTradePrice())); addConfirmationLabelLabel(gridPane, ++rowIndex, Res.get("shared.tradeAmount"), formatter.formatCoinWithCode(contract.getTradeAmount())); - addConfirmationLabelLabel(gridPane, ++rowIndex, BSFormatter.formatVolumeLabel(currencyCode, ":"), - formatter.formatVolumeWithCode(contract.getTradeVolume())); + addConfirmationLabelLabel(gridPane, ++rowIndex, DisplayUtils.formatVolumeLabel(currencyCode, ":"), + DisplayUtils.formatVolumeWithCode(contract.getTradeVolume())); String securityDeposit = Res.getWithColAndCap("shared.buyer") + " " + formatter.formatCoinWithCode(offer.getBuyerSecurityDeposit()) + @@ -261,7 +262,7 @@ private void addContent() { private String getAccountAge(PaymentAccountPayload paymentAccountPayload, PubKeyRing pubKeyRing, String currencyCode) { long age = accountAgeWitnessService.getAccountAge(paymentAccountPayload, pubKeyRing); return CurrencyUtil.isFiatCurrency(currencyCode) ? - age > -1 ? Res.get("peerInfoIcon.tooltip.age", BSFormatter.formatAccountAge(age)) : + age > -1 ? Res.get("peerInfoIcon.tooltip.age", DisplayUtils.formatAccountAge(age)) : Res.get("peerInfoIcon.tooltip.unknownAge") : ""; } diff --git a/desktop/src/main/java/bisq/desktop/main/overlays/windows/DisputeSummaryWindow.java b/desktop/src/main/java/bisq/desktop/main/overlays/windows/DisputeSummaryWindow.java index bdba913b7ed..09cab0c8301 100644 --- a/desktop/src/main/java/bisq/desktop/main/overlays/windows/DisputeSummaryWindow.java +++ b/desktop/src/main/java/bisq/desktop/main/overlays/windows/DisputeSummaryWindow.java @@ -23,6 +23,7 @@ import bisq.desktop.components.InputTextField; import bisq.desktop.main.overlays.Overlay; import bisq.desktop.main.overlays.popups.Popup; +import bisq.desktop.util.DisplayUtils; import bisq.desktop.util.Layout; import bisq.core.arbitration.Dispute; @@ -249,7 +250,7 @@ private void addInfoPane() { addTitledGroupBg(gridPane, ++rowIndex, 17, Res.get("disputeSummaryWindow.title")).getStyleClass().add("last"); addConfirmationLabelLabel(gridPane, rowIndex, Res.get("shared.tradeId"), dispute.getShortTradeId(), Layout.TWICE_FIRST_ROW_DISTANCE); - addConfirmationLabelLabel(gridPane, ++rowIndex, Res.get("disputeSummaryWindow.openDate"), BSFormatter.formatDateTime(dispute.getOpeningDate())); + addConfirmationLabelLabel(gridPane, ++rowIndex, Res.get("disputeSummaryWindow.openDate"), DisplayUtils.formatDateTime(dispute.getOpeningDate())); if (dispute.isDisputeOpenerIsMaker()) { if (dispute.isDisputeOpenerIsBuyer()) role = Res.get("support.buyerOfferer"); @@ -265,9 +266,9 @@ private void addInfoPane() { addConfirmationLabelLabel(gridPane, ++rowIndex, Res.get("shared.tradeAmount"), formatter.formatCoinWithCode(contract.getTradeAmount())); addConfirmationLabelLabel(gridPane, ++rowIndex, Res.get("shared.tradePrice"), - formatter.formatPrice(contract.getTradePrice())); + BSFormatter.formatPrice(contract.getTradePrice())); addConfirmationLabelLabel(gridPane, ++rowIndex, Res.get("shared.tradeVolume"), - formatter.formatVolumeWithCode(contract.getTradeVolume())); + DisplayUtils.formatVolumeWithCode(contract.getTradeVolume())); String securityDeposit = Res.getWithColAndCap("shared.buyer") + " " + formatter.formatCoinWithCode(contract.getOfferPayload().getBuyerSecurityDeposit()) + @@ -566,13 +567,13 @@ private void addButtons(Contract contract) { disputeResult.setLoserPublisher(isLoserPublisherCheckBox.isSelected()); disputeResult.setCloseDate(new Date()); String text = Res.get("disputeSummaryWindow.close.msg", - BSFormatter.formatDateTime(disputeResult.getCloseDate()), + DisplayUtils.formatDateTime(disputeResult.getCloseDate()), role, - BSFormatter.booleanToYesNo(disputeResult.tamperProofEvidenceProperty().get()), + DisplayUtils.booleanToYesNo(disputeResult.tamperProofEvidenceProperty().get()), role, - BSFormatter.booleanToYesNo(disputeResult.idVerificationProperty().get()), + DisplayUtils.booleanToYesNo(disputeResult.idVerificationProperty().get()), role, - BSFormatter.booleanToYesNo(disputeResult.screenCastProperty().get()), + DisplayUtils.booleanToYesNo(disputeResult.screenCastProperty().get()), formatter.formatCoinWithCode(disputeResult.getBuyerPayoutAmount()), formatter.formatCoinWithCode(disputeResult.getSellerPayoutAmount()), disputeResult.summaryNotesProperty().get()); diff --git a/desktop/src/main/java/bisq/desktop/main/overlays/windows/OfferDetailsWindow.java b/desktop/src/main/java/bisq/desktop/main/overlays/windows/OfferDetailsWindow.java index 10fa30f928d..a4f1558198e 100644 --- a/desktop/src/main/java/bisq/desktop/main/overlays/windows/OfferDetailsWindow.java +++ b/desktop/src/main/java/bisq/desktop/main/overlays/windows/OfferDetailsWindow.java @@ -22,6 +22,7 @@ import bisq.desktop.components.BusyAnimation; import bisq.desktop.main.overlays.Overlay; import bisq.desktop.main.overlays.popups.Popup; +import bisq.desktop.util.DisplayUtils; import bisq.desktop.util.Layout; import bisq.core.locale.BankUtil; @@ -170,49 +171,49 @@ private void addContent() { double firstRowDistance = Layout.TWICE_FIRST_ROW_DISTANCE; if (takeOfferHandlerOptional.isPresent()) { addConfirmationLabelLabel(gridPane, rowIndex, offerTypeLabel, - BSFormatter.getDirectionForTakeOffer(direction, currencyCode), firstRowDistance); + DisplayUtils.getDirectionForTakeOffer(direction, currencyCode), firstRowDistance); fiatDirectionInfo = direction == OfferPayload.Direction.BUY ? toReceive : toSpend; btcDirectionInfo = direction == OfferPayload.Direction.SELL ? toReceive : toSpend; } else if (placeOfferHandlerOptional.isPresent()) { addConfirmationLabelLabel(gridPane, rowIndex, offerTypeLabel, - BSFormatter.getOfferDirectionForCreateOffer(direction, currencyCode), firstRowDistance); + DisplayUtils.getOfferDirectionForCreateOffer(direction, currencyCode), firstRowDistance); fiatDirectionInfo = direction == OfferPayload.Direction.SELL ? toReceive : toSpend; btcDirectionInfo = direction == OfferPayload.Direction.BUY ? toReceive : toSpend; } else { addConfirmationLabelLabel(gridPane, rowIndex, offerTypeLabel, - BSFormatter.getDirectionBothSides(direction, currencyCode), firstRowDistance); + DisplayUtils.getDirectionBothSides(direction, currencyCode), firstRowDistance); } String btcAmount = Res.get("shared.btcAmount"); if (takeOfferHandlerOptional.isPresent()) { addConfirmationLabelLabel(gridPane, ++rowIndex, btcAmount + btcDirectionInfo, formatter.formatCoinWithCode(tradeAmount)); - addConfirmationLabelLabel(gridPane, ++rowIndex, formatter.formatVolumeLabel(currencyCode) + fiatDirectionInfo, - formatter.formatVolumeWithCode(offer.getVolumeByAmount(tradeAmount))); + addConfirmationLabelLabel(gridPane, ++rowIndex, DisplayUtils.formatVolumeLabel(currencyCode) + fiatDirectionInfo, + DisplayUtils.formatVolumeWithCode(offer.getVolumeByAmount(tradeAmount))); } else { addConfirmationLabelLabel(gridPane, ++rowIndex, btcAmount + btcDirectionInfo, formatter.formatCoinWithCode(offer.getAmount())); addConfirmationLabelLabel(gridPane, ++rowIndex, Res.get("offerDetailsWindow.minBtcAmount"), formatter.formatCoinWithCode(offer.getMinAmount())); - String volume = formatter.formatVolumeWithCode(offer.getVolume()); + String volume = DisplayUtils.formatVolumeWithCode(offer.getVolume()); String minVolume = ""; if (offer.getVolume() != null && offer.getMinVolume() != null && !offer.getVolume().equals(offer.getMinVolume())) - minVolume = " " + Res.get("offerDetailsWindow.min", formatter.formatVolumeWithCode(offer.getMinVolume())); + minVolume = " " + Res.get("offerDetailsWindow.min", DisplayUtils.formatVolumeWithCode(offer.getMinVolume())); addConfirmationLabelLabel(gridPane, ++rowIndex, - formatter.formatVolumeLabel(currencyCode) + fiatDirectionInfo, volume + minVolume); + DisplayUtils.formatVolumeLabel(currencyCode) + fiatDirectionInfo, volume + minVolume); } String priceLabel = Res.get("shared.price"); if (takeOfferHandlerOptional.isPresent()) { - addConfirmationLabelLabel(gridPane, ++rowIndex, priceLabel, formatter.formatPrice(tradePrice)); + addConfirmationLabelLabel(gridPane, ++rowIndex, priceLabel, BSFormatter.formatPrice(tradePrice)); } else { Price price = offer.getPrice(); if (offer.isUseMarketBasedPrice()) { - addConfirmationLabelLabel(gridPane, ++rowIndex, priceLabel, formatter.formatPrice(price) + + addConfirmationLabelLabel(gridPane, ++rowIndex, priceLabel, BSFormatter.formatPrice(price) + " " + Res.get("offerDetailsWindow.distance", BSFormatter.formatPercentagePrice(offer.getMarketPriceMargin()))); } else { - addConfirmationLabelLabel(gridPane, ++rowIndex, priceLabel, formatter.formatPrice(price)); + addConfirmationLabelLabel(gridPane, ++rowIndex, priceLabel, BSFormatter.formatPrice(price)); } } final PaymentMethod paymentMethod = offer.getPaymentMethod(); @@ -307,7 +308,7 @@ else if (BankUtil.isBankNameRequired(countryCode)) addConfirmationLabelTextFieldWithCopyIcon(gridPane, ++rowIndex, Res.get("offerDetailsWindow.makersOnion"), offer.getMakerNodeAddress().getFullAddress()); addConfirmationLabelLabel(gridPane, ++rowIndex, Res.get("offerDetailsWindow.creationDate"), - BSFormatter.formatDateTime(offer.getDate())); + DisplayUtils.formatDateTime(offer.getDate())); String value = Res.getWithColAndCap("shared.buyer") + " " + formatter.formatCoinWithCode(offer.getBuyerSecurityDeposit()) + diff --git a/desktop/src/main/java/bisq/desktop/main/overlays/windows/ProposalResultsWindow.java b/desktop/src/main/java/bisq/desktop/main/overlays/windows/ProposalResultsWindow.java index a2a3ec6a784..7620e1ac703 100644 --- a/desktop/src/main/java/bisq/desktop/main/overlays/windows/ProposalResultsWindow.java +++ b/desktop/src/main/java/bisq/desktop/main/overlays/windows/ProposalResultsWindow.java @@ -25,6 +25,7 @@ import bisq.desktop.main.dao.governance.ProposalDisplay; import bisq.desktop.main.dao.governance.result.VoteListItem; import bisq.desktop.main.overlays.TabbedOverlay; +import bisq.desktop.util.DisplayUtils; import bisq.desktop.util.GUIUtil; import bisq.desktop.util.Layout; @@ -34,7 +35,6 @@ import bisq.core.dao.state.model.governance.Proposal; import bisq.core.locale.Res; import bisq.core.user.Preferences; -import bisq.core.util.BSFormatter; import bisq.core.util.BsqFormatter; import bisq.common.util.Tuple2; @@ -241,7 +241,7 @@ public void updateItem(final VoteListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { - setText(BSFormatter.formatDateTime(item.getBlindVoteDate())); + setText(DisplayUtils.formatDateTime(item.getBlindVoteDate())); } else { setText(""); } diff --git a/desktop/src/main/java/bisq/desktop/main/overlays/windows/TradeDetailsWindow.java b/desktop/src/main/java/bisq/desktop/main/overlays/windows/TradeDetailsWindow.java index 0f38cb7f30c..ffef0239bf3 100644 --- a/desktop/src/main/java/bisq/desktop/main/overlays/windows/TradeDetailsWindow.java +++ b/desktop/src/main/java/bisq/desktop/main/overlays/windows/TradeDetailsWindow.java @@ -21,6 +21,7 @@ import bisq.desktop.components.TextFieldWithCopyIcon; import bisq.desktop.main.MainView; import bisq.desktop.main.overlays.Overlay; +import bisq.desktop.util.DisplayUtils; import bisq.desktop.util.Layout; import bisq.core.account.witness.AccountAgeWitnessService; @@ -134,12 +135,12 @@ private void addContent() { String offerType = Res.get("shared.offerType"); if (tradeManager.isBuyer(offer)) { addConfirmationLabelLabel(gridPane, rowIndex, offerType, - BSFormatter.getDirectionForBuyer(myOffer, offer.getCurrencyCode()), Layout.TWICE_FIRST_ROW_DISTANCE); + DisplayUtils.getDirectionForBuyer(myOffer, offer.getCurrencyCode()), Layout.TWICE_FIRST_ROW_DISTANCE); fiatDirectionInfo = toSpend; btcDirectionInfo = toReceive; } else { addConfirmationLabelLabel(gridPane, rowIndex, offerType, - BSFormatter.getDirectionForSeller(myOffer, offer.getCurrencyCode()), Layout.TWICE_FIRST_ROW_DISTANCE); + DisplayUtils.getDirectionForSeller(myOffer, offer.getCurrencyCode()), Layout.TWICE_FIRST_ROW_DISTANCE); fiatDirectionInfo = toReceive; btcDirectionInfo = toSpend; } @@ -147,10 +148,10 @@ private void addContent() { addConfirmationLabelLabel(gridPane, ++rowIndex, Res.get("shared.btcAmount") + btcDirectionInfo, formatter.formatCoinWithCode(trade.getTradeAmount())); addConfirmationLabelLabel(gridPane, ++rowIndex, - formatter.formatVolumeLabel(offer.getCurrencyCode()) + fiatDirectionInfo, - formatter.formatVolumeWithCode(trade.getTradeVolume())); + DisplayUtils.formatVolumeLabel(offer.getCurrencyCode()) + fiatDirectionInfo, + DisplayUtils.formatVolumeWithCode(trade.getTradeVolume())); addConfirmationLabelLabel(gridPane, ++rowIndex, Res.get("shared.tradePrice"), - formatter.formatPrice(trade.getTradePrice())); + BSFormatter.formatPrice(trade.getTradePrice())); addConfirmationLabelLabel(gridPane, ++rowIndex, Res.get("shared.paymentMethod"), Res.get(offer.getPaymentMethod().getId())); @@ -198,7 +199,7 @@ private void addContent() { addConfirmationLabelTextFieldWithCopyIcon(gridPane, rowIndex, Res.get("shared.tradeId"), trade.getId(), Layout.TWICE_FIRST_ROW_AND_GROUP_DISTANCE); addConfirmationLabelLabel(gridPane, ++rowIndex, Res.get("tradeDetailsWindow.tradeDate"), - BSFormatter.formatDateTime(trade.getDate())); + DisplayUtils.formatDateTime(trade.getDate())); String securityDeposit = Res.getWithColAndCap("shared.buyer") + " " + formatter.formatCoinWithCode(offer.getBuyerSecurityDeposit()) + @@ -226,7 +227,7 @@ private void addContent() { String paymentDetails = buyerPaymentAccountPayload.getPaymentDetails(); long age = accountAgeWitnessService.getAccountAge(buyerPaymentAccountPayload, contract.getBuyerPubKeyRing()); buyersAccountAge = CurrencyUtil.isFiatCurrency(offer.getCurrencyCode()) ? - age > -1 ? Res.get("peerInfoIcon.tooltip.age", BSFormatter.formatAccountAge(age)) : + age > -1 ? Res.get("peerInfoIcon.tooltip.age", DisplayUtils.formatAccountAge(age)) : Res.get("peerInfoIcon.tooltip.unknownAge") : ""; @@ -240,7 +241,7 @@ private void addContent() { String paymentDetails = sellerPaymentAccountPayload.getPaymentDetails(); long age = accountAgeWitnessService.getAccountAge(sellerPaymentAccountPayload, contract.getSellerPubKeyRing()); sellersAccountAge = CurrencyUtil.isFiatCurrency(offer.getCurrencyCode()) ? - age > -1 ? Res.get("peerInfoIcon.tooltip.age", BSFormatter.formatAccountAge(age)) : + age > -1 ? Res.get("peerInfoIcon.tooltip.age", DisplayUtils.formatAccountAge(age)) : Res.get("peerInfoIcon.tooltip.unknownAge") : ""; String postFix = sellersAccountAge.isEmpty() ? "" : " / " + sellersAccountAge; diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/closedtrades/ClosedTradesView.java b/desktop/src/main/java/bisq/desktop/main/portfolio/closedtrades/ClosedTradesView.java index ebc12ed3893..7cb3696114a 100644 --- a/desktop/src/main/java/bisq/desktop/main/portfolio/closedtrades/ClosedTradesView.java +++ b/desktop/src/main/java/bisq/desktop/main/portfolio/closedtrades/ClosedTradesView.java @@ -26,6 +26,7 @@ import bisq.desktop.components.PeerInfoIcon; import bisq.desktop.main.overlays.windows.OfferDetailsWindow; import bisq.desktop.main.overlays.windows.TradeDetailsWindow; +import bisq.desktop.util.DisplayUtils; import bisq.desktop.util.GUIUtil; import bisq.core.alert.PrivateNotificationManager; @@ -317,7 +318,7 @@ private void applyFilteredListPredicate(String filterString) { Offer offer = item.getTradable().getOffer(); boolean matchesId = offer.getId().contains(filterString); - boolean matchesOfferDate = formatter.formatDate(offer.getDate()).contains(filterString); + boolean matchesOfferDate = DisplayUtils.formatDate(offer.getDate()).contains(filterString); boolean isMakerOnion = offer.getMakerNodeAddress().getFullAddress().contains(filterString); if (item.getTradable() instanceof Trade) { @@ -327,7 +328,7 @@ private void applyFilteredListPredicate(String filterString) { boolean matchesSellersPaymentAccountData = false; Trade trade = (Trade) item.getTradable(); - boolean matchesTradeDate = formatter.formatDate(trade.getTakeOfferDate()).contains(filterString); + boolean matchesTradeDate = DisplayUtils.formatDate(trade.getTakeOfferDate()).contains(filterString); Contract contract = trade.getContract(); if (contract != null) { isBuyerOnion = contract.getBuyerNodeAddress().getFullAddress().contains(filterString); diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/closedtrades/ClosedTradesViewModel.java b/desktop/src/main/java/bisq/desktop/main/portfolio/closedtrades/ClosedTradesViewModel.java index 556a4185035..59bd006e9f3 100644 --- a/desktop/src/main/java/bisq/desktop/main/portfolio/closedtrades/ClosedTradesViewModel.java +++ b/desktop/src/main/java/bisq/desktop/main/portfolio/closedtrades/ClosedTradesViewModel.java @@ -19,6 +19,7 @@ import bisq.desktop.common.model.ActivatableWithDataModel; import bisq.desktop.common.model.ViewModel; +import bisq.desktop.util.DisplayUtils; import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.locale.Res; @@ -68,14 +69,14 @@ String getPrice(ClosedTradableListItem item) { return ""; Tradable tradable = item.getTradable(); if (tradable instanceof Trade) - return formatter.formatPrice(((Trade) tradable).getTradePrice()); + return BSFormatter.formatPrice(((Trade) tradable).getTradePrice()); else - return formatter.formatPrice(tradable.getOffer().getPrice()); + return BSFormatter.formatPrice(tradable.getOffer().getPrice()); } String getVolume(ClosedTradableListItem item) { if (item != null && item.getTradable() instanceof Trade) - return formatter.formatVolumeWithCode(((Trade) item.getTradable()).getTradeVolume()); + return DisplayUtils.formatVolumeWithCode(((Trade) item.getTradable()).getTradeVolume()); else if (item != null && item.getTradable() instanceof OpenOffer) return "-"; else @@ -123,11 +124,11 @@ String getSellerSecurityDeposit(ClosedTradableListItem item) { } String getDirectionLabel(ClosedTradableListItem item) { - return (item != null) ? BSFormatter.getDirectionWithCode(dataModel.getDirection(item.getTradable().getOffer()), item.getTradable().getOffer().getCurrencyCode()) : ""; + return (item != null) ? DisplayUtils.getDirectionWithCode(dataModel.getDirection(item.getTradable().getOffer()), item.getTradable().getOffer().getCurrencyCode()) : ""; } String getDate(ClosedTradableListItem item) { - return BSFormatter.formatDateTime(item.getTradable().getDate()); + return DisplayUtils.formatDateTime(item.getTradable().getDate()); } String getMarketLabel(ClosedTradableListItem item) { diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/editoffer/EditOfferViewModel.java b/desktop/src/main/java/bisq/desktop/main/portfolio/editoffer/EditOfferViewModel.java index 0df009e991d..fe7ca1e80bf 100644 --- a/desktop/src/main/java/bisq/desktop/main/portfolio/editoffer/EditOfferViewModel.java +++ b/desktop/src/main/java/bisq/desktop/main/portfolio/editoffer/EditOfferViewModel.java @@ -77,8 +77,8 @@ public void onInvalidateMarketPriceMargin() { } public void onInvalidatePrice() { - price.set(btcFormatter.formatPrice(null)); - price.set(btcFormatter.formatPrice(dataModel.getPrice().get())); + price.set(BSFormatter.formatPrice(null)); + price.set(BSFormatter.formatPrice(dataModel.getPrice().get())); } public boolean isSecurityDepositValid() { diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/failedtrades/FailedTradesViewModel.java b/desktop/src/main/java/bisq/desktop/main/portfolio/failedtrades/FailedTradesViewModel.java index 62b83ed484b..9adda89e850 100644 --- a/desktop/src/main/java/bisq/desktop/main/portfolio/failedtrades/FailedTradesViewModel.java +++ b/desktop/src/main/java/bisq/desktop/main/portfolio/failedtrades/FailedTradesViewModel.java @@ -19,6 +19,7 @@ import bisq.desktop.common.model.ActivatableWithDataModel; import bisq.desktop.common.model.ViewModel; +import bisq.desktop.util.DisplayUtils; import bisq.core.locale.Res; import bisq.core.util.BSFormatter; @@ -54,18 +55,18 @@ String getAmount(FailedTradesListItem item) { } String getPrice(FailedTradesListItem item) { - return (item != null) ? formatter.formatPrice(item.getTrade().getTradePrice()) : ""; + return (item != null) ? BSFormatter.formatPrice(item.getTrade().getTradePrice()) : ""; } String getVolume(FailedTradesListItem item) { if (item != null && item.getTrade() != null) - return formatter.formatVolumeWithCode(item.getTrade().getTradeVolume()); + return DisplayUtils.formatVolumeWithCode(item.getTrade().getTradeVolume()); else return ""; } String getDirectionLabel(FailedTradesListItem item) { - return (item != null) ? BSFormatter.getDirectionWithCode(dataModel.getDirection(item.getTrade().getOffer()), item.getTrade().getOffer().getCurrencyCode()) : ""; + return (item != null) ? DisplayUtils.getDirectionWithCode(dataModel.getDirection(item.getTrade().getOffer()), item.getTrade().getOffer().getCurrencyCode()) : ""; } String getMarketLabel(FailedTradesListItem item) { @@ -76,7 +77,7 @@ String getMarketLabel(FailedTradesListItem item) { } String getDate(FailedTradesListItem item) { - return BSFormatter.formatDateTime(item.getTrade().getDate()); + return DisplayUtils.formatDateTime(item.getTrade().getDate()); } String getState(FailedTradesListItem item) { diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/openoffer/OpenOffersViewModel.java b/desktop/src/main/java/bisq/desktop/main/portfolio/openoffer/OpenOffersViewModel.java index fb07b149524..c85c9c36d06 100644 --- a/desktop/src/main/java/bisq/desktop/main/portfolio/openoffer/OpenOffersViewModel.java +++ b/desktop/src/main/java/bisq/desktop/main/portfolio/openoffer/OpenOffersViewModel.java @@ -19,6 +19,7 @@ import bisq.desktop.common.model.ActivatableWithDataModel; import bisq.desktop.common.model.ViewModel; +import bisq.desktop.util.DisplayUtils; import bisq.core.locale.Res; import bisq.core.monetary.Price; @@ -71,7 +72,7 @@ String getTradeId(OpenOfferListItem item) { } String getAmount(OpenOfferListItem item) { - return (item != null) ? formatter.formatAmount(item.getOffer()) : ""; + return (item != null) ? DisplayUtils.formatAmount(item.getOffer(), formatter) : ""; } String getPrice(OpenOfferListItem item) { @@ -84,21 +85,21 @@ String getPrice(OpenOfferListItem item) { String postFix = ""; if (offer.isUseMarketBasedPrice()) postFix = " (" + BSFormatter.formatPercentagePrice(offer.getMarketPriceMargin()) + ")"; - return formatter.formatPrice(price) + postFix; + return BSFormatter.formatPrice(price) + postFix; } else { return Res.get("shared.na"); } } String getVolume(OpenOfferListItem item) { - return (item != null) ? formatter.formatVolume(item.getOffer(), false, 0) + " " + item.getOffer().getCurrencyCode() : ""; + return (item != null) ? DisplayUtils.formatVolume(item.getOffer(), false, 0) + " " + item.getOffer().getCurrencyCode() : ""; } String getDirectionLabel(OpenOfferListItem item) { if ((item == null)) return ""; - return BSFormatter.getDirectionWithCode(dataModel.getDirection(item.getOffer()), item.getOffer().getCurrencyCode()); + return DisplayUtils.getDirectionWithCode(dataModel.getDirection(item.getOffer()), item.getOffer().getCurrencyCode()); } String getMarketLabel(OpenOfferListItem item) { @@ -109,7 +110,7 @@ String getMarketLabel(OpenOfferListItem item) { } String getDate(OpenOfferListItem item) { - return BSFormatter.formatDateTime(item.getOffer().getDate()); + return DisplayUtils.formatDateTime(item.getOffer().getDate()); } boolean isDeactivated(OpenOfferListItem item) { diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesView.java b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesView.java index 2b28f86913b..472a60ded90 100644 --- a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesView.java +++ b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesView.java @@ -26,6 +26,7 @@ import bisq.desktop.main.MainView; import bisq.desktop.main.overlays.popups.Popup; import bisq.desktop.main.overlays.windows.TradeDetailsWindow; +import bisq.desktop.util.DisplayUtils; import bisq.desktop.util.FormBuilder; import bisq.desktop.util.CssTheme; @@ -493,7 +494,7 @@ public TableCell call( public void updateItem(final PendingTradesListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { - setGraphic(new AutoTooltipLabel(BSFormatter.formatDateTime(item.getTrade().getDate()))); + setGraphic(new AutoTooltipLabel(DisplayUtils.formatDateTime(item.getTrade().getDate()))); } else { setGraphic(null); } @@ -536,7 +537,7 @@ public TableCell call( public void updateItem(final PendingTradesListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) - setGraphic(new AutoTooltipLabel(formatter.formatPrice(item.getPrice()))); + setGraphic(new AutoTooltipLabel(BSFormatter.formatPrice(item.getPrice()))); else setGraphic(null); } @@ -557,7 +558,7 @@ public TableCell call( public void updateItem(final PendingTradesListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) - setGraphic(new AutoTooltipLabel(formatter.formatVolumeWithCode(item.getTrade().getTradeVolume()))); + setGraphic(new AutoTooltipLabel(DisplayUtils.formatVolumeWithCode(item.getTrade().getTradeVolume()))); else setGraphic(null); } diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesViewModel.java b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesViewModel.java index d83b81d3406..34366ac4d66 100644 --- a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesViewModel.java +++ b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesViewModel.java @@ -19,6 +19,7 @@ import bisq.desktop.common.model.ActivatableWithDataModel; import bisq.desktop.common.model.ViewModel; +import bisq.desktop.util.DisplayUtils; import bisq.desktop.util.GUIUtil; import bisq.core.account.witness.AccountAgeWitnessService; @@ -233,7 +234,7 @@ public double getRemainingTradeDurationAsPercentage() { } public String getDateForOpenDispute() { - return BSFormatter.formatDateTime(new Date(new Date().getTime() + getRemainingTradeDuration())); + return DisplayUtils.formatDateTime(new Date(new Date().getTime() + getRemainingTradeDuration())); } public boolean showWarning() { @@ -278,7 +279,7 @@ public String getTradeVolume() { } public String getFiatVolume() { - return dataModel.getTrade() != null ? btcFormatter.formatVolumeWithCode(dataModel.getTrade().getTradeVolume()) : ""; + return dataModel.getTrade() != null ? DisplayUtils.formatVolumeWithCode(dataModel.getTrade().getTradeVolume()) : ""; } public String getTxFee() { diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/buyer/BuyerStep2View.java b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/buyer/BuyerStep2View.java index 9c12794ede0..cb71e6fcdc5 100644 --- a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/buyer/BuyerStep2View.java +++ b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/buyer/BuyerStep2View.java @@ -49,6 +49,7 @@ import bisq.desktop.main.overlays.popups.Popup; import bisq.desktop.main.portfolio.pendingtrades.PendingTradesViewModel; import bisq.desktop.main.portfolio.pendingtrades.steps.TradeStepView; +import bisq.desktop.util.DisplayUtils; import bisq.desktop.util.Layout; import bisq.core.locale.CurrencyUtil; @@ -500,7 +501,7 @@ private void showPopup() { String fees = Res.get("portfolio.pending.step2_buyer.fees"); String id = trade.getShortId(); String paddedId = " " + id + " "; - String amount = model.btcFormatter.formatVolumeWithCode(trade.getTradeVolume()); + String amount = DisplayUtils.formatVolumeWithCode(trade.getTradeVolume()); if (paymentAccountPayload instanceof AssetsAccountPayload) { //noinspection UnusedAssignment message += Res.get("portfolio.pending.step2_buyer.altcoin", diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/seller/SellerStep3View.java b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/seller/SellerStep3View.java index 846e6d33747..f79ae3f655e 100644 --- a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/seller/SellerStep3View.java +++ b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/seller/SellerStep3View.java @@ -23,6 +23,7 @@ import bisq.desktop.main.overlays.popups.Popup; import bisq.desktop.main.portfolio.pendingtrades.PendingTradesViewModel; import bisq.desktop.main.portfolio.pendingtrades.steps.TradeStepView; +import bisq.desktop.util.DisplayUtils; import bisq.desktop.util.Layout; import bisq.core.locale.CurrencyUtil; @@ -320,7 +321,7 @@ private void showPopup() { //noinspection UnusedAssignment String key = "confirmPayment" + trade.getId(); String message = ""; - String tradeVolumeWithCode = model.btcFormatter.formatVolumeWithCode(trade.getTradeVolume()); + String tradeVolumeWithCode = DisplayUtils.formatVolumeWithCode(trade.getTradeVolume()); String currencyName = CurrencyUtil.getNameByCode(trade.getOffer().getCurrencyCode()); String part1 = Res.get("portfolio.pending.step3_seller.part", currencyName); String id = trade.getShortId(); diff --git a/desktop/src/main/java/bisq/desktop/main/settings/network/P2pNetworkListItem.java b/desktop/src/main/java/bisq/desktop/main/settings/network/P2pNetworkListItem.java index 9ebf5338526..db5e9b9ad37 100644 --- a/desktop/src/main/java/bisq/desktop/main/settings/network/P2pNetworkListItem.java +++ b/desktop/src/main/java/bisq/desktop/main/settings/network/P2pNetworkListItem.java @@ -17,6 +17,8 @@ package bisq.desktop.main.settings.network; +import bisq.desktop.util.DisplayUtils; + import bisq.core.locale.Res; import bisq.core.util.BSFormatter; @@ -118,7 +120,7 @@ else if (connection.getPeerType() == Connection.PeerType.DIRECT_MSG_PEER) } public String getCreationDate() { - return BSFormatter.formatDateTime(statistic.getCreationDate()); + return DisplayUtils.formatDateTime(statistic.getCreationDate()); } public String getOnionAddress() { diff --git a/desktop/src/main/java/bisq/desktop/util/DisplayUtils.java b/desktop/src/main/java/bisq/desktop/util/DisplayUtils.java new file mode 100644 index 00000000000..184e8b41431 --- /dev/null +++ b/desktop/src/main/java/bisq/desktop/util/DisplayUtils.java @@ -0,0 +1,291 @@ +package bisq.desktop.util; + +import bisq.core.locale.CurrencyUtil; +import bisq.core.locale.GlobalSettings; +import bisq.core.locale.Res; +import bisq.core.monetary.Altcoin; +import bisq.core.monetary.Price; +import bisq.core.monetary.Volume; +import bisq.core.offer.Offer; +import bisq.core.offer.OfferPayload; +import bisq.core.util.BSFormatter; + +import org.bitcoinj.core.Coin; +import org.bitcoinj.core.Monetary; +import org.bitcoinj.utils.Fiat; +import org.bitcoinj.utils.MonetaryFormat; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.time.DurationFormatUtils; + +import java.text.DateFormat; + +import java.math.BigDecimal; + +import java.util.Date; +import java.util.Optional; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class DisplayUtils { + private final static int scale = 3; + private static final MonetaryFormat fiatVolumeFormat = new MonetaryFormat().shift(0).minDecimals(2).repeatOptionalDecimals(0, 0); + + public static String formatDateTime(Date date) { + return BSFormatter.formatDateTime(date, true); + } + + public static String formatDateTimeSpan(Date dateFrom, Date dateTo) { + if (dateFrom != null && dateTo != null) { + DateFormat dateFormatter = DateFormat.getDateInstance(DateFormat.DEFAULT, GlobalSettings.getLocale()); + DateFormat timeFormatter = DateFormat.getTimeInstance(DateFormat.DEFAULT, GlobalSettings.getLocale()); + return dateFormatter.format(dateFrom) + " " + timeFormatter.format(dateFrom) + BSFormatter.RANGE_SEPARATOR + timeFormatter.format(dateTo); + } else { + return ""; + } + } + + public static String formatTime(Date date) { + if (date != null) { + DateFormat timeFormatter = DateFormat.getTimeInstance(DateFormat.DEFAULT, GlobalSettings.getLocale()); + return timeFormatter.format(date); + } else { + return ""; + } + } + + public static String formatDate(Date date) { + if (date != null) { + DateFormat dateFormatter = DateFormat.getDateInstance(DateFormat.DEFAULT, GlobalSettings.getLocale()); + return dateFormatter.format(date); + } else { + return ""; + } + } + + public static String formatAccountAge(long durationMillis) { + durationMillis = Math.max(0, durationMillis); + String day = Res.get("time.day").toLowerCase(); + String days = Res.get("time.days"); + String format = "d\' " + days + "\'"; + return StringUtils.replaceOnce(DurationFormatUtils.formatDuration(durationMillis, format), "1 " + days, "1 " + day); + } + + public static String booleanToYesNo(boolean value) { + return value ? Res.get("shared.yes") : Res.get("shared.no"); + } + + /////////////////////////////////////////////////////////////////////////////////////////// + // Volume + /////////////////////////////////////////////////////////////////////////////////////////// + + public static String formatVolume(Offer offer, Boolean decimalAligned, int maxNumberOfDigits) { + return formatVolume(offer, decimalAligned, maxNumberOfDigits, true); + } + + public static String formatVolume(Offer offer, Boolean decimalAligned, int maxNumberOfDigits, boolean showRange) { + String formattedVolume = offer.isRange() && showRange ? formatVolume(offer.getMinVolume()) + BSFormatter.RANGE_SEPARATOR + formatVolume(offer.getVolume()) : formatVolume(offer.getVolume()); + + if (decimalAligned) { + formattedVolume = BSFormatter.fillUpPlacesWithEmptyStrings(formattedVolume, maxNumberOfDigits); + } + return formattedVolume; + } + + public static String formatVolume(Volume volume) { + return formatVolume(volume, fiatVolumeFormat, false); + } + + private static String formatVolume(Volume volume, MonetaryFormat fiatVolumeFormat, boolean appendCurrencyCode) { + if (volume != null) { + Monetary monetary = volume.getMonetary(); + if (monetary instanceof Fiat) + return BSFormatter.formatFiat((Fiat) monetary, fiatVolumeFormat, appendCurrencyCode); + else + return BSFormatter.formatAltcoinVolume((Altcoin) monetary, appendCurrencyCode); + } else { + return ""; + } + } + + public static String formatVolumeWithCode(Volume volume) { + return formatVolume(volume, fiatVolumeFormat, true); + } + + public static String formatVolumeLabel(String currencyCode) { + return formatVolumeLabel(currencyCode, ""); + } + + public static String formatVolumeLabel(String currencyCode, String postFix) { + return Res.get("formatter.formatVolumeLabel", + currencyCode, postFix); + } + + /////////////////////////////////////////////////////////////////////////////////////////// + // Offer direction + /////////////////////////////////////////////////////////////////////////////////////////// + + public static String getDirectionWithCode(OfferPayload.Direction direction, String currencyCode) { + if (CurrencyUtil.isFiatCurrency(currencyCode)) + return (direction == OfferPayload.Direction.BUY) ? Res.get("shared.buyCurrency", Res.getBaseCurrencyCode()) : Res.get("shared.sellCurrency", Res.getBaseCurrencyCode()); + else + return (direction == OfferPayload.Direction.SELL) ? Res.get("shared.buyCurrency", currencyCode) : Res.get("shared.sellCurrency", currencyCode); + } + + public static String getDirectionBothSides(OfferPayload.Direction direction, String currencyCode) { + if (CurrencyUtil.isFiatCurrency(currencyCode)) { + currencyCode = Res.getBaseCurrencyCode(); + return direction == OfferPayload.Direction.BUY ? + Res.get("formatter.makerTaker", currencyCode, Res.get("shared.buyer"), currencyCode, Res.get("shared.seller")) : + Res.get("formatter.makerTaker", currencyCode, Res.get("shared.seller"), currencyCode, Res.get("shared.buyer")); + } else { + return direction == OfferPayload.Direction.SELL ? + Res.get("formatter.makerTaker", currencyCode, Res.get("shared.buyer"), currencyCode, Res.get("shared.seller")) : + Res.get("formatter.makerTaker", currencyCode, Res.get("shared.seller"), currencyCode, Res.get("shared.buyer")); + } + } + + public static String getDirectionForBuyer(boolean isMyOffer, String currencyCode) { + if (CurrencyUtil.isFiatCurrency(currencyCode)) { + String code = Res.getBaseCurrencyCode(); + return isMyOffer ? + Res.get("formatter.youAreAsMaker", Res.get("shared.buying"), code, Res.get("shared.selling"), code) : + Res.get("formatter.youAreAsTaker", Res.get("shared.buying"), code, Res.get("shared.selling"), code); + } else { + return isMyOffer ? + Res.get("formatter.youAreAsMaker", Res.get("shared.selling"), currencyCode, Res.get("shared.buying"), currencyCode) : + Res.get("formatter.youAreAsTaker", Res.get("shared.selling"), currencyCode, Res.get("shared.buying"), currencyCode); + } + } + + public static String getDirectionForSeller(boolean isMyOffer, String currencyCode) { + if (CurrencyUtil.isFiatCurrency(currencyCode)) { + String code = Res.getBaseCurrencyCode(); + return isMyOffer ? + Res.get("formatter.youAreAsMaker", Res.get("shared.selling"), code, Res.get("shared.buying"), code) : + Res.get("formatter.youAreAsTaker", Res.get("shared.selling"), code, Res.get("shared.buying"), code); + } else { + return isMyOffer ? + Res.get("formatter.youAreAsMaker", Res.get("shared.buying"), currencyCode, Res.get("shared.selling"), currencyCode) : + Res.get("formatter.youAreAsTaker", Res.get("shared.buying"), currencyCode, Res.get("shared.selling"), currencyCode); + } + } + + public static String getDirectionForTakeOffer(OfferPayload.Direction direction, String currencyCode) { + String baseCurrencyCode = Res.getBaseCurrencyCode(); + if (CurrencyUtil.isFiatCurrency(currencyCode)) { + return direction == OfferPayload.Direction.BUY ? + Res.get("formatter.youAre", Res.get("shared.selling"), baseCurrencyCode, Res.get("shared.buying"), currencyCode) : + Res.get("formatter.youAre", Res.get("shared.buying"), baseCurrencyCode, Res.get("shared.selling"), currencyCode); + } else { + + return direction == OfferPayload.Direction.SELL ? + Res.get("formatter.youAre", Res.get("shared.selling"), currencyCode, Res.get("shared.buying"), baseCurrencyCode) : + Res.get("formatter.youAre", Res.get("shared.buying"), currencyCode, Res.get("shared.selling"), baseCurrencyCode); + } + } + + public static String getOfferDirectionForCreateOffer(OfferPayload.Direction direction, String currencyCode) { + String baseCurrencyCode = Res.getBaseCurrencyCode(); + if (CurrencyUtil.isFiatCurrency(currencyCode)) { + return direction == OfferPayload.Direction.BUY ? + Res.get("formatter.youAreCreatingAnOffer.fiat", Res.get("shared.buy"), baseCurrencyCode) : + Res.get("formatter.youAreCreatingAnOffer.fiat", Res.get("shared.sell"), baseCurrencyCode); + } else { + return direction == OfferPayload.Direction.SELL ? + Res.get("formatter.youAreCreatingAnOffer.altcoin", Res.get("shared.buy"), currencyCode, Res.get("shared.selling"), baseCurrencyCode) : + Res.get("formatter.youAreCreatingAnOffer.altcoin", Res.get("shared.sell"), currencyCode, Res.get("shared.buying"), baseCurrencyCode); + } + } + + /////////////////////////////////////////////////////////////////////////////////////////// + // Amount + /////////////////////////////////////////////////////////////////////////////////////////// + + public static String formatAmount(Offer offer, BSFormatter formatter) { + return formatAmount(offer, false, formatter); + } + + private static String formatAmount(Offer offer, boolean decimalAligned, BSFormatter bsFormatter) { + String formattedAmount = offer.isRange() ? bsFormatter.formatCoin(offer.getMinAmount()) + BSFormatter.RANGE_SEPARATOR + bsFormatter.formatCoin(offer.getAmount()) : bsFormatter.formatCoin(offer.getAmount()); + if (decimalAligned) { + formattedAmount = BSFormatter.fillUpPlacesWithEmptyStrings(formattedAmount, 15); + } + return formattedAmount; + } + + public static String formatAmount(Offer offer, + int decimalPlaces, + boolean decimalAligned, + int maxPlaces, + BSFormatter bsFormatter) { + String formattedAmount = offer.isRange() ? bsFormatter.formatCoin(offer.getMinAmount(), decimalPlaces) + BSFormatter.RANGE_SEPARATOR + bsFormatter.formatCoin(offer.getAmount(), decimalPlaces) : bsFormatter.formatCoin(offer.getAmount(), decimalPlaces); + + if (decimalAligned) { + formattedAmount = BSFormatter.fillUpPlacesWithEmptyStrings(formattedAmount, maxPlaces); + } + return formattedAmount; + } + + /////////////////////////////////////////////////////////////////////////////////////////// + // Other + /////////////////////////////////////////////////////////////////////////////////////////// + + public static String formatPrice(Price price, Boolean decimalAligned, int maxPlaces) { + String formattedPrice = BSFormatter.formatPrice(price); + + if (decimalAligned) { + formattedPrice = BSFormatter.fillUpPlacesWithEmptyStrings(formattedPrice, maxPlaces); + } + return formattedPrice; + } + + public static String getFeeWithFiatAmount(Coin makerFeeAsCoin, + Optional optionalFeeInFiat, + BSFormatter formatter) { + String fee = makerFeeAsCoin != null ? formatter.formatCoinWithCode(makerFeeAsCoin) : Res.get("shared.na"); + String feeInFiatAsString; + if (optionalFeeInFiat != null && optionalFeeInFiat.isPresent()) { + feeInFiatAsString = formatVolumeWithCode(optionalFeeInFiat.get()); + } else { + feeInFiatAsString = Res.get("shared.na"); + } + return Res.get("feeOptionWindow.fee", fee, feeInFiatAsString); + } + + /** + * Converts to a coin with max. 4 decimal places. Last place gets rounded. + * 0.01234 -> 0.0123 + * 0.01235 -> 0.0124 + * + * @param input + * @param bsFormatter + * @return + */ + public static Coin parseToCoinWith4Decimals(String input, BSFormatter bsFormatter) { + try { + return Coin.valueOf(new BigDecimal(bsFormatter.parseToCoin(BSFormatter.cleanDoubleInput(input)).value).setScale(-scale - 1, + BigDecimal.ROUND_HALF_UP).setScale(scale + 1, BigDecimal.ROUND_HALF_UP).toBigInteger().longValue()); + } catch (Throwable t) { + if (input != null && input.length() > 0) + log.warn("Exception at parseToCoinWith4Decimals: " + t.toString()); + return Coin.ZERO; + } + } + + public static boolean hasBtcValidDecimals(String input, BSFormatter bsFormatter) { + return bsFormatter.parseToCoin(input).equals(parseToCoinWith4Decimals(input, bsFormatter)); + } + + /** + * Transform a coin with the properties defined in the format (used to reduce decimal places) + * + * @param coin The coin which should be transformed + * @param bsFormatter + * @return The transformed coin + */ + public static Coin reduceTo4Decimals(Coin coin, BSFormatter bsFormatter) { + return bsFormatter.parseToCoin(bsFormatter.formatCoin(coin)); + } +} diff --git a/desktop/src/test/java/bisq/desktop/util/BSFormatterTest.java b/desktop/src/test/java/bisq/desktop/util/BSFormatterTest.java index 814964642db..23f0282a3ec 100644 --- a/desktop/src/test/java/bisq/desktop/util/BSFormatterTest.java +++ b/desktop/src/test/java/bisq/desktop/util/BSFormatterTest.java @@ -59,17 +59,6 @@ public void setUp() { Res.setBaseCurrencyName("Bitcoin"); } - @Test - public void testIsValid() { - assertEquals("0 days", BSFormatter.formatAccountAge(TimeUnit.HOURS.toMillis(23))); - assertEquals("0 days", BSFormatter.formatAccountAge(0)); - assertEquals("0 days", BSFormatter.formatAccountAge(-1)); - assertEquals("1 day", BSFormatter.formatAccountAge(TimeUnit.DAYS.toMillis(1))); - assertEquals("2 days", BSFormatter.formatAccountAge(TimeUnit.DAYS.toMillis(2))); - assertEquals("30 days", BSFormatter.formatAccountAge(TimeUnit.DAYS.toMillis(30))); - assertEquals("60 days", BSFormatter.formatAccountAge(TimeUnit.DAYS.toMillis(60))); - } - @Test public void testFormatDurationAsWords() { long oneDay = TimeUnit.DAYS.toMillis(1); @@ -98,8 +87,8 @@ public void testFormatDurationAsWords() { @Test public void testFormatPrice() { - assertEquals("100.0000", formatter.formatPrice(make(usdPrice))); - assertEquals("7098.4700", formatter.formatPrice(make(usdPrice.but(with(priceString, "7098.4700"))))); + assertEquals("100.0000", BSFormatter.formatPrice(make(usdPrice))); + assertEquals("7098.4700", BSFormatter.formatPrice(make(usdPrice.but(with(priceString, "7098.4700"))))); } @Test @@ -110,90 +99,4 @@ public void testFormatCoin() { assertEquals("0.000001", formatter.formatCoin(make(a(CoinMaker.Coin).but(with(satoshis, 100L))))); assertEquals("0.00000001", formatter.formatCoin(make(a(CoinMaker.Coin).but(with(satoshis, 1L))))); } - - @Test - public void testFormatVolume() { - assertEquals("1.00", formatter.formatVolume(make(btcUsdOffer), true, 4)); - assertEquals("100.00", formatter.formatVolume(make(usdVolume))); - assertEquals("1774.62", formatter.formatVolume(make(usdVolume.but(with(volumeString, "1774.62"))))); - } - - @Test - public void testFormatSameVolume() { - Offer offer = mock(Offer.class); - Volume btc = Volume.parse("0.10", "BTC"); - when(offer.getMinVolume()).thenReturn(btc); - when(offer.getVolume()).thenReturn(btc); - - assertEquals("0.10000000", formatter.formatVolume(offer.getVolume())); - } - - @Test - public void testFormatDifferentVolume() { - Offer offer = mock(Offer.class); - Volume btcMin = Volume.parse("0.10", "BTC"); - Volume btcMax = Volume.parse("0.25", "BTC"); - when(offer.isRange()).thenReturn(true); - when(offer.getMinVolume()).thenReturn(btcMin); - when(offer.getVolume()).thenReturn(btcMax); - - assertEquals("0.10000000 - 0.25000000", formatter.formatVolume(offer, false, 0)); - } - - @Test - public void testFormatNullVolume() { - Offer offer = mock(Offer.class); - when(offer.getMinVolume()).thenReturn(null); - when(offer.getVolume()).thenReturn(null); - - assertEquals("", formatter.formatVolume(offer.getVolume())); - } - - @Test - public void testFormatSameAmount() { - Offer offer = mock(Offer.class); - when(offer.getMinAmount()).thenReturn(Coin.valueOf(10000000)); - when(offer.getAmount()).thenReturn(Coin.valueOf(10000000)); - - assertEquals("0.10", formatter.formatAmount(offer)); - } - - @Test - public void testFormatDifferentAmount() { - OfferPayload offerPayload = mock(OfferPayload.class); - Offer offer = new Offer(offerPayload); - when(offerPayload.getMinAmount()).thenReturn(10000000L); - when(offerPayload.getAmount()).thenReturn(20000000L); - - assertEquals("0.10 - 0.20", formatter.formatAmount(offer)); - } - - @Test - public void testFormatAmountWithAlignmenWithDecimals() { - OfferPayload offerPayload = mock(OfferPayload.class); - Offer offer = new Offer(offerPayload); - when(offerPayload.getMinAmount()).thenReturn(10000000L); - when(offerPayload.getAmount()).thenReturn(20000000L); - - assertEquals("0.1000 - 0.2000", formatter.formatAmount(offer, 4, true, 15)); - } - - @Test - public void testFormatAmountWithAlignmenWithDecimalsNoRange() { - OfferPayload offerPayload = mock(OfferPayload.class); - Offer offer = new Offer(offerPayload); - when(offerPayload.getMinAmount()).thenReturn(10000000L); - when(offerPayload.getAmount()).thenReturn(10000000L); - - assertEquals("0.1000", formatter.formatAmount(offer, 4, true, 15)); - } - - @Test - public void testFormatNullAmount() { - Offer offer = mock(Offer.class); - when(offer.getMinAmount()).thenReturn(null); - when(offer.getAmount()).thenReturn(null); - - assertEquals("", formatter.formatAmount(offer)); - } } diff --git a/desktop/src/test/java/bisq/desktop/util/DisplayUtilsTest.java b/desktop/src/test/java/bisq/desktop/util/DisplayUtilsTest.java new file mode 100644 index 00000000000..b19bb890c2e --- /dev/null +++ b/desktop/src/test/java/bisq/desktop/util/DisplayUtilsTest.java @@ -0,0 +1,132 @@ +package bisq.desktop.util; + +import bisq.core.locale.Res; +import bisq.core.monetary.Volume; +import bisq.core.offer.Offer; +import bisq.core.offer.OfferPayload; +import bisq.core.util.BSFormatter; + +import org.bitcoinj.core.Coin; + +import java.util.Locale; +import java.util.concurrent.TimeUnit; + +import org.junit.Before; +import org.junit.Test; + +import static bisq.desktop.maker.OfferMaker.btcUsdOffer; +import static bisq.desktop.maker.VolumeMaker.usdVolume; +import static bisq.desktop.maker.VolumeMaker.volumeString; +import static com.natpryce.makeiteasy.MakeItEasy.make; +import static com.natpryce.makeiteasy.MakeItEasy.with; +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class DisplayUtilsTest { + private final BSFormatter formatter = new BSFormatter(); + + @Before + public void setUp() { + Locale.setDefault(new Locale("en", "US")); + Res.setBaseCurrencyCode("BTC"); + Res.setBaseCurrencyName("Bitcoin"); + } + + @Test + public void testFormatAccountAge() { + assertEquals("0 days", DisplayUtils.formatAccountAge(TimeUnit.HOURS.toMillis(23))); + assertEquals("0 days", DisplayUtils.formatAccountAge(0)); + assertEquals("0 days", DisplayUtils.formatAccountAge(-1)); + assertEquals("1 day", DisplayUtils.formatAccountAge(TimeUnit.DAYS.toMillis(1))); + assertEquals("2 days", DisplayUtils.formatAccountAge(TimeUnit.DAYS.toMillis(2))); + assertEquals("30 days", DisplayUtils.formatAccountAge(TimeUnit.DAYS.toMillis(30))); + assertEquals("60 days", DisplayUtils.formatAccountAge(TimeUnit.DAYS.toMillis(60))); + } + + @Test + public void testFormatVolume() { + assertEquals("1.00", DisplayUtils.formatVolume(make(btcUsdOffer), true, 4)); + assertEquals("100.00", DisplayUtils.formatVolume(make(usdVolume))); + assertEquals("1774.62", DisplayUtils.formatVolume(make(usdVolume.but(with(volumeString, "1774.62"))))); + } + + @Test + public void testFormatSameVolume() { + Offer offer = mock(Offer.class); + Volume btc = Volume.parse("0.10", "BTC"); + when(offer.getMinVolume()).thenReturn(btc); + when(offer.getVolume()).thenReturn(btc); + + assertEquals("0.10000000", DisplayUtils.formatVolume(offer.getVolume())); + } + + @Test + public void testFormatDifferentVolume() { + Offer offer = mock(Offer.class); + Volume btcMin = Volume.parse("0.10", "BTC"); + Volume btcMax = Volume.parse("0.25", "BTC"); + when(offer.isRange()).thenReturn(true); + when(offer.getMinVolume()).thenReturn(btcMin); + when(offer.getVolume()).thenReturn(btcMax); + + assertEquals("0.10000000 - 0.25000000", DisplayUtils.formatVolume(offer, false, 0)); + } + + @Test + public void testFormatNullVolume() { + Offer offer = mock(Offer.class); + when(offer.getMinVolume()).thenReturn(null); + when(offer.getVolume()).thenReturn(null); + + assertEquals("", DisplayUtils.formatVolume(offer.getVolume())); + } + + @Test + public void testFormatSameAmount() { + Offer offer = mock(Offer.class); + when(offer.getMinAmount()).thenReturn(Coin.valueOf(10000000)); + when(offer.getAmount()).thenReturn(Coin.valueOf(10000000)); + + assertEquals("0.10", DisplayUtils.formatAmount(offer, formatter)); + } + + @Test + public void testFormatDifferentAmount() { + OfferPayload offerPayload = mock(OfferPayload.class); + Offer offer = new Offer(offerPayload); + when(offerPayload.getMinAmount()).thenReturn(10000000L); + when(offerPayload.getAmount()).thenReturn(20000000L); + + assertEquals("0.10 - 0.20", DisplayUtils.formatAmount(offer, formatter)); + } + + @Test + public void testFormatAmountWithAlignmenWithDecimals() { + OfferPayload offerPayload = mock(OfferPayload.class); + Offer offer = new Offer(offerPayload); + when(offerPayload.getMinAmount()).thenReturn(10000000L); + when(offerPayload.getAmount()).thenReturn(20000000L); + + assertEquals("0.1000 - 0.2000", DisplayUtils.formatAmount(offer, 4, true, 15, formatter)); + } + + @Test + public void testFormatAmountWithAlignmenWithDecimalsNoRange() { + OfferPayload offerPayload = mock(OfferPayload.class); + Offer offer = new Offer(offerPayload); + when(offerPayload.getMinAmount()).thenReturn(10000000L); + when(offerPayload.getAmount()).thenReturn(10000000L); + + assertEquals("0.1000", DisplayUtils.formatAmount(offer, 4, true, 15, formatter)); + } + + @Test + public void testFormatNullAmount() { + Offer offer = mock(Offer.class); + when(offer.getMinAmount()).thenReturn(null); + when(offer.getAmount()).thenReturn(null); + + assertEquals("", DisplayUtils.formatAmount(offer, formatter)); + } +} From 3b46f3584ffbd59f4df99cd67fcb786f84935dcd Mon Sep 17 00:00:00 2001 From: Justin Carter Date: Wed, 11 Sep 2019 16:07:16 +0200 Subject: [PATCH 2/2] Extract parsing functions from BSFormatter to ParsingUtils Parsing and formatting are 2 different concerns, its better to have 2 classes that handle these. --- .../bisq/core/dao/state/DaoStateService.java | 4 +- .../main/java/bisq/core/monetary/Altcoin.java | 4 +- .../main/java/bisq/core/monetary/Price.java | 4 +- .../main/java/bisq/core/monetary/Volume.java | 4 +- .../main/java/bisq/core/util/BSFormatter.java | 90 +++---------------- .../java/bisq/core/util/BsqFormatter.java | 22 ++--- .../java/bisq/core/util/ParsingUtils.java | 83 +++++++++++++++++ .../MobileNotificationsView.java | 11 +-- .../bonding/reputation/MyReputationView.java | 3 +- .../dao/burnbsq/assetfee/AssetFeeView.java | 3 +- .../burnbsq/proofofburn/ProofOfBurnView.java | 3 +- .../dao/governance/make/MakeProposalView.java | 5 +- .../governance/proposals/ProposalsView.java | 3 +- .../main/dao/wallet/send/BsqSendView.java | 3 +- .../main/funds/deposit/DepositView.java | 5 +- .../main/funds/withdrawal/WithdrawalView.java | 3 +- .../main/offer/MutableOfferViewModel.java | 11 +-- .../windows/DisputeSummaryWindow.java | 9 +- .../settings/preferences/PreferencesView.java | 3 +- .../java/bisq/desktop/util/DisplayUtils.java | 7 +- .../desktop/util/validation/BsqValidator.java | 11 +-- .../util/validation/NumberValidator.java | 4 +- .../validation/SecurityDepositValidator.java | 5 +- 23 files changed, 164 insertions(+), 136 deletions(-) create mode 100644 core/src/main/java/bisq/core/util/ParsingUtils.java diff --git a/core/src/main/java/bisq/core/dao/state/DaoStateService.java b/core/src/main/java/bisq/core/dao/state/DaoStateService.java index f53d3cfa70f..c4e226c746c 100644 --- a/core/src/main/java/bisq/core/dao/state/DaoStateService.java +++ b/core/src/main/java/bisq/core/dao/state/DaoStateService.java @@ -35,8 +35,8 @@ import bisq.core.dao.state.model.governance.Issuance; import bisq.core.dao.state.model.governance.IssuanceType; import bisq.core.dao.state.model.governance.ParamChange; -import bisq.core.util.BSFormatter; import bisq.core.util.BsqFormatter; +import bisq.core.util.ParsingUtils; import org.bitcoinj.core.Coin; @@ -924,7 +924,7 @@ public Coin getParamValueAsCoin(Param param, String paramValue) { } public double getParamValueAsPercentDouble(String paramValue) { - return BSFormatter.parsePercentStringToDouble(paramValue); + return ParsingUtils.parsePercentStringToDouble(paramValue); } public int getParamValueAsBlock(String paramValue) { diff --git a/core/src/main/java/bisq/core/monetary/Altcoin.java b/core/src/main/java/bisq/core/monetary/Altcoin.java index 55ca1f48cc0..87c4e754263 100644 --- a/core/src/main/java/bisq/core/monetary/Altcoin.java +++ b/core/src/main/java/bisq/core/monetary/Altcoin.java @@ -17,7 +17,7 @@ package bisq.core.monetary; -import bisq.core.util.BSFormatter; +import bisq.core.util.ParsingUtils; import org.bitcoinj.core.Monetary; import org.bitcoinj.utils.MonetaryFormat; @@ -89,7 +89,7 @@ public String getCurrencyCode() { * @throws IllegalArgumentException if you try to specify fractional satoshis, or a value out of range. */ public static Altcoin parseAltcoin(final String currencyCode, String input) { - String cleaned = BSFormatter.convertCharsForNumber(input); + String cleaned = ParsingUtils.convertCharsForNumber(input); try { long val = new BigDecimal(cleaned).movePointRight(SMALLEST_UNIT_EXPONENT) .toBigIntegerExact().longValue(); diff --git a/core/src/main/java/bisq/core/monetary/Price.java b/core/src/main/java/bisq/core/monetary/Price.java index cc9a7750575..6e588353681 100644 --- a/core/src/main/java/bisq/core/monetary/Price.java +++ b/core/src/main/java/bisq/core/monetary/Price.java @@ -18,7 +18,7 @@ package bisq.core.monetary; import bisq.core.locale.CurrencyUtil; -import bisq.core.util.BSFormatter; +import bisq.core.util.ParsingUtils; import org.bitcoinj.core.Coin; import org.bitcoinj.core.Monetary; @@ -58,7 +58,7 @@ public Price(Monetary monetary) { * @return The parsed Price. */ public static Price parse(String currencyCode, String input) { - String cleaned = BSFormatter.convertCharsForNumber(input); + String cleaned = ParsingUtils.convertCharsForNumber(input); if (CurrencyUtil.isFiatCurrency(currencyCode)) return new Price(Fiat.parseFiat(currencyCode, cleaned)); else diff --git a/core/src/main/java/bisq/core/monetary/Volume.java b/core/src/main/java/bisq/core/monetary/Volume.java index cd79a0b2115..bd2bc752e04 100644 --- a/core/src/main/java/bisq/core/monetary/Volume.java +++ b/core/src/main/java/bisq/core/monetary/Volume.java @@ -18,7 +18,7 @@ package bisq.core.monetary; import bisq.core.locale.CurrencyUtil; -import bisq.core.util.BSFormatter; +import bisq.core.util.ParsingUtils; import org.bitcoinj.core.Monetary; import org.bitcoinj.utils.Fiat; @@ -36,7 +36,7 @@ public Volume(Monetary monetary) { } public static Volume parse(String input, String currencyCode) { - String cleaned = BSFormatter.convertCharsForNumber(input); + String cleaned = ParsingUtils.convertCharsForNumber(input); if (CurrencyUtil.isFiatCurrency(currencyCode)) return new Volume(Fiat.parseFiat(currencyCode, cleaned)); else diff --git a/core/src/main/java/bisq/core/util/BSFormatter.java b/core/src/main/java/bisq/core/util/BSFormatter.java index 866b09eb630..98ed6f0d5ab 100644 --- a/core/src/main/java/bisq/core/util/BSFormatter.java +++ b/core/src/main/java/bisq/core/util/BSFormatter.java @@ -52,6 +52,7 @@ import java.util.TimeZone; import java.util.stream.Collectors; +import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.jetbrains.annotations.NotNull; @@ -66,7 +67,8 @@ public class BSFormatter { // Input of a group separator (1,123,45) lead to an validation error. // Note: BtcFormat was intended to be used, but it lead to many problems (automatic format to mBit, // no way to remove grouping separator). It seems to be not optimal for user input formatting. - protected MonetaryFormat coinFormat; + @Getter + protected MonetaryFormat monetaryFormat; // protected String currencyCode = CurrencyUtil.getDefaultFiatCurrencyAsCode(); @@ -77,7 +79,7 @@ public class BSFormatter { @Inject public BSFormatter() { - coinFormat = BisqEnvironment.getParameters().getMonetaryFormat(); + monetaryFormat = BisqEnvironment.getParameters().getMonetaryFormat(); } @@ -99,7 +101,7 @@ public String formatCoin(long value, MonetaryFormat coinFormat) { } public String formatCoin(Coin coin, int decimalPlaces, boolean decimalAligned, int maxNumberOfDigits) { - return formatCoin(coin, decimalPlaces, decimalAligned, maxNumberOfDigits, coinFormat); + return formatCoin(coin, decimalPlaces, decimalAligned, maxNumberOfDigits, monetaryFormat); } public static String formatCoin(Coin coin, @@ -129,11 +131,11 @@ public static String formatCoin(Coin coin, } public String formatCoinWithCode(Coin coin) { - return formatCoinWithCode(coin, coinFormat); + return formatCoinWithCode(coin, monetaryFormat); } public String formatCoinWithCode(long value) { - return formatCoinWithCode(Coin.valueOf(value), coinFormat); + return formatCoinWithCode(Coin.valueOf(value), monetaryFormat); } public static String formatCoinWithCode(long value, MonetaryFormat coinFormat) { @@ -155,24 +157,6 @@ public static String formatCoinWithCode(Coin coin, MonetaryFormat coinFormat) { } } - public Coin parseToCoin(String input) { - return parseToCoin(input, coinFormat); - } - - public Coin parseToCoin(String input, MonetaryFormat coinFormat) { - if (input != null && input.length() > 0) { - try { - return coinFormat.parse(cleanDoubleInput(input)); - } catch (Throwable t) { - log.warn("Exception at parseToBtc: " + t.toString()); - return Coin.ZERO; - } - } else { - return Coin.ZERO; - } - } - - /////////////////////////////////////////////////////////////////////////////////////////// // FIAT /////////////////////////////////////////////////////////////////////////////////////////// @@ -194,10 +178,10 @@ public static String formatFiat(Fiat fiat, MonetaryFormat format, boolean append } } - protected static Fiat parseToFiat(String input, String currencyCode) { + private static Fiat parseToFiat(String input, String currencyCode) { if (input != null && input.length() > 0) { try { - return Fiat.parseFiat(currencyCode, cleanDoubleInput(input)); + return Fiat.parseFiat(currencyCode, ParsingUtils.cleanDoubleInput(input)); } catch (Exception e) { log.warn("Exception at parseToFiat: " + e.toString()); return Fiat.valueOf(currencyCode, 0); @@ -220,7 +204,7 @@ protected static Fiat parseToFiat(String input, String currencyCode) { public static Fiat parseToFiatWithPrecision(String input, String currencyCode) { if (input != null && input.length() > 0) { try { - return parseToFiat(new BigDecimal(cleanDoubleInput(input)).setScale(2, BigDecimal.ROUND_HALF_UP).toString(), + return parseToFiat(new BigDecimal(ParsingUtils.cleanDoubleInput(input)).setScale(2, BigDecimal.ROUND_HALF_UP).toString(), currencyCode); } catch (Throwable t) { log.warn("Exception at parseToFiatWithPrecision: " + t.toString()); @@ -387,60 +371,6 @@ public static String formatToPercent(double value) { return decimalFormat.format(MathUtils.roundDouble(value * 100.0, 2)).replace(",", "."); } - public static double parseNumberStringToDouble(String input) throws NumberFormatException { - return Double.parseDouble(cleanDoubleInput(input)); - } - - public static double parsePercentStringToDouble(String percentString) throws NumberFormatException { - String input = percentString.replace("%", ""); - input = cleanDoubleInput(input); - double value = Double.parseDouble(input); - return MathUtils.roundDouble(value / 100d, 4); - } - - public static long parsePriceStringToLong(BSFormatter bsFormatter, - String currencyCode, - String amount, - int precision) { - if (amount == null || amount.isEmpty()) - return 0; - - long value = 0; - try { - double amountValue = Double.parseDouble(amount); - amount = BSFormatter.formatRoundedDoubleWithPrecision(amountValue, precision); - value = Price.parse(currencyCode, amount).getValue(); - } catch (NumberFormatException ignore) { - // expected NumberFormatException if input is not a number - } catch (Throwable t) { - log.error("parsePriceStringToLong: " + t.toString()); - } - - return value; - } - - public static String convertCharsForNumber(String input) { - // Some languages like finnish use the long dash for the minus - input = input.replace("−", "-"); - input = StringUtils.deleteWhitespace(input); - return input.replace(",", "."); - } - - public static String cleanDoubleInput(String input) { - input = convertCharsForNumber(input); - if (input.equals(".")) - input = input.replace(".", "0."); - if (input.equals("-.")) - input = input.replace("-.", "-0."); - // don't use String.valueOf(Double.parseDouble(input)) as return value as it gives scientific - // notation (1.0E-6) which screw up coinFormat.parse - //noinspection ResultOfMethodCallIgnored - // Just called to check if we have a valid double, throws exception otherwise - //noinspection ResultOfMethodCallIgnored - Double.parseDouble(input); - return input; - } - public static String formatDurationAsWords(long durationMillis) { return formatDurationAsWords(durationMillis, false, true); } diff --git a/core/src/main/java/bisq/core/util/BsqFormatter.java b/core/src/main/java/bisq/core/util/BsqFormatter.java index 7f2524598e0..8dd90644434 100644 --- a/core/src/main/java/bisq/core/util/BsqFormatter.java +++ b/core/src/main/java/bisq/core/util/BsqFormatter.java @@ -61,12 +61,12 @@ public BsqFormatter() { GlobalSettings.localeProperty().addListener((observable, oldValue, newValue) -> setFormatter(newValue)); setFormatter(GlobalSettings.getLocale()); - btcCoinFormat = super.coinFormat; + btcCoinFormat = super.monetaryFormat; final String baseCurrencyCode = BisqEnvironment.getBaseCurrencyNetwork().getCurrencyCode(); switch (baseCurrencyCode) { case "BTC": - coinFormat = new MonetaryFormat().shift(6).code(6, "BSQ").minDecimals(2); + monetaryFormat = new MonetaryFormat().shift(6).code(6, "BSQ").minDecimals(2); break; default: throw new RuntimeException("baseCurrencyCode not defined. baseCurrencyCode=" + baseCurrencyCode); @@ -123,11 +123,11 @@ public String formatMarketCap(MarketPrice bsqPriceMarketPrice, MarketPrice fiatM } public String formatBSQSatoshis(long satoshi) { - return super.formatCoin(satoshi, coinFormat); + return super.formatCoin(satoshi, monetaryFormat); } public String formatBSQSatoshisWithCode(long satoshi) { - return super.formatCoinWithCode(satoshi, coinFormat); + return super.formatCoinWithCode(satoshi, monetaryFormat); } public String formatBTCSatoshis(long satoshi) { @@ -147,7 +147,7 @@ public String formatBTC(Coin coin) { } public Coin parseToBTC(String input) { - return super.parseToCoin(input, btcCoinFormat); + return ParsingUtils.parseToCoin(input, btcCoinFormat); } public void validateBtcInput(String input) throws ProposalValidationException { @@ -155,12 +155,12 @@ public void validateBtcInput(String input) throws ProposalValidationException { } public void validateBsqInput(String input) throws ProposalValidationException { - validateCoinInput(input, this.coinFormat); + validateCoinInput(input, this.monetaryFormat); } private void validateCoinInput(String input, MonetaryFormat coinFormat) throws ProposalValidationException { try { - coinFormat.parse(cleanDoubleInput(input)); + coinFormat.parse(ParsingUtils.cleanDoubleInput(input)); } catch (Throwable t) { throw new ProposalValidationException("Invalid format for a " + coinFormat.code() + " value"); } @@ -172,11 +172,11 @@ public String formatParamValue(Param param, String value) { // In case we add a new param old clients will not know that enum and fall back to UNDEFINED. return Res.get("shared.na"); case BSQ: - return formatCoinWithCode(parseToCoin(value)); + return formatCoinWithCode(ParsingUtils.parseToCoin(value, this)); case BTC: return formatBTCWithCode(parseToBTC(value)); case PERCENT: - return formatToPercentWithSymbol(parsePercentStringToDouble(value)); + return formatToPercentWithSymbol(ParsingUtils.parsePercentStringToDouble(value)); case BLOCK: return Res.get("dao.param.blocks", Integer.parseInt(value)); case ADDRESS: @@ -190,7 +190,7 @@ public String formatParamValue(Param param, String value) { public Coin parseParamValueToCoin(Param param, String inputValue) { switch (param.getParamType()) { case BSQ: - return parseToCoin(inputValue); + return ParsingUtils.parseToCoin(inputValue, this); case BTC: return parseToBTC(inputValue); default: @@ -216,7 +216,7 @@ public String parseParamValueToString(Param param, String inputValue) throws Pro case BTC: return formatBTC(parseParamValueToCoin(param, inputValue)); case PERCENT: - return formatToPercent(parsePercentStringToDouble(inputValue)); + return formatToPercent(ParsingUtils.parsePercentStringToDouble(inputValue)); case BLOCK: return Integer.toString(parseParamValueToBlocks(param, inputValue)); case ADDRESS: diff --git a/core/src/main/java/bisq/core/util/ParsingUtils.java b/core/src/main/java/bisq/core/util/ParsingUtils.java new file mode 100644 index 00000000000..c63e5bf138f --- /dev/null +++ b/core/src/main/java/bisq/core/util/ParsingUtils.java @@ -0,0 +1,83 @@ +package bisq.core.util; + +import bisq.core.monetary.Price; + +import bisq.common.util.MathUtils; + +import org.bitcoinj.core.Coin; +import org.bitcoinj.utils.MonetaryFormat; + +import org.apache.commons.lang3.StringUtils; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class ParsingUtils { + public static Coin parseToCoin(String input, BSFormatter bsFormatter) { + return parseToCoin(input, bsFormatter.getMonetaryFormat()); + } + + public static Coin parseToCoin(String input, MonetaryFormat coinFormat) { + if (input != null && input.length() > 0) { + try { + return coinFormat.parse(cleanDoubleInput(input)); + } catch (Throwable t) { + log.warn("Exception at parseToBtc: " + t.toString()); + return Coin.ZERO; + } + } else { + return Coin.ZERO; + } + } + + public static double parseNumberStringToDouble(String input) throws NumberFormatException { + return Double.parseDouble(cleanDoubleInput(input)); + } + + public static double parsePercentStringToDouble(String percentString) throws NumberFormatException { + String input = percentString.replace("%", ""); + input = cleanDoubleInput(input); + double value = Double.parseDouble(input); + return MathUtils.roundDouble(value / 100d, 4); + } + + public static long parsePriceStringToLong(String currencyCode, String amount, int precision) { + if (amount == null || amount.isEmpty()) + return 0; + + long value = 0; + try { + double amountValue = Double.parseDouble(amount); + amount = BSFormatter.formatRoundedDoubleWithPrecision(amountValue, precision); + value = Price.parse(currencyCode, amount).getValue(); + } catch (NumberFormatException ignore) { + // expected NumberFormatException if input is not a number + } catch (Throwable t) { + log.error("parsePriceStringToLong: " + t.toString()); + } + + return value; + } + + public static String convertCharsForNumber(String input) { + // Some languages like finnish use the long dash for the minus + input = input.replace("−", "-"); + input = StringUtils.deleteWhitespace(input); + return input.replace(",", "."); + } + + public static String cleanDoubleInput(String input) { + input = convertCharsForNumber(input); + if (input.equals(".")) + input = input.replace(".", "0."); + if (input.equals("-.")) + input = input.replace("-.", "-0."); + // don't use String.valueOf(Double.parseDouble(input)) as return value as it gives scientific + // notation (1.0E-6) which screw up coinFormat.parse + //noinspection ResultOfMethodCallIgnored + // Just called to check if we have a valid double, throws exception otherwise + //noinspection ResultOfMethodCallIgnored + Double.parseDouble(input); + return input; + } +} diff --git a/desktop/src/main/java/bisq/desktop/main/account/content/notifications/MobileNotificationsView.java b/desktop/src/main/java/bisq/desktop/main/account/content/notifications/MobileNotificationsView.java index e2da49d0e0f..a311d6f5d3c 100644 --- a/desktop/src/main/java/bisq/desktop/main/account/content/notifications/MobileNotificationsView.java +++ b/desktop/src/main/java/bisq/desktop/main/account/content/notifications/MobileNotificationsView.java @@ -48,6 +48,7 @@ import bisq.core.user.Preferences; import bisq.core.user.User; import bisq.core.util.BSFormatter; +import bisq.core.util.ParsingUtils; import bisq.core.util.validation.InputValidator; import bisq.common.UserThread; @@ -347,7 +348,7 @@ private void onPaymentAccountSelected() { private void onAddMarketAlert() { PaymentAccount paymentAccount = paymentAccountsComboBox.getSelectionModel().getSelectedItem(); - double percentAsDouble = BSFormatter.parsePercentStringToDouble(marketAlertTriggerInputTextField.getText()); + double percentAsDouble = ParsingUtils.parsePercentStringToDouble(marketAlertTriggerInputTextField.getText()); int triggerValue = (int) Math.round(percentAsDouble * 10000); boolean isBuyOffer = offerTypeRadioButtonsToggleGroup.getSelectedToggle() == buyOffersRadioButton; MarketAlertFilter marketAlertFilter = new MarketAlertFilter(paymentAccount, triggerValue, isBuyOffer); @@ -510,7 +511,7 @@ public PaymentAccount fromString(String string) { marketAlertTriggerFocusListener = (observable, oldValue, newValue) -> { if (oldValue && !newValue) { try { - double percentAsDouble = BSFormatter.parsePercentStringToDouble(marketAlertTriggerInputTextField.getText()) * 100; + double percentAsDouble = ParsingUtils.parsePercentStringToDouble(marketAlertTriggerInputTextField.getText()) * 100; marketAlertTriggerInputTextField.setText(BSFormatter.formatRoundedDoubleWithPrecision(percentAsDouble, 2) + "%"); } catch (Throwable ignore) { } @@ -747,7 +748,7 @@ private long getPriceAsLong(InputTextField inputTextField) { try { String inputValue = inputTextField.getText(); if (inputValue != null && !inputValue.isEmpty() && selectedPriceAlertTradeCurrency != null) { - double priceAsDouble = BSFormatter.parseNumberStringToDouble(inputValue); + double priceAsDouble = ParsingUtils.parseNumberStringToDouble(inputValue); String currencyCode = selectedPriceAlertTradeCurrency; int precision = CurrencyUtil.isCryptoCurrency(currencyCode) ? Altcoin.SMALLEST_UNIT_EXPONENT : 2; @@ -755,7 +756,7 @@ private long getPriceAsLong(InputTextField inputTextField) { // E.g. if input is 5555.5555 it will be rounded to 5555.55 and we use that as the value for comparing // low and high price... String stringValue = BSFormatter.formatRoundedDoubleWithPrecision(priceAsDouble, precision); - return BSFormatter.parsePriceStringToLong(formatter, currencyCode, stringValue, precision); + return ParsingUtils.parsePriceStringToLong(currencyCode, stringValue, precision); } else { return 0; } @@ -768,7 +769,7 @@ private void applyPriceFormatting(InputTextField inputTextField) { try { String inputValue = inputTextField.getText(); if (inputValue != null && !inputValue.isEmpty() && selectedPriceAlertTradeCurrency != null) { - double priceAsDouble = BSFormatter.parseNumberStringToDouble(inputValue); + double priceAsDouble = ParsingUtils.parseNumberStringToDouble(inputValue); String currencyCode = selectedPriceAlertTradeCurrency; int precision = CurrencyUtil.isCryptoCurrency(currencyCode) ? Altcoin.SMALLEST_UNIT_EXPONENT : 2; diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyReputationView.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyReputationView.java index db30a5569fe..a4d84749dea 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyReputationView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyReputationView.java @@ -38,6 +38,7 @@ import bisq.core.locale.Res; import bisq.core.user.Preferences; import bisq.core.util.BsqFormatter; +import bisq.core.util.ParsingUtils; import bisq.core.util.validation.HexStringValidator; import bisq.core.util.validation.IntegerValidator; @@ -170,7 +171,7 @@ protected void activate() { bsqWalletService.addBsqBalanceListener(this); lockupButton.setOnAction((event) -> { - Coin lockupAmount = bsqFormatter.parseToCoin(amountInputTextField.getText()); + Coin lockupAmount = ParsingUtils.parseToCoin(amountInputTextField.getText(), bsqFormatter); int lockupTime = Integer.parseInt(timeInputTextField.getText()); byte[] salt = Utilities.decodeFromHex(saltInputTextField.getText()); bondingViewUtils.lockupBondForReputation(lockupAmount, diff --git a/desktop/src/main/java/bisq/desktop/main/dao/burnbsq/assetfee/AssetFeeView.java b/desktop/src/main/java/bisq/desktop/main/dao/burnbsq/assetfee/AssetFeeView.java index 6a843bb842f..5988bf6f28e 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/burnbsq/assetfee/AssetFeeView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/burnbsq/assetfee/AssetFeeView.java @@ -36,6 +36,7 @@ import bisq.core.locale.Res; import bisq.core.util.BSFormatter; import bisq.core.util.BsqFormatter; +import bisq.core.util.ParsingUtils; import bisq.common.app.DevEnv; @@ -273,7 +274,7 @@ private void updateButtonState() { } private Coin getListingFee() { - return bsqFormatter.parseToCoin(feeAmountInputTextField.getText()); + return ParsingUtils.parseToCoin(feeAmountInputTextField.getText(), bsqFormatter); } private void doPublishFeeTx(Transaction transaction) { diff --git a/desktop/src/main/java/bisq/desktop/main/dao/burnbsq/proofofburn/ProofOfBurnView.java b/desktop/src/main/java/bisq/desktop/main/dao/burnbsq/proofofburn/ProofOfBurnView.java index 1c82da633f7..7ac3097ce24 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/burnbsq/proofofburn/ProofOfBurnView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/burnbsq/proofofburn/ProofOfBurnView.java @@ -38,6 +38,7 @@ import bisq.core.user.Preferences; import bisq.core.util.BSFormatter; import bisq.core.util.BsqFormatter; +import bisq.core.util.ParsingUtils; import bisq.core.util.validation.InputValidator; import bisq.common.app.DevEnv; @@ -273,7 +274,7 @@ private void updateButtonState() { } private Coin getAmountFee() { - return bsqFormatter.parseToCoin(amountInputTextField.getText()); + return ParsingUtils.parseToCoin(amountInputTextField.getText(), bsqFormatter); } private void doPublishFeeTx(Transaction transaction, String preImageAsString) { diff --git a/desktop/src/main/java/bisq/desktop/main/dao/governance/make/MakeProposalView.java b/desktop/src/main/java/bisq/desktop/main/dao/governance/make/MakeProposalView.java index 4219d86c406..7b9c513d2dc 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/governance/make/MakeProposalView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/governance/make/MakeProposalView.java @@ -52,6 +52,7 @@ import bisq.core.locale.Res; import bisq.core.util.BSFormatter; import bisq.core.util.BsqFormatter; +import bisq.core.util.ParsingUtils; import bisq.asset.Asset; @@ -395,13 +396,13 @@ private ProposalWithTransaction getProposalWithTransaction(ProposalType proposal "proposalDisplay.requestedBsqTextField must not be null"); return daoFacade.getCompensationProposalWithTransaction(name, link, - bsqFormatter.parseToCoin(proposalDisplay.requestedBsqTextField.getText())); + ParsingUtils.parseToCoin(proposalDisplay.requestedBsqTextField.getText(), bsqFormatter)); case REIMBURSEMENT_REQUEST: checkNotNull(proposalDisplay.requestedBsqTextField, "proposalDisplay.requestedBsqTextField must not be null"); return daoFacade.getReimbursementProposalWithTransaction(name, link, - bsqFormatter.parseToCoin(proposalDisplay.requestedBsqTextField.getText())); + ParsingUtils.parseToCoin(proposalDisplay.requestedBsqTextField.getText(), bsqFormatter)); case CHANGE_PARAM: checkNotNull(proposalDisplay.paramComboBox, "proposalDisplay.paramComboBox must no tbe null"); diff --git a/desktop/src/main/java/bisq/desktop/main/dao/governance/proposals/ProposalsView.java b/desktop/src/main/java/bisq/desktop/main/dao/governance/proposals/ProposalsView.java index d5d28609e59..1023e79e778 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/governance/proposals/ProposalsView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/governance/proposals/ProposalsView.java @@ -55,6 +55,7 @@ import bisq.core.user.Preferences; import bisq.core.util.BSFormatter; import bisq.core.util.BsqFormatter; +import bisq.core.util.ParsingUtils; import bisq.common.UserThread; import bisq.common.app.DevEnv; @@ -463,7 +464,7 @@ private void showHowToSetStakeForVotingPopup() { } private void onVote() { - Coin stake = bsqFormatter.parseToCoin(stakeInputTextField.getText()); + Coin stake = ParsingUtils.parseToCoin(stakeInputTextField.getText(), bsqFormatter); try { // We create a dummy tx to get the miningFee for displaying it at the confirmation popup Tuple2 miningFeeAndTxSize = daoFacade.getBlindVoteMiningFeeAndTxSize(stake); diff --git a/desktop/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java b/desktop/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java index 24de472f155..7ba3c38e197 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java @@ -47,6 +47,7 @@ import bisq.core.util.BSFormatter; import bisq.core.util.BsqFormatter; import bisq.core.util.CoinUtil; +import bisq.core.util.ParsingUtils; import bisq.core.util.validation.BtcAddressValidator; import bisq.network.p2p.P2PService; @@ -234,7 +235,7 @@ private void addSendBsqGroup() { // TODO break up in methods if (GUIUtil.isReadyForTxBroadcast(p2PService, walletsSetup)) { String receiversAddressString = bsqFormatter.getAddressFromBsqAddress(receiversAddressInputTextField.getText()).toString(); - Coin receiverAmount = bsqFormatter.parseToCoin(amountInputTextField.getText()); + Coin receiverAmount = ParsingUtils.parseToCoin(amountInputTextField.getText(), bsqFormatter); try { Transaction preparedSendTx = bsqWalletService.getPreparedSendBsqTx(receiversAddressString, receiverAmount); Transaction txWithBtcFee = btcWalletService.completePreparedSendBsqTx(preparedSendTx, true); diff --git a/desktop/src/main/java/bisq/desktop/main/funds/deposit/DepositView.java b/desktop/src/main/java/bisq/desktop/main/funds/deposit/DepositView.java index 0cf2230120b..6d80df920ec 100644 --- a/desktop/src/main/java/bisq/desktop/main/funds/deposit/DepositView.java +++ b/desktop/src/main/java/bisq/desktop/main/funds/deposit/DepositView.java @@ -36,6 +36,7 @@ import bisq.core.provider.fee.FeeService; import bisq.core.user.Preferences; import bisq.core.util.BSFormatter; +import bisq.core.util.ParsingUtils; import bisq.common.UserThread; import bisq.common.app.DevEnv; @@ -232,7 +233,7 @@ protected void activate() { walletService.addBalanceListener(balanceListener); amountTextFieldSubscription = EasyBind.subscribe(amountTextField.textProperty(), t -> { - addressTextField.setAmountAsCoin(formatter.parseToCoin(t)); + addressTextField.setAmountAsCoin(ParsingUtils.parseToCoin(t, formatter)); updateQRCode(); }); @@ -301,7 +302,7 @@ private void updateList() { } private Coin getAmountAsCoin() { - return formatter.parseToCoin(amountTextField.getText()); + return ParsingUtils.parseToCoin(amountTextField.getText(), formatter); } @NotNull diff --git a/desktop/src/main/java/bisq/desktop/main/funds/withdrawal/WithdrawalView.java b/desktop/src/main/java/bisq/desktop/main/funds/withdrawal/WithdrawalView.java index f3565535d0a..02e0e595966 100644 --- a/desktop/src/main/java/bisq/desktop/main/funds/withdrawal/WithdrawalView.java +++ b/desktop/src/main/java/bisq/desktop/main/funds/withdrawal/WithdrawalView.java @@ -41,6 +41,7 @@ import bisq.core.user.Preferences; import bisq.core.util.BSFormatter; import bisq.core.util.CoinUtil; +import bisq.core.util.ParsingUtils; import bisq.core.util.validation.BtcAddressValidator; import bisq.network.p2p.P2PService; @@ -246,7 +247,7 @@ public void onBalanceChanged(Coin balance, Transaction tx) { amountListener = (observable, oldValue, newValue) -> { if (amountTextField.focusedProperty().get()) { try { - amountAsCoin = formatter.parseToCoin(amountTextField.getText()); + amountAsCoin = ParsingUtils.parseToCoin(amountTextField.getText(), formatter); } catch (Throwable t) { log.error("Error at amountTextField input. " + t.toString()); } diff --git a/desktop/src/main/java/bisq/desktop/main/offer/MutableOfferViewModel.java b/desktop/src/main/java/bisq/desktop/main/offer/MutableOfferViewModel.java index 660220ea35d..70f972af3a4 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/MutableOfferViewModel.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/MutableOfferViewModel.java @@ -53,6 +53,7 @@ import bisq.core.user.Preferences; import bisq.core.util.BSFormatter; import bisq.core.util.BsqFormatter; +import bisq.core.util.ParsingUtils; import bisq.core.util.validation.InputValidator; import bisq.network.p2p.P2PService; @@ -316,7 +317,7 @@ private void createListeners() { if (marketPrice != null && marketPrice.isRecentExternalPriceAvailable()) { double marketPriceAsDouble = marketPrice.getPrice(); try { - double priceAsDouble = BSFormatter.parseNumberStringToDouble(price.get()); + double priceAsDouble = ParsingUtils.parseNumberStringToDouble(price.get()); double relation = priceAsDouble / marketPriceAsDouble; final OfferPayload.Direction compareDirection = CurrencyUtil.isCryptoCurrency(currencyCode) ? OfferPayload.Direction.SELL : @@ -342,7 +343,7 @@ private void createListeners() { if (inputIsMarketBasedPrice) { try { if (!newValue.isEmpty() && !newValue.equals("-")) { - double percentage = BSFormatter.parsePercentStringToDouble(newValue); + double percentage = ParsingUtils.parsePercentStringToDouble(newValue); if (percentage >= 1 || percentage <= -1) { new Popup<>().warning(Res.get("popup.warning.tooLargePercentageValue") + "\n" + Res.get("popup.warning.examplePercentageValue")) @@ -866,7 +867,7 @@ void onFocusOutBuyerSecurityDepositTextField(boolean oldValue, boolean newValue) if (result.isValid) { double defaultSecurityDeposit = Restrictions.getDefaultBuyerSecurityDepositAsPercent(getPaymentAccount()); String key = "buyerSecurityDepositIsLowerAsDefault"; - double depositAsDouble = BSFormatter.parsePercentStringToDouble(buyerSecurityDeposit.get()); + double depositAsDouble = ParsingUtils.parsePercentStringToDouble(buyerSecurityDeposit.get()); if (preferences.showAgain(key) && depositAsDouble < defaultSecurityDeposit) { String postfix = dataModel.isBuyOffer() ? Res.get("createOffer.tooLowSecDeposit.makerIsBuyer") : @@ -906,7 +907,7 @@ private void applyBuyerSecurityDepositOnFocusOut() { public boolean isPriceInRange() { if (marketPriceMargin.get() != null && !marketPriceMargin.get().isEmpty()) { - if (Math.abs(BSFormatter.parsePercentStringToDouble(marketPriceMargin.get())) > preferences.getMaxPriceDistanceInPercent()) { + if (Math.abs(ParsingUtils.parsePercentStringToDouble(marketPriceMargin.get())) > preferences.getMaxPriceDistanceInPercent()) { displayPriceOutOfRangePopup(); return false; } else { @@ -1130,7 +1131,7 @@ private void setVolumeToModel() { private void setBuyerSecurityDepositToModel() { if (buyerSecurityDeposit.get() != null && !buyerSecurityDeposit.get().isEmpty()) { - dataModel.setBuyerSecurityDeposit(BSFormatter.parsePercentStringToDouble(buyerSecurityDeposit.get())); + dataModel.setBuyerSecurityDeposit(ParsingUtils.parsePercentStringToDouble(buyerSecurityDeposit.get())); } else { dataModel.setBuyerSecurityDeposit(Restrictions.getDefaultBuyerSecurityDepositAsPercent(getPaymentAccount())); } diff --git a/desktop/src/main/java/bisq/desktop/main/overlays/windows/DisputeSummaryWindow.java b/desktop/src/main/java/bisq/desktop/main/overlays/windows/DisputeSummaryWindow.java index 09cab0c8301..af8d6cf43df 100644 --- a/desktop/src/main/java/bisq/desktop/main/overlays/windows/DisputeSummaryWindow.java +++ b/desktop/src/main/java/bisq/desktop/main/overlays/windows/DisputeSummaryWindow.java @@ -37,6 +37,7 @@ import bisq.core.offer.Offer; import bisq.core.trade.Contract; import bisq.core.util.BSFormatter; +import bisq.core.util.ParsingUtils; import bisq.common.UserThread; import bisq.common.util.Tuple2; @@ -357,8 +358,8 @@ private void removePayoutAmountListeners() { } private boolean isPayoutAmountValid() { - Coin buyerAmount = formatter.parseToCoin(buyerPayoutAmountInputTextField.getText()); - Coin sellerAmount = formatter.parseToCoin(sellerPayoutAmountInputTextField.getText()); + Coin buyerAmount = ParsingUtils.parseToCoin(buyerPayoutAmountInputTextField.getText(), formatter); + Coin sellerAmount = ParsingUtils.parseToCoin(sellerPayoutAmountInputTextField.getText(), formatter); Contract contract = dispute.getContract(); Coin tradeAmount = contract.getTradeAmount(); Offer offer = new Offer(contract.getOfferPayload()); @@ -371,8 +372,8 @@ private boolean isPayoutAmountValid() { private void applyCustomAmounts(InputTextField inputTextField) { Contract contract = dispute.getContract(); - Coin buyerAmount = formatter.parseToCoin(buyerPayoutAmountInputTextField.getText()); - Coin sellerAmount = formatter.parseToCoin(sellerPayoutAmountInputTextField.getText()); + Coin buyerAmount = ParsingUtils.parseToCoin(buyerPayoutAmountInputTextField.getText(), formatter); + Coin sellerAmount = ParsingUtils.parseToCoin(sellerPayoutAmountInputTextField.getText(), formatter); Offer offer = new Offer(contract.getOfferPayload()); Coin available = contract.getTradeAmount(). add(offer.getBuyerSecurityDeposit()) diff --git a/desktop/src/main/java/bisq/desktop/main/settings/preferences/PreferencesView.java b/desktop/src/main/java/bisq/desktop/main/settings/preferences/PreferencesView.java index b04e8562235..8da003572d5 100644 --- a/desktop/src/main/java/bisq/desktop/main/settings/preferences/PreferencesView.java +++ b/desktop/src/main/java/bisq/desktop/main/settings/preferences/PreferencesView.java @@ -47,6 +47,7 @@ import bisq.core.user.BlockChainExplorer; import bisq.core.user.Preferences; import bisq.core.util.BSFormatter; +import bisq.core.util.ParsingUtils; import bisq.core.util.validation.IntegerValidator; import bisq.common.UserThread; @@ -314,7 +315,7 @@ public BaseCurrencyNetwork fromString(String string) { deviationListener = (observable, oldValue, newValue) -> { try { - double value = BSFormatter.parsePercentStringToDouble(newValue); + double value = ParsingUtils.parsePercentStringToDouble(newValue); final double maxDeviation = 0.5; if (value <= maxDeviation) { preferences.setMaxPriceDistanceInPercent(value); diff --git a/desktop/src/main/java/bisq/desktop/util/DisplayUtils.java b/desktop/src/main/java/bisq/desktop/util/DisplayUtils.java index 184e8b41431..7a1f1f8721a 100644 --- a/desktop/src/main/java/bisq/desktop/util/DisplayUtils.java +++ b/desktop/src/main/java/bisq/desktop/util/DisplayUtils.java @@ -9,6 +9,7 @@ import bisq.core.offer.Offer; import bisq.core.offer.OfferPayload; import bisq.core.util.BSFormatter; +import bisq.core.util.ParsingUtils; import org.bitcoinj.core.Coin; import org.bitcoinj.core.Monetary; @@ -265,7 +266,7 @@ public static String getFeeWithFiatAmount(Coin makerFeeAsCoin, */ public static Coin parseToCoinWith4Decimals(String input, BSFormatter bsFormatter) { try { - return Coin.valueOf(new BigDecimal(bsFormatter.parseToCoin(BSFormatter.cleanDoubleInput(input)).value).setScale(-scale - 1, + return Coin.valueOf(new BigDecimal(ParsingUtils.parseToCoin(ParsingUtils.cleanDoubleInput(input), bsFormatter).value).setScale(-scale - 1, BigDecimal.ROUND_HALF_UP).setScale(scale + 1, BigDecimal.ROUND_HALF_UP).toBigInteger().longValue()); } catch (Throwable t) { if (input != null && input.length() > 0) @@ -275,7 +276,7 @@ public static Coin parseToCoinWith4Decimals(String input, BSFormatter bsFormatte } public static boolean hasBtcValidDecimals(String input, BSFormatter bsFormatter) { - return bsFormatter.parseToCoin(input).equals(parseToCoinWith4Decimals(input, bsFormatter)); + return ParsingUtils.parseToCoin(input, bsFormatter).equals(parseToCoinWith4Decimals(input, bsFormatter)); } /** @@ -286,6 +287,6 @@ public static boolean hasBtcValidDecimals(String input, BSFormatter bsFormatter) * @return The transformed coin */ public static Coin reduceTo4Decimals(Coin coin, BSFormatter bsFormatter) { - return bsFormatter.parseToCoin(bsFormatter.formatCoin(coin)); + return ParsingUtils.parseToCoin(bsFormatter.formatCoin(coin), bsFormatter); } } diff --git a/desktop/src/main/java/bisq/desktop/util/validation/BsqValidator.java b/desktop/src/main/java/bisq/desktop/util/validation/BsqValidator.java index 4749354771d..0ab87710ae4 100644 --- a/desktop/src/main/java/bisq/desktop/util/validation/BsqValidator.java +++ b/desktop/src/main/java/bisq/desktop/util/validation/BsqValidator.java @@ -21,6 +21,7 @@ import bisq.core.locale.Res; import bisq.core.util.BsqFormatter; import bisq.core.util.CoinUtil; +import bisq.core.util.ParsingUtils; import org.bitcoinj.core.Coin; @@ -53,7 +54,7 @@ protected double getMinValue() { public BsqValidator(BsqFormatter bsqFormatter) { this.bsqFormatter = bsqFormatter; // Limit to avoid overflows - setMaxValue(bsqFormatter.parseToCoin("10000000")); + setMaxValue(ParsingUtils.parseToCoin("10000000", bsqFormatter)); } public void setMinValue(@NotNull Coin minValue) { @@ -94,7 +95,7 @@ public ValidationResult validate(String input) { } private ValidationResult validateIfAboveDust(String input) { - final Coin coin = bsqFormatter.parseToCoin(input); + final Coin coin = ParsingUtils.parseToCoin(input, bsqFormatter); if (Restrictions.isAboveDust(coin)) return new ValidationResult(true); else @@ -113,7 +114,7 @@ private ValidationResult validateIfNotFractionalBtcValue(String input) { private ValidationResult validateIfNotExceedsMaxBtcValue(String input) { try { - final Coin coin = bsqFormatter.parseToCoin(input); + final Coin coin = ParsingUtils.parseToCoin(input, bsqFormatter); if (maxValue != null && coin.compareTo(maxValue) > 0) return new ValidationResult(false, Res.get("validation.btc.toLarge", bsqFormatter.formatCoinWithCode(maxValue))); else @@ -125,7 +126,7 @@ private ValidationResult validateIfNotExceedsMaxBtcValue(String input) { private ValidationResult validateIfSufficientAvailableBalance(String input) { try { - final Coin coin = bsqFormatter.parseToCoin(input); + final Coin coin = ParsingUtils.parseToCoin(input, bsqFormatter); if (availableBalance != null && availableBalance.compareTo(coin) < 0) return new ValidationResult(false, Res.get("validation.bsq.insufficientBalance", bsqFormatter.formatCoinWithCode(availableBalance))); @@ -138,7 +139,7 @@ private ValidationResult validateIfSufficientAvailableBalance(String input) { private ValidationResult validateIfNotBelowMinValue(String input) { try { - final Coin coin = bsqFormatter.parseToCoin(input); + final Coin coin = ParsingUtils.parseToCoin(input, bsqFormatter); if (minValue != null && coin.compareTo(minValue) < 0) return new ValidationResult(false, Res.get("validation.bsq.amountBelowMinAmount", bsqFormatter.formatCoinWithCode(minValue))); diff --git a/desktop/src/main/java/bisq/desktop/util/validation/NumberValidator.java b/desktop/src/main/java/bisq/desktop/util/validation/NumberValidator.java index 9a4d5496fa4..1aaa4162fbf 100644 --- a/desktop/src/main/java/bisq/desktop/util/validation/NumberValidator.java +++ b/desktop/src/main/java/bisq/desktop/util/validation/NumberValidator.java @@ -18,7 +18,7 @@ package bisq.desktop.util.validation; import bisq.core.locale.Res; -import bisq.core.util.BSFormatter; +import bisq.core.util.ParsingUtils; import bisq.core.util.validation.InputValidator; /** @@ -30,7 +30,7 @@ public abstract class NumberValidator extends InputValidator { protected String cleanInput(String input) { - return BSFormatter.convertCharsForNumber(input); + return ParsingUtils.convertCharsForNumber(input); } protected ValidationResult validateIfNumber(String input) { diff --git a/desktop/src/main/java/bisq/desktop/util/validation/SecurityDepositValidator.java b/desktop/src/main/java/bisq/desktop/util/validation/SecurityDepositValidator.java index 2b64219bbf4..0abfec1a4ef 100644 --- a/desktop/src/main/java/bisq/desktop/util/validation/SecurityDepositValidator.java +++ b/desktop/src/main/java/bisq/desktop/util/validation/SecurityDepositValidator.java @@ -21,6 +21,7 @@ import bisq.core.locale.Res; import bisq.core.payment.PaymentAccount; import bisq.core.util.BSFormatter; +import bisq.core.util.ParsingUtils; import javax.inject.Inject; @@ -58,7 +59,7 @@ public ValidationResult validate(String input) { private ValidationResult validateIfNotTooLowPercentageValue(String input) { try { - double percentage = BSFormatter.parsePercentStringToDouble(input); + double percentage = ParsingUtils.parsePercentStringToDouble(input); double minPercentage = Restrictions.getMinBuyerSecurityDepositAsPercent(paymentAccount); if (percentage < minPercentage) return new ValidationResult(false, @@ -72,7 +73,7 @@ private ValidationResult validateIfNotTooLowPercentageValue(String input) { private ValidationResult validateIfNotTooHighPercentageValue(String input) { try { - double percentage = BSFormatter.parsePercentStringToDouble(input); + double percentage = ParsingUtils.parsePercentStringToDouble(input); double maxPercentage = Restrictions.getMaxBuyerSecurityDepositAsPercent(paymentAccount); if (percentage > maxPercentage) return new ValidationResult(false,