implemented mention in comments almost complete

git-svn-id: http://svn.research-infrastructures.eu/public/d4science/gcube/trunk/portlets/user/news-feed@94652 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
Massimiliano Assante 2014-04-09 16:45:21 +00:00
parent aedf4cb81c
commit 1728e6dfc3
18 changed files with 634 additions and 71 deletions

View File

@ -1,15 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src/main/webapp" />
<classpathentry kind="con"
path="org.eclipse.wst.jsdt.launching.JRE_CONTAINER" />
<classpathentry kind="con"
path="org.eclipse.wst.jsdt.launching.WebProject">
<attributes>
<attribute name="hide" value="true" />
</attributes>
</classpathentry>
<classpathentry kind="con"
path="org.eclipse.wst.jsdt.launching.baseBrowserLibrary" />
<classpathentry kind="output" path="" />
<classpathentry excluding="js/jquery.autosize.js|js/jquery.min.js" kind="src" path="src/main/webapp"/>
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.WebProject">
<attributes>
<attribute name="hide" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.baseBrowserLibrary"/>
<classpathentry kind="output" path=""/>
</classpath>

View File

@ -4,6 +4,9 @@
<wb-resource deploy-path="/" source-path="/src/main/webapp" tag="defaultRootSource"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/target/generated-sources/gwt"/>
<dependent-module archiveName="pickuser-widget-0.4.0-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/pickuser-widget/pickuser-widget">
<dependency-type>uses</dependency-type>
</dependent-module>
<property name="java-output-path" value="/${module}/target/www/WEB-INF/classes"/>
<property name="context-root" value="news-feed"/>
</wb-module>

View File

@ -1 +1 @@
org.eclipse.wst.jsdt.launching.baseBrowserLibrary
org.eclipse.wst.jsdt.launching.JRE_CONTAINER

View File

@ -0,0 +1 @@
Global

View File

@ -81,6 +81,11 @@
<artifactId>session-checker</artifactId>
<version>[0.2.0-SNAPSHOT, 1.0.0-SNAPSHOT)</version>
</dependency>
<dependency>
<groupId>org.gcube.portlets.widgets</groupId>
<artifactId>pickuser-widget</artifactId>
<version>[0.4.0-SNAPSHOT, 1.0.0-SNAPSHOT)</version>
</dependency>
<dependency>
<groupId>org.gcube.applicationsupportlayer</groupId>
<artifactId>aslsocial</artifactId>

View File

@ -8,6 +8,7 @@ import org.gcube.portal.databook.shared.UserInfo;
import org.gcube.portlets.user.newsfeed.shared.EnhancedFeed;
import org.gcube.portlets.user.newsfeed.shared.MoreFeedsBean;
import org.gcube.portlets.user.newsfeed.shared.UserSettings;
import org.gcube.portlets.widgets.pickuser.shared.PickingUser;
import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
@ -46,4 +47,6 @@ public interface NewsService extends RemoteService {
UserSettings getUserSettings();
EnhancedFeed getSingleFeed(String feedKey);
ArrayList<PickingUser> getOrganizationUsers(String currentScope);
}

View File

@ -7,6 +7,7 @@ import org.gcube.portal.databook.shared.Like;
import org.gcube.portlets.user.newsfeed.shared.EnhancedFeed;
import org.gcube.portlets.user.newsfeed.shared.MoreFeedsBean;
import org.gcube.portlets.user.newsfeed.shared.UserSettings;
import org.gcube.portlets.widgets.pickuser.shared.PickingUser;
import com.google.gwt.user.client.rpc.AsyncCallback;
@ -53,5 +54,8 @@ public interface NewsServiceAsync {
void unlike(String feedid, String feedText, String feedOwnerId,
AsyncCallback<Boolean> callback);
void getOrganizationUsers(String currentScope,
AsyncCallback<ArrayList<PickingUser>> callback);
}

View File

@ -79,7 +79,10 @@ import com.google.gwt.user.client.ui.Widget;
*
*/
public class NewsFeedPanel extends Composite {
/**
* the current scope on the client can be static
*/
private static String currentScope;
/**
* Create a remote service proxy to talk to the server-side News service.
*/
@ -107,7 +110,7 @@ public class NewsFeedPanel extends Composite {
public static final String MESSAGE_LABEL = "Message";
private String vreLabel;
private String currentScope;
private boolean showFeedTimelineSource = false;
private boolean isInfrastructure = false;
@ -224,7 +227,6 @@ public class NewsFeedPanel extends Composite {
});
}
/**
*
*/
@ -937,5 +939,11 @@ public class NewsFeedPanel extends Composite {
public void setCurrentFilter(FilterType currentFilter) {
this.currentFilter = currentFilter;
}
/**
*
* @return the current scope on the client
*/
public static String getCurrentScope() {
return currentScope;
}
}

View File

@ -1,19 +1,29 @@
package org.gcube.portlets.user.newsfeed.client.templates;
import java.util.ArrayList;
import org.gcube.portal.databook.shared.Comment;
import org.gcube.portal.databook.shared.UserInfo;
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.EditCommentEvent;
import org.gcube.portlets.user.newsfeed.client.panels.NewsFeedPanel;
import org.gcube.portlets.widgets.pickuser.client.dialog.PickUsersDialog;
import org.gcube.portlets.widgets.pickuser.shared.PickingUser;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.event.shared.HandlerManager;
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.Event;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTML;
@ -22,22 +32,34 @@ import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.Widget;
public class AddCommentTemplate extends Composite{
public class AddCommentTemplate extends Composite {
private static CommentTemplateUiBinder uiBinder = GWT
.create(CommentTemplateUiBinder.class);
interface CommentTemplateUiBinder extends UiBinder<Widget, AddCommentTemplate> {
}
private final static String COMMENT_TEXT = "Add a comment ...";
private static CommentTemplateUiBinder uiBinder = GWT.create(CommentTemplateUiBinder.class);
private final static String COMMENT_TEXT = "Add a comment ... use @ to mention someone";
private final static String ERROR_UPDATE_TEXT = "Looks like empty to me!";
public static final String avatar_default = GWT.getModuleBaseURL() + "../images/Avatar_default.png";
private final static int TEXT_AREA_WIDTH = 450;
private final static int TEXT_AREA_HEIGHT = 40;
private TweetTemplate owner;
private HandlerManager eventBus;
private boolean isEditing = false;
private HTMLPanel commentPanel;
private Comment toEdit;
interface CommentTemplateUiBinder extends UiBinder<Widget, AddCommentTemplate> {
}
@UiField HTMLPanel mainPanel;
@UiField Image avatarImage;
@UiField SuperPosedTextArea commentTextArea;
@UiField Button submitButton;
@UiField Button cancelButton;
/**
* called on add comment
* @param caller
@ -50,7 +72,7 @@ public class AddCommentTemplate extends Composite{
owner = caller;
avatarImage.setPixelSize(30, 30);
avatarImage.setUrl(myUserInfo.getAvatarId());
commentTextArea.setPixelSize(450, 26);
//commentTextArea.setPixelSize(TEXT_AREA_WIDTH, TEXT_AREA_HEIGHT);
commentTextArea.setText(COMMENT_TEXT);
}
/**
@ -60,45 +82,25 @@ public class AddCommentTemplate extends Composite{
*/
public AddCommentTemplate(TweetTemplate caller, Comment toEdit, HTMLPanel commentPanel) {
initWidget(uiBinder.createAndBindUi(this));
this.eventBus = caller.getEventBus();
this.eventBus = caller.getEventBus();
this.commentPanel = commentPanel;
isEditing = true;
this.toEdit = toEdit;
owner = caller;
avatarImage.setPixelSize(30, 30);
avatarImage.setUrl(caller.getMyUserInfo().getAvatarId());
commentTextArea.setPixelSize(450, 26);
//commentTextArea.setPixelSize(TEXT_AREA_WIDTH, TEXT_AREA_HEIGHT);
commentTextArea.setText(new HTML(toEdit.getText()).getText());
mainPanel.removeStyleName("comment-hidden");
mainPanel.setStyleName("single-comment");
commentTextArea.addStyleName("dark-color");
commentTextArea.addStyleName("comment-dark-color");
}
@UiField HTMLPanel mainPanel;
@UiField Image avatarImage;
@UiField TextArea commentTextArea;
@UiField Button submitButton;
@UiField Button cancelButton;
public void setFocus() {
commentTextArea.setFocus(true);
}
/**
* paste event overridden
*/
public void onBrowserEvent(Event event) {
super.onBrowserEvent(event);
switch (event.getTypeInt()) {
case Event.ONPASTE:
if (commentTextArea.getText().equals(COMMENT_TEXT) || commentTextArea.getText().equals(ERROR_UPDATE_TEXT) ) {
commentTextArea.setText("");
commentTextArea.addStyleName("dark-color");
commentTextArea.removeStyleName("error");
}
}
}
@UiHandler("submitButton")
void onSubmitClick(ClickEvent e) {
String userComment = commentTextArea.getText().trim();
@ -155,7 +157,7 @@ public class AddCommentTemplate extends Composite{
void onCommentClick(ClickEvent e) {
if (commentTextArea.getText().equals(COMMENT_TEXT) || commentTextArea.getText().equals(ERROR_UPDATE_TEXT) ) {
commentTextArea.setText("");
commentTextArea.addStyleName("dark-color");
commentTextArea.addStyleName("comment-dark-color");
commentTextArea.removeStyleName("error");
}
}
@ -164,7 +166,7 @@ public class AddCommentTemplate extends Composite{
void onCommentKeyPress(KeyPressEvent e) {
if (commentTextArea.getText().equals(COMMENT_TEXT) || commentTextArea.getText().equals(ERROR_UPDATE_TEXT) ) {
commentTextArea.setText("");
commentTextArea.addStyleName("dark-color");
commentTextArea.addStyleName("comment-dark-color");
commentTextArea.removeStyleName("error");
}
}

View File

@ -1,12 +1,13 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui">
xmlns:g="urn:import:com.google.gwt.user.client.ui"
xmlns:m="urn:import:org.gcube.portlets.user.newsfeed.client.templates">
<ui:style>
.important {
font-weight: bold;
}
</ui:style>
<g:HTMLPanel styleName="comment-hidden" ui:field="mainPanel">
<g:HTMLPanel styleName="comment-hidden" ui:field="mainPanel">
<table class="">
<tr>
<td width="30px;" align="middle">
@ -16,9 +17,18 @@
</td>
<td>
<div class="commentContainer">
<g:TextArea styleName="post-comment" ui:field="commentTextArea" />
<div id="comment-supercontainer">
<div id="comment-highlighterContainer">
<div id="comment-highlighter">
</div>
</div>
<div id="comment-inputContainer">
<m:SuperPosedTextArea styleName="post-comment" ui:field="commentTextArea" />
</div>
</div>
<!-- <div class="commentContainer"> -->
<!-- <g:TextArea styleName="post-comment" ui:field="commentTextArea" /> -->
<!-- </div> -->
</td>
</tr>
<tr>

View File

@ -0,0 +1,196 @@
/**
*
*/
package org.gcube.portlets.user.newsfeed.client.templates;
import java.util.ArrayList;
import org.gcube.portlets.user.newsfeed.client.NewsService;
import org.gcube.portlets.user.newsfeed.client.NewsServiceAsync;
import org.gcube.portlets.user.newsfeed.client.panels.NewsFeedPanel;
import org.gcube.portlets.widgets.pickuser.client.dialog.PickUsersDialog;
import org.gcube.portlets.widgets.pickuser.client.events.PickedUserEvent;
import org.gcube.portlets.widgets.pickuser.client.events.PickedUserEventHandler;
import org.gcube.portlets.widgets.pickuser.shared.PickingUser;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Element;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.TextArea;
/**
* @author massi
*
*/
public class SuperPosedTextArea extends TextArea {
private final NewsServiceAsync newsService = GWT.create(NewsService.class);
private final HandlerManager eventBus = new HandlerManager(null);
private final static String COMMENT_TEXT = "Add a comment ... use @ to mention someone";
private final static String ERROR_UPDATE_TEXT = "Looks like empty to me!";
PickUsersDialog pickUserDlg;
public final static int ARROW_UP = 38;
public final static int ARROW_DOWN = 40;
private ArrayList<String> mentionedUsers = new ArrayList<String>();
/**
*
*/
public SuperPosedTextArea() {
sinkEvents(Event.ONPASTE);
sinkEvents(Event.ONKEYUP);
sinkEvents(Event.ONCONTEXTMENU);
sinkEvents(Event.ONKEYDOWN);
newsService.getOrganizationUsers(NewsFeedPanel.getCurrentScope(), new AsyncCallback<ArrayList<PickingUser>>() {
@Override
public void onSuccess(ArrayList<PickingUser> users) {
pickUserDlg = new PickUsersDialog(users, eventBus, 450);
}
@Override
public void onFailure(Throwable caught) {
}
});
DOM.setElementAttribute(getElement(), "id", "postTextArea");
bind();
Timer t = new Timer() {
@Override
public void run() {
myAutoSize();
}
};
t.schedule(1000);
}
public static native void myAutoSize() /*-{
function autoSizeArea() {
$wnd.jQuery('#postTextArea').autosize();
}
autoSizeArea();
}-*/;
/**
* @param element
*/
public SuperPosedTextArea(Element element) {
super(element);
}
/**
* paste event overridden
*/
public void onBrowserEvent(Event event) {
super.onBrowserEvent(event);
switch (event.getTypeInt()) {
case Event.ONPASTE: {
if (getText().equals(COMMENT_TEXT) || getText().equals(ERROR_UPDATE_TEXT) ) {
setText("");
addStyleName("dark-color");
removeStyleName("error");
}
break;
}
case Event.ONKEYUP: {
injectInDiv(getText());
pickUserDlg.onKeyUp(event.getKeyCode(), this.getAbsoluteLeft(), this.getAbsoluteTop()+45, getText());
break;
}
case Event.ONCONTEXTMENU: {
removeSampleText();
break;
}
case Event.ONKEYDOWN: {
if (pickUserDlg.isShowing()) {
//avoid the arrow up to move the cursor at the beginning of the textbox and the TAB to move around inputs and enter to go newline
if (event.getKeyCode() == ARROW_UP || event.getKeyCode() == KeyCodes.KEY_TAB || event.getKeyCode() == KeyCodes.KEY_ENTER) {
DOM.eventCancelBubble(event, true);
DOM.eventPreventDefault(event);
return;
}
}
break;
}
}
}
protected void removeSampleText() {
if (getText().equals(COMMENT_TEXT) || getText().equals(ERROR_UPDATE_TEXT) ) {
setText("");
addStyleName("darker-color");
removeStyleName("error");
}
}
protected void cleanHighlighterDiv() {
DOM.getElementById("comment-highlighter").setInnerHTML("");
}
private void injectInDiv(String textAreaText) {
String text;
// parse the text:
// replace all the line braks by <br/>, and all the double spaces by the html version &nbsp;
text = textAreaText.replaceAll("(\r\n|\n)","<br />");
text = text.replaceAll("\\s\\s","&nbsp;&nbsp;");
for (String mentionedUser : mentionedUsers) {
text = text.replaceAll(mentionedUser,"<span class=\"highlightedUser\">"+mentionedUser+"</span>");
}
// re-inject the processed text into the div
DOM.getElementById("comment-highlighter").setInnerHTML(text);
}
/**
* events binder
*/
private void bind() {
eventBus.addHandler(PickedUserEvent.TYPE, new PickedUserEventHandler() {
@Override
public void onSelectedUser(PickedUserEvent event) {
String toAdd = event.getSelectedUser().getFullName();
mentionedUsers.add(toAdd);
String[] toSplit = getText().split("@"); //get the preceeding part
setText(toSplit[0]+toAdd);
Element highDiv = DOM.getElementById("comment-highlighter");
String[] htmlToSplit = highDiv.getInnerHTML().split("@"); //get the preceeding part
String highLightedUser = "<span class=\"highlightedUser\">"+toAdd+"</span>";
highDiv.setInnerHTML(htmlToSplit[0]+highLightedUser);
}
});
}
public ArrayList<String> getMentionedUsers() {
ArrayList<String> toReturn = new ArrayList<String>();
for (String mentionedUser : mentionedUsers) {
if (getText().contains(mentionedUser))
toReturn.add(mentionedUser);
}
GWT.log(toReturn.toString());
return mentionedUsers;
}
/*
*
* <script>
$(document).ready(function(){
setTimeout(function(){
$('.postTextArea').autosize();
}, 3000);
});
</script>
*
*
*/
}

View File

@ -40,6 +40,7 @@ import org.gcube.portlets.user.newsfeed.shared.EnhancedFeed;
import org.gcube.portlets.user.newsfeed.shared.MoreFeedsBean;
import org.gcube.portlets.user.newsfeed.shared.NewsConstants;
import org.gcube.portlets.user.newsfeed.shared.UserSettings;
import org.gcube.portlets.widgets.pickuser.shared.PickingUser;
import org.gcube.vomanagement.usermanagement.GroupManager;
import org.gcube.vomanagement.usermanagement.impl.liferay.LiferayGroupManager;
import org.slf4j.Logger;
@ -111,7 +112,7 @@ public class NewsServiceImpl extends RemoteServiceServlet implements NewsService
}
public String getDevelopmentUser() {
String user = "test.user";
//user = "massimiliano.assante";
user = "massimiliano.assante";
return user;
}
/**
@ -680,6 +681,12 @@ public class NewsServiceImpl extends RemoteServiceServlet implements NewsService
return false;
}
}
@Override
public ArrayList<PickingUser> getOrganizationUsers(String currentScope) {
ArrayList<PickingUser> toReturn = UsersUtil.getOrganizationUsers(currentScope, getASLSession().getUsername(), withinPortal);
_log.trace("Returning " + toReturn.size() + " users for scope " + currentScope);
return toReturn;
}
private UserSettings getUserSettingsFromSession() {
try {
@ -860,5 +867,7 @@ public class NewsServiceImpl extends RemoteServiceServlet implements NewsService
}
}

View File

@ -0,0 +1,75 @@
package org.gcube.portlets.user.newsfeed.server;
import java.util.ArrayList;
import java.util.List;
import org.gcube.common.scope.impl.ScopeBean;
import org.gcube.common.scope.impl.ScopeBean.Type;
import org.gcube.portal.custom.communitymanager.OrganizationsUtil;
import org.gcube.portlets.widgets.pickuser.shared.PickingUser;
import org.gcube.vomanagement.usermanagement.GroupManager;
import org.gcube.vomanagement.usermanagement.UserManager;
import org.gcube.vomanagement.usermanagement.impl.liferay.LiferayGroupManager;
import org.gcube.vomanagement.usermanagement.impl.liferay.LiferayUserManager;
import org.gcube.vomanagement.usermanagement.model.UserModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.liferay.portal.service.UserLocalServiceUtil;
public class UsersUtil {
private static final Logger _log = LoggerFactory.getLogger(UsersUtil.class);
/**
*
* @param session the Asl Session
* @param withinPortal true when is on Liferay portal
* @return the users belonging to the current organization (scope)
*/
public static ArrayList<PickingUser> getOrganizationUsers(String scope, String currUser, boolean withinPortal) {
ArrayList<PickingUser> portalUsers = new ArrayList<PickingUser>();
try {
if (withinPortal) {
UserManager um = new LiferayUserManager();
GroupManager gm = new LiferayGroupManager();
ScopeBean sb = new ScopeBean(scope);
List<UserModel> users = null;
if (sb.is(Type.INFRASTRUCTURE))
users = um.listUsersByGroup(gm.getRootVO().getGroupId());
else if (sb.is(Type.VRE)) { //must be in VRE
//get the name from the scope
String orgName = scope.substring(scope.lastIndexOf("/")+1, scope.length());
//ask the users
users = um.listUsersByGroup(gm.getGroupId(orgName));
}
else {
_log.error("Error, you must be in SCOPE VRE OR INFRASTURCTURE, you are in VO SCOPE returning no users");
return portalUsers;
}
for (UserModel user : users) {
if (user.getScreenName().compareTo("test.user") != 0 && user.getScreenName().compareTo(currUser) != 0) { //skip test.user & current user
String thumbnailURL = "";
com.liferay.portal.model.UserModel lifeUser = UserLocalServiceUtil.getUserByScreenName(OrganizationsUtil.getCompany().getCompanyId(), user.getScreenName());
thumbnailURL = "/image/user_male_portrait?img_id="+lifeUser.getPortraitId();
portalUsers.add(new PickingUser(user.getUserId(), user.getScreenName(), user.getFullname(), thumbnailURL));
}
}
}
else { //test users
portalUsers.add(new PickingUser("12111", "massimiliano.assante", "Test User #1", ""));
portalUsers.add(new PickingUser("14111", "massimiliano.assante", "Test Second User #2", ""));
portalUsers.add(new PickingUser("11511", "massimiliano.assante", "Test Third User", ""));
portalUsers.add(new PickingUser("11611", "massimiliano.assante", "Test Fourth User", ""));
portalUsers.add(new PickingUser("11711", "massimiliano.assante", "Test Fifth User", ""));
portalUsers.add(new PickingUser("11811", "massimiliano.assante", "Test Sixth User", ""));
portalUsers.add(new PickingUser("15811", "massimiliano.assante", "Ninth Testing User", ""));
portalUsers.add(new PickingUser("15811", "massimiliano.assante", "Eighth Testing User", ""));
portalUsers.add(new PickingUser("11211", "giogio.giorgi", "Seventh Test User", ""));
portalUsers.add(new PickingUser("2222", "pino.pinetti", "Tenth Testing User", ""));
}
} catch (Exception e) {
_log.error("Error in server get all contacts ", e);
}
return portalUsers;
}
}

View File

@ -4,7 +4,7 @@
<inherits name='com.google.gwt.user.User' />
<!-- To Comment out -->
<!-- <set-property name="user.agent" value="safari,gecko1_8,ie9" /> -->
<set-property name="user.agent" value="safari,gecko1_8,ie9" />
<!-- Other module inherits -->
<inherits name="net.eliasbalasis.tibcopagebus4gwt.tibcopagebus4gwt" />
@ -16,6 +16,7 @@
<inherits name='org.gcube.portlets.widgets.wsmail.WsMail_Widget' />
<inherits name='org.gcube.portlets.widgets.userselection.UserSelection' />
<inherits name='org.gcube.portlets.widgets.sessionchecker.SessionChecker' />
<inherits name='org.gcube.portlets.widgets.pickuser.PickUser' />
<inherits
name='org.gcube.portlets.widgets.lighttree.WorkspacePortletLightTree' />
<inherits name='org.gcube.portal.databook.GCubeSocialNetworking' />

View File

@ -5,6 +5,69 @@ table {
border-spacing: 0;
}
/* Superpose TextArea and Highlight DIV trick starts here */
#comment-supercontainer {
position: relative;
background-color: #FFFFFF;
}
#comment-highlighterContainer {
position: absolute;
left: 0;
top: 0;
cursor: text;
width: 525px;
height: 54px;
}
#comment-inputContainer {
position: relative;
}
#comment-highlighter {
padding: 4px 2px;
color: #ffffff;
background-color: #FFF;
margin-top: 0;
font-family: 'Lucida Grande', Verdana, 'Bitstream Vera Sans', Arial,
sans-serif;
font-size: 11px;
letter-spacing: normal;
line-height: normal;
border: 1px solid transparent;
width: 450px;
min-height: 40px;
word-wrap: break-word; /* this is very important when usere paste long links*/
}
.post-comment {
padding: 4px 2px;
color: #999;
background-color: transparent;
margin-top: 0px;
font-family: 'Lucida Grande', Verdana, 'Bitstream Vera Sans', Arial,
sans-serif;
font-size: 11px;
letter-spacing: normal;
line-height: normal;
border: 1px solid #999;
width: 450px;
min-height: 40px;
}
.highlightedUser {
background-color: #D8DFEA !important;
}
/* DIV trick ends here */
.framed {
margin: 0 0 10px;
padding: 10px;
@ -300,20 +363,6 @@ table {
white-space: nowrap;
}
.post-comment {
height: 30px;
width: 99%;
color: #999;
font-family: 'Lucida Grande', Verdana, 'Bitstream Vera Sans', Arial,
sans-serif;
font-size: 11px;
padding: 4px 2px;
border-color: #999;
border-width: 1px;
letter-spacing: normal;
margin-top: 5px;
}
a.seemore,a.seemore:visited {
font-family: 'Lucida Grande', Verdana, 'Bitstream Vera Sans', Arial,
sans-serif;
@ -520,9 +569,9 @@ a.link:hover {
-webkit-transition: background .45s ease-in-out;
}
.dark-color {
.comment-dark-color {
color: #333;
background-color: #FFF;
background-color: transparent;
transition: background .25s ease-in-out;
-moz-transition: background .25s ease-in-out;
-webkit-transition: background .25s ease-in-out;

View File

@ -17,6 +17,13 @@
<!-- Any title is fine -->
<!-- -->
<title>News Feed</title>
<script src='js/jquery.min.js'></script>
<script src='js/jquery.autosize.js'></script>
</head>
<script src="js/pagebus.js"></script>
<script type="text/javascript">
if(window.parent.PageBus) {

View File

@ -0,0 +1,187 @@
/*!
jQuery Autosize v1.16.12
(c) 2013 Jack Moore - jacklmoore.com
updated: 2013-05-31
license: http://www.opensource.org/licenses/mit-license.php
*/
(function ($) {
var
defaults = {
className: 'autosizejs',
append: '',
callback: false
},
hidden = 'hidden',
borderBox = 'border-box',
lineHeight = 'lineHeight',
// border:0 is unnecessary, but avoids a bug in FireFox on OSX
copy = '<textarea tabindex="-1" style="position:absolute; top:-999px; left:0; right:auto; bottom:auto; border:0; -moz-box-sizing:content-box; -webkit-box-sizing:content-box; box-sizing:content-box; word-wrap:break-word; height:0 !important; min-height:0 !important; overflow:hidden;"/>',
// line-height is conditionally included because IE7/IE8/old Opera do not return the correct value.
copyStyle = [
'fontFamily',
'fontSize',
'fontWeight',
'fontStyle',
'letterSpacing',
'textTransform',
'wordSpacing',
'textIndent'
],
oninput = 'oninput',
onpropertychange = 'onpropertychange',
// to keep track which textarea is being mirrored when adjust() is called.
mirrored,
// the mirror element, which is used to calculate what size the mirrored element should be.
mirror = $(copy).data('autosize', true)[0];
// test that line-height can be accurately copied.
mirror.style.lineHeight = '99px';
if ($(mirror).css(lineHeight) === '99px') {
copyStyle.push(lineHeight);
}
mirror.style.lineHeight = '';
$.fn.autosize = function (options) {
options = $.extend({}, defaults, options || {});
if (mirror.parentNode !== document.body) {
$(document.body).append(mirror);
}
return this.each(function () {
var
ta = this,
$ta = $(ta),
minHeight,
maxHeight,
resize,
boxOffset = 0,
callback = $.isFunction(options.callback);
if ($ta.data('autosize')) {
// exit if autosize has already been applied, or if the textarea is the mirror element.
return;
}
if ($ta.css('box-sizing') === borderBox || $ta.css('-moz-box-sizing') === borderBox || $ta.css('-webkit-box-sizing') === borderBox){
boxOffset = $ta.outerHeight() - $ta.height();
}
// IE8 and lower return 'auto', which parses to NaN, if no min-height is set.
minHeight = Math.max(parseInt($ta.css('minHeight'), 10) - boxOffset || 0, $ta.height());
resize = ($ta.css('resize') === 'none' || $ta.css('resize') === 'vertical') ? 'none' : 'horizontal';
$ta.css({
overflow: hidden,
overflowY: hidden,
wordWrap: 'break-word',
resize: resize
}).data('autosize', true);
function initMirror() {
mirrored = ta;
mirror.className = options.className;
maxHeight = parseInt($ta.css('maxHeight'), 10);
// mirror is a duplicate textarea located off-screen that
// is automatically updated to contain the same text as the
// original textarea. mirror always has a height of 0.
// This gives a cross-browser supported way getting the actual
// height of the text, through the scrollTop property.
$.each(copyStyle, function(i, val){
mirror.style[val] = $ta.css(val);
});
// The textarea overflow is probably now hidden, but Chrome doesn't reflow the text to account for the
// new space made available by removing the scrollbars. This workaround causes Chrome to reflow the text.
if (oninput in ta) {
var value = ta.value;
ta.value = '';
ta.value = value;
}
}
// Using mainly bare JS in this function because it is going
// to fire very often while typing, and needs to very efficient.
function adjust() {
var height, overflow, original;
if (mirrored !== ta) {
initMirror();
}
mirror.value = ta.value + options.append;
mirror.style.overflowY = ta.style.overflowY;
original = parseInt(ta.style.height,10);
// Update the width in case the original textarea width has changed
// A floor of 0 is needed because IE8 returns a negative value for hidden textareas, raising an error.
mirror.style.width = Math.max($ta.width(), 0) + 'px';
// Needed for IE8 and lower to reliably return the correct scrollTop
mirror.scrollTop = 0;
mirror.scrollTop = 9e4;
// Using scrollTop rather than scrollHeight because scrollHeight is non-standard and includes padding.
height = mirror.scrollTop;
if (maxHeight && height > maxHeight) {
height = maxHeight;
overflow = 'scroll';
} else if (height < minHeight) {
height = minHeight;
}
height += boxOffset;
ta.style.overflowY = overflow || hidden;
if (original !== height) {
ta.style.height = height + 'px';
if (callback) {
options.callback.call(ta,ta);
}
}
}
if (onpropertychange in ta) {
if (oninput in ta) {
// Detects IE9. IE9 does not fire onpropertychange or oninput for deletions,
// so binding to onkeyup to catch most of those occassions. There is no way that I
// know of to detect something like 'cut' in IE9.
ta[oninput] = ta.onkeyup = adjust;
} else {
// IE7 / IE8
ta[onpropertychange] = function(){
if(event.propertyName === 'value'){
adjust();
}
};
}
} else {
// Modern Browsers
ta[oninput] = adjust;
}
$(window).on('resize', function(){
active = false;
adjust();
});
// Allow for manual triggering if needed.
$ta.on('autosize', function(){
active = false;
adjust();
});
// Call adjust in case the textarea already contains text.
adjust();
});
};
}(window.jQuery || window.Zepto));

6
src/main/webapp/js/jquery.min.js vendored Normal file

File diff suppressed because one or more lines are too long