diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/components/controls/DrawerMenu.java b/apps/desktop/desktop/src/main/java/bisq/desktop/components/controls/DrawerMenu.java index fda547d12c..6221a3180b 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/components/controls/DrawerMenu.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/components/controls/DrawerMenu.java @@ -36,7 +36,7 @@ public class DrawerMenu extends HBox { private static final String SLIDE_LEFT_CSS_STYLE = "slide-left"; private final Button menuButton = new Button(); - private final HBox itemsHBox = new HBox(); + protected final HBox itemsHBox = new HBox(); private final ImageView defaultIcon, hoverIcon, activeIcon; @Getter private final BooleanProperty isMenuShowing = new SimpleBooleanProperty(false); diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/chat/message_container/list/ChatMessageListItem.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/chat/message_container/list/ChatMessageListItem.java index eaafbabdc3..b8f9b11c3b 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/chat/message_container/list/ChatMessageListItem.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/chat/message_container/list/ChatMessageListItem.java @@ -116,8 +116,9 @@ public final class ChatMessageListItem userReactionsPin = Optional.empty(); + private final Pin userIdentityPin; private final HashMap userReactions = new HashMap<>(); + private Optional userReactionsPin = Optional.empty(); public ChatMessageListItem(M chatMessage, C chatChannel, @@ -172,7 +173,8 @@ public ChatMessageListItem(M chatMessage, lastSeen = senderUserProfile.map(userProfileService::getLastSeen).orElse(-1L); lastSeenAsString = TimeFormatter.formatAge(lastSeen); - // TODO: Release all the listeners when destroying this object + userIdentityPin = userIdentityService.getSelectedUserIdentityObservable().addObserver(userIdentity -> UIThread.run(this::onUserIdentity)); + createAndAddSubscriptionToUserReactions(userProfileService); initializeDeliveryStatusIcons(); addSubscriptionToMessageDeliveryStatus(networkService); @@ -196,6 +198,7 @@ public void dispose() { mapPins.forEach(Pin::unbind); statusPins.forEach(Pin::unbind); userReactionsPin.ifPresent(Pin::unbind); + userIdentityPin.unbind(); } public boolean hasTradeChatOffer() { @@ -380,7 +383,8 @@ private void createAndAddSubscriptionToUserReactions(UserProfileService userProf } // Create all the ReactionItems - Arrays.stream(Reaction.values()).forEach(reaction -> userReactions.put(reaction, new ReactionItem(reaction))); + UserProfile selectedUserProfile = userIdentityService.getSelectedUserIdentity().getUserProfile(); + Arrays.stream(Reaction.values()).forEach(reaction -> userReactions.put(reaction, new ReactionItem(reaction, selectedUserProfile))); // Subscribe to changes userReactionsPin = Optional.ofNullable(chatMessage.getChatMessageReactions().addObserver(new CollectionObserver<>() { @@ -391,7 +395,7 @@ public void add(ChatMessageReaction element) { Optional userProfile = userProfileService.findUserProfile(element.getUserProfileId()); userProfile.ifPresent(profile -> { if (!userProfileService.isChatUserIgnored(profile)) { - userReactions.get(reaction).addUser(element, profile, isMyUser(profile)); + userReactions.get(reaction).addUser(element, profile); } }); } @@ -403,7 +407,7 @@ public void remove(Object element) { Reaction reaction = getReactionFromOrdinal(chatMessageReaction.getReactionId()); if (userReactions.containsKey(reaction)) { Optional userProfile = userProfileService.findUserProfile(chatMessageReaction.getUserProfileId()); - userProfile.ifPresent(profile -> userReactions.get(reaction).removeUser(profile, isMyUser(profile))); + userProfile.ifPresent(profile -> userReactions.get(reaction).removeUser(profile)); } } @@ -419,8 +423,8 @@ private static Reaction getReactionFromOrdinal(int ordinal) { return Reaction.values()[ordinal]; } - private boolean isMyUser(UserProfile profile) { - UserProfile myProfile = userIdentityService.getSelectedUserIdentity().getUserProfile(); - return myProfile.equals(profile); + private void onUserIdentity() { + UserProfile selectedUserProfile = userIdentityService.getSelectedUserIdentity().getUserProfile(); + userReactions.forEach((key, value) -> value.setSelectedUserProfile(selectedUserProfile)); } } diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/chat/message_container/list/ReactionItem.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/chat/message_container/list/ReactionItem.java index f76031960f..90292792bd 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/chat/message_container/list/ReactionItem.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/chat/message_container/list/ReactionItem.java @@ -38,14 +38,32 @@ public class ReactionItem { private long firstAdded; private final SimpleIntegerProperty count = new SimpleIntegerProperty(0); private final SimpleBooleanProperty selected = new SimpleBooleanProperty(false); - Set users = new HashSet<>(); + private final Set users = new HashSet<>(); + private UserProfile selectedUserProfile; - ReactionItem(Reaction reaction) { + ReactionItem(Reaction reaction, UserProfile selectedUserProfile) { this.reaction = reaction; + this.selectedUserProfile = selectedUserProfile; this.iconId = reaction.toString().replace("_", "").toLowerCase(); } - void addUser(ChatMessageReaction chatMessageReaction, UserProfile userProfile, boolean isMyUser) { + public boolean hasActiveReactions() { + return !users.isEmpty(); + } + + public String getCountAsString() { + long count = users.size(); + if (count < 2) { + return ""; + } + return count < 100 ? String.valueOf(count) : "+99"; + } + + public static Comparator firstAddedComparator() { + return Comparator.comparingLong(ReactionItem::getFirstAdded); + } + + void addUser(ChatMessageReaction chatMessageReaction, UserProfile userProfile) { if (hasReactionBeenRemoved(chatMessageReaction)) { return; } @@ -54,27 +72,20 @@ void addUser(ChatMessageReaction chatMessageReaction, UserProfile userProfile, b firstAdded = chatMessageReaction.getDate(); } - selected.set(isMyUser); users.add(userProfile); count.set(users.size()); + updateSelected(); } - void removeUser(UserProfile userProfile, boolean isMyUser) { - selected.set(!isMyUser); + void removeUser(UserProfile userProfile) { users.remove(userProfile); count.set(users.size()); + updateSelected(); } - public boolean hasActiveReactions() { - return !users.isEmpty(); - } - - public String getCountAsString() { - long count = users.size(); - if (count == 1) { - return ""; - } - return count < 100 ? String.valueOf(count) : "+99"; + void setSelectedUserProfile(UserProfile selectedUserProfile) { + this.selectedUserProfile = selectedUserProfile; + updateSelected(); } private boolean hasReactionBeenRemoved(ChatMessageReaction chatMessageReaction) { @@ -82,7 +93,7 @@ private boolean hasReactionBeenRemoved(ChatMessageReaction chatMessageReaction) && ((PrivateChatMessageReaction) chatMessageReaction).isRemoved()); } - public static Comparator firstAddedComparator() { - return Comparator.comparingLong(ReactionItem::getFirstAdded); + private void updateSelected() { + selected.set(getUsers().contains(selectedUserProfile)); } } diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/chat/message_container/list/message_box/BubbleMessageBox.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/chat/message_container/list/message_box/BubbleMessageBox.java index c83f6e08a5..992ae469ab 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/chat/message_container/list/message_box/BubbleMessageBox.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/chat/message_container/list/message_box/BubbleMessageBox.java @@ -26,15 +26,14 @@ import bisq.desktop.common.utils.ImageUtil; import bisq.desktop.components.controls.BisqMenuItem; import bisq.desktop.components.controls.BisqTooltip; -import bisq.desktop.components.controls.DrawerMenu; import bisq.desktop.components.controls.DropdownMenu; import bisq.desktop.main.content.chat.message_container.list.ChatMessageListItem; import bisq.desktop.main.content.chat.message_container.list.ChatMessagesListController; import bisq.desktop.main.content.chat.message_container.list.reactions_box.ActiveReactionsDisplayBox; +import bisq.desktop.main.content.chat.message_container.list.reactions_box.ReactMenuBox; import bisq.desktop.main.content.chat.message_container.list.reactions_box.ToggleReaction; import bisq.desktop.main.content.components.UserProfileIcon; import bisq.i18n.Res; -import javafx.css.PseudoClass; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.Cursor; @@ -43,12 +42,10 @@ import javafx.scene.layout.HBox; import javafx.scene.layout.Priority; import javafx.scene.layout.VBox; -import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.fxmisc.easybind.EasyBind; import org.fxmisc.easybind.Subscription; -import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Optional; @@ -59,7 +56,7 @@ public abstract class BubbleMessageBox extends MessageBox { protected static final double CHAT_MESSAGE_BOX_MAX_WIDTH = 630; // TODO: it should be 510 because of reactions on min size protected static final double OFFER_MESSAGE_USER_ICON_SIZE = 70; protected static final Insets ACTION_ITEMS_MARGIN = new Insets(2, 0, -2, 0); - private static final List REACTIONS = Arrays.asList(Reaction.THUMBS_UP, Reaction.THUMBS_DOWN, Reaction.HAPPY, + private static final List REACTIONS_ORDER = Arrays.asList(Reaction.THUMBS_UP, Reaction.THUMBS_DOWN, Reaction.HAPPY, Reaction.LAUGH, Reaction.HEART, Reaction.PARTY); private final Subscription showHighlightedPin; @@ -68,12 +65,11 @@ public abstract class BubbleMessageBox extends MessageBox { protected final ChatMessagesListController controller; protected final UserProfileIcon userProfileIcon = new UserProfileIcon(60); protected final HBox actionsHBox = new HBox(5); - protected final ActiveReactionsDisplayBox activeReactionsDisplayHBox; protected final VBox quotedMessageVBox, contentVBox; protected final BisqMenuItem deleteAction = new BisqMenuItem("delete-t-grey", "delete-t-red"); - protected DrawerMenu reactMenu; private Subscription reactMenuPin; - protected List reactionMenuItems = new ArrayList<>(); + protected ActiveReactionsDisplayBox activeReactionsDisplayHBox; + protected ReactMenuBox reactMenuBox; protected Label supportedLanguages, userName, dateTime, message; protected HBox userNameAndDateHBox, messageBgHBox, messageHBox; protected VBox userProfileIconVbox; @@ -89,11 +85,11 @@ public BubbleMessageBox(ChatMessageListItem { + private void setUpReactions() { + // Active Reactions Display + ToggleReaction toggleReactionDisplayMenuFunction = reactionItem -> + controller.onReactMessage(item.getChatMessage(), reactionItem.getReaction(), item.getChatChannel()); + activeReactionsDisplayHBox = new ActiveReactionsDisplayBox(item.getUserReactions().values(), toggleReactionDisplayMenuFunction); + + // React Menu + ToggleReaction toggleReactionReactMenuFunction = reactionItem -> { + controller.onReactMessage(item.getChatMessage(), reactionItem.getReaction(), item.getChatChannel()); + reactMenuBox.hideMenu(); + }; + reactMenuBox = new ReactMenuBox(item.getUserReactions(), REACTIONS_ORDER, toggleReactionReactMenuFunction, + "react-grey", "react-white", "react-green"); + reactMenuBox.setTooltip(Res.get("action.react")); + reactMenuBox.setVisible(item.getChatMessage().canShowReactions()); + reactMenuBox.setManaged(item.getChatMessage().canShowReactions()); + + reactMenuPin = EasyBind.subscribe(reactMenuBox.getIsMenuShowing(), isShowing -> { if (!isShowing && !isHover()) { showDateTimeAndActionsMenu(false); } }); + } - reactMenu.setVisible(item.getChatMessage().canShowReactions()); - reactMenu.setManaged(item.getChatMessage().canShowReactions()); - + protected void setUpActions() { + copyAction = new BisqMenuItem("copy-grey", "copy-white"); + copyAction.useIconOnly(); + copyAction.setTooltip(Res.get("action.copyToClipboard")); + actionsHBox.setVisible(false); HBox.setMargin(copyAction, ACTION_ITEMS_MARGIN); - HBox.setMargin(reactMenu, ACTION_ITEMS_MARGIN); + HBox.setMargin(reactMenuBox, ACTION_ITEMS_MARGIN); } protected void addActionsHandlers() { @@ -177,36 +184,28 @@ public void cleanup() { setOnMouseEntered(null); setOnMouseExited(null); - reactionMenuItems.forEach(menuItem -> menuItem.setOnAction(null)); - showHighlightedPin.unsubscribe(); reactMenuPin.unsubscribe(); activeReactionsDisplayHBox.dispose(); + reactMenuBox.dispose(); } private void showDateTimeAndActionsMenu(boolean shouldShow) { if (shouldShow) { - if ((moreActionsMenu != null && moreActionsMenu.getIsMenuShowing().get()) || reactMenu.getIsMenuShowing().get()) { + if ((moreActionsMenu != null && moreActionsMenu.getIsMenuShowing().get()) || reactMenuBox.getIsMenuShowing().get()) { return; } dateTime.setVisible(true); actionsHBox.setVisible(true); } else { - if ((moreActionsMenu == null || !moreActionsMenu.getIsMenuShowing().get()) && !reactMenu.getIsMenuShowing().get()) { + if ((moreActionsMenu == null || !moreActionsMenu.getIsMenuShowing().get()) && !reactMenuBox.getIsMenuShowing().get()) { dateTime.setVisible(false); actionsHBox.setVisible(false); } } } - private ActiveReactionsDisplayBox createAndGetActiveReactionsDisplayBox() { - ToggleReaction toggleReactionFunction = reactionItem -> { - controller.onReactMessage(item.getChatMessage(), reactionItem.getReaction(), item.getChatChannel()); - }; - return new ActiveReactionsDisplayBox(item.getUserReactions().values(), toggleReactionFunction); - } - private Label createAndGetSupportedLanguagesLabel() { Label label = new Label(); if (item.isBisqEasyPublicChatMessageWithOffer()) { @@ -285,49 +284,4 @@ protected static void onCopyMessage(ChatMessage chatMessage) { protected static void onCopyMessage(String chatMessageText) { ClipboardUtil.copyToClipboard(chatMessageText); } - - private DrawerMenu createAndGetReactMenu() { - DrawerMenu drawerMenu = new DrawerMenu("react-grey", "react-white", "react-green"); - drawerMenu.setTooltip(Res.get("action.react")); - drawerMenu.getStyleClass().add("react-menu"); - return drawerMenu; - } - - private void setUpReactMenu() { - REACTIONS.forEach(reaction -> { - String iconId = reaction.toString().replace("_", "").toLowerCase(); - ReactionMenuItem reactionMenuItem = new ReactionMenuItem(iconId, reaction); - reactionMenuItem.setOnAction(e -> toggleReaction(reactionMenuItem)); - reactionMenuItems.add(reactionMenuItem); - }); - } - - private void toggleReaction(ReactionMenuItem reactionMenuItem) { - controller.onReactMessage(item.getChatMessage(), reactionMenuItem.getReaction(), item.getChatChannel()); - reactMenu.hideMenu(); - updateIsReactionSelected(reactionMenuItem); - } - - private void updateIsReactionSelected(ReactionMenuItem reactionMenuItem) { - reactionMenuItem.setIsReactionSelected(item.hasAddedReaction(reactionMenuItem.getReaction())); - } - - @Getter - public static final class ReactionMenuItem extends BisqMenuItem { - private static final PseudoClass SELECTED_PSEUDO_CLASS = PseudoClass.getPseudoClass("selected"); - - private final Reaction reaction; - - public ReactionMenuItem(String iconId, Reaction reaction) { - super(iconId, iconId); - - this.reaction = reaction; - useIconOnly(24); - getStyleClass().add("reaction-menu-item"); - } - - public void setIsReactionSelected(boolean isSelected) { - pseudoClassStateChanged(SELECTED_PSEUDO_CLASS, isSelected); - } - } } diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/chat/message_container/list/message_box/MyTextMessageBox.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/chat/message_container/list/message_box/MyTextMessageBox.java index 4e45958221..1e8f637092 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/chat/message_container/list/message_box/MyTextMessageBox.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/chat/message_container/list/message_box/MyTextMessageBox.java @@ -37,8 +37,6 @@ import org.fxmisc.easybind.EasyBind; import org.fxmisc.easybind.Subscription; -import java.util.Collections; - public final class MyTextMessageBox extends BubbleMessageBox { private final static String EDITED_POST_FIX = " " + Res.get("chat.message.wasEdited"); @@ -65,7 +63,7 @@ public MyTextMessageBox(ChatMessageListItem reactionItems = FXCollections.observableArrayList(); private final FilteredList filteredReactionItems = new FilteredList<>(reactionItems, ReactionItem::hasActiveReactions); private final SortedList sortedReactionItems = new SortedList<>(filteredReactionItems); - private final Map> itemChangeListeners = new HashMap<>(); + private final Map> itemCountChangeListener = new HashMap<>(); + private final Map> itemSelectedChangeListener = new HashMap<>(); private final ListChangeListener listChangeListener; private final ToggleReaction toggleReaction; @@ -63,19 +64,31 @@ public void dispose() { } private void addItemListeners(ReactionItem item) { - ChangeListener listener = (obs, oldValue, newValue) -> { + ChangeListener numberChangeListener = (obs, oldValue, newValue) -> { int idx = reactionItems.indexOf(item); if (idx >= 0) { reactionItems.set(idx, item); } }; - item.getCount().addListener(listener); - itemChangeListeners.put(item, listener); + item.getCount().addListener(numberChangeListener); + itemCountChangeListener.put(item, numberChangeListener); + + ChangeListener booleanChangeListener = (obs, oldValue, newValue) -> { + int idx = reactionItems.indexOf(item); + if (idx >= 0) { + reactionItems.set(idx, item); + } + }; + item.getSelected().addListener(booleanChangeListener); + itemSelectedChangeListener.put(item, booleanChangeListener); } private void removeItemListeners() { - itemChangeListeners.forEach((item, listener) -> { - item.getCount().removeListener(listener); + itemCountChangeListener.forEach((item, changeListener) -> { + item.getCount().removeListener(changeListener); + }); + itemSelectedChangeListener.forEach((item, changeListener) -> { + item.getSelected().removeListener(changeListener); }); } @@ -93,7 +106,7 @@ private static final class ActiveReactionMenuItem extends BisqMenuItem { private ReactionItem reactionItem; private ToggleReaction toggleReaction; - public ActiveReactionMenuItem(ReactionItem reactionItem, ToggleReaction toggleReaction) { + private ActiveReactionMenuItem(ReactionItem reactionItem, ToggleReaction toggleReaction) { this(reactionItem.getIconId()); this.reactionItem = reactionItem; @@ -112,8 +125,6 @@ private void addStyleClasses() { getStyleClass().add("active-reaction-menu-item"); if (reactionItem.getSelected().get()) { getStyleClass().add("active-reaction-selected"); - } else { - getStyleClass().remove("active-reaction-selected"); } } } diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/chat/message_container/list/reactions_box/ReactMenuBox.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/chat/message_container/list/reactions_box/ReactMenuBox.java new file mode 100644 index 0000000000..66320d921b --- /dev/null +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/chat/message_container/list/reactions_box/ReactMenuBox.java @@ -0,0 +1,102 @@ +/* + * 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.desktop.main.content.chat.message_container.list.reactions_box; + +import bisq.chat.reactions.Reaction; +import bisq.desktop.components.controls.BisqMenuItem; +import bisq.desktop.components.controls.DrawerMenu; +import bisq.desktop.main.content.chat.message_container.list.ReactionItem; +import javafx.beans.value.ChangeListener; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.css.PseudoClass; +import javafx.scene.Node; +import lombok.Getter; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class ReactMenuBox extends DrawerMenu { + private final Map> itemSelectedChangeListener = new HashMap<>(); + + public ReactMenuBox(HashMap reactionItems, List orderedReactions, ToggleReaction toggleReaction, + String defaultIconId, String hoverIconId, String activeIconId) { + super(defaultIconId, hoverIconId, activeIconId); + + List reactionMenuItems = new ArrayList<>(); + orderedReactions.forEach(reaction -> { + if (reactionItems.containsKey(reaction)) { + ReactionItem reactionItem = reactionItems.get(reaction); + ReactionMenuItem reactionMenuItem = new ReactionMenuItem(reactionItem, toggleReaction); + reactionMenuItems.add(reactionMenuItem); + addItemListener(reactionItem, reactionMenuItem); + } + }); + addItems(reactionMenuItems); + + getStyleClass().add("react-menu-box"); + } + + public void dispose() { + removeItemListeners(); + } + + public void reverseReactionsDisplayOrder() { + ObservableList items = itemsHBox.getChildren(); + FXCollections.reverse(items); + } + + private void addItemListener(ReactionItem reactionItem, ReactionMenuItem reactionMenuItem) { + ChangeListener booleanChangeListener = (obs, oldValue, newValue) -> reactionMenuItem.setIsReactionSelected(newValue);; + reactionItem.getSelected().addListener(booleanChangeListener); + itemSelectedChangeListener.put(reactionItem, booleanChangeListener); + } + + private void removeItemListeners() { + itemSelectedChangeListener.forEach((item, changeListener) -> item.getSelected().removeListener(changeListener)); + } + + @Getter + private static final class ReactionMenuItem extends BisqMenuItem { + private static final PseudoClass SELECTED_PSEUDO_CLASS = PseudoClass.getPseudoClass("selected"); + + private ReactionItem reactionItem; + private ToggleReaction toggleReaction; + + private ReactionMenuItem(ReactionItem reactionItem, ToggleReaction toggleReaction) { + this(reactionItem.getIconId()); + + this.reactionItem = reactionItem; + this.toggleReaction = toggleReaction; + useIconOnly(24); + getStyleClass().add("reaction-menu-item"); + setOnAction(e -> toggleReaction.execute(reactionItem)); + setIsReactionSelected(reactionItem.getSelected().get()); + } + + private ReactionMenuItem(String iconId) { + super(iconId, iconId); + } + + private void setIsReactionSelected(boolean isSelected) { + pseudoClassStateChanged(SELECTED_PSEUDO_CLASS, isSelected); + } + } +} diff --git a/apps/desktop/desktop/src/main/resources/css/chat.css b/apps/desktop/desktop/src/main/resources/css/chat.css index 303391c857..e1564637ac 100644 --- a/apps/desktop/desktop/src/main/resources/css/chat.css +++ b/apps/desktop/desktop/src/main/resources/css/chat.css @@ -155,7 +155,7 @@ -fx-font-family: "IBM Plex Sans Light"; } -.chat-message-content-box .react-menu .drawer-menu-items .bisq-menu-item:hover { +.chat-message-content-box .react-menu-box .drawer-menu-items .bisq-menu-item:hover { -fx-background-color: -bisq-dark-grey-50 !important; }