From b41bdc63bfcdc1e440e970501323987b6fe980a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pekka=20Maanp=C3=A4=C3=A4?= Date: Tue, 11 May 2021 20:41:40 +0300 Subject: [PATCH 1/3] feat: add theme API to MessageListItem Only with strings at this point, since no theme variants have been implemented so far. This enables developers to apply custom theming per each message in a MessageList. Related issue: https://github.com/vaadin/collaboration-engine/issues/30 --- .../messages/tests/MessageListPage.java | 2 + .../messages/tests/MessageListIT.java | 8 ++++ .../component/messages/MessageListItem.java | 41 +++++++++++++++++++ .../messages/tests/MessageListTest.java | 40 ++++++++++++++++++ .../messages/testbench/MessageElement.java | 9 ++++ 5 files changed, 100 insertions(+) diff --git a/vaadin-messages-flow-parent/vaadin-messages-flow-integration-tests/src/main/java/com/vaadin/flow/component/messages/tests/MessageListPage.java b/vaadin-messages-flow-parent/vaadin-messages-flow-integration-tests/src/main/java/com/vaadin/flow/component/messages/tests/MessageListPage.java index 91e4a14adc1..5b07696205d 100644 --- a/vaadin-messages-flow-parent/vaadin-messages-flow-integration-tests/src/main/java/com/vaadin/flow/component/messages/tests/MessageListPage.java +++ b/vaadin-messages-flow-parent/vaadin-messages-flow-integration-tests/src/main/java/com/vaadin/flow/component/messages/tests/MessageListPage.java @@ -51,6 +51,8 @@ public MessageListPage() { addButton("setUserImage", () -> foo.setUserImage("/test2.jpg")); addButton("setAbbreviation", () -> foo.setUserAbbreviation("CD")); addButton("setUserColorIndex", () -> foo.setUserColorIndex(2)); + addButton("addThemeNames", () -> foo.addThemeNames("foo", "bar")); + addButton("removeThemeNames", () -> foo.removeThemeNames("foo", "bar")); addButton("setItems", () -> messageList .setItems(new MessageListItem(null, null, "sender3"))); diff --git a/vaadin-messages-flow-parent/vaadin-messages-flow-integration-tests/src/test/java/com/vaadin/flow/component/messages/tests/MessageListIT.java b/vaadin-messages-flow-parent/vaadin-messages-flow-integration-tests/src/test/java/com/vaadin/flow/component/messages/tests/MessageListIT.java index d780faddfeb..1d96aea9ffe 100644 --- a/vaadin-messages-flow-parent/vaadin-messages-flow-integration-tests/src/test/java/com/vaadin/flow/component/messages/tests/MessageListIT.java +++ b/vaadin-messages-flow-parent/vaadin-messages-flow-integration-tests/src/test/java/com/vaadin/flow/component/messages/tests/MessageListIT.java @@ -93,6 +93,14 @@ public void updateItemPropertiesAfterRendering_messagesUpdated() { clickElementWithJs("setUserColorIndex"); Assert.assertEquals("Unexpected userColorIndex prop", 2, msg.getUserColorIndex()); + + clickElementWithJs("addThemeNames"); + Assert.assertEquals("Unexpected theme prop after adding theme names", + "foo bar", msg.getTheme()); + + clickElementWithJs("removeThemeNames"); + Assert.assertEquals("Unexpected theme prop after removing theme names", + null, msg.getTheme()); } @Test diff --git a/vaadin-messages-flow-parent/vaadin-messages-flow/src/main/java/com/vaadin/flow/component/messages/MessageListItem.java b/vaadin-messages-flow-parent/vaadin-messages-flow/src/main/java/com/vaadin/flow/component/messages/MessageListItem.java index 85b693b0cff..f3f2d4feb42 100644 --- a/vaadin-messages-flow-parent/vaadin-messages-flow/src/main/java/com/vaadin/flow/component/messages/MessageListItem.java +++ b/vaadin-messages-flow-parent/vaadin-messages-flow/src/main/java/com/vaadin/flow/component/messages/MessageListItem.java @@ -18,9 +18,14 @@ import java.io.Serializable; import java.net.URI; import java.time.Instant; +import java.util.Arrays; import java.util.Collection; +import java.util.LinkedHashSet; import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; +import com.fasterxml.jackson.annotation.JsonGetter; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonSerialize; @@ -58,6 +63,8 @@ public class MessageListItem implements Serializable { private Command pendingHandle; private AbstractStreamResource imageResource; + private Set themeNames = new LinkedHashSet<>(); + /** * Creates an empty message list item. Use the setter methods to configure * what will be displayed in the message. @@ -282,6 +289,40 @@ public void setUserColorIndex(Integer userColorIndex) { propsChanged(); } + /** + * Adds one or more theme names to this message. Multiple theme names can be + * specified by using multiple parameters. + * + * @param themeNames + * the theme name or theme names to be added to the message + */ + public void addThemeNames(String... themeNames) { + this.themeNames.addAll(Arrays.asList(themeNames)); + propsChanged(); + } + + /** + * Removes one or more theme names from this message. Multiple theme names + * can be specified by using multiple parameters. + * + * @param themeNames + * the theme name or theme names to be removed from the message + */ + public void removeThemeNames(String... themeNames) { + this.themeNames.removeAll(Arrays.asList(themeNames)); + propsChanged(); + } + + // Used only for Jackson serialization + @JsonGetter + private String getTheme() { + if (themeNames.isEmpty()) { + return null; + } else { + return themeNames.stream().collect(Collectors.joining(" ")); + } + } + /** * Gets the image resource of the message sender's avatar. * diff --git a/vaadin-messages-flow-parent/vaadin-messages-flow/src/test/java/com/vaadin/flow/component/messages/tests/MessageListTest.java b/vaadin-messages-flow-parent/vaadin-messages-flow/src/test/java/com/vaadin/flow/component/messages/tests/MessageListTest.java index 4e4046ae050..a80c04602c7 100644 --- a/vaadin-messages-flow-parent/vaadin-messages-flow/src/test/java/com/vaadin/flow/component/messages/tests/MessageListTest.java +++ b/vaadin-messages-flow-parent/vaadin-messages-flow/src/test/java/com/vaadin/flow/component/messages/tests/MessageListTest.java @@ -29,8 +29,12 @@ import com.vaadin.flow.component.UI; import com.vaadin.flow.component.messages.MessageList; import com.vaadin.flow.component.messages.MessageListItem; +import com.vaadin.flow.internal.JsonUtils; import com.vaadin.flow.server.StreamResource; +import elemental.json.JsonType; +import elemental.json.JsonValue; + public class MessageListTest { private MessageList messageList; @@ -91,4 +95,40 @@ public void setImageAsUrl_streamResourceBecomesNull() { item1.setUserImage("foo/bar"); Assert.assertNull(item1.getUserImageResource()); } + + @Test + public void addThemeNames_serialize_separatedBySpaces() { + item1.addThemeNames("foo", "bar"); + item1.addThemeNames("baz"); + Assert.assertEquals("foo bar baz", getSerializedThemeProperty(item1)); + } + + @Test + public void addThemeNames_serialize_noDuplicates() { + item1.addThemeNames("foo", "foo"); + Assert.assertEquals("foo", getSerializedThemeProperty(item1)); + } + + @Test + public void removeThemeNames_serialize_themeNamesRemoved() { + item1.addThemeNames("foo", "bar", "baz"); + item1.removeThemeNames("foo", "bar", "qux"); + Assert.assertEquals("baz", getSerializedThemeProperty(item1)); + } + + @Test + public void clearThemeNames_serialize_nullProperty() { + item1.addThemeNames("foo"); + item1.removeThemeNames("foo"); + Assert.assertNull(getSerializedThemeProperty(item1)); + } + + private String getSerializedThemeProperty(MessageListItem item) { + JsonValue theme = JsonUtils.beanToJson(item).get("theme"); + if (theme.getType() == JsonType.NULL) { + return null; + } else { + return theme.asString(); + } + } } diff --git a/vaadin-messages-flow-parent/vaadin-messages-testbench/src/main/java/com/vaadin/flow/component/messages/testbench/MessageElement.java b/vaadin-messages-flow-parent/vaadin-messages-testbench/src/main/java/com/vaadin/flow/component/messages/testbench/MessageElement.java index 98d4a3ca034..6b8f54f045b 100644 --- a/vaadin-messages-flow-parent/vaadin-messages-testbench/src/main/java/com/vaadin/flow/component/messages/testbench/MessageElement.java +++ b/vaadin-messages-flow-parent/vaadin-messages-testbench/src/main/java/com/vaadin/flow/component/messages/testbench/MessageElement.java @@ -82,4 +82,13 @@ public int getUserColorIndex() { return getPropertyInteger("userColorIndex"); } + /** + * Gets the {@code theme} attribute of this element. + * + * @return the {@code theme} attribute + */ + public String getTheme() { + return getAttribute("theme"); + } + } From 74538caaccc45b78bed2e9de55f2eee9445480b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pekka=20Maanp=C3=A4=C3=A4?= Date: Wed, 12 May 2021 15:13:50 +0300 Subject: [PATCH 2/3] feat: add MessageListItem::hasThemeName --- .../flow/component/messages/MessageListItem.java | 12 ++++++++++++ .../component/messages/tests/MessageListTest.java | 11 +++++++++++ 2 files changed, 23 insertions(+) diff --git a/vaadin-messages-flow-parent/vaadin-messages-flow/src/main/java/com/vaadin/flow/component/messages/MessageListItem.java b/vaadin-messages-flow-parent/vaadin-messages-flow/src/main/java/com/vaadin/flow/component/messages/MessageListItem.java index f3f2d4feb42..a9537532baf 100644 --- a/vaadin-messages-flow-parent/vaadin-messages-flow/src/main/java/com/vaadin/flow/component/messages/MessageListItem.java +++ b/vaadin-messages-flow-parent/vaadin-messages-flow/src/main/java/com/vaadin/flow/component/messages/MessageListItem.java @@ -313,6 +313,18 @@ public void removeThemeNames(String... themeNames) { propsChanged(); } + /** + * Checks if the message has the given theme name. + * + * @param themeName + * the theme name to check for + * @return true if the message has the given theme name, + * false otherwise + */ + public boolean hasThemeName(String themeName) { + return themeNames.contains(themeName); + } + // Used only for Jackson serialization @JsonGetter private String getTheme() { diff --git a/vaadin-messages-flow-parent/vaadin-messages-flow/src/test/java/com/vaadin/flow/component/messages/tests/MessageListTest.java b/vaadin-messages-flow-parent/vaadin-messages-flow/src/test/java/com/vaadin/flow/component/messages/tests/MessageListTest.java index a80c04602c7..6071c984efd 100644 --- a/vaadin-messages-flow-parent/vaadin-messages-flow/src/test/java/com/vaadin/flow/component/messages/tests/MessageListTest.java +++ b/vaadin-messages-flow-parent/vaadin-messages-flow/src/test/java/com/vaadin/flow/component/messages/tests/MessageListTest.java @@ -123,6 +123,17 @@ public void clearThemeNames_serialize_nullProperty() { Assert.assertNull(getSerializedThemeProperty(item1)); } + @Test + public void hasThemeName_falseForNonExistingThemeName() { + Assert.assertFalse(item1.hasThemeName("foo")); + } + + @Test + public void hasThemeName_trueForExistingThemeName() { + item1.addThemeNames("foo"); + Assert.assertTrue(item1.hasThemeName("foo")); + } + private String getSerializedThemeProperty(MessageListItem item) { JsonValue theme = JsonUtils.beanToJson(item).get("theme"); if (theme.getType() == JsonType.NULL) { From 02ad4c4ff626baa9e42dd169909e1289e1e447e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pekka=20Maanp=C3=A4=C3=A4?= Date: Tue, 18 May 2021 11:17:04 +0300 Subject: [PATCH 3/3] Add comment about HasTheme methods --- .../vaadin/flow/component/messages/MessageListItem.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/vaadin-messages-flow-parent/vaadin-messages-flow/src/main/java/com/vaadin/flow/component/messages/MessageListItem.java b/vaadin-messages-flow-parent/vaadin-messages-flow/src/main/java/com/vaadin/flow/component/messages/MessageListItem.java index a9537532baf..7daa040c91b 100644 --- a/vaadin-messages-flow-parent/vaadin-messages-flow/src/main/java/com/vaadin/flow/component/messages/MessageListItem.java +++ b/vaadin-messages-flow-parent/vaadin-messages-flow/src/main/java/com/vaadin/flow/component/messages/MessageListItem.java @@ -289,6 +289,13 @@ public void setUserColorIndex(Integer userColorIndex) { propsChanged(); } + /* + * The following theme-related methods are copied from the HasTheme + * interface, because the interface is compatible only with components. For + * more detailed reasoning, see the discussion in: + * https://github.com/vaadin/flow-components/pull/979#discussion_r634097080 + */ + /** * Adds one or more theme names to this message. Multiple theme names can be * specified by using multiple parameters.