Skip to content

Commit

Permalink
Add CustomStackPane allowing to get notified when layoutChildren meth…
Browse files Browse the repository at this point in the history
…od is completed.

Used to trigger update of the scroll state.
  • Loading branch information
HenrikJannsen committed Mar 31, 2024
1 parent 2fc9cc3 commit e564013
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,11 @@
import javafx.scene.control.ListView;
import javafx.scene.layout.HBox;
import javafx.util.Callback;
import lombok.extern.slf4j.Slf4j;
import org.fxmisc.easybind.EasyBind;
import org.fxmisc.easybind.Subscription;

@Slf4j
final class ChatMessageListCellFactory
implements Callback<ListView<ChatMessageListItem<? extends ChatMessage, ? extends ChatChannel<? extends ChatMessage>>>,
ListCell<ChatMessageListItem<? extends ChatMessage, ? extends ChatChannel<? extends ChatMessage>>>> {
Expand All @@ -57,13 +59,13 @@ public ChatMessageListCellFactory(ChatMessagesListController controller, ChatMes
private final static String STYLE_CLASS_WITH_SCROLLBAR_FULL_WIDTH = "chat-message-list-cell-w-scrollbar-full-width";
private final static String STYLE_CLASS_WITH_SCROLLBAR_MAX_WIDTH = "chat-message-list-cell-w-scrollbar-max-width";

private final HBox cellHBox;
private final HBox cellHBox = new HBox();
private Subscription listWidthPropertyPin;
private MessageBox messageBox;

{
cellHBox = new HBox();
cellHBox.setPadding(new Insets(15, 0, 15, 0));
setAlignment(Pos.CENTER);
}

@Override
Expand All @@ -78,24 +80,21 @@ public void updateItem(final ChatMessageListItem<? extends ChatMessage, ? extend

Node flow = this.getListView().lookup(".virtual-flow");
if (flow != null && !flow.isVisible()) {
cleanup();
return;
}

messageBox = createMessage(item, list);
cellHBox.getChildren().setAll(messageBox);
listWidthPropertyPin = EasyBind.subscribe(messageBox.widthProperty(), w -> updateMessageStyle());
setGraphic(cellHBox);
setAlignment(Pos.CENTER);
}

private void cleanup() {
if (messageBox != null) {
messageBox.cleanup();
}

cellHBox.setOnMouseEntered(null);
cellHBox.setOnMouseExited(null);

if (listWidthPropertyPin != null) {
listWidthPropertyPin.unsubscribe();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ public class ChatMessagesListController implements bisq.desktop.common.view.Cont
private final BisqEasyService bisqEasyService;
private final MarketPriceService marketPriceService;
private Pin selectedChannelPin, chatMessagesPin, offerOnlySettingsPin;
private Subscription selectedChannelSubscription, focusSubscription, scrollValuePin, scrollBarVisiblePin;
private Subscription selectedChannelSubscription, focusSubscription, scrollValuePin, scrollBarVisiblePin,
layoutChildrenDonePin;

public ChatMessagesListController(ServiceProvider serviceProvider,
Consumer<UserProfile> mentionUserHandler,
Expand Down Expand Up @@ -141,6 +142,10 @@ public void onActivate() {
}
});

layoutChildrenDonePin = EasyBind.subscribe(model.getLayoutChildrenDone(), layoutChildrenDone -> {
UIThread.runOnNextRenderFrame(this::handleScrollValueChanged);
});

applyScrollValue(1);
}

Expand All @@ -164,6 +169,7 @@ public void onDeactivate() {
selectedChannelSubscription.unsubscribe();
}

layoutChildrenDonePin.unsubscribe();
scrollValuePin.unsubscribe();
scrollBarVisiblePin.unsubscribe();

Expand Down Expand Up @@ -480,6 +486,11 @@ public void doLeaveChannel() {

private void applyScrollValue(double scrollValue) {
model.getScrollValue().set(scrollValue);
handleScrollValueChanged();
}

private void handleScrollValueChanged() {
double scrollValue = model.getScrollValue().get();
model.getHasUnreadMessages().set(model.getNumReadMessages() < model.getChatMessages().size());
boolean isAtBottom = scrollValue == 1d;
model.getShowScrolledDownButton().set(!isAtBottom && model.getScrollBarVisible().get());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ public class ChatMessagesListModel implements bisq.desktop.common.view.Model {
private final FilteredList<ChatMessageListItem<? extends ChatMessage, ? extends ChatChannel<? extends ChatMessage>>> filteredChatMessages = new FilteredList<>(chatMessages);
private final SortedList<ChatMessageListItem<? extends ChatMessage, ? extends ChatChannel<? extends ChatMessage>>> sortedChatMessages = new SortedList<>(filteredChatMessages);
private final Set<String> chatMessageIds = new HashSet<>();
private final BooleanProperty layoutChildrenDone = new SimpleBooleanProperty();

private final BooleanProperty isPublicChannel = new SimpleBooleanProperty();
private final ObjectProperty<ChatMessage> selectedChatMessageForMoreOptionsPopup = new SimpleObjectProperty<>(null);
private final ChatChannelDomain chatChannelDomain;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.geometry.Orientation;
Expand All @@ -28,14 +30,27 @@
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.util.Duration;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.fxmisc.easybind.EasyBind;
import org.fxmisc.easybind.Subscription;

import java.util.Optional;

@Slf4j
public class ChatMessagesListView extends bisq.desktop.common.view.View<StackPane, ChatMessagesListModel, ChatMessagesListController> {
public class ChatMessagesListView extends bisq.desktop.common.view.View<ChatMessagesListView.CustomStackPane, ChatMessagesListModel, ChatMessagesListController> {
@Getter
public static class CustomStackPane extends StackPane {
private final BooleanProperty layoutChildrenDone = new SimpleBooleanProperty();

@Override
protected void layoutChildren() {
layoutChildrenDone.set(false);
super.layoutChildren();
layoutChildrenDone.set(true);
}
}

private final ListView<ChatMessageListItem<? extends ChatMessage, ? extends ChatChannel<? extends ChatMessage>>> listView;
private final ImageView scrollDownImageView;
private final Badge scrollDownBadge;
Expand All @@ -48,7 +63,7 @@ public class ChatMessagesListView extends bisq.desktop.common.view.View<StackPan
private Timeline fadeInScrollDownBadgeTimeline;

public ChatMessagesListView(ChatMessagesListModel model, ChatMessagesListController controller) {
super(new StackPane(), model, controller);
super(new CustomStackPane(), model, controller);

listView = new ListView<>(model.getSortedChatMessages());
listView.getStyleClass().add("chat-messages-list-view");
Expand Down Expand Up @@ -130,6 +145,7 @@ protected void onViewAttached() {
scrollDownTooltip.setText(Res.get("chat.listView.scrollDown"));
}
});
model.getLayoutChildrenDone().bind(root.getLayoutChildrenDone());

scrollDownBadge.setOnMouseClicked(e -> controller.onScrollToBottom());

Expand All @@ -150,6 +166,7 @@ protected void onViewDetached() {
scrollDownBackground.visibleProperty().unbind();
scrollDownBackground.managedProperty().unbind();
scrollDownBadge.textProperty().unbind();
model.getLayoutChildrenDone().unbind();
hasUnreadMessagesPin.unsubscribe();
showScrolledDownButtonPin.unsubscribe();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,11 @@
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import lombok.extern.slf4j.Slf4j;

import java.util.Optional;

@Slf4j
public abstract class BubbleMessageBox extends MessageBox {
protected static final double CHAT_MESSAGE_BOX_MAX_WIDTH = 630;
protected static final double OFFER_MESSAGE_USER_ICON_SIZE = 70;
Expand Down Expand Up @@ -117,10 +119,6 @@ protected void setUpReactions() {
protected void addReactionsHandlers() {
}

protected void hideReactionsBox() {
reactionsHBox.setVisible(false);
}

private void addOnMouseEventHandlers() {
setOnMouseEntered(e -> {
if (model.getSelectedChatMessageForMoreOptionsPopup().get() != null) {
Expand All @@ -132,13 +130,18 @@ private void addOnMouseEventHandlers() {

setOnMouseExited(e -> {
if (model.getSelectedChatMessageForMoreOptionsPopup().get() == null) {
hideReactionsBox();
dateTime.setVisible(false);
reactionsHBox.setVisible(false);
}
});
}

@Override
public void cleanup() {
setOnMouseEntered(null);
setOnMouseExited(null);
}

private Label createAndGetSupportedLanguagesLabel() {
Label label = new Label();
if (item.isBisqEasyPublicChatMessageWithOffer()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,8 @@ private void onCloseEditMessage() {

@Override
public void cleanup() {
super.cleanup();

message.maxWidthProperty().unbind();
editInputField.maxWidthProperty().unbind();
deliveryState.getTooltip().textProperty().unbind();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ protected void setUpReactions() {
protected void addReactionsHandlers() {
ChatMessage chatMessage = item.getChatMessage();
moreOptionsIcon.setOnMouseClicked(e -> onOpenMoreOptions(pmIcon, chatMessage, () -> {
hideReactionsBox();
reactionsHBox.setVisible(false);
model.getSelectedChatMessageForMoreOptionsPopup().set(null);
}));
replyIcon.setOnMouseClicked(e -> controller.onReply(chatMessage));
Expand Down Expand Up @@ -134,6 +134,8 @@ private void onOpenMoreOptions(Node owner, ChatMessage chatMessage, Runnable onC

@Override
public void cleanup() {
super.cleanup();

message.maxWidthProperty().unbind();

userName.setOnMouseClicked(null);
Expand Down

0 comments on commit e564013

Please sign in to comment.