package org.gcube.portlets.user.newsfeed.client.panels; import java.util.ArrayList; import org.gcube.portal.databook.shared.ClientFeed; import org.gcube.portal.databook.shared.Comment; import org.gcube.portal.databook.shared.Feed; import org.gcube.portal.databook.shared.FeedType; import org.gcube.portal.databook.shared.Like; import org.gcube.portal.databook.shared.PrivacyLevel; import org.gcube.portal.databook.shared.UserInfo; import org.gcube.portlets.user.newsfeed.client.FilterType; import org.gcube.portlets.user.newsfeed.client.NewsService; import org.gcube.portlets.user.newsfeed.client.NewsServiceAsync; import org.gcube.portlets.user.newsfeed.client.event.AddCommentEvent; import org.gcube.portlets.user.newsfeed.client.event.AddCommentEventHandler; import org.gcube.portlets.user.newsfeed.client.event.AddLikeEvent; import org.gcube.portlets.user.newsfeed.client.event.AddLikeEventHandler; import org.gcube.portlets.user.newsfeed.client.event.DeleteCommentEvent; import org.gcube.portlets.user.newsfeed.client.event.DeleteCommentEventHandler; import org.gcube.portlets.user.newsfeed.client.event.DeleteFeedEvent; import org.gcube.portlets.user.newsfeed.client.event.DeleteFeedEventHandler; import org.gcube.portlets.user.newsfeed.client.event.EditCommentEvent; import org.gcube.portlets.user.newsfeed.client.event.EditCommentEventHandler; import org.gcube.portlets.user.newsfeed.client.event.SeeCommentsEvent; import org.gcube.portlets.user.newsfeed.client.event.SeeCommentsEventHandler; import org.gcube.portlets.user.newsfeed.client.event.SeeLikesEvent; import org.gcube.portlets.user.newsfeed.client.event.SeeLikesEventHandler; import org.gcube.portlets.user.newsfeed.client.event.StopTimerEvent; import org.gcube.portlets.user.newsfeed.client.event.StopTimerEventHandler; import org.gcube.portlets.user.newsfeed.client.panels.dialog.LikesDialog; import org.gcube.portlets.user.newsfeed.client.templates.FilterPanel; import org.gcube.portlets.user.newsfeed.client.templates.SingleComment; import org.gcube.portlets.user.newsfeed.client.templates.TweetTemplate; import org.gcube.portlets.user.newsfeed.shared.EnhancedFeed; import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.RunAsyncCallback; import com.google.gwt.event.shared.HandlerManager; import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.HasAlignment; import com.google.gwt.user.client.ui.HasVerticalAlignment; import com.google.gwt.user.client.ui.HorizontalPanel; import com.google.gwt.user.client.ui.Image; import com.google.gwt.user.client.ui.VerticalPanel; /** * * @author Massimiliano Assante, ISTI-CNR * */ public class NewsFeedPanel extends Composite { /** * Create a remote service proxy to talk to the server-side News service. */ private final NewsServiceAsync newsService = GWT.create(NewsService.class); private final HandlerManager eventBus = new HandlerManager(null); private VerticalPanel mainPanel = new VerticalPanel(); private HorizontalPanel filterPanel = new HorizontalPanel(); private VerticalPanel newsPanel = new VerticalPanel(); private static final String warning = GWT.getModuleBaseURL() + "../images/warning_blue.png"; private static final String spacer = GWT.getModuleBaseURL() + "../images/feeds-spacer.gif"; public static final String loading = GWT.getModuleBaseURL() + "../images/feeds-loader.gif"; public static final String LIKE_LABEL = "Favorite"; public static final String LIKED_LABEL = "Favorited"; public static final String COMMENT_LABEL = "Reply"; public static final String MESSAGE_LABEL = "Message"; public static final int delayMillis = 300000; //5 minutes private boolean isFirstTweet = false; private Image loadingImage; private UserInfo myUserInfo; private FilterType currentFilter; private Timer feedsTimer; /** * events binder */ private void bind() { eventBus.addHandler(StopTimerEvent.TYPE, new StopTimerEventHandler() { @Override public void onStopTimer(StopTimerEvent event) { GWT.log("Stop timer"); if (event.isRestart()) resetTimer(); else stopTimer(); } }); eventBus.addHandler(AddLikeEvent.TYPE, new AddLikeEventHandler() { @Override public void onAddLike(AddLikeEvent event) { resetTimer(); doAddLike( event.getOwner(), event.getFeedId()); } }); eventBus.addHandler(AddCommentEvent.TYPE, new AddCommentEventHandler() { @Override public void onAddComment(AddCommentEvent event) { resetTimer(); doAddComment(event.getOwner(), event.getText()); } }); eventBus.addHandler(EditCommentEvent.TYPE, new EditCommentEventHandler() { @Override public void onEditComment(EditCommentEvent event) { resetTimer(); doEditComment(event.getOwner(), event.getCommentInstance()); } }); eventBus.addHandler(SeeLikesEvent.TYPE, new SeeLikesEventHandler() { @Override public void onSeeLikes(SeeLikesEvent event) { resetTimer(); doShowLikes(event.getFeedId()); } }); eventBus.addHandler(SeeCommentsEvent.TYPE, new SeeCommentsEventHandler() { @Override public void onSeeComments(SeeCommentsEvent event) { resetTimer(); doShowComments(event.getOwner(), event.isCommentForm2Add()); } }); eventBus.addHandler(DeleteCommentEvent.TYPE, new DeleteCommentEventHandler() { @Override public void onDeleteComment(DeleteCommentEvent event) { resetTimer(); doDeleteComment(event.getOwner(), event.getCommentId()); } }); eventBus.addHandler(DeleteFeedEvent.TYPE, new DeleteFeedEventHandler() { @Override public void onDeleteFeed(DeleteFeedEvent event) { resetTimer(); doDeleteFeed(event.getToDelete()); } }); } /** * */ public NewsFeedPanel() { bind(); mainPanel.add(filterPanel); mainPanel.add(newsPanel); filterPanel.add(new FilterPanel(this, newsService)); initWidget(mainPanel); newsPanel.clear(); newsPanel.setWidth("100%"); newsPanel.setHeight("300px"); newsPanel.setHorizontalAlignment(HasAlignment.ALIGN_CENTER); newsPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_TOP); loadingImage = new Image(loading); newsPanel.add(loadingImage); newsService.getUserInfo(new AsyncCallback() { @Override public void onFailure(Throwable caught) { } @Override public void onSuccess(UserInfo result) { myUserInfo = result; if (result.getUsername().equals("test.user")) { Window.alert("Your session has expired, please log out and login again"); } else { showAllUpdatesFeeds(); currentFilter = FilterType.ALL_UPDATES; } } }); feedsTimer = new Timer() { @Override public void run() { refreshFeeds(); } }; feedsTimer.scheduleRepeating(delayMillis); } private void resetTimer() { feedsTimer.cancel(); feedsTimer.scheduleRepeating(delayMillis); } private void stopTimer() { feedsTimer.cancel(); } /** * */ private void refreshFeeds() { switch (currentFilter) { case ALL_UPDATES: showAllUpdatesFeeds(); break; case CONNECTIONS: showOnlyConnectionsFeeds(); break; case MINE: showOnlyMyFeeds(); break; } } /** * All Updates */ public void showAllUpdatesFeeds() { showLoader(); resetTimer(); newsService.getAllUpdateUserFeeds(new AsyncCallback>() { @Override public void onSuccess(ArrayList feeds) { newsPanel.clear(); if (feeds != null) { if (feeds.size() == 0) { newsPanel.add(new HTML("
" + "Looks like we've got nothing for you at the moment.
" + "You may begin by joining some of the available " + "
Virtual Research Environments.
")); isFirstTweet = true; } else { newsPanel.setHeight(""); newsPanel.setHorizontalAlignment(HasAlignment.ALIGN_LEFT); newsPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_TOP); for (EnhancedFeed feed : feeds) newsPanel.add(new TweetTemplate(myUserInfo, feed, eventBus)); if (feeds.size() < 5) { newsPanel.add(new Image(spacer)); } isFirstTweet = false; } } else { showProblems(); } } @Override public void onFailure(Throwable caught) { newsPanel.clear(); newsPanel.add(new HTML("
" + "Ops! There were problems while retrieving your feeds!.
" + "Please try again in a short while.
")); } }); } /** * Only User Connections */ public void showOnlyConnectionsFeeds() { showLoader(); resetTimer(); newsService.getOnlyConnectionsUserFeeds(new AsyncCallback>() { @Override public void onSuccess(ArrayList feeds) { if (feeds != null) { newsPanel.clear(); if (feeds.size() == 0) { //TODO: provide actual link for Making some friends newsPanel.add(new HTML("
" + "Looks like we've got nothing for you at the moment.
" + "You may begin by adding some friend!
")); isFirstTweet = true; } else { newsPanel.setHeight(""); newsPanel.setHorizontalAlignment(HasAlignment.ALIGN_LEFT); newsPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_TOP); for (EnhancedFeed feed : feeds) newsPanel.add(new TweetTemplate(myUserInfo, feed, eventBus)); if (feeds.size() < 5) { newsPanel.add(new Image(spacer)); } isFirstTweet = false; } } else showProblems(); } @Override public void onFailure(Throwable caught) { loadingImage.setUrl(warning); newsPanel.add(new HTML("Ops! There were problems while retrieving your feeds! Please try again in a short while")); } }); } /** * Only User Feeds */ public void showOnlyMyFeeds() { showLoader(); resetTimer(); newsService.getOnlyMyUserFeeds(new AsyncCallback>() { @Override public void onSuccess(ArrayList feeds) { if (feeds != null) { newsPanel.clear(); if (feeds.size() == 0) { newsPanel.add(new HTML("
" + "Looks like we've got nothing for you at the moment.
" + "You may begin by sharing an update!
")); isFirstTweet = true; } else { newsPanel.setHeight(""); newsPanel.setHorizontalAlignment(HasAlignment.ALIGN_LEFT); newsPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_TOP); for (EnhancedFeed feed : feeds) newsPanel.add(new TweetTemplate(myUserInfo, feed, eventBus)); if (feeds.size() < 5) { newsPanel.add(new Image(spacer)); } isFirstTweet = false; } } else showProblems(); } @Override public void onFailure(Throwable caught) { loadingImage.setUrl(warning); newsPanel.add(new HTML("Ops! There were problems while retrieving your feeds! Please try again in a short while")); } }); } /** * Only User Liked Feeds */ public void showOnlyLikedFeeds() { showLoader(); resetTimer(); newsService.getOnlyLikedFeeds(new AsyncCallback>() { @Override public void onSuccess(ArrayList feeds) { if (feeds != null) { newsPanel.clear(); if (feeds.size() == 0) { newsPanel.add(new HTML("
" + "Looks like we've got nothing for you at the moment.
" + "Set an update as your favorite to see it here
")); isFirstTweet = true; } else { newsPanel.setHeight(""); newsPanel.setHorizontalAlignment(HasAlignment.ALIGN_LEFT); newsPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_TOP); for (EnhancedFeed feed : feeds) newsPanel.add(new TweetTemplate(myUserInfo, feed, eventBus)); if (feeds.size() < 5) { newsPanel.add(new Image(spacer)); } isFirstTweet = false; } } else showProblems(); } @Override public void onFailure(Throwable caught) { loadingImage.setUrl(warning); newsPanel.add(new HTML("Ops! There were problems while retrieving your feeds! Please try again in a short while")); } }); } /** * used when addin directly a feed from the UI (IPC) * @param userid * @param fullName * @param thumbURL * @param description */ public void addJustAddedFeed(ClientFeed cFeed) { Feed feed = new Feed(cFeed.getKey(), FeedType.SHARE, cFeed.getUserid(), null, "", cFeed.getUri(), cFeed.getLinkUrlThumbnail(), cFeed.getDescription(), PrivacyLevel.CONNECTION, cFeed.getFullName(), cFeed.getEmail(), cFeed.getThumbnailURL(), cFeed.getLinkTitle(), cFeed.getLinkDescription(), cFeed.getLinkHost()); EnhancedFeed toAdd = new EnhancedFeed(feed, false, true); //false cuz he could not have liked this yet and true because is the current user's final TweetTemplate tt = new TweetTemplate(myUserInfo, toAdd, eventBus, true); if (isFirstTweet) { newsPanel.clear(); newsPanel.add(new Image(spacer)); isFirstTweet = false; } newsPanel.insert(tt, 0); Timer t = new Timer() { @Override public void run() { tt.setcontentAreaStyle("visible"); } }; t.schedule(500); } private void showLoader() { newsPanel.clear(); newsPanel.setWidth("100%"); newsPanel.setHeight("300px"); newsPanel.setHorizontalAlignment(HasAlignment.ALIGN_CENTER); newsPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE); newsPanel.add(loadingImage); } private void showProblems() { newsPanel.clear(); newsPanel.add(new HTML("
" + "Ops! There were problems while retrieving your feeds!.
" + "Looks like we are not able to communicate with the infrastructure,
please try again in a short while.
")); } private void doAddLike(final TweetTemplate owner, final String feedId) { newsService.like(feedId, owner.getMyFeedText(), owner.getMyFeedUserId(), new AsyncCallback() { @Override public void onFailure(Throwable caught) {} @Override public void onSuccess(Boolean result) { } }); } private void doShowLikes(final String feedId) { GWT.runAsync(new RunAsyncCallback() { @Override public void onSuccess() { final LikesDialog dlg = new LikesDialog(); dlg.center(); dlg.show(); newsService.getAllLikesByFeed(feedId, new AsyncCallback>() { @Override public void onFailure(Throwable caught) { Window.alert("People who liked this could not be retrieved: " + caught.getMessage()); } @Override public void onSuccess(ArrayList result) { dlg.showLikes(result); } }); } public void onFailure(Throwable reason) { Window.alert("Could not load this component: " + reason.getMessage()); } }); } private void doAddComment(final TweetTemplate owner, String text) { newsService.comment(owner.getFeedKey(), text, owner.getMyFeedUserId(), new AsyncCallback() { @Override public void onFailure(Throwable caught) { Window.alert("Could not deliver this comment: " + caught.getMessage()); } @Override public void onSuccess(Comment result) { if (result != null) { owner.addComment(new SingleComment(result, owner, (result.getUserid().equals(myUserInfo.getUsername())) )); owner.setCommentingDisabled(false); owner.updateCommentsNumberCount(); } else { Window.alert("Could not deliver this comment. Please try again in a short while."); } } }); } private void doEditComment(final TweetTemplate owner, Comment edited) { newsService.editComment(edited, new AsyncCallback() { @Override public void onFailure(Throwable caught) { Window.alert("Could not edit this comment: " + caught.getMessage()); } @Override public void onSuccess(Comment result) { if (result != null) { owner.addComment(new SingleComment(result, owner, (result.getUserid().equals(myUserInfo.getUsername())) )); owner.setCommentingDisabled(false); } else { Window.alert("Could not deliver this comment. Please try again in a short while."); } } }); } private void doShowComments(final TweetTemplate owner, final boolean commentForm2Add) { owner.showLoadingComments(); newsService.getAllCommentsByFeed(owner.getFeedKey(), new AsyncCallback>() { @Override public void onFailure(Throwable caught) { Window.alert("Comments could not be retrieved: " + caught.getMessage()); } @Override public void onSuccess(ArrayList comments) { owner.clearComments(); for (Comment comment :comments) owner.addComment(new SingleComment(comment, owner,(comment.getUserid().equals(myUserInfo.getUsername())) )); owner.setCommentsFetched(true); if (commentForm2Add) owner.showAddCommentForm(); owner.updateCommentsNumberCount(); } }); } protected void doDeleteComment(final TweetTemplate owner, String commentId) { newsService.deleteComment(commentId, owner.getFeedKey(), new AsyncCallback() { @Override public void onFailure(Throwable caught) { Window.alert("Comment could not be deleted: " + caught.getMessage()); } @Override public void onSuccess(Boolean result) { if (result) { doShowComments(owner, false); owner.updateCommentsNumberCount(); } else Window.alert("Comment could not be deleted, please try again in a short while."); } }); } private void doDeleteFeed(final TweetTemplate toDelete) { if (Window.confirm("Are you sure you want to delete this feed?")) { newsService.deleteFeed(toDelete.getFeedKey(), new AsyncCallback() { @Override public void onFailure(Throwable caught) { Window.alert("Feed could not be deleted: " + caught.getMessage()); } @Override public void onSuccess(Boolean result) { if (result) { toDelete.removeFromParent(); } else Window.alert("Feed could not be deleted, please try again in a short while."); } }); } } /** * set the filter type status for automatic reloading of tweets * @param currentFilter */ public void setCurrentFilter(FilterType currentFilter) { this.currentFilter = currentFilter; } }