Skip to content

Commit

Permalink
Merge pull request bisq-network#2252 from axpoems/update-dropdown-in-…
Browse files Browse the repository at this point in the history
…chat-msgs

Update dropdown in chat messages
  • Loading branch information
djing-chan authored Jun 11, 2024
2 parents 09e7c91 + 3bd33ad commit 116b9f8
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 132 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
package bisq.desktop.components.controls;

import bisq.desktop.common.utils.ImageUtil;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.WeakChangeListener;
import javafx.collections.ObservableList;
Expand All @@ -33,19 +35,25 @@
import javafx.stage.PopupWindow;
import javafx.stage.WindowEvent;
import lombok.Getter;
import lombok.Setter;

import java.util.Collection;

public class DropdownMenu extends HBox {
public static final Double INITIAL_WIDTH = 24.0;
@Getter
private Label label = new Label();

private final ImageView defaultIcon, activeIcon;
@Getter
private final BooleanProperty isMenuShowing = new SimpleBooleanProperty(false);
private final ContextMenu contextMenu = new ContextMenu();
@Getter
private Label label = new Label();
private ImageView buttonIcon;
// We need to pin it as used in a WeakChangeListener
private ChangeListener<Number> widthPropertyChangeListener;
private boolean isFirstRun = false;
@Setter
private boolean openUpwards = false;

public DropdownMenu(String defaultIconId, String activeIconId, boolean useIconOnly) {
defaultIcon = ImageUtil.getImageViewById(defaultIconId);
Expand Down Expand Up @@ -84,10 +92,12 @@ public void setLabel(Label label) {

private void toggleContextMenu() {
if (!contextMenu.isShowing()) {
contextMenu.setAnchorLocation(PopupWindow.AnchorLocation.WINDOW_TOP_RIGHT);
Bounds bounds = this.localToScreen(this.getBoundsInLocal());
contextMenu.setAnchorLocation(openUpwards
? PopupWindow.AnchorLocation.WINDOW_BOTTOM_RIGHT
: PopupWindow.AnchorLocation.WINDOW_TOP_RIGHT);
Bounds bounds = localToScreen(getBoundsInLocal());
double x = bounds.getMaxX();
double y = bounds.getMaxY() + 3;
double y = openUpwards ? bounds.getMinY() - 3 : bounds.getMaxY() + 3;
contextMenu.show(this, x, y);
} else {
contextMenu.hide();
Expand Down Expand Up @@ -123,7 +133,7 @@ public void setTooltip(Tooltip tooltip) {
}

private void attachListeners() {
setOnMouseClicked(event -> toggleContextMenu());
setOnMouseClicked(e -> toggleContextMenu());
setOnMouseExited(e -> updateIcon(contextMenu.isShowing() ? activeIcon : defaultIcon));
setOnMouseEntered(e -> updateIcon(activeIcon));

Expand All @@ -140,11 +150,12 @@ private void attachListeners() {
contextMenu.setOnShowing(e -> {
getStyleClass().add("dropdown-menu-active");
updateIcon(activeIcon);

isMenuShowing.setValue(true);
});
contextMenu.setOnHidden(e -> {
getStyleClass().remove("dropdown-menu-active");
updateIcon(defaultIcon);
isMenuShowing.setValue(false);
});

widthPropertyChangeListener = (observable, oldValue, newValue) -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,10 @@
import bisq.common.observable.Pin;
import bisq.common.observable.collection.CollectionObserver;
import bisq.desktop.ServiceProvider;
import bisq.desktop.common.observable.FxBindings;
import bisq.desktop.common.threading.UIScheduler;
import bisq.desktop.common.threading.UIThread;
import bisq.desktop.common.utils.ClipboardUtil;
import bisq.desktop.common.view.Navigation;
import bisq.desktop.components.controls.BisqPopup;
import bisq.desktop.components.controls.BisqPopupMenu;
import bisq.desktop.components.controls.BisqPopupMenuItem;
import bisq.desktop.components.overlay.Popup;
import bisq.desktop.main.content.bisq_easy.BisqEasyServiceUtil;
import bisq.desktop.main.content.bisq_easy.take_offer.TakeOfferController;
Expand All @@ -54,7 +50,6 @@
import bisq.user.profile.UserProfileService;
import bisq.user.reputation.ReputationScore;
import bisq.user.reputation.ReputationService;
import javafx.scene.Node;
import javafx.scene.Scene;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -63,7 +58,6 @@

import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Consumer;
Expand Down Expand Up @@ -388,29 +382,6 @@ public void onSaveEditedMessage(ChatMessage chatMessage, String editedText) {
}
}

void onOpenMoreOptions(Node owner, ChatMessage chatMessage, Runnable onClose) {
if (chatMessage.equals(model.getSelectedChatMessageForMoreOptionsPopup().get())) {
return;
}
model.getSelectedChatMessageForMoreOptionsPopup().set(chatMessage);

List<BisqPopupMenuItem> items = new ArrayList<>();
items.add(new BisqPopupMenuItem(Res.get("chat.message.contextMenu.copyMessage"),
() -> onCopyMessage(chatMessage)));
if (!model.isMyMessage(chatMessage)) {
if (chatMessage instanceof PublicChatMessage) {
items.add(new BisqPopupMenuItem(Res.get("chat.message.contextMenu.ignoreUser"),
() -> onIgnoreUser(chatMessage)));
}
items.add(new BisqPopupMenuItem(Res.get("chat.message.contextMenu.reportUser"),
() -> onReportUser(chatMessage)));
}

BisqPopupMenu menu = new BisqPopupMenu(items, onClose);
menu.setAlignment(BisqPopup.Alignment.LEFT);
menu.show(owner);
}

public void onReportUser(ChatMessage chatMessage) {
ChatChannelDomain chatChannelDomain = model.getSelectedChannel().get().getChatChannelDomain();
if (chatMessage instanceof PrivateChatMessage) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ public class ChatMessagesListModel implements bisq.desktop.common.view.Model {
private final BooleanProperty layoutChildrenDone = new SimpleBooleanProperty();

private final BooleanProperty isPublicChannel = new SimpleBooleanProperty();
private final ObjectProperty<ChatMessage> selectedChatMessageForMoreOptionsPopup = new SimpleObjectProperty<>(null);
private final ChatChannelDomain chatChannelDomain;
@Setter
private Predicate<? super ChatMessageListItem<? extends ChatMessage, ? extends ChatChannel<? extends ChatMessage>>> searchPredicate = e -> true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import bisq.desktop.common.utils.ClipboardUtil;
import bisq.desktop.common.utils.ImageUtil;
import bisq.desktop.components.controls.BisqTooltip;
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.ChatMessagesListModel;
Expand Down Expand Up @@ -61,6 +62,7 @@ public abstract class BubbleMessageBox extends MessageBox {
protected Label supportedLanguages, userName, dateTime, message;
protected HBox userNameAndDateHBox, messageBgHBox, messageHBox;
protected VBox userProfileIconVbox;
protected DropdownMenu moreOptionsMenu;

public BubbleMessageBox(ChatMessageListItem<? extends ChatMessage, ? extends ChatChannel<? extends ChatMessage>> item,
ListView<ChatMessageListItem<? extends ChatMessage, ? extends ChatChannel<? extends ChatMessage>>> list,
Expand Down Expand Up @@ -133,15 +135,15 @@ protected void addReactionsHandlers() {

private void addOnMouseEventHandlers() {
setOnMouseEntered(e -> {
if (model.getSelectedChatMessageForMoreOptionsPopup().get() != null) {
if (moreOptionsMenu != null && moreOptionsMenu.getIsMenuShowing().get()) {
return;
}
dateTime.setVisible(true);
reactionsHBox.setVisible(true);
});

setOnMouseExited(e -> {
if (model.getSelectedChatMessageForMoreOptionsPopup().get() == null) {
if (moreOptionsMenu == null || !moreOptionsMenu.getIsMenuShowing().get()) {
dateTime.setVisible(false);
reactionsHBox.setVisible(false);
}
Expand All @@ -152,6 +154,7 @@ private void addOnMouseEventHandlers() {
public void cleanup() {
setOnMouseEntered(null);
setOnMouseExited(null);

showHighlightedPin.unsubscribe();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,9 @@ public PeerOfferMessageBox(ChatMessageListItem<? extends ChatMessage, ? extends
ChatMessagesListController controller, ChatMessagesListModel model) {
super(item, list, controller, model);

HBox.setMargin(copyIcon, new Insets(4, 0, -4, 0));
HBox.setMargin(supportedLanguages, new Insets(5, 0, -5, 0));
reactionsHBox.getChildren().setAll(replyIcon, pmIcon, supportedLanguages, moreOptionsIcon, Spacer.fillHBox());
reactionsHBox.getChildren().setAll(replyIcon, pmIcon, copyIcon, supportedLanguages, moreOptionsMenu, Spacer.fillHBox());

VBox.setMargin(userNameAndDateHBox, new Insets(-5, 0, 5, 10));
contentVBox.getChildren().setAll(userNameAndDateHBox, messageBgHBox, reactionsHBox);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,27 +21,26 @@
import bisq.chat.ChatMessage;
import bisq.chat.pub.PublicChatMessage;
import bisq.desktop.components.containers.Spacer;
import bisq.desktop.components.controls.BisqPopup;
import bisq.desktop.components.controls.BisqPopupMenu;
import bisq.desktop.components.controls.BisqPopupMenuItem;
import bisq.desktop.components.controls.DropdownMenu;
import bisq.desktop.components.controls.DropdownMenuItem;
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.ChatMessagesListModel;
import bisq.i18n.Res;
import de.jensd.fx.fontawesome.AwesomeIcon;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;

import java.util.ArrayList;
import java.util.List;
import org.fxmisc.easybind.EasyBind;
import org.fxmisc.easybind.Subscription;

public class PeerTextMessageBox extends BubbleMessageBox {
protected Label replyIcon, pmIcon, moreOptionsIcon;
private Subscription isMenuShowingPin;
protected Label replyIcon, pmIcon, copyIcon;
protected DropdownMenuItem ignoreUserMenuItem, reportUserMenuItem;

public PeerTextMessageBox(ChatMessageListItem<? extends ChatMessage, ? extends ChatChannel<? extends ChatMessage>> item,
ListView<ChatMessageListItem<? extends ChatMessage, ? extends ChatChannel<? extends ChatMessage>>> list,
Expand All @@ -51,7 +50,7 @@ public PeerTextMessageBox(ChatMessageListItem<? extends ChatMessage, ? extends C
setUpPeerMessage();
setMargin(userNameAndDateHBox, new Insets(-5, 0, -5, 10));
messageHBox.getChildren().setAll(messageBgHBox, Spacer.fillHBox());
reactionsHBox.getChildren().setAll(replyIcon, pmIcon, moreOptionsIcon, Spacer.fillHBox());
reactionsHBox.getChildren().setAll(replyIcon, pmIcon, copyIcon, moreOptionsMenu, Spacer.fillHBox());

contentVBox.getChildren().setAll(userNameAndDateHBox, messageHBox, reactionsHBox);
}
Expand All @@ -68,28 +67,45 @@ protected void setUpUserNameAndDateTime() {
protected void setUpReactions() {
replyIcon = getIconWithToolTip(AwesomeIcon.REPLY, Res.get("chat.message.reply"));
pmIcon = getIconWithToolTip(AwesomeIcon.COMMENT_ALT, Res.get("chat.message.privateMessage"));
moreOptionsIcon = getIconWithToolTip(AwesomeIcon.ELLIPSIS_HORIZONTAL, Res.get("chat.message.moreOptions"));
copyIcon = getIconWithToolTip(AwesomeIcon.COPY, Res.get("action.copyToClipboard"));

// More options dropdown menu
ignoreUserMenuItem = new DropdownMenuItem(Res.get("chat.message.contextMenu.ignoreUser"));
reportUserMenuItem = new DropdownMenuItem(Res.get("chat.message.contextMenu.reportUser"));
moreOptionsMenu = new DropdownMenu("ellipsis-h-grey", "ellipsis-h-white", true);
moreOptionsMenu.setTooltip(Res.get("chat.message.moreOptions"));
moreOptionsMenu.addMenuItems(ignoreUserMenuItem, reportUserMenuItem);
moreOptionsMenu.setOpenUpwards(true);

HBox.setMargin(replyIcon, new Insets(4, 0, -4, 10));
HBox.setMargin(pmIcon, new Insets(3, 0, -3, 0));
HBox.setMargin(moreOptionsIcon, new Insets(5, 0, -5, 0));
HBox.setMargin(copyIcon, new Insets(4, 0, -4, 0));
HBox.setMargin(moreOptionsMenu, new Insets(2, 0, -2, 0));
reactionsHBox.setVisible(false);
}

@Override
protected void addReactionsHandlers() {
ChatMessage chatMessage = item.getChatMessage();
moreOptionsIcon.setOnMouseClicked(e -> onOpenMoreOptions(pmIcon, chatMessage, () -> {
reactionsHBox.setVisible(false);
model.getSelectedChatMessageForMoreOptionsPopup().set(null);
}));

replyIcon.setOnMouseClicked(e -> controller.onReply(chatMessage));
pmIcon.setOnMouseClicked(e -> controller.onOpenPrivateChannel(chatMessage));
copyIcon.setOnMouseClicked(e -> onCopyMessage(chatMessage));
ignoreUserMenuItem.setOnAction(e -> controller.onIgnoreUser(chatMessage));
reportUserMenuItem.setOnAction(e -> controller.onReportUser(chatMessage));

replyIcon.setVisible(true);
replyIcon.setManaged(true);

pmIcon.setVisible(chatMessage instanceof PublicChatMessage);
pmIcon.setManaged(chatMessage instanceof PublicChatMessage);

isMenuShowingPin = EasyBind.subscribe(moreOptionsMenu.getIsMenuShowing(), isShowing -> {
if (!isShowing && !isHover()) {
dateTime.setVisible(false);
reactionsHBox.setVisible(false);
}
});
}

protected void setUpPeerMessage() {
Expand All @@ -110,28 +126,6 @@ protected void setUpPeerMessage() {
messageBgHBox.getChildren().setAll(userProfileIconVbox, messageVBox);
}

private void onOpenMoreOptions(Node owner, ChatMessage chatMessage, Runnable onClose) {
if (chatMessage.equals(model.getSelectedChatMessageForMoreOptionsPopup().get())) {
return;
}
model.getSelectedChatMessageForMoreOptionsPopup().set(chatMessage);

List<BisqPopupMenuItem> items = new ArrayList<>();
items.add(new BisqPopupMenuItem(Res.get("chat.message.contextMenu.copyMessage"),
() -> onCopyMessage(chatMessage)));

if (chatMessage instanceof PublicChatMessage) {
items.add(new BisqPopupMenuItem(Res.get("chat.message.contextMenu.ignoreUser"),
() -> controller.onIgnoreUser(chatMessage)));
}
items.add(new BisqPopupMenuItem(Res.get("chat.message.contextMenu.reportUser"),
() -> controller.onReportUser(chatMessage)));

BisqPopupMenu menu = new BisqPopupMenu(items, onClose);
menu.setAlignment(BisqPopup.Alignment.LEFT);
menu.show(owner);
}

@Override
public void cleanup() {
super.cleanup();
Expand All @@ -142,8 +136,12 @@ public void cleanup() {
userProfileIcon.setOnMouseClicked(null);
replyIcon.setOnMouseClicked(null);
pmIcon.setOnMouseClicked(null);
moreOptionsIcon.setOnMouseClicked(null);
copyIcon.setOnMouseClicked(null);
ignoreUserMenuItem.setOnAction(null);
reportUserMenuItem.setOnAction(null);

userProfileIcon.releaseResources();

isMenuShowingPin.unsubscribe();
}
}

0 comments on commit 116b9f8

Please sign in to comment.