package comms.view.chat; import java.util.Iterator; import org.apache.wicket.Component; import org.apache.wicket.ResourceReference; import org.apache.wicket.ajax.AbstractAjaxTimerBehavior; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.markup.html.form.AjaxButton; import org.apache.wicket.markup.html.IHeaderContributor; import org.apache.wicket.markup.html.IHeaderResponse; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.markup.html.form.TextField; import org.apache.wicket.markup.html.panel.Panel; import org.apache.wicket.model.CompoundPropertyModel; import comms.bus.ChatService; import comms.model.chat.Conversation; import comms.model.chat.Event; import comms.model.chat.MessageEvent; import comms.model.chat.Participant; import comms.model.chat.PublishedEvent; import comms.view.util.OnEnterClicker; /** *

* A Chat panel contains a reference to a conversation within a chat service, a timer * and a one field form to enter messages.

*

Each time the timer fires the conversation's pending events will be retrieved * and send as JavaScript to the page where the script will append them to the DOM * element that displays the conversation.

*

The form's submit button will publish a message event to the conversation

* */ public abstract class Chat extends Panel implements IHeaderContributor { private String message; public Chat( String id, final String serviceId, final String conversationId, final Participant participant ) { super( id ); Conversation conversation = getConversation(serviceId, conversationId); conversation.resetPendingEvents(participant); Form form = new Form( "form", new CompoundPropertyModel( this )); final Component messageField = new TextField( "message" ); form.add( messageField ); messageField.setOutputMarkupId(true); final Component timer = new WebMarkupContainer( "timer" ); timer.setOutputMarkupId(true); timer.add( new AbstractAjaxTimerBehavior( ChatService.getPollInterval()) { @Override protected void onTimer(AjaxRequestTarget target) { Conversation conversation = getConversation( serviceId, conversationId); Iteratoritr = conversation.getPendingEvents(participant); if (!itr.hasNext()) { return; } StringBuffer buf = new StringBuffer(); buf.append( "var e = document.getElementById('"); buf.append( "content"); buf.append( "');" ); buf.append( "e.innerHTML += '" ); while (itr.hasNext()) { PublishedEvent published = itr.next(); Event event = (Event)published.getEvent(); Participant participant = (Participant)published.getParticipant(); buf.append( event.getHtmlDescription(participant)); // buf.append( ";" ); } buf.append( "'" ); buf.append( ";"); buf.append( "e.scrollTop = e.scrollHeight" ); target.appendJavascript( buf.toString()); target.focusComponent(null); } }); add( timer ); AjaxButton sendButton = new AjaxButton("send", form ){ @Override protected void onSubmit(AjaxRequestTarget target, Form form) { String message = ((Chat)form.getModelObject()).getMessage(); if (message!=null && message.trim().length()>0) { Conversation conversation = getConversation( serviceId, conversationId); conversation.publish(participant, new MessageEvent( message )); } //clear message area add focus it target.appendJavascript( "document.getElementById('" + messageField.getMarkupId() + "').value =''"); target.focusComponent(null); } }; form.add( sendButton ); messageField.add( new OnEnterClicker( sendButton )); add( form ); } private Conversation getConversation(String serviceId, String conversationId) { Conversation conversation = ChatService.getInstance(serviceId).getConversation(conversationId); if (conversation==null) { conversation = createConversation( serviceId, conversationId ); ChatService.getInstance(serviceId).putConversation( conversation ); } return conversation; } /** * You can override this method to create a conversation with additional * functionality (like persisting itself) * @param serviceId * @param conversationId * @return */ protected Conversation createConversation(String serviceId, String conversationId) { return new Conversation( conversationId ); } public String getMessage() { return message; } public void setMessage( String message ) { this.message = message; } public void renderHead(IHeaderResponse response) { response.renderCSSReference( new ResourceReference( Chat.class, "Chat.css" )); response.renderJavascriptReference( new ResourceReference( Chat.class, "Chat.js" )); } }