share-updates/src/main/java/org/gcube/portlets/user/shareupdates/client/view/ShareUpdateForm.java

410 lines
14 KiB
Java

package org.gcube.portlets.user.shareupdates.client.view;
import java.util.ArrayList;
import net.eliasbalasis.tibcopagebus4gwt.client.PageBusAdapter;
import net.eliasbalasis.tibcopagebus4gwt.client.PageBusAdapterException;
import org.gcube.portal.databook.shared.ClientFeed;
import org.gcube.portal.databook.shared.ClientFeed.ClientFeedJsonizer;
import org.gcube.portal.databook.shared.FeedType;
import org.gcube.portal.databook.shared.PrivacyLevel;
import org.gcube.portal.databook.shared.UserInfo;
import org.gcube.portlets.user.shareupdates.client.ShareUpdateService;
import org.gcube.portlets.user.shareupdates.client.ShareUpdateServiceAsync;
import org.gcube.portlets.user.shareupdates.shared.LinkPreview;
import org.gcube.portlets.user.shareupdates.shared.UserSettings;
import org.gcube.portlets.widgets.fileupload.client.events.FileUploadCompleteEvent;
import org.gcube.portlets.widgets.fileupload.client.events.FileUploadCompleteEventHandler;
import org.gcube.portlets.widgets.fileupload.client.view.UploadProgressPanel;
import org.jsonmaker.gwt.client.Jsonizer;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.dom.client.Style.Visibility;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiFactory;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FileUpload;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Widget;
/**
*
* @author Massimiliano Assante
* @version 1.2 Nov 2012
*
*/
public class ShareUpdateForm extends Composite {
/**
* Create a remote service proxy to talk to the server-side Greeting service.
*/
private final ShareUpdateServiceAsync shareupdateService = GWT
.create(ShareUpdateService.class);
final PageBusAdapter pageBusAdapter = new PageBusAdapter();
protected final static String SHARE_UPDATE_TEXT = "Share an update or paste a link, use “@” to mention someone";
protected final static String ERROR_UPDATE_TEXT = "Looks like empty to me!";
private final static String LISTBOX_LEVEL = " - ";
public static final String loading = GWT.getModuleBaseURL() + "../images/avatarLoader.gif";
public static final String avatar_default = GWT.getModuleBaseURL() + "../images/Avatar_default.png";
public static final String attach = GWT.getModuleBaseURL() + "../images/attach.png";
private HandlerManager eventBus = new HandlerManager(null);
private static ShareUpdateFormUiBinder uiBinder = GWT
.create(ShareUpdateFormUiBinder.class);
private LinkPreviewer myLinkPreviewer;
private UploadProgressPanel uploadProgress;
interface ShareUpdateFormUiBinder extends UiBinder<Widget, ShareUpdateForm> {
}
private static ShareUpdateForm singleton;
public static ShareUpdateForm get() {
return singleton;
}
@UiField
HTMLPanel mainPanel;
@UiField
LinkPlaceholder preview;
@UiField
Button submitButton;
@UiField
HTML attachButton;
@UiField
Image avatarImage;
@UiField SuperPosedTextArea shareTextArea;
@UiField ListBox privacyLevel = new ListBox(false);
UserInfo myUserInfo;
private void bind() {
/**
* get the uploaded file result
*/
eventBus.addHandler(FileUploadCompleteEvent.TYPE, new FileUploadCompleteEventHandler() {
@Override
public void onUploadComplete(FileUploadCompleteEvent event) {
String absolutePathOnServer = event.getUploadedFileInfo().getAbsolutePath();
GWT.log("uploaded on Server here: " + absolutePathOnServer);
checkFile(event.getUploadedFileInfo().getFilename(), absolutePathOnServer);
}
});
}
public ShareUpdateForm() {
initWidget(uiBinder.createAndBindUi(this));
singleton = this;
bind();
avatarImage.setUrl(loading);
shareTextArea.setText(SHARE_UPDATE_TEXT);
attachButton.getElement().getStyle().setDisplay(Display.INLINE);
attachButton.setHTML("<span style=\"padding: 5px 1px; background: url('"+attach+"') 50% 50% no-repeat;\">&nbsp;&nbsp;&nbsp;&nbsp;</span>");
shareupdateService.getUserSettings(new AsyncCallback<UserSettings>() {
public void onFailure(Throwable caught) {
avatarImage.setSize("60px", "60px");
avatarImage.setUrl(avatar_default);
}
public void onSuccess(UserSettings userSettings) {
myUserInfo = userSettings.getUserInfo();
avatarImage.getElement().getParentElement().setAttribute("href", myUserInfo.getAccountURL());
avatarImage.setSize("60px", "60px");
avatarImage.setUrl(myUserInfo.getAvatarId());
String singleVREName = "";
if (myUserInfo.getOwnVREs().size() > 1) {
privacyLevel.addItem("My VREs", PrivacyLevel.VRES.toString());
for (String vreId : myUserInfo.getOwnVREs().keySet())
privacyLevel.addItem(LISTBOX_LEVEL + myUserInfo.getOwnVREs().get(vreId), vreId);
}
else if (myUserInfo.getOwnVREs().size() == 1)
for (String vreId : myUserInfo.getOwnVREs().keySet()) {
singleVREName = myUserInfo.getOwnVREs().get(vreId);
privacyLevel.addItem(LISTBOX_LEVEL + singleVREName, vreId);
}
//privacyLevel.addItem("My Connections", PrivacyLevel.CONNECTION.toString());
if (myUserInfo.isAdmin() && userSettings.isInfrastructure())
privacyLevel.addItem("Anyone", PrivacyLevel.PORTAL.toString());
//change css if deployed in VRE scope
if (!userSettings.isInfrastructure()) {
mainPanel.addStyleName("framed");
Document.get().getElementById("staticPrivacyLevel").setInnerText(singleVREName);
}
else
privacyLevel.setVisible(true);
}
});
}
/** Used by UiBinder to instantiate UploadProgressView */
@UiFactory
UploadProgressPanel instatiateProgressView() {
uploadProgress = new UploadProgressPanel(eventBus);
uploadProgress.setVisible(false);
return uploadProgress;
}
@UiHandler("shareTextArea")
void onShareUpdateClick(ClickEvent e) {
shareTextArea.removeSampleText();
}
@UiHandler("attachButton")
void onAttachClick(ClickEvent e) {
if (myLinkPreviewer == null) {
FileUpload up = uploadProgress.initialize();
up.setVisible(false);
fileBrowse(up.getElement());
uploadProgress.setVisible(true);
attachButton.getElement().getStyle().setVisibility(Visibility.HIDDEN); //beacuse otherwise it looses the other properties setting
} else {
Window.alert("You cannot post two files, please remove the previous one first.");
}
}
/**
* this simulates the click on the hidden native GWT FileUpload Button
* @param el
*/
public static native void fileBrowse(Element el) /*-{
el.click();
}-*/;
@UiHandler("submitButton")
void onClick(ClickEvent e) {
shareupdateService.getUserSettings(new AsyncCallback<UserSettings>() {
public void onFailure(Throwable caught) {
Window.alert("Ops! we encountered some problems delivering your message, server is not responding, please try again in a short while.");
}
public void onSuccess(UserSettings result) {
if (result.getUserInfo().getUsername().equals("test.user")) {
Window.alert("Your session has expired, please log out and login again");
return;
}
myUserInfo = result.getUserInfo();
String toShare = shareTextArea.getText().trim();
if (toShare.equals(SHARE_UPDATE_TEXT) || toShare.equals(ERROR_UPDATE_TEXT) || toShare.equals("")) {
shareTextArea.addStyleName("error");
shareTextArea.setText(ERROR_UPDATE_TEXT);
return;
}
//then you can post, but pass html
String toPost = shareTextArea.getText();
postTweet(toPost, shareTextArea.getMentionedUsers());
}
});
}
/**
*
* @param textToPost
*/
private void postTweet(String textToPost, ArrayList<String> mentionedUsers) {
String toShare = escapeHtml(textToPost);
if (! checkTextLength(toShare)) {
Window.alert("We found a single word containing more than 50 chars and it's not a link, is it meaningful?");
return;
}
submitButton.setEnabled(false);
shareTextArea.setEnabled(false);
String vreId = "";
if (getPrivacyLevel() == PrivacyLevel.SINGLE_VRE) {
vreId = privacyLevel.getValue(privacyLevel.getSelectedIndex());
}
String linkTitle = "";
String linkDescription = "";
String linkUrl = "";
String linkUrlThumbnail = "";
String linkHost = "";
if (myLinkPreviewer != null) {
linkTitle = myLinkPreviewer.getLinkTitle();
linkDescription = myLinkPreviewer.getLinkDescription();
linkUrl = myLinkPreviewer.getUrl();
linkUrlThumbnail = myLinkPreviewer.getUrlThumbnail();
linkHost = myLinkPreviewer.getHost();
}
shareupdateService.share(toShare, FeedType.TWEET, getPrivacyLevel(), vreId, linkTitle, linkDescription, linkUrl, linkUrlThumbnail, linkHost, mentionedUsers, new AsyncCallback<ClientFeed>() {
public void onFailure(Throwable caught) {
submitButton.setEnabled(true);
shareTextArea.setEnabled(true);
shareTextArea.setText(SHARE_UPDATE_TEXT);
shareTextArea.cleanHighlihterDiv();
preview.clear();
myLinkPreviewer = null;
}
public void onSuccess(ClientFeed feed) {
submitButton.setEnabled(true);
shareTextArea.setEnabled(true);
shareTextArea.setText(SHARE_UPDATE_TEXT);
shareTextArea.cleanHighlihterDiv();
preview.clear();
myLinkPreviewer = null;
if (feed == null)
Window.alert("Ops! we encountered some problems delivering your message, please try again in a short while.");
else {
// publish a message with the refresh notification
try {
pageBusAdapter.PageBusPublish("org.gcube.portal.databook.shared", feed, (Jsonizer)GWT.create(ClientFeedJsonizer.class));
} catch (PageBusAdapterException ex) {
GWT.log(ex.getMessage());
}
}
}
});
}
private PrivacyLevel getPrivacyLevel() {
String selected = privacyLevel.getValue(privacyLevel.getSelectedIndex());
if (selected.compareTo(PrivacyLevel.CONNECTION.toString()) == 0)
return PrivacyLevel.CONNECTION;
else if (selected.compareTo(PrivacyLevel.VRES.toString()) == 0)
return PrivacyLevel.VRES;
else if (selected.compareTo(PrivacyLevel.PRIVATE.toString()) == 0)
return PrivacyLevel.PRIVATE;
else if (selected.compareTo(PrivacyLevel.PORTAL.toString()) == 0)
return PrivacyLevel.PORTAL;
else
return PrivacyLevel.SINGLE_VRE;
}
/**
* Escape an html string. Escaping data received from the client helps to
* prevent cross-site script vulnerabilities.
*
* @param html the html string to escape
* @return the escaped string
*/
private String escapeHtml(String html) {
if (html == null) {
return null;
}
return html.replaceAll("&", "&amp;").replaceAll("<", "&lt;")
.replaceAll(">", "&gt;");
}
/**
* called when pasting a possible link
* @param linkToCheck
*/
protected void checkLink(String textToCheck) {
if (myLinkPreviewer == null) {
String [] parts = textToCheck.split("\\s");
// Attempt to convert each item into an URL.
for( String item : parts ) {
if (item.startsWith("http")) {
preview.add(new LinkLoader());
//GWT.log("It's http link:" + linkToCheck);
shareupdateService.checkLink(textToCheck, new AsyncCallback<LinkPreview>() {
public void onFailure(Throwable caught) {
preview.clear();
}
public void onSuccess(LinkPreview result) {
preview.clear();
if (result != null)
addPreview(result);
}
});
break;
}
}
} else {
Window.alert("You cannot post two links, please remove the previous one first.");
}
}
/**
* called when the file was correctly uploaded on server
* @param fileName the name of the file
* @param absolutePathOnServer the path of the file ending with its name on the server temp
*/
protected void checkFile(String fileName, String absolutePathOnServer) {
preview.add(new LinkLoader());
shareupdateService.checkUploadedFile(fileName, absolutePathOnServer, new AsyncCallback<LinkPreview>() {
public void onFailure(Throwable caught) {
uploadProgress.showRegisteringResult(false);
preview.clear();
attachButton.getElement().getStyle().setVisibility(Visibility.VISIBLE); //beacuse otherwise it looses the other properties setting
}
public void onSuccess(LinkPreview result) {
preview.clear();
uploadProgress.setVisible(false);
if (result != null)
addPreview(result);
}
});
}
/**
* called when pasting. it tries to avoid pasting long non spaced strings
* @param linkToCheck
*/
private boolean checkTextLength(String textToCheck) {
String [] parts = textToCheck.split("\\s");
// check the length of tokens
for( String item : parts ) {
if (! item.startsWith("http")) { //url are accepted as they can be trunked
if (item.length() > 50) {
return false;
}
}
}
return true;
}
/**
* add the link preview in the view
* @param result
*/
private void addPreview(LinkPreview result) {
uploadProgress.setVisible(false);
myLinkPreviewer = new LinkPreviewer(this, result);
preview.add(myLinkPreviewer);
}
/**
*
*/
protected void cancelPreview() {
preview.clear();
myLinkPreviewer = null;
attachButton.getElement().getStyle().setVisibility(Visibility.VISIBLE); //beacuse otherwise it looses the other properties setting
}
}