DND and multiupload now work. The news feed portlet needs to be updated to reflect such changes

git-svn-id: https://svn.research-infrastructures.eu/d4science/gcube/trunk/portlets/user/share-updates@122268 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
Costantino Perciante 2016-01-15 17:24:52 +00:00
parent d29dccac2c
commit 97f39a4ee4
15 changed files with 874 additions and 260 deletions

View File

@ -7,9 +7,6 @@
<dependent-module archiveName="fileupload-progress-bar-1.3.0-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/fileupload-progress-bar/fileupload-progress-bar">
<dependency-type>uses</dependency-type>
</dependent-module>
<dependent-module archiveName="fileupload-progress-bar-1.3.0-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/fileupload-progress-bar/fileupload-progress-bar">
<dependency-type>uses</dependency-type>
</dependent-module>
<property name="java-output-path" value="/${module}/target/www/WEB-INF/classes"/>
<property name="context-root" value="share-updates"/>
</wb-module>

View File

@ -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<String> mentionedUsers, String fileName, String FilePathOnServer, boolean notifyGroup);
ClientFeed sharePostWithLinkPreview(String feedText, FeedType type, PrivacyLevel pLevel, String vreName, LinkPreview preview, String urlThumbnail, ArrayList<String> mentionedUsers, boolean notifyGroup);
ClientFeed sharePostWithAttachments(String feedText, FeedType type, PrivacyLevel pLevel, String vreName,ArrayList<UploadedFile> uploadedFiles, ArrayList<String> mentionedUsers, boolean notifyGroup, boolean saveCopyWokspace);
UserSettings getUserSettings();

View File

@ -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 <code>ShareUpdateService</code>.
*/
public interface ShareUpdateServiceAsync {
void share(String feedText, FeedType type, PrivacyLevel pLevel,
String vreName, LinkPreview preview, String urlThumbnail,
ArrayList<String> mentionedUsers, String fileName,
String FilePathOnServer, boolean notifyGroup,
AsyncCallback<ClientFeed> callback);
void checkLink(String linkToCheck, AsyncCallback<LinkPreview> callback);
@ -31,4 +27,16 @@ public interface ShareUpdateServiceAsync {
AsyncCallback<LinkPreview> callback);
void getHashtags(AsyncCallback<ArrayList<ItemBean>> callback);
void sharePostWithLinkPreview(String feedText, FeedType type,
PrivacyLevel pLevel, String vreName, LinkPreview preview,
String urlThumbnail, ArrayList<String> mentionedUsers, boolean notifyGroup,
AsyncCallback<ClientFeed> callback);
void sharePostWithAttachments(String feedText, FeedType type,
PrivacyLevel pLevel, String vreName,
ArrayList<UploadedFile> uploadedFiles,
ArrayList<String> mentionedUsers, boolean notifyGroup,
boolean saveCopyWokspace, AsyncCallback<ClientFeed> callback);
}

View File

@ -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 + "]";
}
}

View File

@ -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("<a>"+ "<span>Try Again</span></a>");
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);
}
}

View File

@ -16,7 +16,4 @@ public class LinkLoader extends Composite {
public LinkLoader() {
initWidget(uiBinder.createAndBindUi(this));
}
}

View File

@ -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";

View File

@ -33,6 +33,5 @@
</td>
</tr>
</table>
<m:Placeholder ui:field="uploadInWS"></m:Placeholder>
</g:HTMLPanel>
</ui:UiBinder>

View File

@ -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
}

View File

@ -15,16 +15,15 @@ public class SaveInWorkspaceBox extends Composite {
interface SaveInWorkspaceBoxUiBinder extends
UiBinder<Widget, SaveInWorkspaceBox> {
}
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() {

View File

@ -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<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;
@ -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<String> mentionedUsers) {
String toShare = escapeHtml(textToPost);
if (! checkTextLength(toShare)) {
private void postTweet(String textToPost, ArrayList<String> 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<ClientFeed>() {
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<ClientFeed>() {
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<UploadedFile> uploadedFiles = new ArrayList<UploadedFile>();
// 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<ClientFeed>() {
@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<LinkPreview>() {
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<LinkPreview>() {
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("<a href=\"https://support.d4science.research-infrastructures.eu\" target=\"_blank\">"
+ "<span>Report the issue</span></a>");
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;
}
}

View File

@ -25,6 +25,7 @@
</table>
<j:UploadProgressPanel ui:field="uploadProgress"></j:UploadProgressPanel>
<m:Placeholder ui:field="preview"></m:Placeholder>
<m:SaveInWorkspaceBox ui:field="saveInWorkspaceCheckbox"></m:SaveInWorkspaceBox>
<table class="share-updates-table">
<tr>
<td class="share-updates-photo-cell">

View File

@ -14,6 +14,8 @@ import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.net.ssl.HttpsURLConnection;
import org.apache.commons.validator.routines.UrlValidator;
import org.gcube.application.framework.core.session.ASLSession;
import org.gcube.application.framework.core.session.SessionManager;
@ -33,6 +35,7 @@ import org.gcube.portal.custom.communitymanager.impl.OrganizationManagerImpl;
import org.gcube.portal.custom.scopemanager.scopehelper.ScopeHelper;
import org.gcube.portal.databook.server.DBCassandraAstyanaxImpl;
import org.gcube.portal.databook.server.DatabookStore;
import org.gcube.portal.databook.shared.Attachment;
import org.gcube.portal.databook.shared.ClientFeed;
import org.gcube.portal.databook.shared.Feed;
import org.gcube.portal.databook.shared.FeedType;
@ -47,6 +50,7 @@ import org.gcube.portlets.user.shareupdates.client.view.ShareUpdateForm;
import org.gcube.portlets.user.shareupdates.server.opengraph.OpenGraph;
import org.gcube.portlets.user.shareupdates.shared.HashTagAndOccurrence;
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;
import org.gcube.vomanagement.usermanagement.GroupManager;
@ -67,8 +71,6 @@ import com.liferay.portal.model.Role;
import com.liferay.portal.service.OrganizationLocalServiceUtil;
import com.liferay.portal.service.UserLocalServiceUtil;
import com.liferay.portal.theme.ThemeDisplay;
import com.sun.net.ssl.HttpsURLConnection;
/**
* The server side implementation of the RPC service.
*/
@ -85,6 +87,7 @@ public class ShareUpdateServiceImpl extends RemoteServiceServlet implements Shar
public static final String UPLOAD_DIR = "/social-framework-uploads";
private static final String NEWS_FEED_PORTLET_CLASSNAME = "org.gcube.portlets.user.newsfeed.server.NewsServiceImpl";
private final static String ATTR_TO_CHECK = "Postnotificationviaemail";
/**
*
*/
@ -121,7 +124,7 @@ public class ShareUpdateServiceImpl extends RemoteServiceServlet implements Shar
}
public String getDevelopmentUser() {
String user = TEST_USER;
// user = "massimiliano.assante";
user = "costantino.perciante";
return user;
}
/**
@ -140,29 +143,35 @@ public class ShareUpdateServiceImpl extends RemoteServiceServlet implements Shar
}
/**
*
* Share post that could contain a link preview.
*/
public ClientFeed share(String postText, FeedType feedType, PrivacyLevel pLevel,
String vreId, LinkPreview preview, String urlThumbnail, ArrayList<String> mentionedUserFullNames,String fileName, String filePathOnServer, boolean notifyGroup) {
@Override
public ClientFeed sharePostWithLinkPreview(String postText, FeedType feedType, PrivacyLevel pLevel,
String vreId, LinkPreview preview, String urlThumbnail, ArrayList<String> mentionedUserFullNames, boolean notifyGroup) {
_log.debug("Writing a new post with text " + postText);
// escape text
String escapedFeedText = TextTransfromUtils.escapeHtmlAndTransformUrl(postText);
// get hashtags
List<String> hashtags = TextTransfromUtils.getHashTags(postText);
if (hashtags != null && !hashtags.isEmpty())
escapedFeedText = TextTransfromUtils.convertHashtagsAnchorHTML(escapedFeedText, hashtags);
// retrieve mentioned users
ArrayList<ItemBean> mentionedUsers = null;
if (mentionedUserFullNames != null && ! mentionedUserFullNames.isEmpty()) {
mentionedUsers = getSelectedUserIds(mentionedUserFullNames);
escapedFeedText = TextTransfromUtils.convertMentionPeopleAnchorHTML(escapedFeedText, mentionedUsers);
}
// get session
ASLSession session = getASLSession();
String username = session.getUsername();
String email = username+"@isti.cnr.it";
String fullName = username+" FULL";
String thumbnailURL = "images/Avatar_default.png";
String thumbnailAvatarURL = "images/Avatar_default.png";
boolean withinPortal = isWithinPortal();
@ -171,12 +180,13 @@ public class ShareUpdateServiceImpl extends RemoteServiceServlet implements Shar
UserInfo user = getUserSettings().getUserInfo();
email = user.getEmailaddress();
fullName = user.getFullName();
thumbnailURL = user.getAvatarId();
thumbnailAvatarURL = user.getAvatarId();
} catch (Exception e) {
e.printStackTrace();
}
}
// get data from the preview of the link
String linkTitle = preview.getTitle();
String linkDesc = preview.getDescription();
String host = preview.getHost();
@ -185,10 +195,171 @@ public class ShareUpdateServiceImpl extends RemoteServiceServlet implements Shar
urlThumbnail = "null";
Date feedDate = new Date();
//get the VRE scope if single channel post
String vreScope2Set = "";
if (pLevel == PrivacyLevel.SINGLE_VRE && vreId != null && vreId.compareTo("") != 0) {
vreScope2Set = (withinPortal) ? getScopeByOrganizationId(vreId) : session.getScope();
}
// build the feed to share (and save on cassandra)
Feed toShare = new Feed(UUID.randomUUID().toString(), feedType, username, feedDate,
vreScope2Set, url, urlThumbnail, escapedFeedText, pLevel, fullName, email, thumbnailAvatarURL, linkTitle, linkDesc, host);
_log.info("Attempting to save Feed with text: " + escapedFeedText + " Level: " + pLevel + " Timeline="+vreScope2Set);
boolean result = store.saveUserFeed(toShare);
//need to put the feed into VRES Timeline too
if (pLevel == PrivacyLevel.VRES) {
_log.trace("PrivacyLevel was set to VRES attempting to write onto User's VRES Timelines");
for (GroupModel vre : getUserVREs(username)) {
String vreScope = getScopeByOrganizationId(vre.getGroupId());
_log.trace("Attempting to write onto " + vreScope);
try {
store.saveFeedToVRETimeline(toShare.getKey(), vreScope);
} catch (FeedIDNotFoundException e) {
_log.error("Error writing onto VRES Time Line" + vreScope);
} //save the feed
_log.trace("Success writing onto " + vreScope);
}
}
//share on a single VRE Timeline
//receives a VreId(groupId) get the scope from the groupId
else if (pLevel == PrivacyLevel.SINGLE_VRE && vreId != null && vreId.compareTo("") != 0) {
_log.trace("Attempting to write onto " + vreScope2Set);
try {
store.saveFeedToVRETimeline(toShare.getKey(), vreScope2Set);
if (hashtags != null && !hashtags.isEmpty())
store.saveHashTags(toShare.getKey(), vreScope2Set, hashtags);
} catch (FeedIDNotFoundException e) {
_log.error("Error writing onto VRES Time Line" + vreScope2Set);
} //save the feed
_log.trace("Success writing onto " + vreScope2Set);
}
if (!result) return null;
//everything went fine
ClientFeed cf = new ClientFeed(toShare.getKey(), toShare.getType().toString(), username, feedDate, toShare.getUri(),
TextTransfromUtils.replaceAmpersand(toShare.getDescription()), fullName, email, thumbnailAvatarURL, toShare.getLinkTitle(), toShare.getLinkDescription(),
toShare.getUriThumbnail(), toShare.getLinkHost());
//send the notification about this posts to everyone in the group if notifyGroup is true
if (pLevel == PrivacyLevel.SINGLE_VRE && vreId != null && vreId.compareTo("") != 0 && notifyGroup) {
NotificationsManager nm = new ApplicationNotificationsManager(session, NEWS_FEED_PORTLET_CLASSNAME);
Thread thread = new Thread(new PostNotificationsThread(toShare.getKey(), escapedFeedText, ""+session.getGroupId(), nm, hashtags));
thread.start();
}
//send the notification to the mentioned users
if (mentionedUsers != null && mentionedUsers.size() > 0) {
NotificationsManager nm = new ApplicationNotificationsManager(session);
ArrayList<GenericItemBean> toPass = new ArrayList<GenericItemBean>();
for (ItemBean u : mentionedUsers) {
toPass.add(new GenericItemBean(u.getId(), u.getName(), u.getAlternativeName(), u.getThumbnailURL()));
}
Thread thread = new Thread(new MentionNotificationsThread(toShare.getKey(), escapedFeedText, nm, toPass));
thread.start();
}
return cf;
}
/**
* Share a post with at least one attachment.
*/
@Override
public ClientFeed sharePostWithAttachments(String feedText, FeedType feedType,
PrivacyLevel pLevel, String vreId, ArrayList<UploadedFile> uploadedFiles,
ArrayList<String> mentionedUserFullNames, boolean notifyGroup, boolean saveCopyWokspace) {
// escape text
String escapedFeedText = TextTransfromUtils.escapeHtmlAndTransformUrl(feedText);
// get the list of hashtags
List<String> hashtags = TextTransfromUtils.getHashTags(feedText);
if (hashtags != null && !hashtags.isEmpty())
escapedFeedText = TextTransfromUtils.convertHashtagsAnchorHTML(escapedFeedText, hashtags);
// get the list of mentioned users
ArrayList<ItemBean> mentionedUsers = null;
if (mentionedUserFullNames != null && ! mentionedUserFullNames.isEmpty()) {
mentionedUsers = getSelectedUserIds(mentionedUserFullNames);
escapedFeedText = TextTransfromUtils.convertMentionPeopleAnchorHTML(escapedFeedText, mentionedUsers);
}
ASLSession session = getASLSession();
String username = session.getUsername();
String email = username+"@isti.cnr.it";
String fullName = username+" FULL";
String thumbnailAvatarURL = "images/Avatar_default.png";
boolean withinPortal = isWithinPortal();
if (withinPortal && username.compareTo(TEST_USER) != 0) {
try {
UserInfo user = getUserSettings().getUserInfo();
email = user.getEmailaddress();
fullName = user.getFullName();
thumbnailAvatarURL = user.getAvatarId();
} catch (Exception e) {
e.printStackTrace();
}
}
// Managing attachments: the first one (if any) will use the same fields of a link preview.
// If more than one attachments are present, they will be saved as Attachment objects.
// In this way we can handle retro-compatibility.
List<Attachment> attachments = null;
String firstAttachmentName = "",
firstAttachmentDescription = "",
firstAttachmentFormat = "",
firstAttachmentDownloadUrl = "",
firstAttachmenturlThumbnail = "";
if(uploadedFiles.size() > 0){
// retrieve the first element
UploadedFile firstAttachment = uploadedFiles.get(0);
firstAttachmentName = firstAttachment.getFileName();
firstAttachmentDescription = firstAttachment.getDescription();
firstAttachmentFormat = firstAttachment.getFormat();
firstAttachmentDownloadUrl = firstAttachment.getDownloadUrl();
firstAttachmenturlThumbnail = firstAttachment.getThumbnailUrl();
if(uploadedFiles.size() > 1){
attachments = new ArrayList<>();
// check if there are more files
for (UploadedFile file : uploadedFiles) {
attachments.add(new Attachment(
UUID.randomUUID().toString(),
file.getDownloadUrl(),
file.getFileName(),
file.getDescription(),
file.getThumbnailUrl(),
file.getFormat())
);
}
}
}
// evaluate the date (this will be the date of the post)
Date feedDate = new Date();
//this means the user has shared a file without text in it.
String textToPost = "";
if (escapedFeedText.trim().compareTo(ShareUpdateForm.NO_TEXT_FILE_SHARE) == 0) {
textToPost = TextTransfromUtils.convertFileNameAnchorHTML(url);
textToPost = TextTransfromUtils.convertFileNameAnchorHTML(textToPost);
} else {
textToPost = escapedFeedText;
//System.out.println("textToPost=" + textToPost);
@ -200,13 +371,36 @@ public class ShareUpdateServiceImpl extends RemoteServiceServlet implements Shar
vreScope2Set = (withinPortal) ? getScopeByOrganizationId(vreId) : session.getScope();
}
Feed toShare = new Feed(UUID.randomUUID().toString(), feedType, username, feedDate,
vreScope2Set, url, urlThumbnail, textToPost, pLevel, fullName, email, thumbnailURL, linkTitle, linkDesc, host);
Feed toShare = null;
boolean result;
if(uploadedFiles.size() <= 1){
toShare = new Feed(
UUID.randomUUID().toString(), feedType, username, feedDate,
vreScope2Set, firstAttachmentDownloadUrl, firstAttachmenturlThumbnail,
textToPost, pLevel, fullName, email, thumbnailAvatarURL,
firstAttachmentName, firstAttachmentDescription, firstAttachmentFormat);
// save the feed itself
result = store.saveUserFeed(toShare);
}
else{
toShare = new Feed(
UUID.randomUUID().toString(), feedType, username, feedDate,
vreScope2Set, firstAttachmentDownloadUrl, firstAttachmenturlThumbnail,
textToPost, pLevel, fullName, email, thumbnailAvatarURL,
firstAttachmentName, firstAttachmentDescription, firstAttachmentFormat);
// set the field multiFileUpload to true
toShare.setMultiFileUpload(true);
// save the feed itself plus the attachments
result = store.saveUserFeed(toShare, attachments);
}
_log.info("Attempting to save Feed with text: " + textToPost + " Level: " + pLevel + " Timeline="+vreScope2Set);
boolean result = store.saveUserFeed(toShare);
//need to put the feed into VRES Timeline too
if (pLevel == PrivacyLevel.VRES) {
_log.trace("PrivacyLevel was set to VRES attempting to write onto User's VRES Timelines");
@ -238,7 +432,7 @@ public class ShareUpdateServiceImpl extends RemoteServiceServlet implements Shar
//everything went fine
ClientFeed cf = new ClientFeed(toShare.getKey(), toShare.getType().toString(), username, feedDate, toShare.getUri(),
TextTransfromUtils.replaceAmpersand(toShare.getDescription()), fullName, email, thumbnailURL, toShare.getLinkTitle(), toShare.getLinkDescription(),
TextTransfromUtils.replaceAmpersand(toShare.getDescription()), fullName, email, thumbnailAvatarURL, toShare.getLinkTitle(), toShare.getLinkDescription(),
toShare.getUriThumbnail(), toShare.getLinkHost());
@ -260,17 +454,25 @@ public class ShareUpdateServiceImpl extends RemoteServiceServlet implements Shar
thread.start();
}
//it means I also should upload a copy on the user's Workspace root folder
if (fileName != null && filePathOnServer != null) {
//The workspace uploader Thread starts here asyncronously
Thread thread = new Thread(new UploadToWorkspaceThread(fullName, username, fileName, filePathOnServer));
thread.start();
//it means I also should upload a copy of the files on the user's Workspace root folder
if (saveCopyWokspace) {
for(UploadedFile file: uploadedFiles){
new Thread(
new UploadToWorkspaceThread(
fullName,
username,
file.getFileName(),
file.getFileAbsolutePathOnServer()))
.start();
}
}
return cf;
}
@Override
public UserSettings getUserSettings() {
try {
@ -283,17 +485,17 @@ public class ShareUpdateServiceImpl extends RemoteServiceServlet implements Shar
if (isWithinPortal() && username.compareTo(TEST_USER) != 0) {
long companyId = OrganizationsUtil.getCompany().getCompanyId();
com.liferay.portal.model.UserModel user = UserLocalServiceUtil.getUserByScreenName(companyId, username);
thumbnailURL = "/image/user_male_portrait?img_id="+user.getPortraitId();
fullName = user.getFirstName() + " " + user.getLastName();
email = user.getEmailAddress();
ThemeDisplay themeDisplay = (ThemeDisplay) this.getThreadLocalRequest().getSession().getAttribute(WebKeys.THEME_DISPLAY);
String accountURL = themeDisplay.getURLMyAccount().toString();
HashMap<String, String> vreNames = getUserVreNames(username);
UserInfo userInfo = new UserInfo(username, fullName, thumbnailURL, user.getEmailAddress(), accountURL, true, isAdmin(), vreNames);
UserSettings toReturn = new UserSettings(userInfo, 0, session.getScopeName(), isInfrastructureScope(), isNotificationViaEmailEnabled(session));
return toReturn;
}
@ -312,12 +514,12 @@ public class ShareUpdateServiceImpl extends RemoteServiceServlet implements Shar
}
return new UserSettings();
}
private boolean isNotificationViaEmailEnabled(ASLSession session) throws PortalException, SystemException {
Organization currOrg = OrganizationLocalServiceUtil.getOrganization(session.getGroupId());
return OrganizationManagerImpl.readOrganizationCustomAttribute(session.getUsername(), currOrg, ATTR_TO_CHECK);
}
/**
* generate a preview of the file, upload the file on the storage and shorts the link
*/
@ -335,14 +537,14 @@ public class ShareUpdateServiceImpl extends RemoteServiceServlet implements Shar
String httpURL = "";
String smpURI = "";
if (isWithinPortal()) {
//get the url to show, before actually uploading it
smpURI = storageClient.getUrl(true).RFile(remoteFilePath);
//if (isWithinPortal()) {
//get the url to show, before actually uploading it
smpURI = "http://ciccio.com";//storageClient.getUrl(true).RFile(remoteFilePath);
//The storage uploader Thread starts here asyncronously
Thread thread = new Thread(new UploadToStorageThread(storageClient, fileName, fileabsolutePathOnServer, remoteFilePath));
thread.start();
}
//The storage uploader Thread starts here asyncronously
//Thread thread = new Thread(new UploadToStorageThread(storageClient, fileName, fileabsolutePathOnServer, remoteFilePath));
//thread.start();
//}
try {
String mimeType = FilePreviewer.getMimeType(new File(fileabsolutePathOnServer), fileName);
@ -384,7 +586,7 @@ public class ShareUpdateServiceImpl extends RemoteServiceServlet implements Shar
} catch (Exception e1) {
e1.printStackTrace();
}
}
_log.debug("smpURI=" + smpURI);
@ -571,10 +773,6 @@ public class ShareUpdateServiceImpl extends RemoteServiceServlet implements Shar
}
}
/**
* Indicates whether the scope is the whole infrastructure.
* @return <code>true</code> if it is, <code>false</code> otherwise.
@ -688,8 +886,4 @@ public class ShareUpdateServiceImpl extends RemoteServiceServlet implements Shar
}
return portalUsers;
}
}

View File

@ -5,17 +5,17 @@ import java.util.ArrayList;
@SuppressWarnings("serial")
/**
* This class is used for link preview (both actual links and attachments)
* This class is used for link preview (and when a file is attached)
* @author Costantino Perciante at ISTI-CNR
*
*/
public class LinkPreview implements Serializable {
private String title;
private String title; //in case of a file, it is the name of the file itself
private String description;
private String url;
private String host;
private ArrayList<String> imageUrls;
private ArrayList<String> imageUrls; // in case of a file, the first element is the image related to the format (pdf, jpg..)
public LinkPreview() {

View File

@ -0,0 +1,107 @@
package org.gcube.portlets.user.shareupdates.shared;
import java.io.Serializable;
/**
* Information of an already uploaded file.
* @author Costantino Perciante at ISTI-CNR
*/
public class UploadedFile implements Serializable{
/**
* Generated UUID
*/
private static final long serialVersionUID = 1690771870370846188L;
// name of the file
private String fileName;
// path on the server of this file (tomcat tmp)
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;
// mime type (pdf, jpg ecc..)
private String format;
public UploadedFile() {
super();
}
public UploadedFile(String fileName, String fileAbsolutePathOnServer,
String description, String downloadUrl, String thumbnailUrl,
String mime) {
super();
this.fileName = fileName;
this.fileAbsolutePathOnServer = fileAbsolutePathOnServer;
this.description = description;
this.downloadUrl = downloadUrl;
this.thumbnailUrl = thumbnailUrl;
this.format = mime;
}
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 setMime(String format) {
this.format = format;
}
@Override
public String toString() {
return "UploadedFile [fileName=" + fileName
+ ", fileAbsolutePathOnServer=" + fileAbsolutePathOnServer
+ ", description=" + description + ", downloadUrl="
+ downloadUrl + ", thumbnailUrl=" + thumbnailUrl + ", format="
+ format + "]";
}
}