package net.zschech.gwt.chat.client;
import java.io.Serializable;
import java.util.List;
import net.zschech.gwt.chat.client.StatusUpdate.Status;
import net.zschech.gwt.comet.client.CometClient;
import net.zschech.gwt.comet.client.CometListener;
import net.zschech.gwt.comet.client.CometSerializer;
import net.zschech.gwt.comet.client.SerialTypes;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.Document;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.DockPanel;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
public class ChatEntryPoint implements EntryPoint {
private ChatServiceAsync chatService;
private CometClient cometClient;
private String username;
private HTML messages;
private ScrollPanel scrollPanel;
@SerialTypes( { ChatMessage.class, StatusUpdate.class })
public static abstract class ChatCometSerializer extends CometSerializer {
}
@Override
public void onModuleLoad() {
chatService = GWT.create(ChatService.class);
chatService.getUsername(new AsyncCallback<String>() {
@Override
public void onSuccess(String username) {
if (username == null) {
showLogonDialog();
}
else {
loggedOn(username);
}
}
@Override
public void onFailure(Throwable caught) {
output(caught.toString(), "red");
// assume they are not logged in
showLogonDialog();
}
});
FlowPanel controls = new FlowPanel();
final ListBox status = new ListBox();
for (Status s : Status.values()) {
status.addItem(s.name());
}
status.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
setStatus(Status.values()[status.getSelectedIndex()]);
}
});
final TextBox input = new TextBox();
Button send = new Button("Send", new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
sendMessage(input.getValue());
}
});
Button logout = new Button("Logout", new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
logout();
}
});
controls.add(status);
controls.add(input);
controls.add(send);
controls.add(logout);
DockPanel dockPanel = new DockPanel();
messages = new HTML();
scrollPanel = new ScrollPanel();
scrollPanel.setHeight("250px");
scrollPanel.add(messages);
dockPanel.add(scrollPanel, DockPanel.CENTER);
dockPanel.add(controls, DockPanel.SOUTH);
RootPanel.get().add(dockPanel);
}
private void showLogonDialog() {
final DialogBox dialogBox = new DialogBox();
dialogBox.setText("Login");
dialogBox.setGlassEnabled(true);
dialogBox.setAnimationEnabled(true);
VerticalPanel verticalPanel = new VerticalPanel();
verticalPanel.setSpacing(4);
dialogBox.setWidget(verticalPanel);
final TextBox username = new TextBox();
verticalPanel.add(new HTML("Username:"));
verticalPanel.add(username);
Button closeButton = new Button("Logon", new ClickHandler() {
public void onClick(ClickEvent event) {
dialogBox.hide();
login(username.getValue());
}
});
verticalPanel.add(closeButton);
dialogBox.center();
dialogBox.show();
}
private void login(final String username) {
chatService.login(username, new AsyncCallback<Void>() {
@Override
public void onSuccess(Void result) {
loggedOn(username);
}
@Override
public void onFailure(Throwable caught) {
output(caught.toString(), "red");
}
});
}
private void logout() {
chatService.logout(username, new AsyncCallback<Void>() {
@Override
public void onSuccess(Void result) {
cometClient.stop();
showLogonDialog();
}
@Override
public void onFailure(Throwable caught) {
output(caught.toString(), "red");
}
});
}
private void loggedOn(String username) {
this.username = username;
output("logged in as " + username, "silver");
CometSerializer serializer = GWT.create(ChatCometSerializer.class);
cometClient = new CometClient(GWT.getModuleBaseURL() + "comet", serializer, new CometListener() {
public void onConnected(int heartbeat) {
output("connected " + heartbeat, "silver");
}
public void onDisconnected() {
output("disconnected", "silver");
}
public void onError(Throwable exception, boolean connected) {
output("error " + connected + " " + exception, "red");
}
public void onHeartbeat() {
output("heartbeat", "silver");
}
public void onRefresh() {
output("refresh", "silver");
}
public void onMessage(List<? extends Serializable> messages) {
for (Serializable message : messages) {
if (message instanceof ChatMessage) {
ChatMessage chatMessage = (ChatMessage) message;
output(chatMessage.getUsername() + ": " + chatMessage.getMessage(), "black");
}
else if (message instanceof StatusUpdate) {
StatusUpdate statusUpdate = (StatusUpdate) message;
output(statusUpdate.getUsername() + ": " + statusUpdate.getStatus(), "green");
}
else {
output("unrecognised message " + message, "red");
}
}
}
});
cometClient.start();
}
private void sendMessage(String message) {
chatService.send(message, new AsyncCallback<Void>() {
@Override
public void onSuccess(Void result) {
}
@Override
public void onFailure(Throwable caught) {
output(caught.toString(), "red");
}
});
}
private void setStatus(Status status) {
chatService.setStatus(status, new AsyncCallback<Void>() {
@Override
public void onSuccess(Void result) {
}
@Override
public void onFailure(Throwable caught) {
output(caught.toString(), "red");
}
});
}
public void output(String text, String color) {
DivElement div = Document.get().createDivElement();
div.setInnerText(text);
div.setAttribute("style", "color:" + color);
messages.getElement().appendChild(div);
scrollPanel.scrollToBottom();
}
}