Add notifications listener

This commit is contained in:
Fritz Lumnitz 2022-01-09 17:02:44 +01:00 committed by woodser
parent 8332964ac5
commit 800b309a4b
6 changed files with 209 additions and 3 deletions

View file

@ -36,6 +36,8 @@ import bisq.common.config.Config;
import bisq.common.handlers.ErrorMessageHandler;
import bisq.common.handlers.ResultHandler;
import bisq.proto.grpc.NotificationMessage;
import org.bitcoinj.core.Coin;
import org.bitcoinj.core.Transaction;
@ -52,6 +54,7 @@ import java.util.concurrent.TimeoutException;
import java.util.function.Consumer;
import lombok.Getter;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
@ -77,6 +80,7 @@ public class CoreApi {
private final CoreTradesService coreTradesService;
private final CoreWalletsService walletsService;
private final TradeStatisticsManager tradeStatisticsManager;
private final CoreNotificationService notificationService;
@Inject
public CoreApi(Config config,
@ -87,7 +91,8 @@ public class CoreApi {
CorePriceService corePriceService,
CoreTradesService coreTradesService,
CoreWalletsService walletsService,
TradeStatisticsManager tradeStatisticsManager) {
TradeStatisticsManager tradeStatisticsManager,
CoreNotificationService notificationService) {
this.config = config;
this.coreDisputeAgentsService = coreDisputeAgentsService;
this.coreHelpService = coreHelpService;
@ -97,6 +102,7 @@ public class CoreApi {
this.corePriceService = corePriceService;
this.walletsService = walletsService;
this.tradeStatisticsManager = tradeStatisticsManager;
this.notificationService = notificationService;
}
@SuppressWarnings("SameReturnValue")
@ -112,6 +118,21 @@ public class CoreApi {
coreDisputeAgentsService.registerDisputeAgent(disputeAgentType, registrationKey);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Notifications
///////////////////////////////////////////////////////////////////////////////////////////
public interface NotificationListener {
void onMessage(@NonNull NotificationMessage message);
}
public void addNotificationListener(NotificationListener listener) {
notificationService.addListener(listener);
}
public void sendNotification(NotificationMessage notification) {
notificationService.sendNotification(notification);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Help

View file

@ -0,0 +1,42 @@
package bisq.core.api;
import bisq.core.api.CoreApi.NotificationListener;
import bisq.proto.grpc.NotificationMessage;
import javax.inject.Singleton;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
@Singleton
@Slf4j
public class CoreNotificationService {
private final Object lock = new Object();
private final List<NotificationListener> listeners = new LinkedList<>();
public void addListener(@NonNull NotificationListener listener) {
synchronized (lock) {
listeners.add(listener);
}
}
public void sendNotification(@NonNull NotificationMessage notification) {
synchronized (lock) {
for (Iterator<NotificationListener> iter = listeners.iterator(); iter.hasNext(); ) {
NotificationListener listener = iter.next();
try {
listener.onMessage(notification);
} catch (RuntimeException e) {
log.warn("Failed to send message {} to listener {}", notification, listener, e);
iter.remove();
}
}
}
}
}

View file

@ -17,6 +17,7 @@
package bisq.core.trade;
import bisq.core.api.CoreNotificationService;
import bisq.core.btc.model.XmrAddressEntry;
import bisq.core.btc.wallet.XmrWalletService;
import bisq.core.locale.Res;
@ -33,6 +34,7 @@ import bisq.core.provider.price.PriceFeedService;
import bisq.core.support.dispute.arbitration.arbitrator.ArbitratorManager;
import bisq.core.support.dispute.mediation.mediator.Mediator;
import bisq.core.support.dispute.mediation.mediator.MediatorManager;
import bisq.core.trade.Trade.Phase;
import bisq.core.trade.closed.ClosedTradableManager;
import bisq.core.trade.failed.FailedTradesManager;
import bisq.core.trade.handlers.TradeResultHandler;
@ -64,6 +66,7 @@ import bisq.network.p2p.DecryptedMessageWithPubKey;
import bisq.network.p2p.NodeAddress;
import bisq.network.p2p.P2PService;
import bisq.network.p2p.network.TorNetworkNode;
import bisq.proto.grpc.NotificationMessage;
import com.google.common.collect.ImmutableList;
import bisq.common.ClockWatcher;
import bisq.common.config.Config;
@ -89,7 +92,8 @@ import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import org.bouncycastle.crypto.params.KeyParameter;
import org.fxmisc.easybind.EasyBind;
import org.fxmisc.easybind.Subscription;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
@ -127,6 +131,7 @@ public class TradeManager implements PersistedDataHost, DecryptedDirectMessageLi
@Getter
private final KeyRing keyRing;
private final XmrWalletService xmrWalletService;
private final CoreNotificationService notificationService;
private final OfferBookService offerBookService;
private final OpenOfferManager openOfferManager;
private final ClosedTradableManager closedTradableManager;
@ -166,6 +171,7 @@ public class TradeManager implements PersistedDataHost, DecryptedDirectMessageLi
public TradeManager(User user,
KeyRing keyRing,
XmrWalletService xmrWalletService,
CoreNotificationService notificationService,
OfferBookService offerBookService,
OpenOfferManager openOfferManager,
ClosedTradableManager closedTradableManager,
@ -186,6 +192,7 @@ public class TradeManager implements PersistedDataHost, DecryptedDirectMessageLi
this.user = user;
this.keyRing = keyRing;
this.xmrWalletService = xmrWalletService;
this.notificationService = notificationService;
this.offerBookService = offerBookService;
this.openOfferManager = openOfferManager;
this.closedTradableManager = closedTradableManager;
@ -510,6 +517,17 @@ public class TradeManager implements PersistedDataHost, DecryptedDirectMessageLi
trade.getSelf().setReserveTxKey(openOffer.getReserveTxKey());
trade.getSelf().setReserveTxKeyImages(offer.getOfferPayload().getReserveTxKeyImages());
tradableList.add(trade);
// notify on phase changes
// TODO (woodser): save subscription, bind on startup
EasyBind.subscribe(trade.statePhaseProperty(), phase -> {
if (phase == Phase.DEPOSIT_PUBLISHED) {
notificationService.sendNotification(NotificationMessage.newBuilder()
.setTimestamp(System.currentTimeMillis())
.setTitle("Offer Taken")
.setMessage("Your offer " + offer.getId() + " has been accepted").build());
}
});
((MakerProtocol) getTradeProtocol(trade)).handleInitTradeRequest(request, sender, errorMessage -> {
log.warn("Maker error during trade initialization: " + errorMessage);