!7 abstract sclass DynConvo > DynModule { L posts = dm_synchroList(this); S userInput; transient JChatConvo view; Pt minimumSize() { ret pt(300, 300); } visualize { view = swing(() -> new JChatConvo); view.usePostsList(posts); ret centerAndSouth( jscroll_trackWidth(view), withMargin(dm_textFieldAndSubmit userInput('sendInput, buttonText := "Send"))); } void sendInput { S s = trim(userInput); if (nempty(s)) { addPost(htmlEncode2(s), false); vmBus_send chatUserInput(module(), s); setField(userInput := ""); } } // API void addPost(S html, bool right) swing { posts.add(new JChatConvo.Post(html, right)); view?.updateAndScrollDown(); } void clearPosts swing { posts.clear(); view?.updateAndScrollDown(); } void reply(S s) { if (empty(s = trim(s))) ret; addPost(htmlEncode2(s), true); } }