!7 cmodule ConvoPopup > DynModule { L posts = synchroList(); int windowWidth = 400, windowHeight = 400; S text; bool right; // for form transient JChatConvo view; srecord Post(S html, bool right) {} start { componentFieldsToKeep = litset('view); // we clean it up ourselves } visual withCenteredButtons(withMargin(jvstack( centerAndEastWithMargin(dm_textField text(), jline(dm_checkBox right(), jbutton("Add post", rEnter { addPost(text, right) }))))), "Show popup", rEnter openPopup, "Clear posts", rEnter clearPosts); void cleanMeUp { disposeFrame(view); view = null; } // API void openPopup swing { if (view == null) { view = new JChatConvo; for (Post p : cloneList(posts)) view.addPost(p.html, p.right); alwaysOnTop(showFrameInBottomRightCorner(jscroll_trackWidth(view), windowWidth, windowHeight)); } else activateFrame(view); } void addPost(S html, bool right) swing { posts.add(new Post(html, right)); view?.addPost(html, right); } void clearPosts swing { posts.clear(); } }