Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chat messages selectable / copyable #521

Closed
wants to merge 8 commits into from
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,40 @@

import de.qabel.desktop.daemon.drop.TextMessage;
import javafx.scene.Node;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.layout.StackPane;

import java.util.ResourceBundle;

public class PlaintextMessageRenderer implements FXMessageRenderer {

@Override
public Node render(String dropPayload, ResourceBundle resourceBundle) {
Label label = new Label(renderString(dropPayload, resourceBundle));
label.getStyleClass().add("message-text");
return makeSelectable(label);
}

private Label makeSelectable(Label label) {
StackPane textStack = new StackPane();
textStack.getStyleClass().add("selectable-text");

TextArea textField = new TextArea(label.getText());
textField.setEditable(false);
textField.setWrapText(true);
String style = "-fx-background-color: transparent; -fx-background-insets: 0; -fx-background-radius: 0; -fx-padding: 0;";
textField.setStyle(style);
// the invisible label is a hack to get the textField to size like a label.
Label invisibleLabel = new Label();
invisibleLabel.textProperty().bind(label.textProperty());
invisibleLabel.setVisible(false);
textStack.getChildren().addAll(invisibleLabel, textField);

label.textProperty().bindBidirectional(textField.textProperty());
label.setGraphic(textStack);
label.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
return label;
}

Expand Down
8 changes: 8 additions & 0 deletions src/main/resources/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -822,3 +822,11 @@ VBox.spaced, HBox.spaced {
.error-textfield {
-fx-effect: dropshadow(three-pass-box, red, 8, 0.0, 0, 1);
}

.selectable-text * {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works but in html this would be very expensive because it selects from right to left and would select every element and then check its perent recursively. Not sure how javafx does this but I would prefer to replace * by the exact element if you can figure that out. Scenic View might be of help...

-fx-background-color: transparent;
-fx-background-insets: 0;
-fx-background-radius: 0;
-fx-padding: 0;
-fx-text-fill: white;
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public void testSendMessage() {
String text = "Message";
waitUntil(() -> controller.textarea != null);
Identity i = controller.identity;
controller.contact = new Contact(i.getAlias(),i.getDropUrls(), i.getEcPublicKey());
controller.contact = new Contact(i.getAlias(), i.getDropUrls(), i.getEcPublicKey());
clickOn("#textarea").write(text);
robot.push(KeyCode.ENTER);
List<DropMessage> list = receiveMessages();
Expand All @@ -48,6 +48,22 @@ private List<DropMessage> receiveMessages() {
@Test
public void multilineInput() {
controller.contact = new Contact(identity.getAlias(), identity.getDropUrls(), identity.getEcPublicKey());
writeTwoLinesOfText();

submitChat();

DropMessage message = receiveMessages().get(0);
assertEquals(DropMessageRepository.PAYLOAD_TYPE_MESSAGE, message.getDropPayloadType());
assertEquals("line1\nline2", TextMessage.fromJson(message.getDropPayload()).getText());
}

private void submitChat() {
assertTrue(receiveMessages().isEmpty());
robot.push(KeyCode.ENTER);
assertFalse(receiveMessages().isEmpty());
}

private void writeTwoLinesOfText() {
FxRobot textArea = clickOn("#textarea");
textArea.write("line1");
robot.press(KeyCode.SHIFT);
Expand All @@ -57,16 +73,21 @@ public void multilineInput() {
robot.release(KeyCode.SHIFT);
}
robot.write("line2");
}

assertTrue(receiveMessages().isEmpty());
robot.push(KeyCode.ENTER);
assertFalse(receiveMessages().isEmpty());

DropMessage message = receiveMessages().get(0);
assertEquals(DropMessageRepository.PAYLOAD_TYPE_MESSAGE, message.getDropPayloadType());
assertEquals("line1\nline2", TextMessage.fromJson(message.getDropPayload()).getText());
private void writeTwoLinesOfText(String line1, String line2) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unused. Either remove it or use it instead of writeTwoLinesOfText. I would prefer the latter because it increases the tests readability / clearifies the intent:

writeTwoLinesOfText("line1", "line2");
...
assertEquals("line1\nline2", ...);

FxRobot textArea = clickOn("#textarea");
textArea.write(line1);
robot.press(KeyCode.SHIFT);
try {
robot.push(KeyCode.ENTER);
} finally {
robot.release(KeyCode.SHIFT);
}
robot.write(line2);
}


@Test
public void testSendMessageWithoutContent() {
waitUntil(() -> controller.textarea != null);
Expand Down