Skip to content

Commit 24d331f

Browse files
committed
feat: add markdown support via markdown-editor-add-on
Closes #23
1 parent b028337 commit 24d331f

6 files changed

Lines changed: 117 additions & 5 deletions

File tree

pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
<drivers.dir>${project.basedir}/drivers</drivers.dir>
1919
<jetty.version>11.0.12</jetty.version>
2020
<flowingcode.commons.demo.version>3.10.0</flowingcode.commons.demo.version>
21+
<markdown-editor.version>1.0.0</markdown-editor.version>
2122
<frontend.hotdeploy>true</frontend.hotdeploy>
2223
</properties>
2324

@@ -127,6 +128,11 @@
127128
<artifactId>vaadin-core</artifactId>
128129
<optional>true</optional>
129130
</dependency>
131+
<dependency>
132+
<groupId>com.flowingcode.vaadin.addons</groupId>
133+
<artifactId>markdown-editor-addon</artifactId>
134+
<version>${markdown-editor.version}</version>
135+
</dependency>
130136
<dependency>
131137
<groupId>org.projectlombok</groupId>
132138
<artifactId>lombok</artifactId>

src/main/java/com/flowingcode/vaadin/addons/chatassistant/ChatAssistant.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,21 +74,28 @@ public class ChatAssistant extends Div {
7474
* Default constructor. Creates a ChatAssistant with no messages.
7575
*/
7676
public ChatAssistant() {
77-
this(new ArrayList<>());
77+
this(new ArrayList<>(), false);
7878
}
7979

80+
/**
81+
* Default constructor. Creates a ChatAssistant with no messages.
82+
*/
83+
public ChatAssistant(boolean markdownEnabled) {
84+
this(new ArrayList<>(), markdownEnabled);
85+
}
86+
8087
/**
8188
* Creates a ChatAssistant with the given list of messages.
8289
*
8390
* @param messages the list of messages
8491
*/
85-
public ChatAssistant(List<Message> messages) {
92+
public ChatAssistant(List<Message> messages, Boolean markdownEnabled) {
8693
this.messages = messages;
8794
content.getElement().setAttribute("slot", "content");
8895
content.setItems(messages);
8996

9097
content.setRenderer(new ComponentRenderer<ChatMessage, Message>(
91-
message -> new ChatMessage(message), (component, message) -> {
98+
message -> new ChatMessage(message, markdownEnabled), (component, message) -> {
9299
((ChatMessage) component).setMessage(message);
93100
return component;
94101
}));

src/main/java/com/flowingcode/vaadin/addons/chatassistant/ChatMessage.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
package com.flowingcode.vaadin.addons.chatassistant;
2121

2222
import com.flowingcode.vaadin.addons.chatassistant.model.Message;
23+
import com.flowingcode.vaadin.addons.markdown.BaseMarkdownComponent.DataColorMode;
24+
import com.flowingcode.vaadin.addons.markdown.MarkdownViewer;
2325
import com.vaadin.flow.component.Component;
2426
import com.vaadin.flow.component.HasComponents;
2527
import com.vaadin.flow.component.Tag;
@@ -42,14 +44,16 @@
4244
public class ChatMessage extends Component implements HasComponents {
4345

4446
private Message message;
47+
private boolean markdownEnabled;
4548
private Div loader;
4649

4750
/**
4851
* Creates a new ChatMessage based on the supplied message.
4952
*
5053
* @param message message used to populate the ChatMessage instance
5154
*/
52-
public ChatMessage(Message message) {
55+
public ChatMessage(Message message, Boolean markdownEnabled) {
56+
this.markdownEnabled = markdownEnabled;
5357
setMessage(message);
5458
}
5559

@@ -83,7 +87,13 @@ private void updateLoadingState(Message message) {
8387
this.remove(loader);
8488
loader = null;
8589
}
86-
this.getElement().executeJs("this.appendChild(document.createTextNode($0));", message.getContent());
90+
if (markdownEnabled) {
91+
MarkdownViewer mdv = new MarkdownViewer(message.getContent());
92+
mdv.setDataColorMode(DataColorMode.LIGTH);
93+
this.add(mdv);
94+
} else {
95+
this.getElement().executeJs("this.appendChild(document.createTextNode($0));", message.getContent());
96+
}
8797
}
8898
}
8999

src/main/resources/META-INF/frontend/styles/chat-message-styles.css

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,18 @@
8888
font-family: var(--lumo-font-family);
8989
color: var(--lumo-secondary-text-color);
9090
}
91+
92+
.wmde-markdown {
93+
height: 100%;
94+
margin-top: 0px;
95+
margin-bottom: 0px;
96+
padding-top: 0px;
97+
padding-bottom: 0px;
98+
display: flex;
99+
flex-direction: column;
100+
background: none !important;
101+
}
102+
103+
.language-mermaid {
104+
padding: 0px !important;
105+
}

src/test/java/com/flowingcode/vaadin/addons/chatassistant/ChatAssistantDemoView.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ public class ChatAssistantDemoView extends TabbedDemo {
3434
public ChatAssistantDemoView() {
3535
addDemo(ChatAssistantDemo.class);
3636
addDemo(ChatAssistantLazyLoadingDemo.class);
37+
addDemo(ChatAssistantMarkdownDemo.class);
3738
setSizeFull();
3839
}
3940
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*-
2+
* #%L
3+
* Chat Assistant Add-on
4+
* %%
5+
* Copyright (C) 2023 - 2024 Flowing Code
6+
* %%
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
* #L%
19+
*/
20+
package com.flowingcode.vaadin.addons.chatassistant;
21+
22+
import com.flowingcode.vaadin.addons.chatassistant.model.Message;
23+
import com.flowingcode.vaadin.addons.demo.DemoSource;
24+
import com.flowingcode.vaadin.addons.demo.SourcePosition;
25+
import com.google.common.base.Strings;
26+
import com.vaadin.flow.component.UI;
27+
import com.vaadin.flow.component.button.Button;
28+
import com.vaadin.flow.component.dependency.CssImport;
29+
import com.vaadin.flow.component.html.Span;
30+
import com.vaadin.flow.component.icon.Icon;
31+
import com.vaadin.flow.component.icon.VaadinIcon;
32+
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
33+
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
34+
import com.vaadin.flow.component.textfield.TextArea;
35+
import com.vaadin.flow.router.PageTitle;
36+
import com.vaadin.flow.router.Route;
37+
import java.time.LocalDateTime;
38+
import java.util.Timer;
39+
40+
@DemoSource(sourcePosition = SourcePosition.PRIMARY)
41+
@PageTitle("Markdown Demo")
42+
@SuppressWarnings("serial")
43+
@Route(value = "chat-assistant/markdown-demo", layout = ChatAssistantDemoView.class)
44+
@CssImport("./styles/chat-assistant-styles-demo.css")
45+
public class ChatAssistantMarkdownDemo extends VerticalLayout {
46+
47+
public ChatAssistantMarkdownDemo() {
48+
ChatAssistant chatAssistant = new ChatAssistant(true);
49+
TextArea message = new TextArea();
50+
message.setLabel("Enter a message from the assistant (try using Markdown)");
51+
message.setSizeFull();
52+
message.addKeyPressListener(ev->{
53+
if (Strings.isNullOrEmpty(chatAssistant.getWhoIsTyping())) {
54+
chatAssistant.setWhoIsTyping("Assistant is generating an answer ...");
55+
}
56+
});
57+
message.addBlurListener(ev->chatAssistant.clearWhoIsTyping());
58+
59+
Button chat = new Button("Chat");
60+
chat.addClickListener(ev -> {
61+
Message m = Message.builder().content(message.getValue()).messageTime(LocalDateTime.now())
62+
.name("Assistant").avatar("chatbot.png").build();
63+
64+
chatAssistant.sendMessage(m);
65+
message.clear();
66+
});
67+
chatAssistant.sendMessage(Message.builder().content("**Hello, I am here to assist you**")
68+
.messageTime(LocalDateTime.now())
69+
.name("Assistant").avatar("chatbot.png").build());
70+
71+
add(message, chat, chatAssistant);
72+
}
73+
}

0 commit comments

Comments
 (0)