mirror of
https://github.com/bisq-network/bisq.git
synced 2025-02-24 23:18:17 +01:00
Merge pull request #4929 from chimp1984/make-sign-age-column-sortable
Make sign age column sortable
This commit is contained in:
commit
f4df51c213
8 changed files with 159 additions and 69 deletions
|
@ -102,12 +102,12 @@ public class AccountAgeWitnessService {
|
|||
PEER_SIGNER(Res.get("offerbook.timeSinceSigning.info.signer")),
|
||||
BANNED(Res.get("offerbook.timeSinceSigning.info.banned"));
|
||||
|
||||
private String presentation;
|
||||
private String displayString;
|
||||
private String hash = "";
|
||||
private long daysUntilLimitLifted = 0;
|
||||
|
||||
SignState(String presentation) {
|
||||
this.presentation = presentation;
|
||||
SignState(String displayString) {
|
||||
this.displayString = displayString;
|
||||
}
|
||||
|
||||
public SignState addHash(String hash) {
|
||||
|
@ -120,11 +120,11 @@ public class AccountAgeWitnessService {
|
|||
return this;
|
||||
}
|
||||
|
||||
public String getPresentation() {
|
||||
public String getDisplayString() {
|
||||
if (!hash.isEmpty()) { // Only showing in DEBUG mode
|
||||
return presentation + " " + hash;
|
||||
return displayString + " " + hash;
|
||||
}
|
||||
return String.format(presentation, daysUntilLimitLifted);
|
||||
return String.format(displayString, daysUntilLimitLifted);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -265,7 +265,7 @@ public class AccountAgeWitnessService {
|
|||
return getWitnessByHash(hash);
|
||||
}
|
||||
|
||||
private Optional<AccountAgeWitness> findWitness(Offer offer) {
|
||||
public Optional<AccountAgeWitness> findWitness(Offer offer) {
|
||||
final Optional<String> accountAgeWitnessHash = offer.getAccountAgeWitnessHashAsHex();
|
||||
return accountAgeWitnessHash.isPresent() ?
|
||||
getWitnessByHashAsHex(accountAgeWitnessHash.get()) :
|
||||
|
@ -613,7 +613,10 @@ public class AccountAgeWitnessService {
|
|||
if (!result) {
|
||||
String msg = "The peers trade limit is less than the traded amount.\n" +
|
||||
"tradeAmount=" + tradeAmount.toFriendlyString() +
|
||||
"\nPeers trade limit=" + Coin.valueOf(peersCurrentTradeLimit).toFriendlyString();
|
||||
"\nPeers trade limit=" + Coin.valueOf(peersCurrentTradeLimit).toFriendlyString() +
|
||||
"\nOffer ID=" + offer.getShortId() +
|
||||
"\nPaymentMethod=" + offer.getPaymentMethod().getId() +
|
||||
"\nCurrencyCode=" + offer.getCurrencyCode();
|
||||
log.warn(msg);
|
||||
errorMessageHandler.handleErrorMessage(msg);
|
||||
}
|
||||
|
|
|
@ -123,7 +123,7 @@ public class AccountAgeWitnessUtils {
|
|||
|
||||
AccountAgeWitnessService.SignState signState =
|
||||
accountAgeWitnessService.getSignState(accountAgeWitness.get());
|
||||
return signState.name() + " " + signState.getPresentation() +
|
||||
return signState.name() + " " + signState.getDisplayString() +
|
||||
"\n" + accountAgeWitness.toString();
|
||||
}
|
||||
|
||||
|
|
|
@ -279,7 +279,7 @@ public class PeerInfoIcon extends Group {
|
|||
|
||||
if (hasChargebackRisk(trade, offer)) {
|
||||
String signAgeInfo = Res.get("peerInfo.age.chargeBackRisk");
|
||||
String accountSigningState = StringUtils.capitalize(signState.getPresentation());
|
||||
String accountSigningState = StringUtils.capitalize(signState.getDisplayString());
|
||||
if (signState.equals(AccountAgeWitnessService.SignState.UNSIGNED))
|
||||
signAgeInfo = null;
|
||||
|
||||
|
|
|
@ -218,7 +218,7 @@ public abstract class PaymentMethodForm {
|
|||
AccountAgeWitnessService.SignState signState =
|
||||
accountAgeWitnessService.getSignState(myWitness);
|
||||
|
||||
accountSigningStateText = StringUtils.capitalize(signState.getPresentation());
|
||||
accountSigningStateText = StringUtils.capitalize(signState.getDisplayString());
|
||||
|
||||
long daysSinceSigning = TimeUnit.MILLISECONDS.toDays(
|
||||
accountAgeWitnessService.getWitnessSignAge(myWitness, new Date()));
|
||||
|
|
|
@ -9,14 +9,12 @@ import bisq.desktop.main.overlays.popups.Popup;
|
|||
import bisq.desktop.util.GUIUtil;
|
||||
import bisq.desktop.util.ImageUtil;
|
||||
|
||||
import bisq.core.account.sign.SignedWitnessService;
|
||||
import bisq.core.account.witness.AccountAgeWitnessService;
|
||||
import bisq.core.locale.Res;
|
||||
import bisq.core.payment.PaymentAccount;
|
||||
import bisq.core.payment.payload.PaymentMethod;
|
||||
|
||||
import bisq.common.UserThread;
|
||||
import bisq.common.app.DevEnv;
|
||||
import bisq.common.util.Utilities;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
@ -144,7 +142,7 @@ public abstract class PaymentAccountsView<R extends Node, M extends ActivatableW
|
|||
accountAgeWitnessService.getSignState(accountAgeWitnessService.getMyWitness(
|
||||
item.paymentAccountPayload));
|
||||
|
||||
String info = StringUtils.capitalize(signState.getPresentation());
|
||||
String info = StringUtils.capitalize(signState.getDisplayString());
|
||||
label.setIcon(GUIUtil.getIconForSignState(signState), info);
|
||||
} else {
|
||||
label.hideIcon();
|
||||
|
|
|
@ -17,12 +17,140 @@
|
|||
|
||||
package bisq.desktop.main.offer.offerbook;
|
||||
|
||||
import bisq.desktop.util.GUIUtil;
|
||||
|
||||
import bisq.core.account.sign.SignedWitnessService;
|
||||
import bisq.core.account.witness.AccountAgeWitness;
|
||||
import bisq.core.account.witness.AccountAgeWitnessService;
|
||||
import bisq.core.locale.CurrencyUtil;
|
||||
import bisq.core.locale.Res;
|
||||
import bisq.core.offer.Offer;
|
||||
import bisq.core.payment.payload.PaymentMethod;
|
||||
|
||||
import de.jensd.fx.glyphs.GlyphIcons;
|
||||
import de.jensd.fx.glyphs.materialdesignicons.MaterialDesignIcon;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Value;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
|
||||
@Value
|
||||
public class OfferBookListItem {
|
||||
@Getter
|
||||
private final Offer offer;
|
||||
|
||||
// We cache the data once created for performance reasons. AccountAgeWitnessService calls can
|
||||
// be a bit expensive.
|
||||
private WitnessAgeData witnessAgeData;
|
||||
|
||||
public OfferBookListItem(Offer offer) {
|
||||
this.offer = offer;
|
||||
}
|
||||
|
||||
public WitnessAgeData getWitnessAgeData(AccountAgeWitnessService accountAgeWitnessService,
|
||||
SignedWitnessService signedWitnessService) {
|
||||
if (witnessAgeData == null) {
|
||||
long ageInMs;
|
||||
long daysSinceSignedAsLong = -1;
|
||||
long accountAgeDaysAsLong = -1;
|
||||
long accountAgeDaysNotYetSignedAsLong = -1;
|
||||
String displayString;
|
||||
String info;
|
||||
GlyphIcons icon;
|
||||
|
||||
if (CurrencyUtil.isCryptoCurrency(offer.getCurrencyCode())) {
|
||||
// Altcoins
|
||||
displayString = Res.get("offerbook.timeSinceSigning.notSigned.noNeed");
|
||||
info = Res.get("shared.notSigned.noNeedAlts");
|
||||
icon = MaterialDesignIcon.INFORMATION_OUTLINE;
|
||||
} else if (PaymentMethod.hasChargebackRisk(offer.getPaymentMethod(), offer.getCurrencyCode())) {
|
||||
// Fiat and signed witness required
|
||||
Optional<AccountAgeWitness> optionalWitness = accountAgeWitnessService.findWitness(offer);
|
||||
AccountAgeWitnessService.SignState signState = optionalWitness.map(accountAgeWitnessService::getSignState)
|
||||
.orElse(AccountAgeWitnessService.SignState.UNSIGNED);
|
||||
boolean isSignedAccountAgeWitness = optionalWitness.map(signedWitnessService::isSignedAccountAgeWitness)
|
||||
.orElse(false);
|
||||
if (isSignedAccountAgeWitness || !signState.equals(AccountAgeWitnessService.SignState.UNSIGNED)) {
|
||||
// either signed & limits lifted, or waiting for limits to be lifted
|
||||
// Or banned
|
||||
daysSinceSignedAsLong = TimeUnit.MILLISECONDS.toDays(optionalWitness.map(witness ->
|
||||
accountAgeWitnessService.getWitnessSignAge(witness, new Date()))
|
||||
.orElse(0L));
|
||||
displayString = Res.get("offerbook.timeSinceSigning.daysSinceSigning", daysSinceSignedAsLong);
|
||||
info = Res.get("offerbook.timeSinceSigning.info", signState.getDisplayString());
|
||||
} else {
|
||||
// Unsigned case
|
||||
ageInMs = optionalWitness.map(e -> accountAgeWitnessService.getAccountAge(e, new Date()))
|
||||
.orElse(-1L);
|
||||
accountAgeDaysNotYetSignedAsLong = ageInMs > -1 ? TimeUnit.MILLISECONDS.toDays(ageInMs) : 0;
|
||||
displayString = Res.get("offerbook.timeSinceSigning.notSigned");
|
||||
info = Res.get("shared.notSigned", accountAgeDaysNotYetSignedAsLong);
|
||||
}
|
||||
|
||||
icon = GUIUtil.getIconForSignState(signState);
|
||||
} else {
|
||||
// Fiat, no signed witness required, we show account age
|
||||
ageInMs = accountAgeWitnessService.getAccountAge(offer);
|
||||
accountAgeDaysAsLong = ageInMs > -1 ? TimeUnit.MILLISECONDS.toDays(ageInMs) : 0;
|
||||
displayString = Res.get("offerbook.timeSinceSigning.notSigned.ageDays", accountAgeDaysAsLong);
|
||||
info = Res.get("shared.notSigned.noNeedDays", accountAgeDaysAsLong);
|
||||
icon = MaterialDesignIcon.CHECKBOX_MARKED_OUTLINE;
|
||||
}
|
||||
|
||||
witnessAgeData = new WitnessAgeData(displayString, info, icon, daysSinceSignedAsLong, accountAgeDaysNotYetSignedAsLong, accountAgeDaysAsLong);
|
||||
}
|
||||
return witnessAgeData;
|
||||
}
|
||||
|
||||
@Value
|
||||
public static class WitnessAgeData {
|
||||
private final String displayString;
|
||||
private final String info;
|
||||
private final GlyphIcons icon;
|
||||
private final Long daysSinceSignedAsLong;
|
||||
private final long accountAgeDaysNotYetSignedAsLong;
|
||||
private final Long accountAgeDaysAsLong;
|
||||
// Used for sorting
|
||||
private final Long type;
|
||||
// Used for sorting
|
||||
private final Long days;
|
||||
|
||||
public WitnessAgeData(String displayString,
|
||||
String info,
|
||||
GlyphIcons icon,
|
||||
long daysSinceSignedAsLong,
|
||||
long accountAgeDaysNotYetSignedAsLong,
|
||||
long accountAgeDaysAsLong) {
|
||||
this.displayString = displayString;
|
||||
this.info = info;
|
||||
this.icon = icon;
|
||||
this.daysSinceSignedAsLong = daysSinceSignedAsLong;
|
||||
this.accountAgeDaysNotYetSignedAsLong = accountAgeDaysNotYetSignedAsLong;
|
||||
this.accountAgeDaysAsLong = accountAgeDaysAsLong;
|
||||
|
||||
if (daysSinceSignedAsLong > -1) {
|
||||
// First we show signed accounts sorted by days
|
||||
this.type = 3L;
|
||||
this.days = daysSinceSignedAsLong;
|
||||
} else if (accountAgeDaysNotYetSignedAsLong > -1) {
|
||||
// Next group is not yet signed accounts sorted by account age
|
||||
this.type = 2L;
|
||||
this.days = accountAgeDaysNotYetSignedAsLong;
|
||||
} else if (accountAgeDaysAsLong > -1) {
|
||||
// Next group is not signing required accounts sorted by account age
|
||||
this.type = 1L;
|
||||
this.days = accountAgeDaysAsLong;
|
||||
} else {
|
||||
// No signing and age required (altcoins)
|
||||
this.type = 0L;
|
||||
this.days = 0L;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -69,7 +69,6 @@ import javax.inject.Inject;
|
|||
import javax.inject.Named;
|
||||
|
||||
import de.jensd.fx.fontawesome.AwesomeIcon;
|
||||
import de.jensd.fx.glyphs.GlyphIcons;
|
||||
import de.jensd.fx.glyphs.materialdesignicons.MaterialDesignIcon;
|
||||
|
||||
import javafx.scene.canvas.Canvas;
|
||||
|
@ -107,9 +106,7 @@ import javafx.util.Callback;
|
|||
import javafx.util.StringConverter;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
@ -124,6 +121,7 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi
|
|||
private final PrivateNotificationManager privateNotificationManager;
|
||||
private final boolean useDevPrivilegeKeys;
|
||||
private final AccountAgeWitnessService accountAgeWitnessService;
|
||||
private final SignedWitnessService signedWitnessService;
|
||||
|
||||
private AutocompleteComboBox<TradeCurrency> currencyComboBox;
|
||||
private AutocompleteComboBox<PaymentMethod> paymentMethodComboBox;
|
||||
|
@ -151,7 +149,8 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi
|
|||
@Named(FormattingUtils.BTC_FORMATTER_KEY) CoinFormatter formatter,
|
||||
PrivateNotificationManager privateNotificationManager,
|
||||
@Named(Config.USE_DEV_PRIVILEGE_KEYS) boolean useDevPrivilegeKeys,
|
||||
AccountAgeWitnessService accountAgeWitnessService) {
|
||||
AccountAgeWitnessService accountAgeWitnessService,
|
||||
SignedWitnessService signedWitnessService) {
|
||||
super(model);
|
||||
|
||||
this.navigation = navigation;
|
||||
|
@ -160,6 +159,7 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi
|
|||
this.privateNotificationManager = privateNotificationManager;
|
||||
this.useDevPrivilegeKeys = useDevPrivilegeKeys;
|
||||
this.accountAgeWitnessService = accountAgeWitnessService;
|
||||
this.signedWitnessService = signedWitnessService;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -261,6 +261,11 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi
|
|||
|
||||
}, Comparator.nullsFirst(Comparator.naturalOrder())));
|
||||
|
||||
Comparator<OfferBookListItem> comparator = Comparator.comparing(e -> e.getWitnessAgeData(accountAgeWitnessService, signedWitnessService).getType(), Comparator.nullsFirst(Comparator.naturalOrder()));
|
||||
signingStateColumn.setComparator(comparator.
|
||||
thenComparing(e -> e.getWitnessAgeData(accountAgeWitnessService, signedWitnessService).getDays(),
|
||||
Comparator.nullsFirst(Comparator.naturalOrder())));
|
||||
|
||||
nrOfOffersLabel = new AutoTooltipLabel("");
|
||||
nrOfOffersLabel.setId("num-offers");
|
||||
GridPane.setHalignment(nrOfOffersLabel, HPos.LEFT);
|
||||
|
@ -1108,55 +1113,11 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi
|
|||
super.updateItem(item, empty);
|
||||
|
||||
if (item != null && !empty) {
|
||||
|
||||
GlyphIcons icon;
|
||||
String info;
|
||||
String timeSinceSigning;
|
||||
|
||||
boolean needsSigning = PaymentMethod.hasChargebackRisk(
|
||||
item.getOffer().getPaymentMethod(), item.getOffer().getCurrencyCode());
|
||||
|
||||
if (needsSigning) {
|
||||
if (accountAgeWitnessService.hasSignedWitness(item.getOffer())) {
|
||||
// either signed & limits lifted, or waiting for limits to be lifted
|
||||
AccountAgeWitnessService.SignState signState = accountAgeWitnessService.getSignState(item.getOffer());
|
||||
icon = GUIUtil.getIconForSignState(signState);
|
||||
info = Res.get("offerbook.timeSinceSigning.info",
|
||||
signState.getPresentation());
|
||||
long daysSinceSigning = TimeUnit.MILLISECONDS.toDays(
|
||||
accountAgeWitnessService.getWitnessSignAge(item.getOffer(), new Date()));
|
||||
timeSinceSigning = Res.get("offerbook.timeSinceSigning.daysSinceSigning",
|
||||
daysSinceSigning);
|
||||
} else {
|
||||
// either banned, unsigned
|
||||
AccountAgeWitnessService.SignState signState = accountAgeWitnessService.getSignState(item.getOffer());
|
||||
icon = GUIUtil.getIconForSignState(signState);
|
||||
if (!signState.equals(AccountAgeWitnessService.SignState.UNSIGNED)) {
|
||||
info = Res.get("offerbook.timeSinceSigning.info", signState.getPresentation());
|
||||
long daysSinceSigning = TimeUnit.MILLISECONDS.toDays(
|
||||
accountAgeWitnessService.getWitnessSignAge(item.getOffer(), new Date()));
|
||||
timeSinceSigning = Res.get("offerbook.timeSinceSigning.daysSinceSigning",
|
||||
daysSinceSigning);
|
||||
} else {
|
||||
long accountAge = TimeUnit.MILLISECONDS.toDays(accountAgeWitnessService.getAccountAge(item.getOffer()));
|
||||
info = Res.get("shared.notSigned", accountAge);
|
||||
timeSinceSigning = Res.get("offerbook.timeSinceSigning.notSigned", accountAge);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (CurrencyUtil.isFiatCurrency(item.getOffer().getCurrencyCode())) {
|
||||
icon = MaterialDesignIcon.CHECKBOX_MARKED_OUTLINE;
|
||||
long days = TimeUnit.MILLISECONDS.toDays(accountAgeWitnessService.getAccountAge(item.getOffer()));
|
||||
info = Res.get("shared.notSigned.noNeedDays", days);
|
||||
timeSinceSigning = Res.get("offerbook.timeSinceSigning.notSigned.ageDays", days);
|
||||
} else { // altcoins
|
||||
icon = MaterialDesignIcon.INFORMATION_OUTLINE;
|
||||
info = Res.get("shared.notSigned.noNeedAlts");
|
||||
timeSinceSigning = Res.get("offerbook.timeSinceSigning.notSigned.noNeed");
|
||||
}
|
||||
}
|
||||
|
||||
InfoAutoTooltipLabel label = new InfoAutoTooltipLabel(timeSinceSigning, icon, ContentDisplay.RIGHT, info);
|
||||
var witnessAgeData = item.getWitnessAgeData(accountAgeWitnessService, signedWitnessService);
|
||||
InfoAutoTooltipLabel label = new InfoAutoTooltipLabel(witnessAgeData.getDisplayString(),
|
||||
witnessAgeData.getIcon(),
|
||||
ContentDisplay.RIGHT,
|
||||
witnessAgeData.getInfo());
|
||||
setGraphic(label);
|
||||
} else {
|
||||
setGraphic(null);
|
||||
|
|
|
@ -876,7 +876,7 @@ public class GUIUtil {
|
|||
item.paymentAccountPayload);
|
||||
AccountAgeWitnessService.SignState signState =
|
||||
accountAgeWitnessService.getSignState(myWitness);
|
||||
String info = StringUtils.capitalize(signState.getPresentation());
|
||||
String info = StringUtils.capitalize(signState.getDisplayString());
|
||||
|
||||
MaterialDesignIcon icon;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue