diff --git a/.settings/org.eclipse.wst.common.component b/.settings/org.eclipse.wst.common.component index 8ed83f9..8c4a917 100644 --- a/.settings/org.eclipse.wst.common.component +++ b/.settings/org.eclipse.wst.common.component @@ -7,9 +7,6 @@ uses - - uses - diff --git a/src/main/java/org/gcube/portlets/user/shareupdates/client/ShareUpdateService.java b/src/main/java/org/gcube/portlets/user/shareupdates/client/ShareUpdateService.java index 0baad80..ebc78f2 100644 --- a/src/main/java/org/gcube/portlets/user/shareupdates/client/ShareUpdateService.java +++ b/src/main/java/org/gcube/portlets/user/shareupdates/client/ShareUpdateService.java @@ -6,6 +6,7 @@ import org.gcube.portal.databook.shared.ClientFeed; import org.gcube.portal.databook.shared.FeedType; import org.gcube.portal.databook.shared.PrivacyLevel; import org.gcube.portlets.user.shareupdates.shared.LinkPreview; +import org.gcube.portlets.user.shareupdates.shared.UploadedFile; import org.gcube.portlets.user.shareupdates.shared.UserSettings; import org.gcube.portlets.widgets.pickitem.shared.ItemBean; @@ -17,8 +18,10 @@ import com.google.gwt.user.client.rpc.RemoteServiceRelativePath; */ @RemoteServiceRelativePath("shareupdateServlet") public interface ShareUpdateService extends RemoteService { - ClientFeed share(String feedText, FeedType type, PrivacyLevel pLevel, String vreName, LinkPreview preview, String urlThumbnail, ArrayList mentionedUsers, String fileName, String FilePathOnServer, boolean notifyGroup); + ClientFeed sharePostWithLinkPreview(String feedText, FeedType type, PrivacyLevel pLevel, String vreName, LinkPreview preview, String urlThumbnail, ArrayList mentionedUsers, boolean notifyGroup); + + ClientFeed sharePostWithAttachments(String feedText, FeedType type, PrivacyLevel pLevel, String vreName,ArrayList uploadedFiles, ArrayList mentionedUsers, boolean notifyGroup, boolean saveCopyWokspace); UserSettings getUserSettings(); diff --git a/src/main/java/org/gcube/portlets/user/shareupdates/client/ShareUpdateServiceAsync.java b/src/main/java/org/gcube/portlets/user/shareupdates/client/ShareUpdateServiceAsync.java index 4cb3da5..7efa21d 100644 --- a/src/main/java/org/gcube/portlets/user/shareupdates/client/ShareUpdateServiceAsync.java +++ b/src/main/java/org/gcube/portlets/user/shareupdates/client/ShareUpdateServiceAsync.java @@ -6,6 +6,7 @@ import org.gcube.portal.databook.shared.ClientFeed; import org.gcube.portal.databook.shared.FeedType; import org.gcube.portal.databook.shared.PrivacyLevel; import org.gcube.portlets.user.shareupdates.shared.LinkPreview; +import org.gcube.portlets.user.shareupdates.shared.UploadedFile; import org.gcube.portlets.user.shareupdates.shared.UserSettings; import org.gcube.portlets.widgets.pickitem.shared.ItemBean; @@ -15,11 +16,6 @@ import com.google.gwt.user.client.rpc.AsyncCallback; * The async counterpart of ShareUpdateService. */ public interface ShareUpdateServiceAsync { - void share(String feedText, FeedType type, PrivacyLevel pLevel, - String vreName, LinkPreview preview, String urlThumbnail, - ArrayList mentionedUsers, String fileName, - String FilePathOnServer, boolean notifyGroup, - AsyncCallback callback); void checkLink(String linkToCheck, AsyncCallback callback); @@ -31,4 +27,16 @@ public interface ShareUpdateServiceAsync { AsyncCallback callback); void getHashtags(AsyncCallback> callback); + + void sharePostWithLinkPreview(String feedText, FeedType type, + PrivacyLevel pLevel, String vreName, LinkPreview preview, + String urlThumbnail, ArrayList mentionedUsers, boolean notifyGroup, + AsyncCallback callback); + + void sharePostWithAttachments(String feedText, FeedType type, + PrivacyLevel pLevel, String vreName, + ArrayList uploadedFiles, + ArrayList mentionedUsers, boolean notifyGroup, + boolean saveCopyWokspace, AsyncCallback callback); + } diff --git a/src/main/java/org/gcube/portlets/user/shareupdates/client/view/AttachedFile.java b/src/main/java/org/gcube/portlets/user/shareupdates/client/view/AttachedFile.java index b2648bb..26d5db5 100644 --- a/src/main/java/org/gcube/portlets/user/shareupdates/client/view/AttachedFile.java +++ b/src/main/java/org/gcube/portlets/user/shareupdates/client/view/AttachedFile.java @@ -1,50 +1,135 @@ package org.gcube.portlets.user.shareupdates.client.view; +/** + * Attached file class. + * @author Costantino Perciante at ISTI-CNR + */ public class AttachedFile { + // the name of the file private String fileName; - private String fileAbsolutePathOnServer; - private AttachmentPreviewer atPrev; - private boolean correctlyUploaded; - /** - * - * @param fileName name of the file - * @param fileAbsolutePathOnServer path on the server - * @param atPrev object that shows such attachment - * @param uploaded has been it correctly uploaded on the server? - */ + // where it has been uploaded on the server (tmp directory of tomcat) + private String fileAbsolutePathOnServer; + + // a description of the file (its content for a pdf, size for images) + private String description; + + // when showing a file, this is the url that can be used for download + private String downloadUrl; + + // thumbnail url related to the type of file (pdf, png, jpg) + private String thumbnailUrl; + + // format type (pdf, jpg ecc..) + private String format; + + // object used to show on the client the attachment + private AttachmentPreviewer atPrev; + + // has been it correctly uploaded on the server? + private boolean correctlyUploaded; + public AttachedFile(String fileName, String fileAbsolutePathOnServer, - AttachmentPreviewer atPrev, boolean uploaded) { + String description, String downloadUrl, String thumbnailUrl, + String format, AttachmentPreviewer atPrev, boolean correctlyUploaded) { super(); this.fileName = fileName; this.fileAbsolutePathOnServer = fileAbsolutePathOnServer; + this.description = description; + this.downloadUrl = downloadUrl; + this.thumbnailUrl = thumbnailUrl; + this.format = format; this.atPrev = atPrev; - this.correctlyUploaded = uploaded; + this.correctlyUploaded = correctlyUploaded; } + + /** + * Constructor used when the check uploaded file fails + * @param fileName + * @param absolutePathOnServer + * @param atPrev attachment previewer + * @param thumbnail url thumbnail + */ + public AttachedFile(String fileName, String fileAbsolutePathOnServer, + AttachmentPreviewer atPrev, String thumbnailUrl) { + this.fileName = fileName; + this.fileAbsolutePathOnServer = fileAbsolutePathOnServer; + this.atPrev = atPrev; + this.thumbnailUrl = thumbnailUrl; + this.correctlyUploaded = false; + } + public String getFileName() { return fileName; } + public void setFileName(String fileName) { this.fileName = fileName; } + public String getFileAbsolutePathOnServer() { return fileAbsolutePathOnServer; } + public void setFileAbsolutePathOnServer(String fileAbsolutePathOnServer) { this.fileAbsolutePathOnServer = fileAbsolutePathOnServer; } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getDownloadUrl() { + return downloadUrl; + } + + public void setDownloadUrl(String downloadUrl) { + this.downloadUrl = downloadUrl; + } + + public String getThumbnailUrl() { + return thumbnailUrl; + } + + public void setThumbnailUrl(String thumbnailUrl) { + this.thumbnailUrl = thumbnailUrl; + } + + public String getFormat() { + return format; + } + + public void setFormat(String format) { + this.format = format; + } + public AttachmentPreviewer getAtPrev() { return atPrev; } + public void setAtPrev(AttachmentPreviewer atPrev) { this.atPrev = atPrev; } + public boolean isCorrectlyUploaded() { return correctlyUploaded; } + public void setCorrectlyUploaded(boolean correctlyUploaded) { this.correctlyUploaded = correctlyUploaded; } - + @Override + public String toString() { + return "AttachedFile [fileName=" + fileName + + ", fileAbsolutePathOnServer=" + fileAbsolutePathOnServer + + ", description=" + description + ", downloadUrl=" + + downloadUrl + ", thumbnailUrl=" + thumbnailUrl + ", mime=" + + format + ", atPrev=" + atPrev + ", correctlyUploaded=" + + correctlyUploaded + "]"; + } } diff --git a/src/main/java/org/gcube/portlets/user/shareupdates/client/view/AttachmentPreviewer.java b/src/main/java/org/gcube/portlets/user/shareupdates/client/view/AttachmentPreviewer.java index b57e2bd..c06d4be 100644 --- a/src/main/java/org/gcube/portlets/user/shareupdates/client/view/AttachmentPreviewer.java +++ b/src/main/java/org/gcube/portlets/user/shareupdates/client/view/AttachmentPreviewer.java @@ -1,18 +1,25 @@ package org.gcube.portlets.user.shareupdates.client.view; import com.google.gwt.core.client.GWT; +import com.google.gwt.dom.client.Style.Cursor; +import com.google.gwt.dom.client.Style.Unit; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.uibinder.client.UiHandler; -import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.HTML; +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.Widget; +/** + * Class to show an attached file. + * @author Costantino Perciante at ISTI-CNR + * + */ public class AttachmentPreviewer extends Composite { private static AttachmentPreviewerUiBinder uiBinder = GWT @@ -25,8 +32,9 @@ public class AttachmentPreviewer extends Composite { public AttachmentPreviewer() { initWidget(uiBinder.createAndBindUi(this)); } - - private static final String DELETE_ATTACHMENT = "The attachment won't be saved. Would you like to continue?"; + + //private static final String DELETE_ATTACHMENT = "Delete this attachment?"; + private static final String RETRY_TO_UPLOAD = "Retry to upload this attachment on the server."; @UiField HTML deleteAttachment; @@ -42,13 +50,19 @@ public class AttachmentPreviewer extends Composite { @UiField Image resultImage; - + + @UiField + HorizontalPanel attachmentResult; + // Parent of this AttachmentPreviewer object private Placeholder parent; - + // the ShareUpdateForm private ShareUpdateForm shareUpdateForm; - + + // retry upload button reference + private HTML retryButton; + public AttachmentPreviewer(String fileName, String urlImagePreview, Placeholder parent, ShareUpdateForm shareUpdateForm) { initWidget(uiBinder.createAndBindUi(this)); @@ -60,32 +74,34 @@ public class AttachmentPreviewer extends Composite { // style the delete button this.deleteAttachment.setStyleName("su-deleteAttachment"); this.deleteAttachment.setTitle("Cancel"); - + // save parent this.parent = parent; - + // save the shareUpdateForm object, since it maintains the list of attached files this.shareUpdateForm = shareUpdateForm; } @UiHandler("deleteAttachment") void onClick(ClickEvent e) { - - // alert the user - boolean confirm = Window.confirm(DELETE_ATTACHMENT); - if(!confirm) - return; - + // alert the user (In some firefox versions, this may cause the bug + //uncaught exception: java.lang.AssertionError: Negative entryDepth value at exit -1) + // due to the fact that a window.alert or window.confirm is invoked within an handler + // boolean confirm = Window.confirm(DELETE_ATTACHMENT); + // + // if(!confirm) + // return; + // we have to remove the AttachmentPreview object (that is, this object) and // remove the file from the List of AttachedFiles parent.remove(this); shareUpdateForm.removeAttachedFile(this); - + } /** - * set the label and the that shows if the file has been saved or not + * set the label and the icon that shows if the file has been saved or not * @param result * @param urlImageResult */ @@ -103,24 +119,32 @@ public class AttachmentPreviewer extends Composite { } /** - * Change style of part of this object to allow the user to retry to upload the file - * @param tooltip - * @param retryToAttachImageUrl + * + * Change style of part of this object to allow the user to retry to upload the file. + * */ - public void setImagePreviewToRetry(String tooltip, String retryToAttachImageUrl) { - - this.imagePreview.setUrl(retryToAttachImageUrl); - this.imagePreview.setTitle(tooltip); - - // add the handler on the icon - this.imagePreview.addClickHandler(new ClickHandler() { - + public void retryToUpload(final AttachmentPreviewer thisPreviewer) { + + // add the button to retry to upload such file + retryButton = new HTML(""+ "Try Again"); + retryButton.getElement().getStyle().setMarginLeft(5, Unit.PX); + retryButton.getElement().getStyle().setCursor(Cursor.POINTER); + retryButton.setTitle(RETRY_TO_UPLOAD); + + retryButton.addClickHandler(new ClickHandler() { + @Override public void onClick(ClickEvent event) { - Window.alert("Retry to attach handler to be implemented..."); + + // we have to remove the AttachmentPreview object (that is, this object) and + // remove the file from the List of AttachedFiles + parent.remove(thisPreviewer); + shareUpdateForm.removeAttachedFile(thisPreviewer); + } }); - + + attachmentResult.add(retryButton); } } diff --git a/src/main/java/org/gcube/portlets/user/shareupdates/client/view/LinkLoader.java b/src/main/java/org/gcube/portlets/user/shareupdates/client/view/LinkLoader.java index db7bd26..43d6776 100644 --- a/src/main/java/org/gcube/portlets/user/shareupdates/client/view/LinkLoader.java +++ b/src/main/java/org/gcube/portlets/user/shareupdates/client/view/LinkLoader.java @@ -16,7 +16,4 @@ public class LinkLoader extends Composite { public LinkLoader() { initWidget(uiBinder.createAndBindUi(this)); } - - - } diff --git a/src/main/java/org/gcube/portlets/user/shareupdates/client/view/LinkPreviewer.java b/src/main/java/org/gcube/portlets/user/shareupdates/client/view/LinkPreviewer.java index af24f63..a1dae52 100644 --- a/src/main/java/org/gcube/portlets/user/shareupdates/client/view/LinkPreviewer.java +++ b/src/main/java/org/gcube/portlets/user/shareupdates/client/view/LinkPreviewer.java @@ -12,6 +12,11 @@ import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.Widget; +/** + * Class used to show a link preview. + * @author Massimiliano Assante at ISTI-CNR + * + */ public class LinkPreviewer extends Composite { private static final String HTTP_ERROR_301 = "Moved Permanently"; diff --git a/src/main/java/org/gcube/portlets/user/shareupdates/client/view/LinkPreviewer.ui.xml b/src/main/java/org/gcube/portlets/user/shareupdates/client/view/LinkPreviewer.ui.xml index 508bac4..cfa53f6 100644 --- a/src/main/java/org/gcube/portlets/user/shareupdates/client/view/LinkPreviewer.ui.xml +++ b/src/main/java/org/gcube/portlets/user/shareupdates/client/view/LinkPreviewer.ui.xml @@ -33,6 +33,5 @@ - \ No newline at end of file diff --git a/src/main/java/org/gcube/portlets/user/shareupdates/client/view/PostContent.java b/src/main/java/org/gcube/portlets/user/shareupdates/client/view/PostContent.java new file mode 100644 index 0000000..af4e1b1 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/shareupdates/client/view/PostContent.java @@ -0,0 +1,11 @@ +package org.gcube.portlets.user.shareupdates.client.view; + +/** + * Type of posts. + * @author Costantino Perciante at ISTI-CNR + */ +public enum PostContent { + + ONLY_TEXT, TEXT_AND_LINK, TEXT_AND_ATTACHMENTS + +} diff --git a/src/main/java/org/gcube/portlets/user/shareupdates/client/view/SaveInWorkspaceBox.java b/src/main/java/org/gcube/portlets/user/shareupdates/client/view/SaveInWorkspaceBox.java index 2cccdab..481ac0f 100644 --- a/src/main/java/org/gcube/portlets/user/shareupdates/client/view/SaveInWorkspaceBox.java +++ b/src/main/java/org/gcube/portlets/user/shareupdates/client/view/SaveInWorkspaceBox.java @@ -15,16 +15,15 @@ public class SaveInWorkspaceBox extends Composite { interface SaveInWorkspaceBoxUiBinder extends UiBinder { } - - public SaveInWorkspaceBox() { - initWidget(uiBinder.createAndBindUi(this)); - } - + @UiField CheckBox saveCheckBox; - public SaveInWorkspaceBox(String firstName) { - initWidget(uiBinder.createAndBindUi(this)); + public SaveInWorkspaceBox() { + initWidget(uiBinder.createAndBindUi(this)); + + // set as not visibile + this.setVisible(false); } protected boolean getValue() { diff --git a/src/main/java/org/gcube/portlets/user/shareupdates/client/view/ShareUpdateForm.java b/src/main/java/org/gcube/portlets/user/shareupdates/client/view/ShareUpdateForm.java index 641a0ba..b7f38e1 100644 --- a/src/main/java/org/gcube/portlets/user/shareupdates/client/view/ShareUpdateForm.java +++ b/src/main/java/org/gcube/portlets/user/shareupdates/client/view/ShareUpdateForm.java @@ -15,6 +15,7 @@ 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.UploadedFile; 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; @@ -51,7 +52,7 @@ import com.google.gwt.user.client.ui.ListBox; import com.google.gwt.user.client.ui.ValueBoxBase.TextAlignment; import com.google.gwt.user.client.ui.Widget; /** - * + * The main share update class. * @author Massimiliano Assante at ISTI CNR * @author Costantino Perciante at ISTI CNR * @@ -67,6 +68,9 @@ public class ShareUpdateForm extends Composite { // the label for all Vres/channels private final static String ALL_VRES = "Share with: your Virtual Research Environments"; + // maximum number of files that can be attached + private static final int MAX_NUMBER_ATTACHMENTS = 10; + // Labels protected final static String SHARE_UPDATE_TEXT = "Share an update or a link, use “@” to mention and “#” to add a topic"; protected final static String ERROR_UPDATE_TEXT = "Looks like empty to me!"; @@ -75,21 +79,17 @@ public class ShareUpdateForm extends Composite { public static final String DROP_FILE_HERE_TEXT = "Drop your file(s) here!"; public static final String ATTACHMENT_LOADED = "Attachment loaded!"; public static final String ATTACHMENT_NOT_LOADED = "Attachment not loaded!"; - private static final String RETRY_TO_ATTACH_MESSAGE = "Retry to attach this file"; private static final String DELETE_LINK_PREVIEW = "The link preview will be removed. Would you like to continue?"; private static final String DELETE_ATTACHMENTS = "The attachment(s) will be removed. Would you like to continue?"; + private static final String TOO_MUCH_ATTACHMENT_ALERT = "Sorry, but you cannot upload more than " + MAX_NUMBER_ATTACHMENTS + " attachments!"; // image urls 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"; - public static final String attachedDefault = GWT.getModuleBaseURL() + "../images/attachment_default.png"; - public static final String loadedAttachment = GWT.getModuleBaseURL() + "../images/load.png"; - public static final String notLoadedAttachment = GWT.getModuleBaseURL() + "../images/not_load.png"; - public static final String retryToAttach = GWT.getModuleBaseURL() + "../images/reload.png"; - - // maximum number of files that can be attached! - private static final int MAX_NUMBER_ATTACHMENTS = 10; + public static final String attachImageUrl = GWT.getModuleBaseURL() + "../images/attach.png"; + public static final String attachedDefaultImageUrl = GWT.getModuleBaseURL() + "../images/attachment_default.png"; + public static final String loadedAttachmentImageUrl = GWT.getModuleBaseURL() + "../images/load.png"; + public static final String notLoadedAttachmentImageUrl = GWT.getModuleBaseURL() + "../images/not_load.png"; // remember the previous text in the textarea (while handling drag and drop) private static String previousText; @@ -103,7 +103,7 @@ public class ShareUpdateForm extends Composite { .create(ShareUpdateFormUiBinder.class); // The link previewer - private LinkPreviewer myLinkPreviewer; + private LinkPreviewer linkPreviewer; // panel that show the in progress upload of an attachment private UploadProgressPanel uploadProgress; @@ -114,6 +114,10 @@ public class ShareUpdateForm extends Composite { // this instance private static ShareUpdateForm singleton; + /** + * Get this ShareUpdateForm object + * @return + */ public static ShareUpdateForm get() { return singleton; } @@ -142,6 +146,9 @@ public class ShareUpdateForm extends Composite { @UiField ListBox notifyListbox = new ListBox(); + @UiField + SaveInWorkspaceBox saveInWorkspaceCheckbox; + // requested user's information private UserInfo myUserInfo; @@ -211,33 +218,8 @@ public class ShareUpdateForm extends Composite { GWT.log("Drag over handler"); - // save current text (note that the DragOverEvent event can be fired several times) - boolean conditionToSave = !shareTextArea.getText().equals(DROP_FILE_HERE_TEXT) && !shareTextArea.getText().equals(SHARE_UPDATE_TEXT); - previousText = conditionToSave ? shareTextArea.getText() : previousText; - - // change border properties - shareTextArea.getElement().getStyle().setBorderStyle(BorderStyle.DASHED); - shareTextArea.getElement().getStyle().setBorderColor("rgba(82, 168, 236, 0.6)"); - shareTextArea.getElement().getStyle().setBorderWidth(2.5, Unit.PX); - - // change background color - shareTextArea.getElement().getStyle().setBackgroundColor("rgba(82, 168, 236, 0.2)"); - - // enlarge the window - Document.get().getElementById("highlighterContainer").getStyle().setHeight(52, Unit.PX); - Document.get().getElementById("highlighter").getStyle().setHeight(52, Unit.PX); - Document.get().getElementById("postTextArea").getStyle().setHeight(52, Unit.PX); - - // add "Drop file here" text - shareTextArea.setText(DROP_FILE_HERE_TEXT); - shareTextArea.setAlignment(TextAlignment.CENTER); - shareTextArea.getElement().getStyle().setFontWeight(FontWeight.BOLD); - shareTextArea.getElement().getStyle().setPaddingTop( - (Double.parseDouble(shareTextArea.getElement().getStyle().getHeight().replace("px", "")) + 20)/2.0, Unit.PX); - - // set the color of the text if needed to gray - if(!previousText.equals(SHARE_UPDATE_TEXT)) - shareTextArea.getElement().getStyle().setColor("#999"); + // add style change + addDNDStyleEffects(); } }); @@ -260,6 +242,10 @@ public class ShareUpdateForm extends Composite { // enable shareTextArea as drop target (using native javascript) addNativeDropHandler(singleton, FileSubmit.URL); + }else{ + + GWT.log("Drag and drop not supported."); + } } }); @@ -272,6 +258,7 @@ public class ShareUpdateForm extends Composite { //get the uploaded file result eventBus.addHandler(FileUploadCompleteEvent.TYPE, new FileUploadCompleteEventHandler() { + @Override public void onUploadComplete(FileUploadCompleteEvent event) { String absolutePathOnServer = event.getUploadedFileInfo().getAbsolutePath(); @@ -303,7 +290,7 @@ public class ShareUpdateForm extends Composite { void onAttachClick(ClickEvent e) { // check if there is a linkpreview - if(myLinkPreviewer != null){ + if(linkPreviewer != null){ // in this case let the user choose what to do boolean confirm = Window.confirm(DELETE_LINK_PREVIEW); @@ -315,6 +302,14 @@ public class ShareUpdateForm extends Composite { cancelLinkPreview(); } + // check the number of already attached files + if(numberOfAttachments() >= MAX_NUMBER_ATTACHMENTS){ + + Window.alert(TOO_MUCH_ATTACHMENT_ALERT); + return; + + } + // proceed with the upload FileUpload up = uploadProgress.initialize(); up.setVisible(false); @@ -328,7 +323,9 @@ public class ShareUpdateForm extends Composite { * @param el */ public static native void fileBrowse(Element el) /*-{ + el.click(); + }-*/; @@ -340,9 +337,12 @@ public class ShareUpdateForm extends Composite { shareupdateService.getUserSettings(new AsyncCallback() { 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; @@ -350,90 +350,200 @@ public class ShareUpdateForm extends Composite { myUserInfo = result.getUserInfo(); String toShare = shareTextArea.getText().trim(); - //We allow to post a file without writing nothing in the sharing textarea - if (myLinkPreviewer != null && (toShare.equals(SHARE_UPDATE_TEXT) || toShare.equals(ERROR_UPDATE_TEXT) || toShare.equals("")) ) { - toShare = NO_TEXT_FILE_SHARE; + // Establish the content of this post + PostContent postContent = PostContent.ONLY_TEXT; + + // check if we are going to send a link preview (The shared text cannot be empty nor it can be an error message) + if(linkPreviewer != null && (toShare.equals(SHARE_UPDATE_TEXT) || toShare.equals(ERROR_UPDATE_TEXT) || toShare.equals(""))){ + + shareTextArea.addStyleName("error"); + shareTextArea.setText(ERROR_UPDATE_TEXT); + return; + + }else{ + + if(linkPreviewer != null) + postContent = PostContent.TEXT_AND_LINK; + + if(numberOfAttachmentsUploaded() > 0){ + postContent = PostContent.TEXT_AND_ATTACHMENTS; + toShare = NO_TEXT_FILE_SHARE; + } + } + + // check the text (attachment can be sent without shared text) 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 you have to pass html checks now String toPost = toShare; - postTweet(toPost, shareTextArea.getMentionedUsers()); + postTweet(toPost, shareTextArea.getMentionedUsers(), postContent); } }); } /** - * - * @param textToPost + * Publish a post. + * @param textToPost the text of this port + * @param mentionedUsers list of users mentioned in the text (if any) + * @param postContent the type of post */ - private void postTweet(String textToPost, ArrayList mentionedUsers) { - String toShare = escapeHtml(textToPost); - if (! checkTextLength(toShare)) { + private void postTweet(String textToPost, ArrayList mentionedUsers, PostContent postContent) { + + // escape html text + String toShareText = escapeHtml(textToPost); + if (! checkTextLength(toShareText)) { Window.alert("We found a single word containing more than 50 chars and it's not a link, is it meaningful?"); return; } + // disable text edit and submission button submitButton.setEnabled(false); shareTextArea.setEnabled(false); + // retrieve the vre id String vreId = ""; if (getPrivacyLevel() == PrivacyLevel.SINGLE_VRE) { vreId = privacyLevel.getValue(privacyLevel.getSelectedIndex()); } - //preparing to send stuff - String linkTitle = "", linkDescription = "" , linkUrl = "", linkUrlThumbnail = "", linkHost = "", fileName = null, filePath = null; - if (myLinkPreviewer != null) { - linkTitle = myLinkPreviewer.getLinkTitle(); - linkDescription = myLinkPreviewer.getLinkDescription(); - linkUrl = myLinkPreviewer.getUrl(); - linkUrlThumbnail = myLinkPreviewer.getUrlThumbnail(); - linkHost = myLinkPreviewer.getHost(); - // TODO handle attachments - // if (myLinkPreviewer.isSaveCopySelected()) { - // fileName = uploadedFileNameOnServer; - // filePath = uploadedFilePathOnServer; - // } - } - LinkPreview preview2Share = new LinkPreview(linkTitle, linkDescription, linkUrl, linkHost, null); - boolean notifyGroup = notifyListbox.getSelectedIndex() > 0; - shareupdateService.share(toShare, FeedType.TWEET, getPrivacyLevel(), vreId, preview2Share, linkUrlThumbnail, mentionedUsers, fileName, filePath, notifyGroup, new AsyncCallback() { - public void onFailure(Throwable caught) { - submitButton.setEnabled(true); - shareTextArea.setEnabled(true); - shareTextArea.setText(SHARE_UPDATE_TEXT); - shareTextArea.cleanHighlighterDiv(); - preview.clear(); - myLinkPreviewer = null; + // notify group information + boolean notifyGroup = notifyListbox.getSelectedIndex() > 0; + + // case in which there are no attachments but there could be a link preview + if(postContent == PostContent.ONLY_TEXT || postContent == PostContent.TEXT_AND_LINK){ + + //preparing to send stuff + String linkTitle = "", linkDescription = "" , linkUrl = "", linkUrlThumbnail = "", linkHost = ""; + + if (linkPreviewer != null) { + linkTitle = linkPreviewer.getLinkTitle(); + linkDescription = linkPreviewer.getLinkDescription(); + linkUrl = linkPreviewer.getUrl(); + linkUrlThumbnail = linkPreviewer.getUrlThumbnail(); + linkHost = linkPreviewer.getHost(); } - public void onSuccess(ClientFeed feed) { - submitButton.setEnabled(true); - shareTextArea.setEnabled(true); - shareTextArea.setText(SHARE_UPDATE_TEXT); - shareTextArea.cleanHighlighterDiv(); - 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()); - } + LinkPreview preview2Share = new LinkPreview(linkTitle, linkDescription, linkUrl, linkHost, null); + + // share post (it could contain a link preview) + shareupdateService.sharePostWithLinkPreview(toShareText, FeedType.TWEET, getPrivacyLevel(), vreId, preview2Share, linkUrlThumbnail, mentionedUsers, notifyGroup, new AsyncCallback() { + + public void onFailure(Throwable caught) { + submitButton.setEnabled(true); + shareTextArea.setEnabled(true); + shareTextArea.setText(SHARE_UPDATE_TEXT); + shareTextArea.cleanHighlighterDiv(); + preview.clear(); + linkPreviewer = null; } - //needed when posting long texts otherwise it stays with the current height - shareTextArea.getElement().getStyle().setHeight(54, Unit.PX); + + public void onSuccess(ClientFeed feed) { + + submitButton.setEnabled(true); + shareTextArea.setEnabled(true); + shareTextArea.setText(SHARE_UPDATE_TEXT); + shareTextArea.cleanHighlighterDiv(); + preview.clear(); + linkPreviewer = 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()); + } + } + + //needed when posting long texts otherwise it stays with the current height + shareTextArea.getElement().getStyle().setHeight(54, Unit.PX); + } + }); + } + else{ + + // case with at least one attachment available + ArrayList uploadedFiles = new ArrayList(); + + // consider only correctly uploaded file(s) + for(AttachedFile file: listOfAttachedFiles){ + + if(file.isCorrectlyUploaded()) + uploadedFiles.add( + new UploadedFile( + file.getFileName(), + file.getFileAbsolutePathOnServer(), + file.getDescription(), + file.getDownloadUrl(), + file.getThumbnailUrl(), + file.getFormat())); + } - }); + + // share the post + shareupdateService.sharePostWithAttachments(toShareText, FeedType.TWEET, getPrivacyLevel(), vreId, uploadedFiles, mentionedUsers, notifyGroup, saveInWorkspaceCheckbox.getValue(), new AsyncCallback() { + + @Override + public void onSuccess(ClientFeed result) { + + GWT.log("OK"); + + + submitButton.setEnabled(true); + shareTextArea.setEnabled(true); + shareTextArea.setText(SHARE_UPDATE_TEXT); + shareTextArea.cleanHighlighterDiv(); + saveInWorkspaceCheckbox.setVisible(false); + preview.clear(); + listOfAttachedFiles.clear(); + + if (result == 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", result, (Jsonizer)GWT.create(ClientFeedJsonizer.class)); + } catch (PageBusAdapterException ex) { + GWT.log(ex.getMessage()); + } + } + + //needed when posting long texts otherwise it stays with the current height + shareTextArea.getElement().getStyle().setHeight(54, Unit.PX); + + } + + @Override + public void onFailure(Throwable caught) { + + GWT.log(caught.toString()); + + submitButton.setEnabled(true); + shareTextArea.setEnabled(true); + shareTextArea.setText(SHARE_UPDATE_TEXT); + shareTextArea.cleanHighlighterDiv(); + saveInWorkspaceCheckbox.setVisible(false); + preview.clear(); + listOfAttachedFiles.clear(); + + } + }); + + } } + + /** + * Determines the privacy level of the post to be shared. + * @return + */ private PrivacyLevel getPrivacyLevel() { String selected = privacyLevel.getValue(privacyLevel.getSelectedIndex()); if (selected.compareTo(PrivacyLevel.CONNECTION.toString()) == 0) @@ -467,7 +577,7 @@ public class ShareUpdateForm extends Composite { * @param linkToCheck */ protected void checkLink(String textToCheck) { - if (myLinkPreviewer == null) { + if (linkPreviewer == null) { String [] parts = textToCheck.split("\\s"); // Attempt to convert each item into an URL. for( String item : parts ) { @@ -485,11 +595,13 @@ public class ShareUpdateForm extends Composite { // else... remove attachments and continue listOfAttachedFiles.clear(); preview.clear(); + saveInWorkspaceCheckbox.setVisible(false); } preview.add(new LinkLoader()); submitButton.setEnabled(false); + //GWT.log("It's http link:" + linkToCheck); shareupdateService.checkLink(textToCheck, new AsyncCallback() { public void onFailure(Throwable caught) { @@ -498,6 +610,11 @@ public class ShareUpdateForm extends Composite { } public void onSuccess(LinkPreview result) { + + // For a link, the LinkPreview object is like this + // LinkPreview [title=ANSA.it - Homepage, description=ANSA.it: Il sito Internet dell'Agenzia ANSA. Ultime notizie, foto, video e approfondimenti su: cronaca, politica, economia, regioni, mondo, sport, calcio, cultura e tecnologia, + // url=http://www.ansa.it/, host=ansa.it, imageUrls=[http://www.ansa.it/sito/img/ico/ansa-57-precomposed.png]] + // GWT.log(result.toString()); preview.clear(); if (result != null) addPreviewLink(result); @@ -521,53 +638,56 @@ public class ShareUpdateForm extends Composite { protected void checkFile(final String fileName, final String absolutePathOnServer) { // create temp view of the attached file and add to the previewer - final AttachmentPreviewer atPrev = new AttachmentPreviewer(fileName, attachedDefault, preview, this); + final AttachmentPreviewer atPrev = new AttachmentPreviewer(fileName, attachedDefaultImageUrl, preview, this); preview.add(atPrev); - + // disable the submit button till we know the result of the upload process submitButton.setEnabled(false); shareupdateService.checkUploadedFile(fileName, absolutePathOnServer, new AsyncCallback() { public void onFailure(Throwable caught) { - GWT.log("Upload of the file failed!"); - uploadProgress.showRegisteringResult(false); + + GWT.log("Unable to check uploaded file!"); + + // hide progress bar uploadProgress.setVisible(false); + // attach the file with error.. + listOfAttachedFiles.add( + new AttachedFile( + fileName, + absolutePathOnServer, + atPrev, + null) + ); + + // there is no a linkPreview... addPreviewAttachment(null, atPrev); - listOfAttachedFiles.add(new AttachedFile(fileName, absolutePathOnServer, atPrev, false)); + + // enable anyway the button submitButton.setEnabled(true); - - /*preview.clear(); - - final HorizontalPanel hp = new HorizontalPanel(); - final Button close = new Button("Try Again"); - final HTML reportIssue = new HTML("" - + "Report the issue"); - - close.addClickHandler(new ClickHandler() { - @Override - public void onClick(ClickEvent event) { - uploadProgress.setVisible(false); - preview.remove(hp); - } - }); - - hp.setVerticalAlignment(HasAlignment.ALIGN_MIDDLE); - hp.add(close); - hp.add(reportIssue); - preview.add(hp);*/ } + // it returns a LinkPreview (for compatibility with old code) public void onSuccess(LinkPreview result) { if(result == null) return; - uploadProgress.setVisible(false); - addPreviewAttachment(result, atPrev); - listOfAttachedFiles.add(new AttachedFile(fileName, absolutePathOnServer, atPrev, true)); - submitButton.setEnabled(true); + listOfAttachedFiles.add( + new AttachedFile( + result.getTitle(), + absolutePathOnServer, + result.getDescription(), + result.getUrl(), + result.getImageUrls().get(0), + result.getHost(), + atPrev, + true) + ); + addPreviewAttachment(result, atPrev); + submitButton.setEnabled(true); } }); } @@ -594,10 +714,11 @@ public class ShareUpdateForm extends Composite { * @param result */ private void addPreviewLink(LinkPreview result) { + //GWT.log(result.toString()); preview.clear(); uploadProgress.setVisible(false); - myLinkPreviewer = new LinkPreviewer(this, result); - preview.add(myLinkPreviewer); + linkPreviewer = new LinkPreviewer(this, result); + preview.add(linkPreviewer); } /** @@ -605,30 +726,41 @@ public class ShareUpdateForm extends Composite { */ private void addPreviewAttachment(LinkPreview result, AttachmentPreviewer atPrev){ - uploadProgress.setVisible(false); + // GWT.log(result.toString()); + + // disable progress bar + uploadProgress.setVisible(false); // check the result if(result == null){ - // failed upload - atPrev.setResultAttachment(ATTACHMENT_NOT_LOADED, notLoadedAttachment); - // change the preview image to reload icon to let the user retry - atPrev.setImagePreviewToRetry(RETRY_TO_ATTACH_MESSAGE, retryToAttach); + // failed upload + atPrev.setResultAttachment(ATTACHMENT_NOT_LOADED, notLoadedAttachmentImageUrl); + + // change the atPrev object and let the user retry the upload + atPrev.retryToUpload(atPrev); + } else{ - // set the preview information (the first image is the one related to attachments) - atPrev.setResultAttachment(ATTACHMENT_LOADED, loadedAttachment); + + // set the preview information (the first image is the one related to the type of file) + atPrev.setResultAttachment(ATTACHMENT_LOADED, loadedAttachmentImageUrl); atPrev.setImagePreview(result.getImageUrls().get(0)); + } preview.add(atPrev); + + // enable checkbox to save in workspace if it's the case + if(numberOfAttachments() > 0 && !saveInWorkspaceCheckbox.isVisible()) + saveInWorkspaceCheckbox.setVisible(true); } /** - * + * Delete the only link previewer allowed. */ protected void cancelLinkPreview() { preview.clear(); - myLinkPreviewer = null; + linkPreviewer = null; attachButton.getElement().getStyle().setVisibility(Visibility.VISIBLE); //beacuse otherwise it looses the other properties setting } @@ -639,11 +771,8 @@ public class ShareUpdateForm extends Composite { private static native void addNativeDropHandler(ShareUpdateForm instance, String servletUrl)/*-{ - console.log("Adding drop handler to text area"); - // retrieve textArea by id - var drop = $wnd.$('#postTextArea')[0]; - console.log("drop is " + drop); + var drop = $wnd.$('#postTextArea')[0]; // check if this file is a folder function isFolder(file) { @@ -725,13 +854,13 @@ public class ShareUpdateForm extends Composite { console.log("Number of dropped file(s): " + files.length); var numFolder = 0; - + // save maximum allowed size var maximumSize = @org.gcube.portlets.widgets.fileupload.client.view.FileSubmit::MAX_SIZE_ATTACHED_FILE_MB; - + // msg for ignored (too big files) var ignoredFilesAlert = " file(s) ignored because larger than " + maximumSize + "MB"; - + // number of ignored files var numberIgnoredFiles = 0; @@ -745,12 +874,12 @@ public class ShareUpdateForm extends Composite { if (!isFolder(file)) { console.log("filesSelected: " + fileSelected); console.log("files: " + files); - + // check its size var fileSize = file.size / 1024 / 1024; - - console.log("File size is " + fileSize); - + + console.log("File size is " + fileSize + "MB"); + if(fileSize > maximumSize){ numberIgnoredFiles ++; continue; @@ -802,14 +931,14 @@ public class ShareUpdateForm extends Composite { console.log(msg); instance.@org.gcube.portlets.user.shareupdates.client.view.ShareUpdateForm::showAlert(Ljava/lang/String;)(msg); } - + // alert for too large files if(numberIgnoredFiles > 0){ var msg = numberIgnoredFiles + ignoredFilesAlert; - + if(numberIgnoredFiles == files.length){ - msg = file.name + " can't be uploaded since it is too large!"; + msg = file.name + " can't be uploaded because it is too large!"; instance.@org.gcube.portlets.user.shareupdates.client.view.ShareUpdateForm::showAlert(Ljava/lang/String;)(msg); // reset text area @@ -817,7 +946,7 @@ public class ShareUpdateForm extends Composite { return; } - + var msg = numberIgnoredFiles + ignoredFilesAlert; console.log(msg); instance.@org.gcube.portlets.user.shareupdates.client.view.ShareUpdateForm::showAlert(Ljava/lang/String;)(msg); @@ -828,6 +957,7 @@ public class ShareUpdateForm extends Composite { }); }-*/; + /** * Check if DND could be enabled (i.e, it's supported by the browser) @@ -839,6 +969,40 @@ public class ShareUpdateForm extends Composite { }-*/; + /** + * Add DND style effect on drag over. + */ + private void addDNDStyleEffects() { + // save current text (note that the DragOverEvent event can be fired several times) + boolean conditionToSave = !shareTextArea.getText().equals(DROP_FILE_HERE_TEXT) && !shareTextArea.getText().equals(SHARE_UPDATE_TEXT); + previousText = conditionToSave ? shareTextArea.getText() : previousText; + + // change border properties + shareTextArea.getElement().getStyle().setBorderStyle(BorderStyle.DASHED); + shareTextArea.getElement().getStyle().setBorderColor("rgba(82, 168, 236, 0.6)"); + shareTextArea.getElement().getStyle().setBorderWidth(2.5, Unit.PX); + + // change background color + shareTextArea.getElement().getStyle().setBackgroundColor("rgba(82, 168, 236, 0.2)"); + + // enlarge the window + Document.get().getElementById("highlighterContainer").getStyle().setHeight(52, Unit.PX); + Document.get().getElementById("highlighter").getStyle().setHeight(52, Unit.PX); + Document.get().getElementById("postTextArea").getStyle().setHeight(52, Unit.PX); + + // add "Drop file here" text + shareTextArea.setText(DROP_FILE_HERE_TEXT); + shareTextArea.setAlignment(TextAlignment.CENTER); + shareTextArea.getElement().getStyle().setFontWeight(FontWeight.BOLD); + shareTextArea.getElement().getStyle().setPaddingTop( + (Double.parseDouble(shareTextArea.getElement().getStyle().getHeight().replace("px", "")) + 20)/2.0, Unit.PX); + + // set the color of the text if needed to gray + if(!previousText.equals(SHARE_UPDATE_TEXT)) + shareTextArea.getElement().getStyle().setColor("#999"); + + } + /** * On dragLeave reset changes on the text area */ @@ -897,22 +1061,42 @@ public class ShareUpdateForm extends Composite { while (iterator.hasNext()) { AttachedFile attachedFile = (AttachedFile) iterator.next(); - if(attachedFile.getAtPrev().equals(attachedFile)){ + if(attachedFile.getAtPrev().equals(attachmentPreviewer)){ iterator.remove(); - return; + break; } - } + // check the final number of attachments and if it's less than one, set to false + // the save in workspace checkbox visibility + if(numberOfAttachments() == 0) + saveInWorkspaceCheckbox.setVisible(false); + } - + /** - * Get the number of attached files + * Get the number of attached files (both uploaded and not). * @return number of attached files */ public int numberOfAttachments(){ - + return listOfAttachedFiles.size(); - + + } + + /** + * Retrieve the number of correctly uploaded attached files. + * @return number of attached files correctly uploaded. + */ + private int numberOfAttachmentsUploaded(){ + + int counter = 0; + for (AttachedFile attachedFile : listOfAttachedFiles) { + + if(attachedFile.isCorrectlyUploaded()) + counter ++; + + } + return counter; } } diff --git a/src/main/java/org/gcube/portlets/user/shareupdates/client/view/ShareUpdateForm.ui.xml b/src/main/java/org/gcube/portlets/user/shareupdates/client/view/ShareUpdateForm.ui.xml index 09f5a7a..8ba85bd 100644 --- a/src/main/java/org/gcube/portlets/user/shareupdates/client/view/ShareUpdateForm.ui.xml +++ b/src/main/java/org/gcube/portlets/user/shareupdates/client/view/ShareUpdateForm.ui.xml @@ -25,6 +25,7 @@ +