package com.andreiolar.abms.client.widgets;
import java.util.List;
import com.andreiolar.abms.client.constants.ConversationWidgetConstants;
import com.andreiolar.abms.client.constants.DialogBoxConstants;
import com.andreiolar.abms.client.rpc.DBDeleteConversation;
import com.andreiolar.abms.client.rpc.DBDeleteConversationAsync;
import com.andreiolar.abms.client.rpc.DBGetAllConversations;
import com.andreiolar.abms.client.rpc.DBGetAllConversationsAsync;
import com.andreiolar.abms.client.rpc.DBGetAllSuggestions;
import com.andreiolar.abms.client.rpc.DBGetAllSuggestionsAsync;
import com.andreiolar.abms.client.rpc.DBGetMessagesForConversation;
import com.andreiolar.abms.client.rpc.DBGetMessagesForConversationAsync;
import com.andreiolar.abms.client.rpc.DBMoveConversation;
import com.andreiolar.abms.client.rpc.DBMoveConversationAsync;
import com.andreiolar.abms.client.rpc.DBReplyToConversation;
import com.andreiolar.abms.client.rpc.DBReplyToConversationAsync;
import com.andreiolar.abms.client.utils.DialogBoxCreator;
import com.andreiolar.abms.shared.Conversation;
import com.andreiolar.abms.shared.Message;
import com.andreiolar.abms.shared.ReplyMessage;
import com.andreiolar.abms.shared.UserInfo;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.dom.client.Style.Unit;
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.event.dom.client.ContextMenuEvent;
import com.google.gwt.event.dom.client.ContextMenuHandler;
import com.google.gwt.event.logical.shared.SelectionEvent;
import com.google.gwt.event.logical.shared.SelectionHandler;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.ServiceDefTarget;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HTMLTable.CellFormatter;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.MenuBar;
import com.google.gwt.user.client.ui.MenuItem;
import com.google.gwt.user.client.ui.MultiWordSuggestOracle;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.PushButton;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.SuggestBox;
import com.google.gwt.user.client.ui.SuggestOracle;
import com.google.gwt.user.client.ui.SuggestOracle.Suggestion;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
public class ConversationWidget extends Composite implements CustomWidget {
private UserInfo userInfo;
private boolean isConversationView;
private boolean isMessageView;
private int lastId;
public ConversationWidget(UserInfo userInfo) {
this.userInfo = userInfo;
initWidget(initializeWidget());
}
@Override
public Widget initializeWidget() {
final VerticalPanel panel = new VerticalPanel();
final SimplePanel convPanel = new SimplePanel();
// Top layer
HorizontalPanel topLayer = new HorizontalPanel();
PushButton backButton = new PushButton(new Image("images/icons/back_button.png"));
backButton.getElement().getStyle().setMarginTop(10.0, Unit.PX);
backButton.getElement().getStyle().setMarginRight(30.0, Unit.PX);
backButton.addStyleName("no-border-button");
backButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
if (isMessageView) {
panel.clear();
Widget renewedWidget = initializeWidget();
panel.add(renewedWidget);
}
}
});
PushButton refreshButton = new PushButton(new Image("images/icons/refresh_button.png"));
refreshButton.getElement().getStyle().setMarginTop(6.0, Unit.PX);
refreshButton.getElement().getStyle().setMarginRight(100.0, Unit.PX);
refreshButton.addStyleName("no-border-button");
refreshButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
if (isConversationView) {
panel.clear();
Widget renewedWidget = initializeWidget();
panel.add(renewedWidget);
} else {
viewConversation(lastId, convPanel);
}
}
});
Label filterLabel = new Label();
filterLabel.setText("Filter");
filterLabel.getElement().getStyle().setFontSize(18.0, Unit.PX);
filterLabel.getElement().getStyle().setMarginTop(15.0, Unit.PX);
filterLabel.getElement().getStyle().setMarginRight(7.0, Unit.PX);
final ListBox filter = new ListBox();
filter.addItem("Inbox");
filter.addItem("Important");
filter.addItem("Archive");
filter.getElement().getStyle().setMarginTop(17.0, Unit.PX);
filter.getElement().getStyle().setMarginRight(1220.0, Unit.PX);
filter.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
if (isConversationView) {
String conversationFilter = filter.getSelectedItemText();
convPanel.clear();
fillConversationPanel(convPanel, conversationFilter);
}
}
});
Label searchLabel = new Label();
searchLabel.setText("Search");
searchLabel.getElement().getStyle().setFontSize(18.0, Unit.PX);
searchLabel.getElement().getStyle().setMarginTop(15.0, Unit.PX);
searchLabel.getElement().getStyle().setMarginRight(10.0, Unit.PX);
MultiWordSuggestOracle oracle = getDBSuggestions();
final CustomTexBox searchBox = new CustomTexBox();
searchBox.getElement().getStyle().setMarginTop(15.0, Unit.PX);
searchBox.getElement().getStyle().setMarginRight(10.0, Unit.PX);
SuggestBox suggestBox = new SuggestBox(oracle, searchBox);
suggestBox.addSelectionHandler(new SelectionHandler<SuggestOracle.Suggestion>() {
@Override
public void onSelection(SelectionEvent<Suggestion> event) {
String returnedString = event.getSelectedItem().getReplacementString();
String id = returnedString.split("\\|")[0].trim();
int convId = Integer.parseInt(id);
viewConversation(convId, convPanel);
}
});
topLayer.add(backButton);
topLayer.add(refreshButton);
topLayer.add(filterLabel);
topLayer.add(filter);
topLayer.add(searchLabel);
topLayer.add(suggestBox);
HTML separatorLine = new HTML("<hr class=\"width:100%;\" />");
panel.add(topLayer);
panel.add(separatorLine);
// Start conversation panel
String conversationFilter = filter.getSelectedItemText();
fillConversationPanel(convPanel, conversationFilter);
panel.add(convPanel);
return panel;
}
private MultiWordSuggestOracle getDBSuggestions() {
final MultiWordSuggestOracle oracle = new MultiWordSuggestOracle();
DBGetAllSuggestionsAsync rpc = (DBGetAllSuggestionsAsync) GWT.create(DBGetAllSuggestions.class);
ServiceDefTarget tar = (ServiceDefTarget) rpc;
String moduleURL = GWT.getModuleBaseURL() + "DBGetAllSuggestionsImpl";
tar.setServiceEntryPoint(moduleURL);
rpc.getAllSuggestions(userInfo, new AsyncCallback<List<String>>() {
@Override
public void onSuccess(List<String> result) {
oracle.addAll(result);
}
@Override
public void onFailure(Throwable caught) {
// Do nothing
}
});
return oracle;
}
private void fillConversationPanel(final SimplePanel convPanel, final String conversationFilter) {
final FlexTable flexTable = new FlexTable();
flexTable.addStyleName("flexTable");
CellFormatter cellFormatter = flexTable.getCellFormatter();
flexTable.setHTML(0, 0, ConversationWidgetConstants.ID);
flexTable.setHTML(0, 1, ConversationWidgetConstants.DATE);
flexTable.setHTML(0, 2, ConversationWidgetConstants.CONVERSATION_WITH);
flexTable.setHTML(0, 3, ConversationWidgetConstants.SUBJECT);
flexTable.setHTML(0, 4, ConversationWidgetConstants.UNREAD_MESSAGES);
flexTable.setHTML(0, 5, ConversationWidgetConstants.STATUS);
DOM.getElementById("loading").getStyle().setDisplay(Display.BLOCK);
DBGetAllConversationsAsync rpc = (DBGetAllConversationsAsync) GWT.create(DBGetAllConversations.class);
ServiceDefTarget tar = (ServiceDefTarget) rpc;
String moduleURL = GWT.getModuleBaseURL() + "DBGetAllConversationsImpl";
tar.setServiceEntryPoint(moduleURL);
rpc.getAllMessages(userInfo, conversationFilter, new AsyncCallback<List<Conversation>>() {
@Override
public void onSuccess(List<Conversation> result) {
DOM.getElementById("loading").getStyle().setDisplay(Display.NONE);
isConversationView = true;
isMessageView = false;
int start = 1;
for (Conversation conversation : result) {
final int id = conversation.getId();
Anchor idAnchor = new Anchor(String.valueOf(id));
idAnchor.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
viewConversation(id, convPanel);
}
});
final PopupPanel contextMenu = new PopupPanel(true);
Widget panel = populateContextMenu(id, convPanel, conversationFilter);
contextMenu.add(panel);
contextMenu.hide();
idAnchor.sinkEvents(Event.ONCONTEXTMENU);
idAnchor.addHandler(new ContextMenuHandler() {
@Override
public void onContextMenu(ContextMenuEvent event) {
event.preventDefault();
event.stopPropagation();
int x = event.getNativeEvent().getClientX();
int y = event.getNativeEvent().getClientY();
contextMenu.setPopupPosition(x, y);
contextMenu.show();
}
}, ContextMenuEvent.getType());
flexTable.setWidget(start, 0, idAnchor);
flexTable.setHTML(start, 1, conversation.getDate());
String username = userInfo.getUsername();
String source = conversation.getSource();
String destination = conversation.getDestination();
flexTable.setHTML(start, 2, source.equals(username) ? destination : source);
Anchor subjectAnchor = new Anchor(String.valueOf(""));
subjectAnchor.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
viewConversation(id, convPanel);
}
});
subjectAnchor.sinkEvents(Event.ONCONTEXTMENU);
subjectAnchor.addHandler(new ContextMenuHandler() {
@Override
public void onContextMenu(ContextMenuEvent event) {
event.preventDefault();
event.stopPropagation();
int x = event.getNativeEvent().getClientX();
int y = event.getNativeEvent().getClientY();
contextMenu.setPopupPosition(x, y);
contextMenu.show();
}
}, ContextMenuEvent.getType());
flexTable.setWidget(start, 3, subjectAnchor);
flexTable.setHTML(start, 4, "0");
flexTable.setHTML(start, 5, "Unread");
start++;
}
}
@Override
public void onFailure(Throwable caught) {
DOM.getElementById("loading").getStyle().setDisplay(Display.NONE);
}
});
cellFormatter.addStyleName(0, 0, "firstHeaderCell");
cellFormatter.addStyleName(0, 5, "lastHeaderCell");
cellFormatter.setWidth(0, 1, "200px");
cellFormatter.setWidth(0, 2, "100px");
cellFormatter.setWidth(0, 4, "150px");
cellFormatter.setWidth(0, 5, "150px");
flexTable.getRowFormatter().addStyleName(0, "headerRow");
convPanel.add(flexTable);
}
protected Widget populateContextMenu(final int id, final SimplePanel convPanel, final String conversationFilter) {
MenuBar menuBar = new MenuBar(true);
MenuItem importantItem = new MenuItem(ConversationWidgetConstants.FILTER_IMPORTANT, new Command() {
@Override
public void execute() {
moveConversationTo(id, ConversationWidgetConstants.FILTER_IMPORTANT, convPanel, conversationFilter);
}
});
menuBar.addItem(importantItem);
MenuItem archiveItem = new MenuItem(ConversationWidgetConstants.FILTER_ARCHIVE, new Command() {
@Override
public void execute() {
moveConversationTo(id, ConversationWidgetConstants.FILTER_ARCHIVE, convPanel, conversationFilter);
}
});
menuBar.addItem(archiveItem);
MenuItem inboxItem = new MenuItem(ConversationWidgetConstants.FILTER_INBOX, new Command() {
@Override
public void execute() {
moveConversationTo(id, ConversationWidgetConstants.FILTER_INBOX, convPanel, conversationFilter);
}
});
menuBar.addItem(inboxItem);
MenuItem moveToItem = new MenuItem("Move To", menuBar);
MenuItem deleteItem = new MenuItem("Delete", new Command() {
@Override
public void execute() {
deleteConversation(id, convPanel, conversationFilter);
}
});
MenuBar menu = new MenuBar(true);
menu.addItem(moveToItem);
menu.addItem(deleteItem);
menu.setAutoOpen(true);
menu.setWidth("100%");
menu.setAnimationEnabled(true);
menu.addSeparator();
menu.setStyleName("move-conversation-context-menu");
moveToItem.addStyleName("move-conversation-context-menu-item-moveto");
deleteItem.addStyleName("move-conversation-context-menu-item-moveto");
archiveItem.addStyleName("move-conversation-context-menu-item-moveto");
importantItem.addStyleName("move-conversation-context-menu-item-moveto");
return menu;
}
protected void deleteConversation(int convId, final SimplePanel convPanel, final String conversationFilter) {
DOM.getElementById("loading").getStyle().setDisplay(Display.BLOCK);
DBDeleteConversationAsync rpc = (DBDeleteConversationAsync) GWT.create(DBDeleteConversation.class);
ServiceDefTarget tar = (ServiceDefTarget) rpc;
String moduleURL = GWT.getModuleBaseURL() + "DBDeleteConversationImpl";
tar.setServiceEntryPoint(moduleURL);
rpc.deleteConversation(convId, userInfo, new AsyncCallback<Void>() {
@Override
public void onSuccess(Void result) {
DOM.getElementById("loading").getStyle().setDisplay(Display.NONE);
convPanel.clear();
fillConversationPanel(convPanel, conversationFilter);
}
@Override
public void onFailure(Throwable caught) {
DOM.getElementById("loading").getStyle().setDisplay(Display.NONE);
DialogBox dialogBox = DialogBoxCreator.createDialogBox(ConversationWidgetConstants.DIALOG_BOX_FAILED_DELETING_CONVERSATION_TITLE,
caught.getMessage(), DialogBoxConstants.CLOSE_BUTTON, false, false);
dialogBox.setGlassEnabled(true);
dialogBox.setAnimationEnabled(true);
dialogBox.center();
dialogBox.show();
}
});
}
private void moveConversationTo(int id, String filter, final SimplePanel convPanel, final String conversationFilter) {
DOM.getElementById("loading").getStyle().setDisplay(Display.BLOCK);
DBMoveConversationAsync rpc = (DBMoveConversationAsync) GWT.create(DBMoveConversation.class);
ServiceDefTarget tar = (ServiceDefTarget) rpc;
String moduleURL = GWT.getModuleBaseURL() + "DBMoveConversationImpl";
tar.setServiceEntryPoint(moduleURL);
rpc.moveConversation(id, filter, userInfo, new AsyncCallback<Void>() {
@Override
public void onSuccess(Void result) {
DOM.getElementById("loading").getStyle().setDisplay(Display.NONE);
convPanel.clear();
fillConversationPanel(convPanel, conversationFilter);
}
@Override
public void onFailure(Throwable caught) {
DOM.getElementById("loading").getStyle().setDisplay(Display.NONE);
DialogBox dialogBox = DialogBoxCreator.createDialogBox(ConversationWidgetConstants.DIALOG_BOX_FAILED_MOVING_CONVERSATION_TITLE,
caught.getMessage(), DialogBoxConstants.CLOSE_BUTTON, false, false);
dialogBox.setGlassEnabled(true);
dialogBox.setAnimationEnabled(true);
dialogBox.center();
dialogBox.show();
}
});
}
private void viewConversation(int id, final SimplePanel convPanel) {
convPanel.clear();
lastId = id;
VerticalPanel vPanel = new VerticalPanel();
final FlexTable flexTable = new FlexTable();
flexTable.addStyleName("flexTable");
CellFormatter cellFormatter = flexTable.getCellFormatter();
flexTable.setHTML(0, 0, ConversationWidgetConstants.NR);
flexTable.setHTML(0, 1, ConversationWidgetConstants.DATE);
flexTable.setHTML(0, 2, ConversationWidgetConstants.FROM);
flexTable.setHTML(0, 3, ConversationWidgetConstants.MESSAGE);
DOM.getElementById("loading").getStyle().setDisplay(Display.BLOCK);
DBGetMessagesForConversationAsync rpc = (DBGetMessagesForConversationAsync) GWT.create(DBGetMessagesForConversation.class);
ServiceDefTarget tar = (ServiceDefTarget) rpc;
String moduleURL = GWT.getModuleBaseURL() + "DBGetMessagesForConversationImpl";
tar.setServiceEntryPoint(moduleURL);
rpc.getAllMessagesForConversation(id, new AsyncCallback<List<Message>>() {
@Override
public void onSuccess(List<Message> result) {
DOM.getElementById("loading").getStyle().setDisplay(Display.NONE);
isConversationView = false;
isMessageView = true;
int start = 1;
for (Message message : result) {
flexTable.setHTML(start, 0, String.valueOf(message.getNumber()));
flexTable.setHTML(start, 1, message.getDate());
flexTable.setHTML(start, 2,
message.getFrom().equals(userInfo.getUsername()) ? message.getFrom() : "<b>" + message.getFrom() + "</b>");
flexTable.setHTML(start, 3, message.getMessage());
start++;
}
}
@Override
public void onFailure(Throwable caught) {
DOM.getElementById("loading").getStyle().setDisplay(Display.NONE);
DialogBox dialogBox = DialogBoxCreator.createDialogBox(ConversationWidgetConstants.DIALOG_BOX_FAILED_GETTING_MESSAGES_TITLE,
caught.getMessage(), DialogBoxConstants.CLOSE_BUTTON, false, false);
dialogBox.setGlassEnabled(true);
dialogBox.setAnimationEnabled(true);
dialogBox.center();
dialogBox.show();
}
});
cellFormatter.addStyleName(0, 0, "firstHeaderCell");
cellFormatter.addStyleName(0, 3, "lastHeaderCell");
cellFormatter.setWidth(0, 1, "200px");
cellFormatter.setWidth(0, 2, "200px");
cellFormatter.setWidth(0, 3, "800px");
flexTable.getRowFormatter().addStyleName(0, "headerRow");
// Reply Box
VerticalPanel replyPanel = new VerticalPanel();
HTML replyText = new HTML("<br><br><b>Respond to this conversation:</b>");
final TextArea replyBox = new TextArea();
replyBox.setVisibleLines(8);
replyBox.setWidth("400px");
replyBox.addStyleName("reply-box");
Button replyButton = new Button();
replyButton.setText("Send");
replyButton.addStyleName("reply-button");
replyButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
String text = replyBox.getText();
if (text != null && !text.trim().equals("")) {
ReplyMessage message = new ReplyMessage(text, userInfo.getUsername(), lastId);
DOM.getElementById("loading").getStyle().setDisplay(Display.BLOCK);
DBReplyToConversationAsync rpc = (DBReplyToConversationAsync) GWT.create(DBReplyToConversation.class);
ServiceDefTarget tar = (ServiceDefTarget) rpc;
String moduleURL = GWT.getModuleBaseURL() + "DBReplyToConversationImpl";
tar.setServiceEntryPoint(moduleURL);
// rpc.replyToConversation(message, new AsyncCallback<Void>() {
//
// @Override
// public void onFailure(Throwable caught) {
// DOM.getElementById("loading").getStyle().setDisplay(Display.NONE);
//
// DialogBox dialogBox = DialogBoxCreator.createDialogBox(ConversationWidgetConstants.DIALOG_BOX_EMPTY_REPLY_TITLE,
// caught.getMessage(), DialogBoxConstants.CLOSE_BUTTON, false, false);
// dialogBox.setGlassEnabled(true);
// dialogBox.setAnimationEnabled(true);
// dialogBox.center();
// dialogBox.show();
//
// viewConversation(lastId, convPanel);
// }
//
// @Override
// public void onSuccess(Void result) {
// DOM.getElementById("loading").getStyle().setDisplay(Display.NONE);
// viewConversation(lastId, convPanel);
// }
// });
} else {
DialogBox dialogBox = DialogBoxCreator.createDialogBox(ConversationWidgetConstants.DIALOG_BOX_EMPTY_REPLY_TITLE,
ConversationWidgetConstants.DIALOG_BOX_EMPTY_REPLY_MESSAGE, DialogBoxConstants.CLOSE_BUTTON, false, false);
dialogBox.setGlassEnabled(true);
dialogBox.setAnimationEnabled(true);
dialogBox.center();
dialogBox.show();
}
}
});
replyPanel.add(replyText);
replyPanel.add(replyBox);
replyPanel.add(replyButton);
vPanel.add(flexTable);
vPanel.add(replyPanel);
convPanel.add(vPanel);
}
}