Merge pull request #4929 from chimp1984/make-sign-age-column-sortable

Make sign age column sortable
This commit is contained in:
Christoph Atteneder 2020-12-10 12:00:04 +01:00 committed by GitHub
commit f4df51c213
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 159 additions and 69 deletions

View file

@ -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);
}

View file

@ -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();
}

View file

@ -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;

View file

@ -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()));

View file

@ -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();

View file

@ -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;
}
}
}
}

View file

@ -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);

View file

@ -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;