rendered paste bodypackage 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;
/**
* <p>
* A Chat panel contains a reference to a conversation within a chat service, a timer
* and a one field form to enter messages.</p>
* <p>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.</p>
* <p>The form's submit button will publish a message event to the conversation</p>
*
*/
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);
Iterator<PublishedEvent>itr = 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" ));
}
}