From 6919552e918b28cc947bb2fdc4e24c1948fd9b47 Mon Sep 17 00:00:00 2001 From: woodser <13068859+woodser@users.noreply.github.com> Date: Sat, 20 Dec 2025 08:10:43 -0500 Subject: [PATCH] remove popup and improve label for empty or invalid offer amount input --- .../java/haveno/core/trade/HavenoUtils.java | 2 +- .../main/offer/MutableOfferViewModel.java | 66 ++++++++++--------- 2 files changed, 36 insertions(+), 32 deletions(-) diff --git a/core/src/main/java/haveno/core/trade/HavenoUtils.java b/core/src/main/java/haveno/core/trade/HavenoUtils.java index 2ec5989919..2acf4950e4 100644 --- a/core/src/main/java/haveno/core/trade/HavenoUtils.java +++ b/core/src/main/java/haveno/core/trade/HavenoUtils.java @@ -321,7 +321,7 @@ public class HavenoUtils { } public static BigInteger parseXmr(String input) { - if (input == null || input.length() == 0) return BigInteger.ZERO; + if (input == null || input.length() == 0) return BigInteger.ZERO; // TODO: throw instead? try { return new BigDecimal(input).multiply(new BigDecimal(XMR_AU_MULTIPLIER)).toBigInteger(); } catch (Exception e) { diff --git a/desktop/src/main/java/haveno/desktop/main/offer/MutableOfferViewModel.java b/desktop/src/main/java/haveno/desktop/main/offer/MutableOfferViewModel.java index 96c083cb73..73ed4f49e0 100644 --- a/desktop/src/main/java/haveno/desktop/main/offer/MutableOfferViewModel.java +++ b/desktop/src/main/java/haveno/desktop/main/offer/MutableOfferViewModel.java @@ -741,38 +741,42 @@ public abstract class MutableOfferViewModel ext if (minAmount.get() != null) minAmountValidationResult.set(isXmrInputValid(minAmount.get())); - } else if (amount.get() != null && xmrValidator.getMaxTradeLimit() != null && xmrValidator.getMaxTradeLimit().longValueExact() == OfferRestrictions.TOLERATED_SMALL_TRADE_AMOUNT.longValueExact()) { - if (ParsingUtils.parseNumberStringToDouble(amount.get()) < HavenoUtils.atomicUnitsToXmr(dataModel.getMinTradeLimit())) { - amountValidationResult.set(result); - } else { - amount.set(HavenoUtils.formatXmr(xmrValidator.getMaxTradeLimit())); - boolean isBuy = dataModel.getDirection() == OfferDirection.BUY; - boolean isSellerWithinReleaseWindow = !isBuy && HavenoUtils.isReleasedWithinDays(HavenoUtils.RELEASE_LIMIT_DAYS); - if (isSellerWithinReleaseWindow) { - - // format release date plus days - Date releaseDate = HavenoUtils.getReleaseDate(); - Calendar c = Calendar.getInstance(); - c.setTime(releaseDate); - c.add(Calendar.DATE, HavenoUtils.RELEASE_LIMIT_DAYS); - Date releaseDatePlusDays = c.getTime(); - SimpleDateFormat formatter = new SimpleDateFormat("MMMM d, yyyy"); - String releaseDatePlusDaysAsString = formatter.format(releaseDatePlusDays); - - // popup temporary restriction - new Popup().information(Res.get("popup.warning.tradeLimitDueAccountAgeRestriction.seller.releaseLimit", - HavenoUtils.formatXmr(OfferRestrictions.TOLERATED_SMALL_TRADE_AMOUNT, true), - releaseDatePlusDaysAsString, - Res.get("offerbook.warning.newVersionAnnouncement"))) - .width(900) - .show(); + } else if (amount.get() != null && !amount.get().isEmpty() && xmrValidator.getMaxTradeLimit() != null && xmrValidator.getMaxTradeLimit().longValueExact() == OfferRestrictions.TOLERATED_SMALL_TRADE_AMOUNT.longValueExact()) { // TODO: tolerated small amount will only equal max trade limit for riskiest payment methods, so that logic is not relevant? + try { + if (ParsingUtils.parseNumberStringToDouble(amount.get()) < HavenoUtils.atomicUnitsToXmr(dataModel.getMinTradeLimit())) { + amountValidationResult.set(result); } else { - new Popup().information(Res.get(isBuy ? "popup.warning.tradeLimitDueAccountAgeRestriction.buyer" : "popup.warning.tradeLimitDueAccountAgeRestriction.seller", - HavenoUtils.formatXmr(OfferRestrictions.TOLERATED_SMALL_TRADE_AMOUNT, true), - Res.get("offerbook.warning.newVersionAnnouncement"))) - .width(900) - .show(); + amount.set(HavenoUtils.formatXmr(xmrValidator.getMaxTradeLimit())); + boolean isBuy = dataModel.getDirection() == OfferDirection.BUY; + boolean isSellerWithinReleaseWindow = !isBuy && HavenoUtils.isReleasedWithinDays(HavenoUtils.RELEASE_LIMIT_DAYS); + if (isSellerWithinReleaseWindow) { + + // format release date plus days + Date releaseDate = HavenoUtils.getReleaseDate(); + Calendar c = Calendar.getInstance(); + c.setTime(releaseDate); + c.add(Calendar.DATE, HavenoUtils.RELEASE_LIMIT_DAYS); + Date releaseDatePlusDays = c.getTime(); + SimpleDateFormat formatter = new SimpleDateFormat("MMMM d, yyyy"); + String releaseDatePlusDaysAsString = formatter.format(releaseDatePlusDays); + + // popup temporary restriction + new Popup().information(Res.get("popup.warning.tradeLimitDueAccountAgeRestriction.seller.releaseLimit", + HavenoUtils.formatXmr(xmrValidator.getMaxTradeLimit(), true), + releaseDatePlusDaysAsString, + Res.get("offerbook.warning.newVersionAnnouncement"))) + .width(900) + .show(); + } else { + new Popup().information(Res.get(isBuy ? "popup.warning.tradeLimitDueAccountAgeRestriction.buyer" : "popup.warning.tradeLimitDueAccountAgeRestriction.seller", + HavenoUtils.formatXmr(xmrValidator.getMaxTradeLimit(), true), + Res.get("offerbook.warning.newVersionAnnouncement"))) + .width(900) + .show(); + } } + } catch (Exception e) { + log.warn("Error while parsing amount on focus out: ", e); } } @@ -1248,7 +1252,7 @@ public abstract class MutableOfferViewModel ext } private InputValidator.ValidationResult isXmrInputValid(String input) { - return xmrValidator.validate("" + HavenoUtils.atomicUnitsToXmr(HavenoUtils.parseXmr(input))); + return xmrValidator.validate(input); } private InputValidator.ValidationResult isPriceInputValid(String input) {