smart refresh partially implemented
git-svn-id: http://svn.research-infrastructures.eu/public/d4science/gcube/trunk/portlets/user/news-feed@72970 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
parent
ae51ecbc94
commit
b496c36a5a
|
@ -1,6 +1,7 @@
|
||||||
package org.gcube.portlets.user.newsfeed.client.panels;
|
package org.gcube.portlets.user.newsfeed.client.panels;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
import org.gcube.portal.databook.shared.ClientFeed;
|
import org.gcube.portal.databook.shared.ClientFeed;
|
||||||
import org.gcube.portal.databook.shared.Comment;
|
import org.gcube.portal.databook.shared.Comment;
|
||||||
|
@ -30,6 +31,7 @@ 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.event.StopTimerEventHandler;
|
||||||
import org.gcube.portlets.user.newsfeed.client.panels.dialog.LikesDialog;
|
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.FilterPanel;
|
||||||
|
import org.gcube.portlets.user.newsfeed.client.templates.NewFeedsAvailable;
|
||||||
import org.gcube.portlets.user.newsfeed.client.templates.SingleComment;
|
import org.gcube.portlets.user.newsfeed.client.templates.SingleComment;
|
||||||
import org.gcube.portlets.user.newsfeed.client.templates.TweetTemplate;
|
import org.gcube.portlets.user.newsfeed.client.templates.TweetTemplate;
|
||||||
import org.gcube.portlets.user.newsfeed.shared.EnhancedFeed;
|
import org.gcube.portlets.user.newsfeed.shared.EnhancedFeed;
|
||||||
|
@ -47,6 +49,7 @@ import com.google.gwt.user.client.ui.HasAlignment;
|
||||||
import com.google.gwt.user.client.ui.HasVerticalAlignment;
|
import com.google.gwt.user.client.ui.HasVerticalAlignment;
|
||||||
import com.google.gwt.user.client.ui.HorizontalPanel;
|
import com.google.gwt.user.client.ui.HorizontalPanel;
|
||||||
import com.google.gwt.user.client.ui.Image;
|
import com.google.gwt.user.client.ui.Image;
|
||||||
|
import com.google.gwt.user.client.ui.SimplePanel;
|
||||||
import com.google.gwt.user.client.ui.VerticalPanel;
|
import com.google.gwt.user.client.ui.VerticalPanel;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -63,6 +66,7 @@ public class NewsFeedPanel extends Composite {
|
||||||
|
|
||||||
private VerticalPanel mainPanel = new VerticalPanel();
|
private VerticalPanel mainPanel = new VerticalPanel();
|
||||||
private HorizontalPanel filterPanel = new HorizontalPanel();
|
private HorizontalPanel filterPanel = new HorizontalPanel();
|
||||||
|
private SimplePanel newUpdatesPanel = new SimplePanel();
|
||||||
private VerticalPanel newsPanel = new VerticalPanel();
|
private VerticalPanel newsPanel = new VerticalPanel();
|
||||||
|
|
||||||
private static final String warning = GWT.getModuleBaseURL() + "../images/warning_blue.png";
|
private static final String warning = GWT.getModuleBaseURL() + "../images/warning_blue.png";
|
||||||
|
@ -74,7 +78,9 @@ public class NewsFeedPanel extends Composite {
|
||||||
public static final String COMMENT_LABEL = "Reply";
|
public static final String COMMENT_LABEL = "Reply";
|
||||||
public static final String MESSAGE_LABEL = "Message";
|
public static final String MESSAGE_LABEL = "Message";
|
||||||
|
|
||||||
private int delayMillis = 300000; //5 minutes by default
|
private int delayMillis = 300000; //5 minutes by default (is read from a configuration file in the first async callback)
|
||||||
|
|
||||||
|
private int currNewUpdatesNo = 0;
|
||||||
|
|
||||||
private boolean isFirstTweet = false;
|
private boolean isFirstTweet = false;
|
||||||
|
|
||||||
|
@ -82,6 +88,11 @@ public class NewsFeedPanel extends Composite {
|
||||||
private UserInfo myUserInfo;
|
private UserInfo myUserInfo;
|
||||||
private FilterType currentFilter;
|
private FilterType currentFilter;
|
||||||
private Timer feedsTimer;
|
private Timer feedsTimer;
|
||||||
|
|
||||||
|
private ArrayList<EnhancedFeed> allUpdates = new ArrayList<EnhancedFeed>();
|
||||||
|
|
||||||
|
private ArrayList<EnhancedFeed> tempCacheNewUpdates = new ArrayList<EnhancedFeed>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* events binder
|
* events binder
|
||||||
*/
|
*/
|
||||||
|
@ -164,6 +175,7 @@ public class NewsFeedPanel extends Composite {
|
||||||
public NewsFeedPanel() {
|
public NewsFeedPanel() {
|
||||||
bind();
|
bind();
|
||||||
mainPanel.add(filterPanel);
|
mainPanel.add(filterPanel);
|
||||||
|
mainPanel.add(newUpdatesPanel);
|
||||||
mainPanel.add(newsPanel);
|
mainPanel.add(newsPanel);
|
||||||
|
|
||||||
filterPanel.add(new FilterPanel(this, newsService));
|
filterPanel.add(new FilterPanel(this, newsService));
|
||||||
|
@ -198,7 +210,7 @@ public class NewsFeedPanel extends Composite {
|
||||||
feedsTimer = new Timer() {
|
feedsTimer = new Timer() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
refreshFeeds();
|
checkForNewUpdates();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
feedsTimer.scheduleRepeating(delayMillis);
|
feedsTimer.scheduleRepeating(delayMillis);
|
||||||
|
@ -214,10 +226,10 @@ public class NewsFeedPanel extends Composite {
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private void refreshFeeds() {
|
private void checkForNewUpdates() {
|
||||||
switch (currentFilter) {
|
switch (currentFilter) {
|
||||||
case ALL_UPDATES:
|
case ALL_UPDATES:
|
||||||
showAllUpdatesFeeds();
|
checkAllUpdatesFeeds();
|
||||||
break;
|
break;
|
||||||
case CONNECTIONS:
|
case CONNECTIONS:
|
||||||
showOnlyConnectionsFeeds();
|
showOnlyConnectionsFeeds();
|
||||||
|
@ -227,6 +239,43 @@ public class NewsFeedPanel extends Composite {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//TODO: finish this
|
||||||
|
private void checkAllUpdatesFeeds() {
|
||||||
|
newsService.getAllUpdateUserFeeds(new AsyncCallback<ArrayList<EnhancedFeed>>() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(ArrayList<EnhancedFeed> feeds) {
|
||||||
|
if (feeds != null && allUpdates.size() > 0) {
|
||||||
|
|
||||||
|
Date myLastUpdateTime = allUpdates.get(0).getFeed().getTime(); //this is the last update in the View
|
||||||
|
|
||||||
|
tempCacheNewUpdates = new ArrayList<EnhancedFeed>(); //need to reset it everytime i check (in case someone deleted the updated in the meanwhile)
|
||||||
|
|
||||||
|
//check if there are new updates (enter the while) and put them in a temporary cache for displaying on user click
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
while (i < feeds.size() && feeds.get(i).getFeed().getTime().after(myLastUpdateTime)) {
|
||||||
|
tempCacheNewUpdates.add(feeds.get(i));
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* currNewUpdatesNo keeps the number of updates to be added on user clicks,
|
||||||
|
* i keeps the total number as it arrives,
|
||||||
|
* if they differ you got to refresh the updates to show the new number
|
||||||
|
*/
|
||||||
|
if (currNewUpdatesNo < i) {
|
||||||
|
newUpdatesPanel.clear(); //remove the current show update button if present
|
||||||
|
newUpdatesPanel.add(new NewFeedsAvailable(i));
|
||||||
|
currNewUpdatesNo = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void onFailure(Throwable caught) {}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All Updates
|
* All Updates
|
||||||
*/
|
*/
|
||||||
|
@ -249,8 +298,10 @@ public class NewsFeedPanel extends Composite {
|
||||||
newsPanel.setHeight("");
|
newsPanel.setHeight("");
|
||||||
newsPanel.setHorizontalAlignment(HasAlignment.ALIGN_LEFT);
|
newsPanel.setHorizontalAlignment(HasAlignment.ALIGN_LEFT);
|
||||||
newsPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_TOP);
|
newsPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_TOP);
|
||||||
for (EnhancedFeed feed : feeds)
|
for (EnhancedFeed feed : feeds) {
|
||||||
newsPanel.add(new TweetTemplate(myUserInfo, feed, eventBus));
|
newsPanel.add(new TweetTemplate(myUserInfo, feed, eventBus));
|
||||||
|
allUpdates.add(feed);
|
||||||
|
}
|
||||||
if (feeds.size() < 5) {
|
if (feeds.size() < 5) {
|
||||||
newsPanel.add(new Image(spacer));
|
newsPanel.add(new Image(spacer));
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
package org.gcube.portlets.user.newsfeed.client.templates;
|
||||||
|
|
||||||
|
import com.google.gwt.core.client.GWT;
|
||||||
|
import com.google.gwt.uibinder.client.UiBinder;
|
||||||
|
import com.google.gwt.uibinder.client.UiField;
|
||||||
|
import com.google.gwt.user.client.Timer;
|
||||||
|
import com.google.gwt.user.client.ui.Composite;
|
||||||
|
import com.google.gwt.user.client.ui.HTML;
|
||||||
|
import com.google.gwt.user.client.ui.Widget;
|
||||||
|
|
||||||
|
public class NewFeedsAvailable extends Composite {
|
||||||
|
|
||||||
|
private static NewFeedsAvailableUiBinder uiBinder = GWT
|
||||||
|
.create(NewFeedsAvailableUiBinder.class);
|
||||||
|
|
||||||
|
interface NewFeedsAvailableUiBinder extends
|
||||||
|
UiBinder<Widget, NewFeedsAvailable> {
|
||||||
|
}
|
||||||
|
@UiField HTML caption;
|
||||||
|
|
||||||
|
public NewFeedsAvailable(int newUpdatesNo) {
|
||||||
|
initWidget(uiBinder.createAndBindUi(this));
|
||||||
|
if (newUpdatesNo > 0) {
|
||||||
|
caption.setHTML(newUpdatesNo > 1 ? "See " + newUpdatesNo + " new Updates" : "See 1 new Update");
|
||||||
|
//create the fade transition effect
|
||||||
|
Timer t = new Timer() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
caption.addStyleName("new-feeds-show");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
t.schedule(100);
|
||||||
|
}
|
||||||
|
else throw new IllegalArgumentException("newUpdatesNo must be greater than 0");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
<!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">
|
||||||
|
<g:HTMLPanel styleName="new-feeds-container">
|
||||||
|
<g:HTML ui:field="caption" styleName="new-feeds-available" />
|
||||||
|
</g:HTMLPanel>
|
||||||
|
</ui:UiBinder>
|
|
@ -62,6 +62,11 @@ public class NewsServiceImpl extends RemoteServiceServlet implements NewsService
|
||||||
*/
|
*/
|
||||||
private static final String SESSION_ADMIN_ATTR = "SESSION_ADMIN_ATTR";
|
private static final String SESSION_ADMIN_ATTR = "SESSION_ADMIN_ATTR";
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final String USER_SETTINGS_ATTR = "USER_SETTINGS_ATTR";
|
||||||
|
|
||||||
private DatabookStore store;
|
private DatabookStore store;
|
||||||
|
|
||||||
private boolean withinPortal = false;
|
private boolean withinPortal = false;
|
||||||
|
@ -238,28 +243,28 @@ public class NewsServiceImpl extends RemoteServiceServlet implements NewsService
|
||||||
ArrayList<Feed> toMerge = new ArrayList<Feed>();
|
ArrayList<Feed> toMerge = new ArrayList<Feed>();
|
||||||
HashMap<String, Feed> feedsMap = new HashMap<String, Feed>();
|
HashMap<String, Feed> feedsMap = new HashMap<String, Feed>();
|
||||||
|
|
||||||
ArrayList<Feed> OrganizationFeeds = (ArrayList<Feed>) store.getRecentFeedsByVRE("/gcube/devsec/devVRE", 10);
|
ArrayList<Feed> OrganizationFeeds = (ArrayList<Feed>) store.getRecentFeedsByVRE("/gcube/devsec/devVRE", 5);
|
||||||
for (Feed feed : OrganizationFeeds) {
|
for (Feed feed : OrganizationFeeds) {
|
||||||
feedsMap.put(feed.getKey(), feed);
|
feedsMap.put(feed.getKey(), feed);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! onlyConnections) {
|
// if (! onlyConnections) {
|
||||||
//User Own Feeds
|
// //User Own Feeds
|
||||||
ArrayList<Feed> userFeeds = (ArrayList<Feed>) store.getRecentFeedsByUser(userName, 10);
|
// ArrayList<Feed> userFeeds = (ArrayList<Feed>) store.getRecentFeedsByUser(userName, 10);
|
||||||
for (Feed feed : userFeeds)
|
// for (Feed feed : userFeeds)
|
||||||
feedsMap.put(feed.getKey(), feed);
|
// feedsMap.put(feed.getKey(), feed);
|
||||||
// //Portal Feeds
|
// // //Portal Feeds
|
||||||
ArrayList<Feed> portalFeeds = (ArrayList<Feed>) store.getAllPortalPrivacyLevelFeeds();
|
// ArrayList<Feed> portalFeeds = (ArrayList<Feed>) store.getAllPortalPrivacyLevelFeeds();
|
||||||
for (Feed feed : portalFeeds)
|
// for (Feed feed : portalFeeds)
|
||||||
feedsMap.put(feed.getKey(), feed);
|
// feedsMap.put(feed.getKey(), feed);
|
||||||
}
|
// }
|
||||||
//UserFriends Feeds
|
// //UserFriends Feeds
|
||||||
ArrayList<String> userFriendsIds = (ArrayList<String>)store.getFriends(userName);
|
// ArrayList<String> userFriendsIds = (ArrayList<String>)store.getFriends(userName);
|
||||||
for (String userid : userFriendsIds) {
|
// for (String userid : userFriendsIds) {
|
||||||
for (Feed feed : store.getRecentFeedsByUser(userid, 10)) {
|
// for (Feed feed : store.getRecentFeedsByUser(userid, 10)) {
|
||||||
feedsMap.put(feed.getKey(), feed);
|
// feedsMap.put(feed.getKey(), feed);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
for (String key: feedsMap.keySet()) {
|
for (String key: feedsMap.keySet()) {
|
||||||
toMerge.add(feedsMap.get(key));
|
toMerge.add(feedsMap.get(key));
|
||||||
}
|
}
|
||||||
|
@ -451,8 +456,8 @@ public class NewsServiceImpl extends RemoteServiceServlet implements NewsService
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserSettings getUserSettings() {
|
public UserSettings getUserSettings() {
|
||||||
if (getUserFromSession() != null)
|
if (getUserSettingsFromSession() != null)
|
||||||
return getUserFromSession();
|
return getUserSettingsFromSession();
|
||||||
try {
|
try {
|
||||||
String username = getASLSession().getUsername();
|
String username = getASLSession().getUsername();
|
||||||
String email = username+"@isti.cnr.it";
|
String email = username+"@isti.cnr.it";
|
||||||
|
@ -469,7 +474,7 @@ public class NewsServiceImpl extends RemoteServiceServlet implements NewsService
|
||||||
|
|
||||||
UserInfo userInfo = new UserInfo(username, fullName, thumbnailURL, user.getEmailAddress(), accountURL, true, false, null);
|
UserInfo userInfo = new UserInfo(username, fullName, thumbnailURL, user.getEmailAddress(), accountURL, true, false, null);
|
||||||
UserSettings toReturn = new UserSettings(userInfo, getFeedsRefreshTimeInMillis());
|
UserSettings toReturn = new UserSettings(userInfo, getFeedsRefreshTimeInMillis());
|
||||||
setUserInSession(toReturn);
|
setUserSettingsInSession(toReturn);
|
||||||
return toReturn;
|
return toReturn;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -525,12 +530,12 @@ public class NewsServiceImpl extends RemoteServiceServlet implements NewsService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private UserSettings getUserFromSession() {
|
private UserSettings getUserSettingsFromSession() {
|
||||||
return (UserSettings) getASLSession().getAttribute(UserInfo.USER_INFO_ATTR);
|
return (UserSettings) getASLSession().getAttribute(USER_SETTINGS_ATTR);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUserInSession(UserSettings user) {
|
private void setUserSettingsInSession(UserSettings user) {
|
||||||
getASLSession().setAttribute(UserInfo.USER_INFO_ATTR, user);
|
getASLSession().setAttribute(USER_SETTINGS_ATTR, user);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* tell if a feed is belonging to the current user or not
|
* tell if a feed is belonging to the current user or not
|
||||||
|
@ -631,31 +636,34 @@ public class NewsServiceImpl extends RemoteServiceServlet implements NewsService
|
||||||
* @return the refreshingTime in milliseconds
|
* @return the refreshingTime in milliseconds
|
||||||
*/
|
*/
|
||||||
private int getFeedsRefreshTimeInMillis() {
|
private int getFeedsRefreshTimeInMillis() {
|
||||||
Properties props = new Properties();
|
return 15000;
|
||||||
int toReturn = 0;
|
//TODO:
|
||||||
int minutes = 0;
|
// Properties props = new Properties();
|
||||||
try {
|
// int toReturn = 0;
|
||||||
String propertyfile = this.getThreadLocalRequest().getServletPath()+"conf/settings.properties";
|
// int minutes = 0;
|
||||||
File propsFile = new File(propertyfile);
|
// String propertyfile = "";
|
||||||
FileInputStream fis = new FileInputStream(propsFile);
|
// try {
|
||||||
props.load( fis);
|
// propertyfile = this.getThreadLocalRequest().getContextPath()+"conf/settings.properties";
|
||||||
|
// File propsFile = new File(propertyfile);
|
||||||
minutes = Integer.parseInt(props.getProperty("REFRESH_TIME"));
|
// FileInputStream fis = new FileInputStream(propsFile);
|
||||||
toReturn = minutes*60*1000;
|
// props.load( fis);
|
||||||
}
|
//
|
||||||
//catch exception in case properties file does not exist
|
// minutes = Integer.parseInt(props.getProperty("REFRESH_TIME"));
|
||||||
catch(IOException e) {
|
// toReturn = minutes*60*1000;
|
||||||
toReturn = 300000; //5 minutes
|
// }
|
||||||
_log.error("settings.properties file not found under conf dir, returning 5 minutes");
|
// //catch exception in case properties file does not exist
|
||||||
return toReturn;
|
// catch(IOException e) {
|
||||||
}
|
// toReturn = 300000; //5 minutes
|
||||||
//catch exception in case the property value isNot a Number
|
// _log.error("settings.properties file not found under " + propertyfile +", returning 5 minutes");
|
||||||
catch (ClassCastException ex) {
|
// return toReturn;
|
||||||
toReturn = 300000; //5 minutes
|
// }
|
||||||
_log.error("REFRESH_TIME must be a number (in minutes) returning 5 minutes");
|
// //catch exception in case the property value isNot a Number
|
||||||
return toReturn;
|
// catch (ClassCastException ex) {
|
||||||
}
|
// toReturn = 300000; //5 minutes
|
||||||
_log.debug("Returning REFRESH_TIME in millis: " + toReturn + " minutes: " + minutes);
|
// _log.error("REFRESH_TIME must be a number (in minutes) returning 5 minutes");
|
||||||
return toReturn;
|
// return toReturn;
|
||||||
|
// }
|
||||||
|
// _log.debug("Returning REFRESH_TIME in millis: " + toReturn + ", (" + minutes + " minutes)");
|
||||||
|
// return toReturn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,56 @@
|
||||||
@import url(http://fonts.googleapis.com/css?family=Architects+Daughter);
|
@import url(http://fonts.googleapis.com/css?family=Architects+Daughter);
|
||||||
|
|
||||||
/* FILTER Widget*/
|
|
||||||
table {
|
table {
|
||||||
border-collapse: separate !important;
|
border-collapse: separate !important;
|
||||||
border-spacing: 0;
|
border-spacing: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.new-feeds-container {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.new-feeds-available {
|
||||||
|
color: #444;
|
||||||
|
font-family: 'Lucida Grande', Verdana, 'Bitstream Vera Sans', Arial,
|
||||||
|
sans-serif;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 13px;
|
||||||
|
width: 576px;
|
||||||
|
margin: 0px 25px 0px 8px;
|
||||||
|
padding: 3px;
|
||||||
|
border: 1px solid #75AAD0;
|
||||||
|
-webkit-border-radius: 3px;
|
||||||
|
-moz-border-radius: 3px;
|
||||||
|
border-radius: 3px;
|
||||||
|
height: 0px;
|
||||||
|
opacity: 0;
|
||||||
|
transition-property: opacity, height;
|
||||||
|
transition-duration: .40s;
|
||||||
|
transition-timing-function: ease-out;
|
||||||
|
-moz-transition-property: opacity, height;
|
||||||
|
-moz-transition-duration: .40s;
|
||||||
|
-moz-transition-timing-function: ease-out;
|
||||||
|
-webkit-transition-property: opacity, height;
|
||||||
|
-webkit-transition-duration: .40s;
|
||||||
|
-webkit-transition-timing-function: ease-out;
|
||||||
|
-ms-transition-property: opacity, height;
|
||||||
|
-ms-transition-duration: .40s;
|
||||||
|
-ms-transition-timing-function: ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.new-feeds-show {
|
||||||
|
opacity: 1;
|
||||||
|
background: #D6E2FC;
|
||||||
|
height: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.new-feeds-available:hover {
|
||||||
|
background: #EDEFF4;
|
||||||
|
cursor: pointer;
|
||||||
|
cursor: hand;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
.nofeed-message {
|
.nofeed-message {
|
||||||
line-height: 40px;
|
line-height: 40px;
|
||||||
font-family: 'Architects Daughter', arial, sans-serif;
|
font-family: 'Architects Daughter', arial, sans-serif;
|
||||||
|
|
Loading…
Reference in New Issue