mirror of
https://github.com/haveno-dex/haveno.git
synced 2024-12-27 08:19:41 -05:00
enable cancel button while placing an offer
This commit is contained in:
parent
35f275805b
commit
68a4c21b17
@ -246,6 +246,10 @@ public final class OpenOffer implements Tradable {
|
|||||||
return state == State.DEACTIVATED;
|
return state == State.DEACTIVATED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isCanceled() {
|
||||||
|
return state == State.CANCELED;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "OpenOffer{" +
|
return "OpenOffer{" +
|
||||||
|
@ -218,6 +218,7 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
|||||||
this.persistenceManager = persistenceManager;
|
this.persistenceManager = persistenceManager;
|
||||||
this.signedOfferPersistenceManager = signedOfferPersistenceManager;
|
this.signedOfferPersistenceManager = signedOfferPersistenceManager;
|
||||||
this.accountAgeWitnessService = accountAgeWitnessService;
|
this.accountAgeWitnessService = accountAgeWitnessService;
|
||||||
|
HavenoUtils.openOfferManager = this;
|
||||||
|
|
||||||
this.persistenceManager.initialize(openOffers, "OpenOffers", PersistenceManager.Source.PRIVATE);
|
this.persistenceManager.initialize(openOffers, "OpenOffers", PersistenceManager.Source.PRIVATE);
|
||||||
this.signedOfferPersistenceManager.initialize(signedOffers, "SignedOffers", PersistenceManager.Source.PRIVATE); // arbitrator stores reserve tx for signed offers
|
this.signedOfferPersistenceManager.initialize(signedOffers, "SignedOffers", PersistenceManager.Source.PRIVATE); // arbitrator stores reserve tx for signed offers
|
||||||
@ -548,11 +549,14 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
|||||||
latch.countDown();
|
latch.countDown();
|
||||||
resultHandler.handleResult(transaction);
|
resultHandler.handleResult(transaction);
|
||||||
}, (errorMessage) -> {
|
}, (errorMessage) -> {
|
||||||
log.warn("Error processing unposted offer {}: {}", openOffer.getId(), errorMessage);
|
if (openOffer.isCanceled()) latch.countDown();
|
||||||
onCancelled(openOffer);
|
else {
|
||||||
offer.setErrorMessage(errorMessage);
|
log.warn("Error processing unposted offer {}: {}", openOffer.getId(), errorMessage);
|
||||||
latch.countDown();
|
doCancel(openOffer);
|
||||||
errorMessageHandler.handleErrorMessage(errorMessage);
|
offer.setErrorMessage(errorMessage);
|
||||||
|
latch.countDown();
|
||||||
|
errorMessageHandler.handleErrorMessage(errorMessage);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
HavenoUtils.awaitLatch(latch);
|
HavenoUtils.awaitLatch(latch);
|
||||||
}
|
}
|
||||||
@ -612,21 +616,22 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
|||||||
public void cancelOpenOffer(OpenOffer openOffer,
|
public void cancelOpenOffer(OpenOffer openOffer,
|
||||||
ResultHandler resultHandler,
|
ResultHandler resultHandler,
|
||||||
ErrorMessageHandler errorMessageHandler) {
|
ErrorMessageHandler errorMessageHandler) {
|
||||||
|
log.info("Canceling open offer: {}", openOffer.getId());
|
||||||
if (!offersToBeEdited.containsKey(openOffer.getId())) {
|
if (!offersToBeEdited.containsKey(openOffer.getId())) {
|
||||||
if (openOffer.isDeactivated()) {
|
if (openOffer.isAvailable()) {
|
||||||
ThreadUtils.execute(() -> {
|
|
||||||
onCancelled(openOffer);
|
|
||||||
resultHandler.handleResult();
|
|
||||||
}, THREAD_ID);
|
|
||||||
} else {
|
|
||||||
offerBookService.removeOffer(openOffer.getOffer().getOfferPayload(),
|
offerBookService.removeOffer(openOffer.getOffer().getOfferPayload(),
|
||||||
() -> {
|
() -> {
|
||||||
ThreadUtils.execute(() -> { // TODO: this runs off thread and then shows popup when done. should show overlay spinner until done
|
ThreadUtils.submitToPool(() -> { // TODO: this runs off thread and then shows popup when done. should show overlay spinner until done
|
||||||
onCancelled(openOffer);
|
doCancel(openOffer);
|
||||||
resultHandler.handleResult();
|
resultHandler.handleResult();
|
||||||
}, THREAD_ID);
|
});
|
||||||
},
|
},
|
||||||
errorMessageHandler);
|
errorMessageHandler);
|
||||||
|
} else {
|
||||||
|
ThreadUtils.submitToPool(() -> {
|
||||||
|
doCancel(openOffer);
|
||||||
|
resultHandler.handleResult();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
errorMessageHandler.handleErrorMessage("You can't remove an offer that is currently edited.");
|
errorMessageHandler.handleErrorMessage("You can't remove an offer that is currently edited.");
|
||||||
@ -703,12 +708,12 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
|||||||
}
|
}
|
||||||
|
|
||||||
// remove open offer which thaws its key images
|
// remove open offer which thaws its key images
|
||||||
private void onCancelled(@NotNull OpenOffer openOffer) {
|
private void doCancel(@NotNull OpenOffer openOffer) {
|
||||||
Offer offer = openOffer.getOffer();
|
Offer offer = openOffer.getOffer();
|
||||||
offer.setState(Offer.State.REMOVED);
|
offer.setState(Offer.State.REMOVED);
|
||||||
openOffer.setState(OpenOffer.State.CANCELED);
|
openOffer.setState(OpenOffer.State.CANCELED);
|
||||||
removeOpenOffer(openOffer);
|
removeOpenOffer(openOffer);
|
||||||
closedTradableManager.add(openOffer);
|
closedTradableManager.add(openOffer); // TODO: don't add these to closed tradables?
|
||||||
xmrWalletService.resetAddressEntriesForOpenOffer(offer.getId());
|
xmrWalletService.resetAddressEntriesForOpenOffer(offer.getId());
|
||||||
requestPersistence();
|
requestPersistence();
|
||||||
xmrWalletService.thawOutputs(offer.getOfferPayload().getReserveTxKeyImages());
|
xmrWalletService.thawOutputs(offer.getOfferPayload().getReserveTxKeyImages());
|
||||||
@ -785,6 +790,10 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasOpenOffer(String offerId) {
|
||||||
|
return getOpenOfferById(offerId).isPresent();
|
||||||
|
}
|
||||||
|
|
||||||
public Optional<SignedOffer> getSignedOfferById(String offerId) {
|
public Optional<SignedOffer> getSignedOfferById(String offerId) {
|
||||||
synchronized (signedOffers) {
|
synchronized (signedOffers) {
|
||||||
return signedOffers.stream().filter(e -> e.getOfferId().equals(offerId)).findFirst();
|
return signedOffers.stream().filter(e -> e.getOfferId().equals(offerId)).findFirst();
|
||||||
@ -803,6 +812,10 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
|||||||
synchronized (openOffers) {
|
synchronized (openOffers) {
|
||||||
openOffers.remove(openOffer);
|
openOffers.remove(openOffer);
|
||||||
}
|
}
|
||||||
|
synchronized (placeOfferProtocols) {
|
||||||
|
PlaceOfferProtocol protocol = placeOfferProtocols.remove(openOffer.getId());
|
||||||
|
if (protocol != null) protocol.cancelOffer();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addSignedOffer(SignedOffer signedOffer) {
|
private void addSignedOffer(SignedOffer signedOffer) {
|
||||||
@ -856,13 +869,15 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
|||||||
processUnpostedOffer(openOffers, scheduledOffer, (transaction) -> {
|
processUnpostedOffer(openOffers, scheduledOffer, (transaction) -> {
|
||||||
latch.countDown();
|
latch.countDown();
|
||||||
}, errorMessage -> {
|
}, errorMessage -> {
|
||||||
log.warn("Error processing unposted offer, offerId={}, attempt={}/{}, error={}", scheduledOffer.getId(), scheduledOffer.getNumProcessingAttempts(), MAX_PROCESS_ATTEMPTS, errorMessage);
|
if (!scheduledOffer.isCanceled()) {
|
||||||
if (scheduledOffer.getNumProcessingAttempts() >= MAX_PROCESS_ATTEMPTS) {
|
log.warn("Error processing unposted offer, offerId={}, attempt={}/{}, error={}", scheduledOffer.getId(), scheduledOffer.getNumProcessingAttempts(), MAX_PROCESS_ATTEMPTS, errorMessage);
|
||||||
log.warn("Offer canceled after {} attempts, offerId={}, error={}", scheduledOffer.getNumProcessingAttempts(), scheduledOffer.getId(), errorMessage);
|
if (scheduledOffer.getNumProcessingAttempts() >= MAX_PROCESS_ATTEMPTS) {
|
||||||
HavenoUtils.havenoSetup.getTopErrorMsg().set("Offer canceled after " + scheduledOffer.getNumProcessingAttempts() + " attempts. Please switch to a better Monero connection and try again.\n\nOffer ID: " + scheduledOffer.getId() + "\nError: " + errorMessage);
|
log.warn("Offer canceled after {} attempts, offerId={}, error={}", scheduledOffer.getNumProcessingAttempts(), scheduledOffer.getId(), errorMessage);
|
||||||
onCancelled(scheduledOffer);
|
HavenoUtils.havenoSetup.getTopErrorMsg().set("Offer canceled after " + scheduledOffer.getNumProcessingAttempts() + " attempts. Please switch to a better Monero connection and try again.\n\nOffer ID: " + scheduledOffer.getId() + "\nError: " + errorMessage);
|
||||||
|
doCancel(scheduledOffer);
|
||||||
|
}
|
||||||
|
errorMessages.add(errorMessage);
|
||||||
}
|
}
|
||||||
errorMessages.add(errorMessage);
|
|
||||||
latch.countDown();
|
latch.countDown();
|
||||||
});
|
});
|
||||||
HavenoUtils.awaitLatch(latch);
|
HavenoUtils.awaitLatch(latch);
|
||||||
@ -941,7 +956,7 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
|||||||
// handle result
|
// handle result
|
||||||
resultHandler.handleResult(null);
|
resultHandler.handleResult(null);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
if (!openOffer.isCanceled()) e.printStackTrace();
|
||||||
errorMessageHandler.handleErrorMessage(e.getMessage());
|
errorMessageHandler.handleErrorMessage(e.getMessage());
|
||||||
}
|
}
|
||||||
}).start();
|
}).start();
|
||||||
@ -1737,7 +1752,7 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
|||||||
} else {
|
} else {
|
||||||
|
|
||||||
// cancel and recreate offer
|
// cancel and recreate offer
|
||||||
onCancelled(openOffer);
|
doCancel(openOffer);
|
||||||
Offer updatedOffer = new Offer(openOffer.getOffer().getOfferPayload());
|
Offer updatedOffer = new Offer(openOffer.getOffer().getOfferPayload());
|
||||||
updatedOffer.setPriceFeedService(priceFeedService);
|
updatedOffer.setPriceFeedService(priceFeedService);
|
||||||
OpenOffer updatedOpenOffer = new OpenOffer(updatedOffer, openOffer.getTriggerPrice());
|
OpenOffer updatedOpenOffer = new OpenOffer(updatedOffer, openOffer.getTriggerPrice());
|
||||||
@ -1751,9 +1766,11 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
|||||||
latch.countDown();
|
latch.countDown();
|
||||||
if (completeHandler != null) completeHandler.run();
|
if (completeHandler != null) completeHandler.run();
|
||||||
}, (errorMessage) -> {
|
}, (errorMessage) -> {
|
||||||
log.warn("Error reposting offer {}: {}", updatedOpenOffer.getId(), errorMessage);
|
if (!updatedOpenOffer.isCanceled()) {
|
||||||
onCancelled(updatedOpenOffer);
|
log.warn("Error reposting offer {}: {}", updatedOpenOffer.getId(), errorMessage);
|
||||||
updatedOffer.setErrorMessage(errorMessage);
|
doCancel(updatedOpenOffer);
|
||||||
|
updatedOffer.setErrorMessage(errorMessage);
|
||||||
|
}
|
||||||
latch.countDown();
|
latch.countDown();
|
||||||
if (completeHandler != null) completeHandler.run();
|
if (completeHandler != null) completeHandler.run();
|
||||||
});
|
});
|
||||||
|
@ -84,6 +84,10 @@ public class PlaceOfferProtocol {
|
|||||||
|
|
||||||
taskRunner.run();
|
taskRunner.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void cancelOffer() {
|
||||||
|
handleError("Offer was canceled: " + model.getOpenOffer().getOffer().getId()); // cancel is treated as error for callers to handle
|
||||||
|
}
|
||||||
|
|
||||||
// TODO (woodser): switch to fluent
|
// TODO (woodser): switch to fluent
|
||||||
public void handleSignOfferResponse(SignOfferResponse response, NodeAddress sender) {
|
public void handleSignOfferResponse(SignOfferResponse response, NodeAddress sender) {
|
||||||
@ -147,9 +151,11 @@ public class PlaceOfferProtocol {
|
|||||||
private void handleError(String errorMessage) {
|
private void handleError(String errorMessage) {
|
||||||
if (timeoutTimer != null) {
|
if (timeoutTimer != null) {
|
||||||
taskRunner.cancel();
|
taskRunner.cancel();
|
||||||
log.error(errorMessage);
|
if (!model.getOpenOffer().isCanceled()) {
|
||||||
|
log.error(errorMessage);
|
||||||
|
model.getOpenOffer().getOffer().setErrorMessage(errorMessage);
|
||||||
|
}
|
||||||
stopTimeoutTimer();
|
stopTimeoutTimer();
|
||||||
model.getOpenOffer().getOffer().setErrorMessage(errorMessage);
|
|
||||||
errorMessageHandler.handleErrorMessage(errorMessage);
|
errorMessageHandler.handleErrorMessage(errorMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,7 @@ public class MakerReserveOfferFunds extends Task<PlaceOfferModel> {
|
|||||||
synchronized (XmrWalletService.WALLET_LOCK) {
|
synchronized (XmrWalletService.WALLET_LOCK) {
|
||||||
|
|
||||||
// reset protocol timeout
|
// reset protocol timeout
|
||||||
verifyOpen();
|
verifyScheduled();
|
||||||
model.getProtocol().startTimeoutTimer();
|
model.getProtocol().startTimeoutTimer();
|
||||||
|
|
||||||
// collect relevant info
|
// collect relevant info
|
||||||
@ -92,7 +92,7 @@ public class MakerReserveOfferFunds extends Task<PlaceOfferModel> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// verify still open
|
// verify still open
|
||||||
verifyOpen();
|
verifyScheduled();
|
||||||
if (reserveTx != null) break;
|
if (reserveTx != null) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -119,11 +119,7 @@ public class MakerReserveOfferFunds extends Task<PlaceOfferModel> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void verifyOpen() {
|
public void verifyScheduled() {
|
||||||
if (!isOpen()) throw new RuntimeException("Offer " + model.getOpenOffer().getOffer().getId() + " is no longer open");
|
if (!model.getOpenOffer().isScheduled()) throw new RuntimeException("Offer " + model.getOpenOffer().getOffer().getId() + " is canceled");
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isOpen() {
|
|
||||||
return model.getOpenOfferManager().getOpenOfferById(model.getOpenOffer().getId()).isPresent();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -137,6 +137,12 @@ public class MakerSendSignOfferRequest extends Task<PlaceOfferModel> {
|
|||||||
log.warn("Arbitrator unavailable: address={}, error={}", arbitratorNodeAddress, errorMessage);
|
log.warn("Arbitrator unavailable: address={}, error={}", arbitratorNodeAddress, errorMessage);
|
||||||
excludedArbitrators.add(arbitratorNodeAddress);
|
excludedArbitrators.add(arbitratorNodeAddress);
|
||||||
|
|
||||||
|
// check if offer still scheduled
|
||||||
|
if (!model.getOpenOffer().isScheduled()) {
|
||||||
|
errorMessageHandler.handleErrorMessage("Offer is no longer scheduled, offerId=" + model.getOpenOffer().getId());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// get alternative arbitrator
|
// get alternative arbitrator
|
||||||
Arbitrator altArbitrator = DisputeAgentSelection.getRandomArbitrator(model.getArbitratorManager(), excludedArbitrators);
|
Arbitrator altArbitrator = DisputeAgentSelection.getRandomArbitrator(model.getArbitratorManager(), excludedArbitrators);
|
||||||
if (altArbitrator == null) {
|
if (altArbitrator == null) {
|
||||||
|
@ -30,6 +30,7 @@ import haveno.common.crypto.Sig;
|
|||||||
import haveno.common.util.Utilities;
|
import haveno.common.util.Utilities;
|
||||||
import haveno.core.app.HavenoSetup;
|
import haveno.core.app.HavenoSetup;
|
||||||
import haveno.core.offer.OfferPayload;
|
import haveno.core.offer.OfferPayload;
|
||||||
|
import haveno.core.offer.OpenOfferManager;
|
||||||
import haveno.core.support.dispute.arbitration.ArbitrationManager;
|
import haveno.core.support.dispute.arbitration.ArbitrationManager;
|
||||||
import haveno.core.support.dispute.arbitration.arbitrator.Arbitrator;
|
import haveno.core.support.dispute.arbitration.arbitrator.Arbitrator;
|
||||||
import haveno.core.trade.messages.PaymentReceivedMessage;
|
import haveno.core.trade.messages.PaymentReceivedMessage;
|
||||||
@ -97,9 +98,11 @@ public class HavenoUtils {
|
|||||||
public static final DecimalFormat XMR_FORMATTER = new DecimalFormat("##############0.000000000000", DECIMAL_FORMAT_SYMBOLS);
|
public static final DecimalFormat XMR_FORMATTER = new DecimalFormat("##############0.000000000000", DECIMAL_FORMAT_SYMBOLS);
|
||||||
public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
|
public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
|
||||||
|
|
||||||
|
// TODO: better way to share references?
|
||||||
public static HavenoSetup havenoSetup;
|
public static HavenoSetup havenoSetup;
|
||||||
public static ArbitrationManager arbitrationManager; // TODO: better way to share references?
|
public static ArbitrationManager arbitrationManager;
|
||||||
public static XmrWalletService xmrWalletService;
|
public static XmrWalletService xmrWalletService;
|
||||||
|
public static OpenOfferManager openOfferManager;
|
||||||
|
|
||||||
public static boolean isSeedNode() {
|
public static boolean isSeedNode() {
|
||||||
return havenoSetup == null;
|
return havenoSetup == null;
|
||||||
|
@ -348,9 +348,12 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel<?>> exten
|
|||||||
if (model.getDataModel().canPlaceOffer()) {
|
if (model.getDataModel().canPlaceOffer()) {
|
||||||
Offer offer = model.createAndGetOffer();
|
Offer offer = model.createAndGetOffer();
|
||||||
if (!DevEnv.isDevMode()) {
|
if (!DevEnv.isDevMode()) {
|
||||||
offerDetailsWindow.onPlaceOffer(() ->
|
offerDetailsWindow.onPlaceOffer(() -> {
|
||||||
model.onPlaceOffer(offer, offerDetailsWindow::hide))
|
model.onPlaceOffer(offer, offerDetailsWindow::hide);
|
||||||
.show(offer);
|
}).show(offer);
|
||||||
|
offerDetailsWindow.onClose(() -> {
|
||||||
|
model.onCancelOffer(null, null);
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
balanceSubscription.unsubscribe();
|
balanceSubscription.unsubscribe();
|
||||||
model.onPlaceOffer(offer, () -> {
|
model.onPlaceOffer(offer, () -> {
|
||||||
|
@ -21,6 +21,8 @@ import com.google.inject.Inject;
|
|||||||
import com.google.inject.name.Named;
|
import com.google.inject.name.Named;
|
||||||
import haveno.common.UserThread;
|
import haveno.common.UserThread;
|
||||||
import haveno.common.app.DevEnv;
|
import haveno.common.app.DevEnv;
|
||||||
|
import haveno.common.handlers.ErrorMessageHandler;
|
||||||
|
import haveno.common.handlers.ResultHandler;
|
||||||
import haveno.common.util.MathUtils;
|
import haveno.common.util.MathUtils;
|
||||||
import haveno.core.account.witness.AccountAgeWitnessService;
|
import haveno.core.account.witness.AccountAgeWitnessService;
|
||||||
import haveno.core.locale.CurrencyUtil;
|
import haveno.core.locale.CurrencyUtil;
|
||||||
@ -34,6 +36,8 @@ import haveno.core.offer.Offer;
|
|||||||
import haveno.core.offer.OfferDirection;
|
import haveno.core.offer.OfferDirection;
|
||||||
import haveno.core.offer.OfferRestrictions;
|
import haveno.core.offer.OfferRestrictions;
|
||||||
import haveno.core.offer.OfferUtil;
|
import haveno.core.offer.OfferUtil;
|
||||||
|
import haveno.core.offer.OpenOffer;
|
||||||
|
import haveno.core.offer.OpenOfferManager;
|
||||||
import haveno.core.payment.PaymentAccount;
|
import haveno.core.payment.PaymentAccount;
|
||||||
import haveno.core.payment.payload.PaymentMethod;
|
import haveno.core.payment.payload.PaymentMethod;
|
||||||
import haveno.core.payment.validation.FiatVolumeValidator;
|
import haveno.core.payment.validation.FiatVolumeValidator;
|
||||||
@ -68,6 +72,7 @@ import java.math.BigInteger;
|
|||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import static javafx.beans.binding.Bindings.createStringBinding;
|
import static javafx.beans.binding.Bindings.createStringBinding;
|
||||||
import javafx.beans.property.BooleanProperty;
|
import javafx.beans.property.BooleanProperty;
|
||||||
@ -617,7 +622,6 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
|||||||
updateButtonDisableState();
|
updateButtonDisableState();
|
||||||
updateSpinnerInfo();
|
updateSpinnerInfo();
|
||||||
resultHandler.run();
|
resultHandler.run();
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -625,6 +629,30 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
|||||||
updateSpinnerInfo();
|
updateSpinnerInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void onCancelOffer(ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
|
||||||
|
createOfferRequested = false;
|
||||||
|
OpenOfferManager openOfferManager = HavenoUtils.openOfferManager;
|
||||||
|
Optional<OpenOffer> openOffer = openOfferManager.getOpenOfferById(offer.getId());
|
||||||
|
if (openOffer.isPresent()) {
|
||||||
|
openOfferManager.cancelOpenOffer(openOffer.get(), () -> {
|
||||||
|
UserThread.execute(() -> {
|
||||||
|
updateButtonDisableState();
|
||||||
|
updateSpinnerInfo();
|
||||||
|
});
|
||||||
|
if (resultHandler != null) resultHandler.handleResult();
|
||||||
|
}, errorMessage -> {
|
||||||
|
UserThread.execute(() -> {
|
||||||
|
updateButtonDisableState();
|
||||||
|
updateSpinnerInfo();
|
||||||
|
if (errorMessageHandler != null) errorMessageHandler.handleErrorMessage(errorMessage);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if (resultHandler != null) resultHandler.handleResult();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void onPaymentAccountSelected(PaymentAccount paymentAccount) {
|
public void onPaymentAccountSelected(PaymentAccount paymentAccount) {
|
||||||
dataModel.onPaymentAccountSelected(paymentAccount);
|
dataModel.onPaymentAccountSelected(paymentAccount);
|
||||||
if (amount.get() != null)
|
if (amount.get() != null)
|
||||||
|
@ -417,7 +417,7 @@ public class OfferDetailsWindow extends Overlay<OfferDetailsWindow> {
|
|||||||
button.setOnAction(e -> {
|
button.setOnAction(e -> {
|
||||||
if (GUIUtil.canCreateOrTakeOfferOrShowPopup(user, navigation)) {
|
if (GUIUtil.canCreateOrTakeOfferOrShowPopup(user, navigation)) {
|
||||||
button.setDisable(true);
|
button.setDisable(true);
|
||||||
cancelButton.setDisable(true);
|
cancelButton.setDisable(isPlaceOffer ? false : true); // TODO: enable cancel button for taking an offer until messages sent
|
||||||
// temporarily disabled due to high CPU usage (per issue #4649)
|
// temporarily disabled due to high CPU usage (per issue #4649)
|
||||||
// busyAnimation.play();
|
// busyAnimation.play();
|
||||||
if (isPlaceOffer) {
|
if (isPlaceOffer) {
|
||||||
|
Loading…
Reference in New Issue
Block a user