From c4757c08b8368d64f0b2b8c42d30f44f3ba41232 Mon Sep 17 00:00:00 2001 From: axpoems <145597137+axpoems@users.noreply.github.com> Date: Mon, 25 Mar 2024 20:05:06 +0100 Subject: [PATCH 01/10] add service --- .../alert/AlertNotificationsService.java | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 bonded-roles/src/main/java/bisq/bonded_roles/security_manager/alert/AlertNotificationsService.java diff --git a/bonded-roles/src/main/java/bisq/bonded_roles/security_manager/alert/AlertNotificationsService.java b/bonded-roles/src/main/java/bisq/bonded_roles/security_manager/alert/AlertNotificationsService.java new file mode 100644 index 0000000000..c687af0107 --- /dev/null +++ b/bonded-roles/src/main/java/bisq/bonded_roles/security_manager/alert/AlertNotificationsService.java @@ -0,0 +1,34 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.bonded_roles.security_manager.alert; + +import bisq.common.application.Service; + +import java.util.concurrent.CompletableFuture; + +public class AlertNotificationsService implements Service { + @Override + public CompletableFuture initialize() { + return null; + } + + @Override + public CompletableFuture shutdown() { + return null; + } +} From 6c81d1842b6c1c7db878b5f786d448df82af8ea0 Mon Sep 17 00:00:00 2001 From: axpoems <145597137+axpoems@users.noreply.github.com> Date: Mon, 25 Mar 2024 20:06:14 +0100 Subject: [PATCH 02/10] Remove unused property --- .../src/main/java/bisq/desktop/main/alert/AlertBannerModel.java | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/alert/AlertBannerModel.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/alert/AlertBannerModel.java index f394904b87..bc385dd6bc 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/alert/AlertBannerModel.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/alert/AlertBannerModel.java @@ -36,7 +36,6 @@ public class AlertBannerModel implements Model { private final ObservableList observableList = FXCollections.observableArrayList(); private final FilteredList filteredList = new FilteredList<>(observableList); private final SortedList sortedList = new SortedList<>(filteredList); - private final Set displayedAlerts = new HashSet<>(); @Setter private AuthorizedAlertData displayedAuthorizedAlertData; From a2f365d8047ed343b03ea60d4e01497a707326de Mon Sep 17 00:00:00 2001 From: axpoems <145597137+axpoems@users.noreply.github.com> Date: Mon, 25 Mar 2024 21:39:21 +0100 Subject: [PATCH 03/10] Implement alert notifications service --- .../DesktopApplicationService.java | 10 ++- .../java/bisq/desktop/ServiceProvider.java | 6 +- bonded-roles/build.gradle.kts | 1 + .../alert/AlertNotificationsService.java | 70 ++++++++++++++++++- 4 files changed, 83 insertions(+), 4 deletions(-) diff --git a/apps/desktop/desktop-app/src/main/java/bisq/desktop_app/DesktopApplicationService.java b/apps/desktop/desktop-app/src/main/java/bisq/desktop_app/DesktopApplicationService.java index d524997a47..25cd5409a2 100644 --- a/apps/desktop/desktop-app/src/main/java/bisq/desktop_app/DesktopApplicationService.java +++ b/apps/desktop/desktop-app/src/main/java/bisq/desktop_app/DesktopApplicationService.java @@ -22,6 +22,7 @@ import bisq.application.ShutDownHandler; import bisq.bisq_easy.BisqEasyService; import bisq.bonded_roles.BondedRolesService; +import bisq.bonded_roles.security_manager.alert.AlertNotificationsService; import bisq.chat.ChatService; import bisq.common.application.Service; import bisq.common.observable.Observable; @@ -47,6 +48,7 @@ import bisq.wallets.electrum.ElectrumWalletService; import lombok.Getter; import lombok.extern.slf4j.Slf4j; +import org.checkerframework.checker.units.qual.A; import java.util.Optional; import java.util.concurrent.CompletableFuture; @@ -92,6 +94,7 @@ public class DesktopApplicationService extends ApplicationService { private final TradeService tradeService; private final UpdaterService updaterService; private final BisqEasyService bisqEasyService; + private final AlertNotificationsService alertNotificationsService; public DesktopApplicationService(String[] args, ShutDownHandler shutDownHandler) { super("desktop", args); @@ -179,6 +182,8 @@ public DesktopApplicationService(String[] args, ShutDownHandler shutDownHandler) sendNotificationService, tradeService); + alertNotificationsService = new AlertNotificationsService(settingsService, bondedRolesService.getAlertService()); + // TODO (refactor, low prio): Not sure if ServiceProvider is still needed as we added BisqEasyService which exposes most of the services. serviceProvider = new ServiceProvider(shutDownHandler, getConfig(), @@ -198,7 +203,8 @@ public DesktopApplicationService(String[] args, ShutDownHandler shutDownHandler) sendNotificationService, tradeService, updaterService, - bisqEasyService); + bisqEasyService, + alertNotificationsService); } @Override @@ -243,6 +249,7 @@ public CompletableFuture initialize() { .thenCompose(result -> tradeService.initialize()) .thenCompose(result -> updaterService.initialize()) .thenCompose(result -> bisqEasyService.initialize()) + .thenCompose(result -> alertNotificationsService.initialize()) .orTimeout(STARTUP_TIMEOUT_SEC, TimeUnit.SECONDS) .handle((result, throwable) -> { if (throwable == null) { @@ -274,6 +281,7 @@ public CompletableFuture shutdown() { .thenCompose(result -> sendNotificationService.shutdown()) .thenCompose(result -> chatService.shutdown()) .thenCompose(result -> offerService.shutdown()) + .thenCompose(result -> alertNotificationsService.shutdown()) .thenCompose(result -> settingsService.shutdown()) .thenCompose(result -> userService.shutdown()) .thenCompose(result -> contractService.shutdown()) diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/ServiceProvider.java b/apps/desktop/desktop/src/main/java/bisq/desktop/ServiceProvider.java index 5d78525914..983ba48eec 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/ServiceProvider.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/ServiceProvider.java @@ -26,6 +26,7 @@ import bisq.application.ShutDownHandler; import bisq.bisq_easy.BisqEasyService; import bisq.bonded_roles.BondedRolesService; +import bisq.bonded_roles.security_manager.alert.AlertNotificationsService; import bisq.chat.ChatService; import bisq.contract.ContractService; import bisq.identity.IdentityService; @@ -67,6 +68,7 @@ public class ServiceProvider { private final TradeService tradeService; private final UpdaterService updaterService; private final BisqEasyService bisqEasyService; + private final AlertNotificationsService alertNotificationsService; public ServiceProvider(ShutDownHandler shutDownHandler, ApplicationService.Config config, @@ -86,7 +88,8 @@ public ServiceProvider(ShutDownHandler shutDownHandler, SendNotificationService sendNotificationService, TradeService tradeService, UpdaterService updaterService, - BisqEasyService bisqEasyService) { + BisqEasyService bisqEasyService, + AlertNotificationsService alertNotificationsService) { this.shutDownHandler = shutDownHandler; this.config = config; this.persistenceService = persistenceService; @@ -106,5 +109,6 @@ public ServiceProvider(ShutDownHandler shutDownHandler, this.tradeService = tradeService; this.updaterService = updaterService; this.bisqEasyService = bisqEasyService; + this.alertNotificationsService = alertNotificationsService; } } diff --git a/bonded-roles/build.gradle.kts b/bonded-roles/build.gradle.kts index 898edb1dd7..f7e4c37d79 100644 --- a/bonded-roles/build.gradle.kts +++ b/bonded-roles/build.gradle.kts @@ -8,6 +8,7 @@ dependencies { implementation(project(":security")) implementation(project(":i18n")) implementation(project(":identity")) + implementation(project(":settings")) implementation("network:network-common") implementation("network:network-identity") diff --git a/bonded-roles/src/main/java/bisq/bonded_roles/security_manager/alert/AlertNotificationsService.java b/bonded-roles/src/main/java/bisq/bonded_roles/security_manager/alert/AlertNotificationsService.java index c687af0107..0f1fb671af 100644 --- a/bonded-roles/src/main/java/bisq/bonded_roles/security_manager/alert/AlertNotificationsService.java +++ b/bonded-roles/src/main/java/bisq/bonded_roles/security_manager/alert/AlertNotificationsService.java @@ -18,17 +18,83 @@ package bisq.bonded_roles.security_manager.alert; import bisq.common.application.Service; +import bisq.common.observable.Observable; +import bisq.common.observable.Pin; +import bisq.common.observable.collection.CollectionObserver; +import bisq.common.observable.collection.ObservableSet; +import bisq.settings.SettingsService; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; import java.util.concurrent.CompletableFuture; +@Slf4j public class AlertNotificationsService implements Service { + private final SettingsService settingsService; + private final AlertService alertService; + @Getter + private final Observable isNotificationBannerVisible = new Observable<>(); + private Pin authorizedAlertDataSetPin, unconsumedAlertsPin; + private ObservableSet unconsumedAlerts; + + public AlertNotificationsService(SettingsService settingsService, AlertService alertService) { + this.settingsService = settingsService; + this.alertService = alertService; + } + @Override public CompletableFuture initialize() { - return null; + log.info("initialize"); + + authorizedAlertDataSetPin = alertService.getAuthorizedAlertDataSet().addObserver(new CollectionObserver<>() { + @Override + public void add(AuthorizedAlertData authorizedAlertData) { + if (authorizedAlertData == null) { + return; + } + + if (shouldProcessAlert(authorizedAlertData)) { + unconsumedAlerts.add(authorizedAlertData); + } + } + + @Override + public void remove(Object element) { + if (element instanceof AuthorizedAlertData) { + unconsumedAlerts.remove((AuthorizedAlertData) element); + } + } + + @Override + public void clear() { + unconsumedAlerts.clear(); + } + }); + + unconsumedAlertsPin = unconsumedAlerts.addObserver(this::updateIsNotificationBannerVisible); + + return CompletableFuture.completedFuture(true); } @Override public CompletableFuture shutdown() { - return null; + authorizedAlertDataSetPin.unbind(); + unconsumedAlertsPin.unbind(); + + return CompletableFuture.completedFuture(true); + } + + public void dismissAlert(AuthorizedAlertData authorizedAlertData) { + settingsService.getConsumedAlertIds().add(authorizedAlertData.getId()); + unconsumedAlerts.remove(authorizedAlertData); + } + + private void updateIsNotificationBannerVisible() { + isNotificationBannerVisible.set(!unconsumedAlerts.isEmpty()); + } + + private boolean shouldProcessAlert(AuthorizedAlertData authorizedAlertData) { + return authorizedAlertData.getAlertType() != AlertType.BAN + && !settingsService.getConsumedAlertIds().contains(authorizedAlertData.getId()); } } From d1cc4ebc7f9cf679eab27e3ea4ea5a8f53b9c860 Mon Sep 17 00:00:00 2001 From: axpoems <145597137+axpoems@users.noreply.github.com> Date: Mon, 25 Mar 2024 21:56:06 +0100 Subject: [PATCH 04/10] Use AlertNotificationsService instead of AlertService --- .../bisq/desktop/main/MainController.java | 10 ++---- .../main/alert/AlertBannerController.java | 32 +++++-------------- .../desktop/main/alert/AlertBannerModel.java | 3 +- .../alert/AlertNotificationsService.java | 3 +- 4 files changed, 14 insertions(+), 34 deletions(-) diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/MainController.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/MainController.java index 1deba25165..4a3393e25c 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/MainController.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/MainController.java @@ -19,7 +19,7 @@ import bisq.application.ApplicationService; import bisq.bisq_easy.NavigationTarget; -import bisq.bonded_roles.security_manager.alert.AlertService; +import bisq.bonded_roles.security_manager.alert.AlertNotificationsService; import bisq.desktop.ServiceProvider; import bisq.desktop.common.threading.UIThread; import bisq.desktop.common.view.Controller; @@ -31,7 +31,6 @@ import bisq.desktop.main.left.LeftNavController; import bisq.desktop.main.notification.NotificationPanelController; import bisq.desktop.main.top.TopPanelController; -import bisq.settings.SettingsService; import bisq.updater.UpdaterService; import bisq.updater.UpdaterUtils; import lombok.Getter; @@ -48,24 +47,21 @@ public class MainController extends NavigationController { private final MainView view; private final ServiceProvider serviceProvider; private final LeftNavController leftNavController; - private final SettingsService settingsService; private final UpdaterService updaterService; private final ApplicationService.Config config; - private final AlertBannerController alertBannerController; public MainController(ServiceProvider serviceProvider) { super(NavigationTarget.MAIN); this.serviceProvider = serviceProvider; - settingsService = serviceProvider.getSettingsService(); - AlertService alertService = serviceProvider.getBondedRolesService().getAlertService(); + AlertNotificationsService alertNotificationsService = serviceProvider.getAlertNotificationsService(); updaterService = serviceProvider.getUpdaterService(); config = serviceProvider.getConfig(); leftNavController = new LeftNavController(serviceProvider); TopPanelController topPanelController = new TopPanelController(serviceProvider); NotificationPanelController notificationPanelController = new NotificationPanelController(serviceProvider); - alertBannerController = new AlertBannerController(settingsService, alertService); + AlertBannerController alertBannerController = new AlertBannerController(alertNotificationsService); view = new MainView(model, this, leftNavController.getView().getRoot(), diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/alert/AlertBannerController.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/alert/AlertBannerController.java index 6499d75edb..70e4c2febf 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/alert/AlertBannerController.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/alert/AlertBannerController.java @@ -17,14 +17,12 @@ package bisq.desktop.main.alert; -import bisq.bonded_roles.security_manager.alert.AlertService; -import bisq.bonded_roles.security_manager.alert.AlertType; +import bisq.bonded_roles.security_manager.alert.AlertNotificationsService; import bisq.bonded_roles.security_manager.alert.AuthorizedAlertData; import bisq.common.observable.Pin; import bisq.common.observable.collection.CollectionObserver; import bisq.desktop.common.threading.UIThread; import bisq.desktop.common.view.Controller; -import bisq.settings.SettingsService; import javafx.collections.ListChangeListener; import lombok.Getter; import lombok.extern.slf4j.Slf4j; @@ -37,14 +35,12 @@ public class AlertBannerController implements Controller { private final AlertBannerModel model; @Getter private final AlertBannerView view; - private final SettingsService settingsService; - private final AlertService alertService; + private final AlertNotificationsService alertNotificationsService; private final ListChangeListener listChangeListener; - private Pin authorizedAlertDataSetPin; + private Pin unconsumedAlertsPin; - public AlertBannerController(SettingsService settingsService, AlertService alertService) { - this.settingsService = settingsService; - this.alertService = alertService; + public AlertBannerController(AlertNotificationsService alertNotificationsService) { + this.alertNotificationsService = alertNotificationsService; model = new AlertBannerModel(); view = new AlertBannerView(model, this); @@ -69,14 +65,9 @@ public AlertBannerController(SettingsService settingsService, AlertService alert @Override public void onActivate() { - updatePredicate(); - - authorizedAlertDataSetPin = alertService.getAuthorizedAlertDataSet().addObserver(new CollectionObserver<>() { + unconsumedAlertsPin = alertNotificationsService.getUnconsumedAlerts().addObserver(new CollectionObserver<>() { @Override public void add(AuthorizedAlertData authorizedAlertData) { - if (authorizedAlertData == null) { - return; - } UIThread.run(() -> model.getObservableList().add(authorizedAlertData)); } @@ -99,13 +90,12 @@ public void clear() { @Override public void onDeactivate() { - authorizedAlertDataSetPin.unbind(); + unconsumedAlertsPin.unbind(); model.getSortedList().removeListener(listChangeListener); } void onClose() { - settingsService.getConsumedAlertIds().add(model.getDisplayedAuthorizedAlertData().getId()); - updatePredicate(); + alertNotificationsService.dismissAlert(model.getDisplayedAuthorizedAlertData()); handleRemove(); } @@ -129,10 +119,4 @@ private void handleRemove() { model.reset(); model.getSortedList().stream().findFirst().ifPresent(this::add); } - - private void updatePredicate() { - model.getFilteredList().setPredicate(authorizedAlertData -> - !settingsService.getConsumedAlertIds().contains(authorizedAlertData.getId()) && - authorizedAlertData.getAlertType() != AlertType.BAN); - } } diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/alert/AlertBannerModel.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/alert/AlertBannerModel.java index bc385dd6bc..41442c6ba4 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/alert/AlertBannerModel.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/alert/AlertBannerModel.java @@ -34,8 +34,7 @@ @Getter public class AlertBannerModel implements Model { private final ObservableList observableList = FXCollections.observableArrayList(); - private final FilteredList filteredList = new FilteredList<>(observableList); - private final SortedList sortedList = new SortedList<>(filteredList); + private final SortedList sortedList = new SortedList<>(observableList); @Setter private AuthorizedAlertData displayedAuthorizedAlertData; diff --git a/bonded-roles/src/main/java/bisq/bonded_roles/security_manager/alert/AlertNotificationsService.java b/bonded-roles/src/main/java/bisq/bonded_roles/security_manager/alert/AlertNotificationsService.java index 0f1fb671af..2cc8b787ff 100644 --- a/bonded-roles/src/main/java/bisq/bonded_roles/security_manager/alert/AlertNotificationsService.java +++ b/bonded-roles/src/main/java/bisq/bonded_roles/security_manager/alert/AlertNotificationsService.java @@ -35,7 +35,8 @@ public class AlertNotificationsService implements Service { @Getter private final Observable isNotificationBannerVisible = new Observable<>(); private Pin authorizedAlertDataSetPin, unconsumedAlertsPin; - private ObservableSet unconsumedAlerts; + @Getter + private final ObservableSet unconsumedAlerts = new ObservableSet<>(); public AlertNotificationsService(SettingsService settingsService, AlertService alertService) { this.settingsService = settingsService; From bdf8ab890085fb3fc6bd179ff9f8b2683d75347c Mon Sep 17 00:00:00 2001 From: axpoems <145597137+axpoems@users.noreply.github.com> Date: Mon, 25 Mar 2024 22:41:30 +0100 Subject: [PATCH 05/10] Set visibility of alerts --- .../desktop/main/alert/AlertBannerController.java | 15 ++++++++++++--- .../alert/AlertNotificationsService.java | 15 +++++---------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/alert/AlertBannerController.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/alert/AlertBannerController.java index 70e4c2febf..3f63f10637 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/alert/AlertBannerController.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/alert/AlertBannerController.java @@ -26,6 +26,8 @@ import javafx.collections.ListChangeListener; import lombok.Getter; import lombok.extern.slf4j.Slf4j; +import org.fxmisc.easybind.EasyBind; +import org.fxmisc.easybind.Subscription; import java.util.Comparator; import java.util.Optional; @@ -38,6 +40,7 @@ public class AlertBannerController implements Controller { private final AlertNotificationsService alertNotificationsService; private final ListChangeListener listChangeListener; private Pin unconsumedAlertsPin; + private Subscription isAlertVisiblePin; public AlertBannerController(AlertNotificationsService alertNotificationsService) { this.alertNotificationsService = alertNotificationsService; @@ -84,6 +87,8 @@ public void clear() { } }); + isAlertVisiblePin = EasyBind.subscribe(model.getIsAlertVisible(), this::updateIsNotificationBannerVisible); + model.getSortedList().addListener(listChangeListener); model.getSortedList().stream().findFirst().ifPresent(this::add); } @@ -91,6 +96,9 @@ public void clear() { @Override public void onDeactivate() { unconsumedAlertsPin.unbind(); + + isAlertVisiblePin.unsubscribe(); + model.getSortedList().removeListener(listChangeListener); } @@ -109,9 +117,6 @@ private void add(AuthorizedAlertData authorizedAlertData) { model.getMessage().set(authorizedAlertData.getMessage().orElseThrow()); model.getAlertType().set(authorizedAlertData.getAlertType()); model.getIsAlertVisible().set(true); - } else { - log.warn("optionalMessage not present"); - model.getIsAlertVisible().set(false); } } @@ -119,4 +124,8 @@ private void handleRemove() { model.reset(); model.getSortedList().stream().findFirst().ifPresent(this::add); } + + private void updateIsNotificationBannerVisible(boolean isVisible) { + alertNotificationsService.getIsNotificationBannerVisible().set(isVisible); + } } diff --git a/bonded-roles/src/main/java/bisq/bonded_roles/security_manager/alert/AlertNotificationsService.java b/bonded-roles/src/main/java/bisq/bonded_roles/security_manager/alert/AlertNotificationsService.java index 2cc8b787ff..7d0186694d 100644 --- a/bonded-roles/src/main/java/bisq/bonded_roles/security_manager/alert/AlertNotificationsService.java +++ b/bonded-roles/src/main/java/bisq/bonded_roles/security_manager/alert/AlertNotificationsService.java @@ -24,6 +24,7 @@ import bisq.common.observable.collection.ObservableSet; import bisq.settings.SettingsService; import lombok.Getter; +import lombok.Setter; import lombok.extern.slf4j.Slf4j; import java.util.concurrent.CompletableFuture; @@ -33,8 +34,8 @@ public class AlertNotificationsService implements Service { private final SettingsService settingsService; private final AlertService alertService; @Getter - private final Observable isNotificationBannerVisible = new Observable<>(); - private Pin authorizedAlertDataSetPin, unconsumedAlertsPin; + private final Observable isNotificationBannerVisible = new Observable<>(false); + private Pin authorizedAlertDataSetPin; @Getter private final ObservableSet unconsumedAlerts = new ObservableSet<>(); @@ -72,15 +73,12 @@ public void clear() { } }); - unconsumedAlertsPin = unconsumedAlerts.addObserver(this::updateIsNotificationBannerVisible); - return CompletableFuture.completedFuture(true); } @Override public CompletableFuture shutdown() { authorizedAlertDataSetPin.unbind(); - unconsumedAlertsPin.unbind(); return CompletableFuture.completedFuture(true); } @@ -90,12 +88,9 @@ public void dismissAlert(AuthorizedAlertData authorizedAlertData) { unconsumedAlerts.remove(authorizedAlertData); } - private void updateIsNotificationBannerVisible() { - isNotificationBannerVisible.set(!unconsumedAlerts.isEmpty()); - } - private boolean shouldProcessAlert(AuthorizedAlertData authorizedAlertData) { return authorizedAlertData.getAlertType() != AlertType.BAN - && !settingsService.getConsumedAlertIds().contains(authorizedAlertData.getId()); + && !settingsService.getConsumedAlertIds().contains(authorizedAlertData.getId()) + && authorizedAlertData.getMessage().isPresent(); } } From 65587d5d49bd62f6fc15b93902026fa5d7a17f2a Mon Sep 17 00:00:00 2001 From: axpoems <145597137+axpoems@users.noreply.github.com> Date: Mon, 25 Mar 2024 22:58:14 +0100 Subject: [PATCH 06/10] Update paddings in content tab controller according to alerts as well --- .../main/alert/AlertBannerController.java | 6 +++--- .../main/content/ContentTabController.java | 21 ++++++++++++++----- .../alert/AlertNotificationsService.java | 3 +-- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/alert/AlertBannerController.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/alert/AlertBannerController.java index 3f63f10637..8af82d1a56 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/alert/AlertBannerController.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/alert/AlertBannerController.java @@ -87,7 +87,7 @@ public void clear() { } }); - isAlertVisiblePin = EasyBind.subscribe(model.getIsAlertVisible(), this::updateIsNotificationBannerVisible); + isAlertVisiblePin = EasyBind.subscribe(model.getIsAlertVisible(), this::updateIsAlertBannerVisible); model.getSortedList().addListener(listChangeListener); model.getSortedList().stream().findFirst().ifPresent(this::add); @@ -125,7 +125,7 @@ private void handleRemove() { model.getSortedList().stream().findFirst().ifPresent(this::add); } - private void updateIsNotificationBannerVisible(boolean isVisible) { - alertNotificationsService.getIsNotificationBannerVisible().set(isVisible); + private void updateIsAlertBannerVisible(boolean isVisible) { + alertNotificationsService.getIsAlertBannerVisible().set(isVisible); } } diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/ContentTabController.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/ContentTabController.java index 6e2bf6f01b..3d7f170c33 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/ContentTabController.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/ContentTabController.java @@ -19,9 +19,9 @@ import bisq.bisq_easy.BisqEasyNotificationsService; import bisq.bisq_easy.NavigationTarget; +import bisq.bonded_roles.security_manager.alert.AlertNotificationsService; import bisq.common.observable.Pin; import bisq.desktop.ServiceProvider; -import bisq.desktop.common.observable.FxBindings; import bisq.desktop.common.view.TabController; import lombok.extern.slf4j.Slf4j; @@ -29,25 +29,36 @@ public abstract class ContentTabController extends TabController { protected final ServiceProvider serviceProvider; private final BisqEasyNotificationsService bisqEasyNotificationsService; - private Pin isNotificationVisiblePin; + private final AlertNotificationsService alertNotificationsService; + private Pin isNotificationPanelVisiblePin, isAlertBannerVisiblePin; public ContentTabController(M model, NavigationTarget host, ServiceProvider serviceProvider) { super(model, host); this.serviceProvider = serviceProvider; bisqEasyNotificationsService = serviceProvider.getBisqEasyService().getBisqEasyNotificationsService(); + alertNotificationsService = serviceProvider.getAlertNotificationsService(); } @Override public void onActivate() { - isNotificationVisiblePin = FxBindings.bind(model.getIsNotificationVisible()) - .to(bisqEasyNotificationsService.getIsNotificationPanelVisible()); + isNotificationPanelVisiblePin = bisqEasyNotificationsService.getIsNotificationPanelVisible().addObserver( + isVisible -> updateIsNotificationVisible()); + isAlertBannerVisiblePin = alertNotificationsService.getIsAlertBannerVisible().addObserver( + isVisible -> updateIsNotificationVisible()); } @Override public void onDeactivate() { - isNotificationVisiblePin.unbind(); + isNotificationPanelVisiblePin.unbind(); + isAlertBannerVisiblePin.unbind(); resetResolvedTarget(); } + + private void updateIsNotificationVisible() { + model.getIsNotificationVisible().set( + bisqEasyNotificationsService.getIsNotificationPanelVisible().get() + || alertNotificationsService.getIsAlertBannerVisible().get()); + } } diff --git a/bonded-roles/src/main/java/bisq/bonded_roles/security_manager/alert/AlertNotificationsService.java b/bonded-roles/src/main/java/bisq/bonded_roles/security_manager/alert/AlertNotificationsService.java index 7d0186694d..d16f17bf80 100644 --- a/bonded-roles/src/main/java/bisq/bonded_roles/security_manager/alert/AlertNotificationsService.java +++ b/bonded-roles/src/main/java/bisq/bonded_roles/security_manager/alert/AlertNotificationsService.java @@ -24,7 +24,6 @@ import bisq.common.observable.collection.ObservableSet; import bisq.settings.SettingsService; import lombok.Getter; -import lombok.Setter; import lombok.extern.slf4j.Slf4j; import java.util.concurrent.CompletableFuture; @@ -34,7 +33,7 @@ public class AlertNotificationsService implements Service { private final SettingsService settingsService; private final AlertService alertService; @Getter - private final Observable isNotificationBannerVisible = new Observable<>(false); + private final Observable isAlertBannerVisible = new Observable<>(false); private Pin authorizedAlertDataSetPin; @Getter private final ObservableSet unconsumedAlerts = new ObservableSet<>(); From 1ab16d47b7c6c4ee56e00e0eece01e50358e4301 Mon Sep 17 00:00:00 2001 From: axpoems <145597137+axpoems@users.noreply.github.com> Date: Tue, 26 Mar 2024 21:47:36 +0100 Subject: [PATCH 07/10] Replicate current functionality using service for alert management --- .../main/alert/AlertBannerController.java | 95 +++++-------------- .../desktop/main/alert/AlertBannerModel.java | 10 -- .../alert/AlertNotificationsService.java | 16 +++- 3 files changed, 37 insertions(+), 84 deletions(-) diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/alert/AlertBannerController.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/alert/AlertBannerController.java index 8af82d1a56..716d6df3dd 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/alert/AlertBannerController.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/alert/AlertBannerController.java @@ -20,14 +20,10 @@ import bisq.bonded_roles.security_manager.alert.AlertNotificationsService; import bisq.bonded_roles.security_manager.alert.AuthorizedAlertData; import bisq.common.observable.Pin; -import bisq.common.observable.collection.CollectionObserver; import bisq.desktop.common.threading.UIThread; import bisq.desktop.common.view.Controller; -import javafx.collections.ListChangeListener; import lombok.Getter; import lombok.extern.slf4j.Slf4j; -import org.fxmisc.easybind.EasyBind; -import org.fxmisc.easybind.Subscription; import java.util.Comparator; import java.util.Optional; @@ -38,94 +34,51 @@ public class AlertBannerController implements Controller { @Getter private final AlertBannerView view; private final AlertNotificationsService alertNotificationsService; - private final ListChangeListener listChangeListener; private Pin unconsumedAlertsPin; - private Subscription isAlertVisiblePin; public AlertBannerController(AlertNotificationsService alertNotificationsService) { this.alertNotificationsService = alertNotificationsService; model = new AlertBannerModel(); view = new AlertBannerView(model, this); - - model.getSortedList().setComparator(Comparator.comparing(AuthorizedAlertData::getAlertType).reversed()); - - listChangeListener = change -> { - change.next(); - if (change.wasAdded()) { - AuthorizedAlertData newItem = model.getSortedList().get(0); - AuthorizedAlertData displayed = model.getDisplayedAuthorizedAlertData(); - if (displayed == null || newItem.getAlertType().ordinal() >= displayed.getAlertType().ordinal()) { - add(newItem); - } - } else if (change.wasRemoved()) { - change.getRemoved().stream() - .filter(e -> e.equals(model.getDisplayedAuthorizedAlertData())) - .findFirst() - .ifPresent(e -> handleRemove()); - } - }; } @Override public void onActivate() { - unconsumedAlertsPin = alertNotificationsService.getUnconsumedAlerts().addObserver(new CollectionObserver<>() { - @Override - public void add(AuthorizedAlertData authorizedAlertData) { - UIThread.run(() -> model.getObservableList().add(authorizedAlertData)); - } - - @Override - public void remove(Object element) { - if (element instanceof AuthorizedAlertData) { - UIThread.run(() -> model.getObservableList().remove((AuthorizedAlertData) element)); - } - } - - @Override - public void clear() { - UIThread.run(() -> model.getObservableList().clear()); - } - }); - - isAlertVisiblePin = EasyBind.subscribe(model.getIsAlertVisible(), this::updateIsAlertBannerVisible); - - model.getSortedList().addListener(listChangeListener); - model.getSortedList().stream().findFirst().ifPresent(this::add); + unconsumedAlertsPin = alertNotificationsService.getUnconsumedAlerts().addObserver(this::showAlertBanner); } @Override public void onDeactivate() { unconsumedAlertsPin.unbind(); - - isAlertVisiblePin.unsubscribe(); - - model.getSortedList().removeListener(listChangeListener); } void onClose() { - alertNotificationsService.dismissAlert(model.getDisplayedAuthorizedAlertData()); - handleRemove(); - } - - private void add(AuthorizedAlertData authorizedAlertData) { - model.setDisplayedAuthorizedAlertData(authorizedAlertData); - Optional optionalMessage = authorizedAlertData.getMessage(); - - if (optionalMessage.isPresent()) { - log.info("Showing alert with message {}", optionalMessage.get()); - model.getHeadline().set(authorizedAlertData.getHeadline().orElseThrow()); - model.getMessage().set(authorizedAlertData.getMessage().orElseThrow()); - model.getAlertType().set(authorizedAlertData.getAlertType()); - model.getIsAlertVisible().set(true); - } + UIThread.run(() -> { + alertNotificationsService.dismissAlert(model.getDisplayedAuthorizedAlertData()); + model.reset(); + showAlertBanner(); + }); } - private void handleRemove() { - model.reset(); - model.getSortedList().stream().findFirst().ifPresent(this::add); + private void showAlertBanner() { + UIThread.run(() -> { + Optional mostRelevantAlert = alertNotificationsService.getUnconsumedAlerts().stream() + .max(Comparator.comparing(AuthorizedAlertData::getAlertType).thenComparing(AuthorizedAlertData::getDate)); + if (mostRelevantAlert.isPresent()) { + if (!mostRelevantAlert.get().equals(model.getDisplayedAuthorizedAlertData())) { + // Only show incoming alert effect if newly added alert is more relevant than current one + model.reset(); + } + add(mostRelevantAlert.get()); + } + }); } - private void updateIsAlertBannerVisible(boolean isVisible) { - alertNotificationsService.getIsAlertBannerVisible().set(isVisible); + private void add(AuthorizedAlertData authorizedAlertData) { + model.setDisplayedAuthorizedAlertData(authorizedAlertData); + model.getHeadline().set(authorizedAlertData.getHeadline().orElseThrow()); + authorizedAlertData.getMessage().ifPresent(message -> model.getMessage().set(message)); + model.getAlertType().set(authorizedAlertData.getAlertType()); + model.getIsAlertVisible().set(true); } } diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/alert/AlertBannerModel.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/alert/AlertBannerModel.java index 41442c6ba4..4897aa18d0 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/alert/AlertBannerModel.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/alert/AlertBannerModel.java @@ -21,21 +21,11 @@ import bisq.bonded_roles.security_manager.alert.AuthorizedAlertData; import bisq.desktop.common.view.Model; import javafx.beans.property.*; -import javafx.collections.FXCollections; -import javafx.collections.ObservableList; -import javafx.collections.transformation.FilteredList; -import javafx.collections.transformation.SortedList; import lombok.Getter; import lombok.Setter; -import java.util.HashSet; -import java.util.Set; - @Getter public class AlertBannerModel implements Model { - private final ObservableList observableList = FXCollections.observableArrayList(); - private final SortedList sortedList = new SortedList<>(observableList); - @Setter private AuthorizedAlertData displayedAuthorizedAlertData; private final BooleanProperty isAlertVisible = new SimpleBooleanProperty(); diff --git a/bonded-roles/src/main/java/bisq/bonded_roles/security_manager/alert/AlertNotificationsService.java b/bonded-roles/src/main/java/bisq/bonded_roles/security_manager/alert/AlertNotificationsService.java index d16f17bf80..378c6471c1 100644 --- a/bonded-roles/src/main/java/bisq/bonded_roles/security_manager/alert/AlertNotificationsService.java +++ b/bonded-roles/src/main/java/bisq/bonded_roles/security_manager/alert/AlertNotificationsService.java @@ -28,15 +28,17 @@ import java.util.concurrent.CompletableFuture; +import static com.google.common.base.Preconditions.checkNotNull; + @Slf4j public class AlertNotificationsService implements Service { private final SettingsService settingsService; private final AlertService alertService; @Getter - private final Observable isAlertBannerVisible = new Observable<>(false); - private Pin authorizedAlertDataSetPin; - @Getter private final ObservableSet unconsumedAlerts = new ObservableSet<>(); + @Getter + private final Observable isAlertBannerVisible = new Observable<>(false); + private Pin authorizedAlertDataSetPin, unconsumedAlertsPin; public AlertNotificationsService(SettingsService settingsService, AlertService alertService) { this.settingsService = settingsService; @@ -72,17 +74,21 @@ public void clear() { } }); + unconsumedAlertsPin = unconsumedAlerts.addObserver(this::updateIsNotificationBannerVisible); + return CompletableFuture.completedFuture(true); } @Override public CompletableFuture shutdown() { authorizedAlertDataSetPin.unbind(); + unconsumedAlertsPin.unbind(); return CompletableFuture.completedFuture(true); } public void dismissAlert(AuthorizedAlertData authorizedAlertData) { + checkNotNull(authorizedAlertData, "Cannot dismiss alert because it's null."); settingsService.getConsumedAlertIds().add(authorizedAlertData.getId()); unconsumedAlerts.remove(authorizedAlertData); } @@ -92,4 +98,8 @@ private boolean shouldProcessAlert(AuthorizedAlertData authorizedAlertData) { && !settingsService.getConsumedAlertIds().contains(authorizedAlertData.getId()) && authorizedAlertData.getMessage().isPresent(); } + + private void updateIsNotificationBannerVisible() { + isAlertBannerVisible.set(!unconsumedAlerts.isEmpty()); + } } From 4bcaaa92c3bf31baab6a19ebad3e969796bc8087 Mon Sep 17 00:00:00 2001 From: axpoems <145597137+axpoems@users.noreply.github.com> Date: Tue, 26 Mar 2024 22:10:47 +0100 Subject: [PATCH 08/10] Correct paddings based on whether there's another notification --- .../java/bisq/desktop/main/MainController.java | 3 +-- .../main/alert/AlertBannerController.java | 17 ++++++++++++++--- .../desktop/main/alert/AlertBannerModel.java | 1 + .../desktop/main/alert/AlertBannerView.java | 16 +++++++++++----- .../desktop/main/content/ContentTabModel.java | 2 +- 5 files changed, 28 insertions(+), 11 deletions(-) diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/MainController.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/MainController.java index 4a3393e25c..f210192de9 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/MainController.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/MainController.java @@ -54,14 +54,13 @@ public MainController(ServiceProvider serviceProvider) { super(NavigationTarget.MAIN); this.serviceProvider = serviceProvider; - AlertNotificationsService alertNotificationsService = serviceProvider.getAlertNotificationsService(); updaterService = serviceProvider.getUpdaterService(); config = serviceProvider.getConfig(); leftNavController = new LeftNavController(serviceProvider); TopPanelController topPanelController = new TopPanelController(serviceProvider); NotificationPanelController notificationPanelController = new NotificationPanelController(serviceProvider); - AlertBannerController alertBannerController = new AlertBannerController(alertNotificationsService); + AlertBannerController alertBannerController = new AlertBannerController(serviceProvider); view = new MainView(model, this, leftNavController.getView().getRoot(), diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/alert/AlertBannerController.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/alert/AlertBannerController.java index 716d6df3dd..1dfa2712ec 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/alert/AlertBannerController.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/alert/AlertBannerController.java @@ -17,9 +17,11 @@ package bisq.desktop.main.alert; +import bisq.bisq_easy.BisqEasyNotificationsService; import bisq.bonded_roles.security_manager.alert.AlertNotificationsService; import bisq.bonded_roles.security_manager.alert.AuthorizedAlertData; import bisq.common.observable.Pin; +import bisq.desktop.ServiceProvider; import bisq.desktop.common.threading.UIThread; import bisq.desktop.common.view.Controller; import lombok.Getter; @@ -34,10 +36,12 @@ public class AlertBannerController implements Controller { @Getter private final AlertBannerView view; private final AlertNotificationsService alertNotificationsService; - private Pin unconsumedAlertsPin; + private final BisqEasyNotificationsService bisqEasyNotificationsService; + private Pin unconsumedAlertsPin, isBisqEasyNotificationVisiblePin; - public AlertBannerController(AlertNotificationsService alertNotificationsService) { - this.alertNotificationsService = alertNotificationsService; + public AlertBannerController(ServiceProvider serviceProvider) { + alertNotificationsService = serviceProvider.getAlertNotificationsService(); + bisqEasyNotificationsService = serviceProvider.getBisqEasyService().getBisqEasyNotificationsService(); model = new AlertBannerModel(); view = new AlertBannerView(model, this); } @@ -45,11 +49,14 @@ public AlertBannerController(AlertNotificationsService alertNotificationsService @Override public void onActivate() { unconsumedAlertsPin = alertNotificationsService.getUnconsumedAlerts().addObserver(this::showAlertBanner); + isBisqEasyNotificationVisiblePin = bisqEasyNotificationsService.getIsNotificationPanelVisible().addObserver( + this::updateIsBisqEasyNotificationVisible); } @Override public void onDeactivate() { unconsumedAlertsPin.unbind(); + isBisqEasyNotificationVisiblePin.unbind(); } void onClose() { @@ -81,4 +88,8 @@ private void add(AuthorizedAlertData authorizedAlertData) { model.getAlertType().set(authorizedAlertData.getAlertType()); model.getIsAlertVisible().set(true); } + + private void updateIsBisqEasyNotificationVisible(boolean isVisible) { + model.getIsBisqEasyNotificationVisible().set(isVisible); + } } diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/alert/AlertBannerModel.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/alert/AlertBannerModel.java index 4897aa18d0..7d8857580e 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/alert/AlertBannerModel.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/alert/AlertBannerModel.java @@ -32,6 +32,7 @@ public class AlertBannerModel implements Model { private final StringProperty headline = new SimpleStringProperty(); private final StringProperty message = new SimpleStringProperty(); private final ObjectProperty alertType = new SimpleObjectProperty<>(); + private final BooleanProperty isBisqEasyNotificationVisible = new SimpleBooleanProperty(); public AlertBannerModel() { } diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/alert/AlertBannerView.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/alert/AlertBannerView.java index 751f928ded..473a607bcf 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/alert/AlertBannerView.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/alert/AlertBannerView.java @@ -40,15 +40,17 @@ @Slf4j public class AlertBannerView extends View { public static final int DURATION = Transitions.DEFAULT_DURATION / 2; - private final VBox contentVBox; + public static final Insets DEFAULT_PADDING = new Insets(20, 40, 20, 40); + public static final Insets PADDING_WITH_NOTIFICATION = new Insets(0, 40, 20, 40); - Label headline = new Label(); - Label message = new Label(); + private final VBox contentVBox; private final Button closeButton; private final HBox banner; private final ChangeListener heightListener; + Label headline = new Label(); + Label message = new Label(); private Timeline slideInRightTimeline, slideOutTopTimeline; - private Subscription isVisiblePin, alertTypePin; + private Subscription isVisiblePin, alertTypePin, isBisqEasyNotificationVisiblePin; public AlertBannerView(AlertBannerModel model, AlertBannerController controller) { super(new BorderPane(), model, controller); @@ -74,7 +76,7 @@ public AlertBannerView(AlertBannerModel model, AlertBannerController controller) heightListener = ((observable, oldValue, newValue) -> banner.setMinHeight(contentVBox.getHeight() + 25)); // padding = 25 root.setCenter(banner); - root.setPadding(new Insets(20, 40, 20, 40)); + root.setPadding(DEFAULT_PADDING); } @Override @@ -119,6 +121,9 @@ protected void onViewAttached() { } }); + isBisqEasyNotificationVisiblePin = EasyBind.subscribe(model.getIsBisqEasyNotificationVisible(), isVisible -> + root.setPadding(isVisible ? PADDING_WITH_NOTIFICATION : DEFAULT_PADDING)); + message.heightProperty().addListener(heightListener); closeButton.setOnAction(e -> controller.onClose()); @@ -131,6 +136,7 @@ protected void onViewDetached() { isVisiblePin.unsubscribe(); alertTypePin.unsubscribe(); + isBisqEasyNotificationVisiblePin.unsubscribe(); message.heightProperty().removeListener(heightListener); diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/ContentTabModel.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/ContentTabModel.java index 0036b51e8e..da9c0e6160 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/ContentTabModel.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/ContentTabModel.java @@ -25,4 +25,4 @@ @Getter public abstract class ContentTabModel extends TabModel { private final BooleanProperty isNotificationVisible = new SimpleBooleanProperty(); -} \ No newline at end of file +} From 5d97a3395bbc99de6ce5048968688767956689ae Mon Sep 17 00:00:00 2001 From: axpoems <145597137+axpoems@users.noreply.github.com> Date: Tue, 26 Mar 2024 22:21:41 +0100 Subject: [PATCH 09/10] Remove unused import --- .../main/java/bisq/desktop_app/DesktopApplicationService.java | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/desktop/desktop-app/src/main/java/bisq/desktop_app/DesktopApplicationService.java b/apps/desktop/desktop-app/src/main/java/bisq/desktop_app/DesktopApplicationService.java index 25cd5409a2..9fcbbb0ffc 100644 --- a/apps/desktop/desktop-app/src/main/java/bisq/desktop_app/DesktopApplicationService.java +++ b/apps/desktop/desktop-app/src/main/java/bisq/desktop_app/DesktopApplicationService.java @@ -48,7 +48,6 @@ import bisq.wallets.electrum.ElectrumWalletService; import lombok.Getter; import lombok.extern.slf4j.Slf4j; -import org.checkerframework.checker.units.qual.A; import java.util.Optional; import java.util.concurrent.CompletableFuture; From a8dcc617815ba01b85896151cb7eb4dfd970a65e Mon Sep 17 00:00:00 2001 From: axpoems <145597137+axpoems@users.noreply.github.com> Date: Tue, 26 Mar 2024 22:27:39 +0100 Subject: [PATCH 10/10] Only add alert if different from current --- .../bisq/desktop/main/alert/AlertBannerController.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/alert/AlertBannerController.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/alert/AlertBannerController.java index 1dfa2712ec..0ad1019d22 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/alert/AlertBannerController.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/alert/AlertBannerController.java @@ -71,11 +71,8 @@ private void showAlertBanner() { UIThread.run(() -> { Optional mostRelevantAlert = alertNotificationsService.getUnconsumedAlerts().stream() .max(Comparator.comparing(AuthorizedAlertData::getAlertType).thenComparing(AuthorizedAlertData::getDate)); - if (mostRelevantAlert.isPresent()) { - if (!mostRelevantAlert.get().equals(model.getDisplayedAuthorizedAlertData())) { - // Only show incoming alert effect if newly added alert is more relevant than current one - model.reset(); - } + if (mostRelevantAlert.isPresent() && !mostRelevantAlert.get().equals(model.getDisplayedAuthorizedAlertData())) { + model.reset(); add(mostRelevantAlert.get()); } });