hoover cards (almost finished)

This commit is contained in:
Hannes Mannerheim 2015-09-16 22:41:48 +02:00
parent 3de43b6b33
commit c22eaa9f1b
8 changed files with 1731 additions and 1301 deletions

View File

@ -1345,7 +1345,7 @@ body.rtl #footer-spinner-container {
font-size:12px;
background-color: #fff;
color: #eee;
z-index: 10000;
z-index: 9998;
position:absolute;
display:block;
font-style: normal;
@ -1357,7 +1357,7 @@ body.rtl #footer-spinner-container {
box-shadow: 0 0 10px rgba(0,0,0,0.4);
}
.hoover-card-caret {
z-index: 10001;
z-index: 9999;
opacity:0;
display:block;
content:' ';
@ -1375,12 +1375,6 @@ body.rtl #footer-spinner-container {
border-bottom:0 none;
}
.hoover-card .profile-card {
width:290px;
margin-bottom:0;
border:0 none;
}
#settings-container {
padding:10px 10px 150px 10px;
}
@ -2200,24 +2194,37 @@ body.rtl .view-more-container-bottom { direction:rtl; }
}
.stream-item-header .name {
color: #333333;
display: inline-block;
font-size: 14px;
font-weight: 700;
color: #333333;
line-height: 18px;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
vertical-align: top;
white-space: nowrap;
}
.stream-item-header .screen-name,
.stream-item-header .reply-to,
.stream-item-header .in-groups,
.stream-item-header .h-card {
font-size: 13px;
color: #999999;
line-height: 18px;
direction: ltr;
display: inline-block;
font-size: 13px;
font-style: normal;
height: 18px;
line-height: 18px;
vertical-align: top;
}
.stream-item-header .h-card:hover {
text-decoration:underline;
}
.stream-item-header .addressees {
display: inline-block;
vertical-align: top;
}
.stream-item-header .addressees span:first-child:before {
content: "\f105";
display:inline-block;
@ -2565,6 +2572,14 @@ ul.queet-actions li .icon.is-mine:before {
color:#999;
font-weight:normal;
}
.queet > .context .with-icn .requeet-text a b {
display: inline-block;
max-width: 350px;
overflow: hidden;
text-overflow: ellipsis;
vertical-align: top;
white-space: nowrap;
}
.queet > .context .with-icn .requeet-text a:hover b {
text-decoration:underline;
color:#555;
@ -2672,6 +2687,14 @@ ul.stats li {
.profile-card ul.stats li {
padding-top: 7px;
}
.hoover-card .profile-card ul.stats li {
padding-top: 6px;
min-width:70px;
}
.hoover-card .profile-card ul.stats li.follower-num,
.hoover-card .profile-card ul.stats li.groups-num {
display:none;
}
.queet.rtl ul.stats li {
float:right;
}
@ -2685,6 +2708,9 @@ ul.stats a {
line-height: 18px;
font-weight: normal;
}
.hoover-card ul.stats a {
font-size: 9px;
}
.queet.rtl ul.stats a{
border-right: 1px solid #E8E8E8;
border-left: 0 none;
@ -2696,6 +2722,9 @@ ul.stats a strong {
line-height: 16px;
display: block;
}
.hoover-card ul.stats a strong {
font-size: 17px;
}
ul.stats .avatar-row {
overflow: hidden;
@ -2949,6 +2978,11 @@ span.inline-reply-caret .caret-inner {
position: relative;
z-index: 200;
margin-top:8px;
overflow:hidden;
height:16px;
text-overflow: ellipsis;
max-width: 260px;
white-space:nowrap;
}
#user-screen-name {
font-weight:normal;
@ -3432,6 +3466,13 @@ div.nav-session {
position: relative;
width: 588px;
}
.hoover-card .profile-card {
width:290px;
margin-bottom:0;
border:0 none;
}
.modal-body .profile-card {
margin-right:-1px;
margin-top:-5px;
@ -3454,6 +3495,13 @@ div.nav-session {
-o-background-size: cover;
background-size: cover;
}
.hoover-card .profile-header-inner {
height: 200px;
}
.profile-header-inner a:hover {
text-decoration: underline;
color:#fff;
}
.profile-header-inner .profile-header-inner-overlay {
background: -moz-linear-gradient(top, rgba(0,0,0,0) 0%, rgba(0,0,0,0.65) 100%);
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(0,0,0,0)), color-stop(100%,rgba(0,0,0,0.65)));
@ -3466,6 +3514,9 @@ div.nav-session {
top: 60px;
width: 100%;
}
.hoover-card .profile-header-inner .profile-header-inner-overlay {
height: 140px;
}
.profile-header-inner .profile-picture {
outline: 0 none;
background-color: #FFFFFF;
@ -3479,12 +3530,27 @@ div.nav-session {
width: 73px;
z-index: 5;
}
.hoover-card .profile-header-inner .profile-picture {
border: 2px solid #ffffff;
border-radius: 4px;
height: 40px;
overflow: hidden;
width: 40px;
}
.profile-header-inner .profile-picture img {
height: 73px;
width: 73px;
border-radius: 3px 3px 3px 3px;
float: none;
}
.hoover-card .profile-header-inner .profile-picture img {
border-radius: 3px;
height: 40px;
width: 40px;
}
.profile-header-inner .profile-card-inner {
text-align: center;
line-height: 16px;
@ -3499,13 +3565,23 @@ div.nav-session {
font-weight: bold;
line-height: 1;
margin: 0 auto 2px auto;
color: #FFFFFF;
color: #fff;
font-size: 24px;
white-space: nowrap;
padding:0;
height:24px;
height:28px;
line-height:24px;
display:block;
overflow: hidden;
max-width:100%;
text-overflow: ellipsis;
}
.hoover-card .profile-card-inner .fullname {
font-size: 14px;
font-weight: 700;
height: 26px;
line-height: 16px;
margin:0;
}
.profile-header-inner .profile-card-inner h1.fullname span {
font-size: 24px;
@ -3520,6 +3596,28 @@ div.nav-session {
line-height: 24px;
margin-bottom: 1px;
text-rendering: optimizelegibility;
overflow: hidden;
max-width:100%;
white-space: nowrap;
text-overflow: ellipsis;
}
.hoover-card .profile-header-inner .profile-card-inner h2.username {
font-size: 14px;
line-height:18px;
margin-bottom: 4px;
}
.profile-header-inner .profile-card-inner h2.username .ostatus-link {
background-position: 7px -240px;
font-size: 0;
opacity: 0.9 !important;
overflow: hidden;
right: -22px;
text-shadow: none;
top: -74px;
}
.profile-header-inner .profile-card-inner h2.username .ostatus-link:hover {
background-position: 7px -210px;
}
.profile-header-inner .profile-card-inner h2.username .follows-you {
@ -3534,6 +3632,14 @@ div.nav-session {
margin-left:7px;
text-transform:uppercase;
}
.hoover-card .profile-header-inner .profile-card-inner h2.username .follows-you {
background-color: rgba(0, 0, 0, 0.5);
bottom: -36px;
display: block;
font-size: 10px;
position: absolute;
right: -13px;
}
.profile-header-inner .profile-card-inner h2.username a {
color:#fff;
@ -3545,8 +3651,19 @@ div.nav-session {
font-size: 14px;
}
.profile-header-inner .profile-card-inner .bio-container p {
color: #FFFFFF;
color: #fff;
line-height: 18px;
margin: 0;
max-height: 54px;
overflow: hidden;
text-overflow: ellipsis;
}
.hoover-card .profile-header-inner .profile-card-inner .bio-container p {
font-size: 12px;
letter-spacing: 0.2px;
line-height: 15px;
height: 15px;
white-space: nowrap;
}
.profile-header-inner .profile-card-inner .location-and-url,
.profile-header-inner .profile-card-inner .location-and-url input {
@ -3555,6 +3672,22 @@ div.nav-session {
line-height: 18px;
margin:0;
}
.hoover-card .profile-header-inner .profile-card-inner .location-and-url,
.hoover-card .profile-header-inner .profile-card-inner .location-and-url input {
font-size: 12px;
letter-spacing: 0.2px;
line-height: 15px;
}
.profile-header-inner .profile-card-inner .location-and-url span {
vertical-align: top;
display:inline-block;
overflow: hidden;
max-width:46%;
white-space: nowrap;
text-overflow: ellipsis;
}
.profile-header-inner .profile-card-inner .location-and-url span.divider {
padding: 0 2px;
}
@ -3580,6 +3713,9 @@ div.nav-session {
min-height: 52px;
position: relative;
}
.hoover-card .profile-banner-footer {
min-height: 47px;
}
.profile-banner-footer ul.stats {
border-bottom: 0 none;
border-top: 0 none;
@ -3589,9 +3725,15 @@ div.nav-session {
.profile-banner-footer ul.stats li a {
padding: 0 15px 8px 12px;
}
.hoover-card .profile-banner-footer ul.stats li a {
padding-bottom: 5px;
}
.profile-banner-footer ul.stats li:first-child a {
padding-left: 12px;
}
.hoover-card .profile-banner-footer ul.stats li:first-child a {
padding-left: 6px;
}
.profile-banner-footer ul.stats li a strong {
}
@ -3600,6 +3742,10 @@ div.nav-session {
float: right;
margin: 10px;
}
.hoover-card .profile-card .user-actions {
margin-right: 5px;
margin-bottom: 5px;
}
div.clearfix {
clear:both;
height:0;

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 51 KiB

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 48 KiB

View File

@ -222,10 +222,10 @@ function buildProfileCard(data) {
</div>\
<div class="profile-banner-footer">\
<ul class="stats">\
<li><a class="tweet-stats">' + window.sL.notices + '<strong>' + data.statuses_count + '</strong></a></li>\
<li><a class="following-stats">' + window.sL.following + '<strong>' + data.friends_count + '</strong></a></li>\
<li><a class="follower-stats">' + window.sL.followers + '<strong>' + data.followers_count + '</strong></a></li>\
<li><a class="groups-stats">' + window.sL.groups + '<strong>' + data.groups_count + '</strong></a></li>\
<li class="tweet-num"><a class="tweet-stats">' + window.sL.notices + '<strong>' + data.statuses_count + '</strong></a></li>\
<li class="following-num"><a class="following-stats">' + window.sL.following + '<strong>' + data.friends_count + '</strong></a></li>\
<li class="follower-num"><a class="follower-stats">' + window.sL.followers + '<strong>' + data.followers_count + '</strong></a></li>\
<li class="groups-num"><a class="groups-stats">' + window.sL.groups + '<strong>' + data.groups_count + '</strong></a></li>\
</ul>\
' + followButton + '\
<div class="clearfix"></div>\
@ -304,13 +304,14 @@ function buildExternalProfileCard(data) {
<div class="profile-header-inner-overlay"></div>\
<a class="profile-picture"><img src="' + data.profile_image_url_profile_size + '" /></a>\
<div class="profile-card-inner">\
<a target="_blank" href="' + data.statusnet_profile_url + '">\
<h1 class="fullname">' + data.name + '<span></span></h1>\
<h2 class="username">\
<span class="screen-name">\
<a target="_blank" href="' + data.statusnet_profile_url + '">' + data.screenNameWithServer + '</a>\
</span>\
<span class="screen-name">' + data.screenNameWithServer + '</span>\
<span class="ostatus-link" data-tooltip="' + window.sL.goToTheUsersRemoteProfile + '">' + window.sL.goToTheUsersRemoteProfile + '</span>\
' + follows_you + '\
</h2>\
</a>\
<div class="bio-container"><p>' + data.description + '</p></div>\
<p class="location-and-url">\
<span class="location">' + data.location + '</span>\
@ -323,9 +324,9 @@ function buildExternalProfileCard(data) {
</div>\
<div class="profile-banner-footer">\
<ul class="stats">\
<li><a target="_blank" href="' + data.statusnet_profile_url + '">' + window.sL.notices + '<strong>' + data.statuses_count + '</strong></a></li>\
<li><a target="_blank" href="' + data.statusnet_profile_url + '/subscriptions">' + window.sL.following + '<strong>' + data.friends_count + '</strong></a></li>\
<li><a target="_blank" href="' + data.statusnet_profile_url + '/subscribers">' + window.sL.followers + '<strong>' + data.followers_count + '</strong></a></li>\
<li class="tweet-num"><a class="tweet-stats" target="_blank" href="' + data.statusnet_profile_url + '">' + window.sL.notices + '<strong>' + data.statuses_count + '</strong></a></li>\
<li class="following-num"><a class="following-stats" target="_blank" href="' + data.statusnet_profile_url + '/subscriptions">' + window.sL.following + '<strong>' + data.friends_count + '</strong></a></li>\
<li class="follower-num"><a class="follower-stats" target="_blank" href="' + data.statusnet_profile_url + '/subscribers">' + window.sL.followers + '<strong>' + data.followers_count + '</strong></a></li>\
</ul>\
' + followButton + '\
<div class="clearfix"></div>\
@ -772,186 +773,267 @@ function setUrlFromStream(stream) {
/* ·
·
· Get stream from location bar
· Local URL to stream router
·
· @param stream: the stream, e.g. 'public_timeline.json'
· @param url: any URL
·
· · · · · · · · · */
function URLtoStreamRouter(url) {
// structure of the returned object
var streamObject = new Object();
streamObject.nickname = false;
streamObject.id = false;
streamObject.stream = false;
streamObject.name = false;
// we don't expect protocol to matter
url = removeProtocolFromUrl(url);
// remove anchor tags
if(url.indexOf('#')>-1) {
url = url.substring(0,url.indexOf('#'));
}
// not a local URL
if(url != window.siteRootDomain && url.indexOf(window.siteRootDomain + '/') != 0) {
console.log('not a local url: ' + url);
return false;
}
// remove server
var path = url.substring(window.siteRootDomain.length);
// remove starting slash
if(path.indexOf('/') == 0) {
path = path.substring(1);
}
// remove ending slash
if(path.length>0 && path.lastIndexOf('/') == (path.length-1)) {
path = path.substring(0,path.length-1);
}
// front page
if(path.length == 0) {
if(window.siteLocalOnlyDefaultPath) {
streamObject.stream = 'statuses/public_timeline.json';
streamObject.name = 'public timeline';
return streamObject;
}
else {
streamObject.stream = 'statuses/public_and_external_timeline.json';
streamObject.name = 'public and external timeline';
return streamObject;
}
}
// main/all, i.e. full network
if(path == 'main/all') {
streamObject.stream = 'statuses/public_and_external_timeline.json';
streamObject.name = 'public and external timeline';
return streamObject;
}
// main/public, i.e. site's public timeline, new gnu social style
if(path == 'main/public') {
streamObject.stream = 'statuses/public_timeline.json';
streamObject.name = 'public timeline';
return streamObject;
}
// groups directory, qvitter can't handle that yet
if(path == 'groups') {
streamObject.name = 'group directory';
return streamObject;
}
// search/notice?q={urlencoded search terms}
if(path.indexOf('search/notice?q=') == 0) {
var searchQuery = replaceHtmlSpecialChars(loc.replace('/search/notice?q=',''));
if(searchQuery.length>0) {
streamToSet.id = searchQuery;
streamToSet.stream = 'search.json?q=' + searchToStream;
streamObject.name = 'search';
return streamObject;
}
}
// {screen_name}
if(/^[a-zA-Z0-9]+$/.test(path)) {
streamObject.nickname = path;
streamObject.stream = 'statuses/user_timeline.json?screen_name=' + streamObject.nickname;
streamObject.name = 'profile';
return streamObject;
}
var pathSplit = path.split('/');
// tag/{tag}
if(pathSplit.length == 2 && pathSplit[0] == 'tag') {
streamObject.id = pathSplit[1];
streamObject.stream = 'statusnet/tags/timeline/' + streamObject.id + '.json';
streamObject.name = 'tag stream';
return streamObject;
}
// notice/{id}
if(pathSplit.length == 2 && pathSplit[0] == 'notice' && /^[0-9]+$/.test(pathSplit[1])) {
streamObject.id = pathSplit[1];
streamObject.stream = 'statuses/show/' + streamObject.id + '.json';
streamObject.name = 'notice';
return streamObject;
}
// user/{id}
if(pathSplit.length == 2 && pathSplit[0] == 'user' && /^[0-9]+$/.test(pathSplit[1])) {
streamObject.id = pathSplit[1];
streamObject.stream = 'statuses/user_timeline.json?id=' + streamObject.id;
streamObject.name = 'profile';
return streamObject;
}
// group/{group_nickname}
if(pathSplit.length == 2 && pathSplit[0] == 'group' && /^[a-zA-Z0-9]+$/.test(pathSplit[1])) {
streamObject.nickname = pathSplit[1];
streamObject.stream = 'statusnet/groups/timeline/' + streamObject.nickname + '.json';
streamObject.name = 'group notice stream';
return streamObject;
}
// group/{group_nickname}/members
if(pathSplit.length == 3 && pathSplit[0] == 'group' && /^[a-zA-Z0-9]+$/.test(pathSplit[1]) && pathSplit[2] == 'members') {
streamObject.nickname = pathSplit[1];
streamObject.stream = 'statusnet/groups/membership/' + streamObject.nickname + '.json?count=20';
streamObject.name = 'group member list';
return streamObject;
}
// group/{group_nickname}/admins
if(pathSplit.length == 3 && pathSplit[0] == 'group' && /^[a-zA-Z0-9]+$/.test(pathSplit[1]) && pathSplit[2] == 'admins') {
streamObject.nickname = pathSplit[1];
streamObject.stream = 'statusnet/groups/admins/' + streamObject.nickname + '.json?count=20';
streamObject.name = 'group admin list';
return streamObject;
}
// {screen_name}/all
if(pathSplit.length == 2 && /^[a-zA-Z0-9]+$/.test(pathSplit[0]) && pathSplit[1] == 'all') {
streamObject.nickname = pathSplit[0];
if(window.loggedIn.screen_name == streamObject.nickname) {
streamObject.stream = 'statuses/friends_timeline.json';
}
else {
streamObject.stream = 'statuses/friends_timeline.json?screen_name=' + streamObject.nickname;
}
streamObject.name = 'friends timeline';
return streamObject;
}
// {screen_name}/replies
if(pathSplit.length == 2 && /^[a-zA-Z0-9]+$/.test(pathSplit[0]) && pathSplit[1] == 'replies') {
streamObject.nickname = pathSplit[0];
if(window.loggedIn.screen_name == streamObject.nickname) {
streamObject.stream = 'statuses/mentions.json';
}
else {
streamObject.stream = 'statuses/mentions.json?screen_name=' + streamObject.nickname;
}
streamObject.name = 'mentions';
return streamObject;
}
// {screen_name}/notifications
if(pathSplit.length == 2 && /^[a-zA-Z0-9]+$/.test(pathSplit[0]) && pathSplit[1] == 'notifications') {
streamObject.nickname = pathSplit[0];
// only accessible to the logged in user
if(window.loggedIn.screen_name == streamObject.nickname) {
streamObject.stream = 'qvitter/statuses/notifications.json';
}
streamObject.name = 'notifications';
return streamObject;
}
// {screen_name}/favorites
if(pathSplit.length == 2 && /^[a-zA-Z0-9]+$/.test(pathSplit[0]) && pathSplit[1] == 'favorites') {
streamObject.nickname = pathSplit[0];
if(window.loggedIn.screen_name == streamObject.nickname) {
streamObject.stream = 'favorites.json';
}
else {
streamObject.stream = 'favorites.json?screen_name=' + streamObject.nickname;
}
streamObject.name = 'favorites';
return streamObject;
}
// {screen_name}/subscribers
if(pathSplit.length == 2 && /^[a-zA-Z0-9]+$/.test(pathSplit[0]) && pathSplit[1] == 'subscribers') {
streamObject.nickname = pathSplit[0];
if(window.loggedIn.screen_name == streamObject.nickname) {
streamObject.stream = 'statuses/followers.json?count=20';
}
else {
streamObject.stream = 'statuses/followers.json?count=20&screen_name=' + streamObject.nickname;
}
streamObject.name = 'subscribers';
return streamObject;
}
// {screen_name}/subscriptions
if(pathSplit.length == 2 && /^[a-zA-Z0-9]+$/.test(pathSplit[0]) && pathSplit[1] == 'subscriptions') {
streamObject.nickname = pathSplit[0];
if(window.loggedIn.screen_name == streamObject.nickname) {
streamObject.stream = 'statuses/friends.json?count=20';
}
else {
streamObject.stream = 'statuses/friends.json?count=20&screen_name=' + streamObject.nickname;
}
streamObject.name = 'subscriptions';
return streamObject;
}
// {screen_name}/groups
if(pathSplit.length == 2 && /^[a-zA-Z0-9]+$/.test(pathSplit[0]) && pathSplit[1] == 'groups') {
streamObject.nickname = pathSplit[0];
if(window.loggedIn.screen_name == streamObject.nickname) {
streamObject.stream = 'statusnet/groups/list.json?count=10';
}
else {
streamObject.stream = 'statusnet/groups/list.json?count=10&screen_name=' + streamObject.nickname;
}
streamObject.name = 'user group list';
return streamObject;
}
}
/* ·
·
· Get stream from location bar
·
· · · · · · · · · */
function getStreamFromUrl() {
var loc = window.location.href.replace('http://','').replace('https://','').replace(window.siteRootDomain,'');
// default/fallback
if(window.loggedIn) {
var streamToSet = 'statuses/friends_timeline.json';
var streamObject = URLtoStreamRouter(window.location.href);
if(streamObject.stream) {
return streamObject.stream;
}
// fallback to friends timeline or public timeline if URLtoStreamRouter can't find a stream
else if(window.loggedIn) {
return 'statuses/friends_timeline.json';
}
else if(window.siteLocalOnlyDefaultPath) {
var streamToSet = 'statuses/public_timeline.json';
return 'statuses/public_timeline.json';
}
else {
var streamToSet = 'statuses/public_and_external_timeline.json';
return 'statuses/public_and_external_timeline.json';
}
// main/all, i.e. full network
if (loc == '/main/all') {
streamToSet = 'statuses/public_and_external_timeline.json';
}
// main/public, i.e. site's public timeline, new gnu social style
else if (loc == '/main/public') {
streamToSet = 'statuses/public_timeline.json';
}
// {domain}/{screen_name} or {domain}/{screen_name}/
else if ((/^[a-zA-Z0-9]+$/.test(loc.substring(0, loc.length - 1).replace('/','')))) {
var userToStream = loc.replace('/','').replace('/','');
if(userToStream.length>0) {
streamToSet = 'statuses/user_timeline.json?screen_name=' + userToStream;
}
}
// {domain}/{screen_name}/all
else if ((/^[a-zA-Z0-9]+$/.test(loc.replace('/','').replace('/all','')))) {
var userToStream = loc.replace('/','').replace('/all','');
if(userToStream.length>0) {
if(window.loggedIn.screen_name == userToStream) {
streamToSet = 'statuses/friends_timeline.json';
}
else {
streamToSet = 'statuses/friends_timeline.json?screen_name=' + userToStream;
}
}
}
// {domain}/{screen_name}/replies
else if ((/^[a-zA-Z0-9]+$/.test(loc.replace('/','').replace('/replies','')))) {
var userToStream = loc.replace('/','').replace('/replies','');
if(userToStream.length>0) {
if(window.loggedIn.screen_name == userToStream) {
streamToSet = 'statuses/mentions.json';
}
else {
streamToSet = 'statuses/mentions.json?screen_name=' + userToStream;
}
}
}
// {domain}/{screen_name}/notifications
else if ((/^[a-zA-Z0-9]+$/.test(loc.replace('/','').replace('/notifications','')))) {
var userToStream = loc.replace('/','').replace('/notifications','');
if(userToStream.length>0) {
if(window.loggedIn.screen_name == userToStream) {
streamToSet = 'qvitter/statuses/notifications.json';
}
else {
// not allowed for others than logged in user
window.location.replace(window.siteInstanceURL);
}
}
}
// {domain}/{screen_name}/favorites
else if ((/^[a-zA-Z0-9]+$/.test(loc.replace('/','').replace('/favorites','')))) {
var userToStream = loc.replace('/','').replace('/favorites','');
if(userToStream.length>0) {
if(window.loggedIn.screen_name == userToStream) {
streamToSet = 'favorites.json';
}
else {
streamToSet = 'favorites.json?screen_name=' + userToStream;
}
}
}
// {domain}/{screen_name}/subscribers
else if ((/^[a-zA-Z0-9]+$/.test(loc.replace('/','').replace('/subscribers','')))) {
var userToStream = loc.replace('/','').replace('/subscribers','');
if(userToStream.length>0) {
if(window.loggedIn.screen_name == userToStream) {
streamToSet = 'statuses/followers.json?count=20';
}
else {
streamToSet = 'statuses/followers.json?count=20&screen_name=' + userToStream;
}
}
}
// {domain}/{screen_name}/subscriptions
else if ((/^[a-zA-Z0-9]+$/.test(loc.replace('/','').replace('/subscriptions','')))) {
var userToStream = loc.replace('/','').replace('/subscriptions','');
if(userToStream.length>0) {
if(window.loggedIn.screen_name == userToStream) {
streamToSet = 'statuses/friends.json?count=20';
}
else {
streamToSet = 'statuses/friends.json?count=20&screen_name=' + userToStream;
}
}
}
// {domain}/{screen_name}/groups
else if ((/^[a-zA-Z0-9]+$/.test(loc.replace('/','').replace('/groups','')))) {
var userToStream = loc.replace('/','').replace('/groups','');
if(userToStream.length>0) {
if(window.loggedIn.screen_name == userToStream) {
streamToSet = 'statusnet/groups/list.json?count=10';
}
else {
streamToSet = 'statusnet/groups/list.json?count=10&screen_name=' + userToStream;
}
}
}
// {domain}/tag/{tag}
else if (loc.indexOf('/tag/')>-1) {
var tagToStream = loc.replace('/tag/','');
if(tagToStream.length>0) {
streamToSet = 'statusnet/tags/timeline/' + tagToStream + '.json';
}
}
// {domain}/notice/{notide_id}
else if (loc.indexOf('/notice/')>-1) {
var noticeToStream = loc.replace('/notice/','');
if(noticeToStream.length>0) {
streamToSet = 'statuses/show/' + noticeToStream + '.json';
}
}
// {domain}/group/{group}/members, {domain}/group/{group}/admins or {domain}/group/{group}
else if (loc.indexOf('/group/')>-1) {
if(loc.indexOf('/members')>-1) {
var groupToStream = loc.replace('/group/','').replace('/members','');
if(groupToStream.length>0) {
streamToSet = 'statusnet/groups/membership/' + groupToStream + '.json?count=20';
}
}
else if(loc.indexOf('/admins')>-1) {
var groupToStream = loc.replace('/group/','').replace('/admins','');
if(groupToStream.length>0) {
streamToSet = 'statusnet/groups/admins/' + groupToStream + '.json?count=20';
}
}
else {
var groupToStream = loc.replace('/group/','');
if(groupToStream.length>0) {
streamToSet = 'statusnet/groups/timeline/' + groupToStream + '.json';
}
}
}
// {domain}/search/notice?q={urlencoded searh terms}
else if (loc.indexOf('/search/notice?q=')>-1) {
var searchToStream = replaceHtmlSpecialChars(loc.replace('/search/notice?q=',''));
if(searchToStream.length>0) {
streamToSet = 'search.json?q=' + searchToStream;
}
}
return streamToSet;
}

View File

@ -383,6 +383,10 @@ function userArrayCacheStore(data) {
// store
if(typeof window.userArrayCache[key] == 'undefined') {
window.userArrayCache[key] = dataToStore;
// easy conversion between URI and statusnet_profile_url and the key we're using in window.userArrayCache
window.convertUriToUserArrayCacheKey[dataToStore.local.ostatus_uri] = key;
window.convertStatusnetProfileUrlToUserArrayCacheKey[dataToStore.local.statusnet_profile_url] = key;
}
else {
if(dataToStore.local) {

View File

@ -189,7 +189,7 @@ $('body').on('mouseover',function (e) {
}
// see if we have it in cache, otherwise query server
getUserArrayData(hrefAttr,possibleNickname,function(userArray){
getUserArrayData(hrefAttr, possibleNickname, timeNow, function(userArray, timeOut){
// bad data
if(typeof userArray.local == 'undefined') {
@ -265,26 +265,63 @@ $('body').on('mouseover',function (e) {
hooverCardCaret.css('opacity','1');
}
}
},600);
},timeOut);
});
});
// get user array from cache (or from server TODO!!)
function getUserArrayData(maybeProfileUrl,maybeNickname,callback) {
function getUserArrayData(maybeProfileUrl,maybeNickname,timeNow,callback) {
if(maybeProfileUrl && maybeNickname) {
userArray = userArrayCacheGetByProfileUrlAndNickname(maybeProfileUrl, maybeNickname);
// no cached user array found
// no cached user array found, query server if this seems to be a profile url
if(!userArray) {
// see if we have reason to believe that maybeProfileUrl really is a profile url
var routedUrl = URLtoStreamRouter(maybeProfileUrl);
// query server for that
// likely an uncached local profile
if(routedUrl && routedUrl.name == 'profile') {
var nicknameOrId = routedUrl.nickname;
if(!nicknameOrId) {
nicknameOrId = routedUrl.id;
}
// don't query too often for the same user
if(typeof window.userArrayLastRetrieved[nicknameOrId] == 'undefined' || (timeNow - window.userArrayLastRetrieved[nicknameOrId]) > 60000) {
window.userArrayLastRetrieved[nicknameOrId] = timeNow;
// query server and cache user data (done automatically in getFromAPI)
getFromAPI('users/show.json?id=' + nicknameOrId, function(data){
if(data) {
userArray = {local:data};
// we want hoover cards to appear _at least_ 600ms after hoover
// we could just set the timeout to 0 and let the card appear
// whenever it's loaded, but this will not feel good if we're
// on a crazy fast server. so we calculate the diff time and makes
// sure the total delay is at least 600ms
var timeAfterServerQuery = new Date().getTime();
var queryTime = timeAfterServerQuery-timeNow;
if(queryTime<600) {
var timeOut = 600-queryTime;
}
else {
var timeOut = 0;
}
// continue to display the hoover card
callback(userArray,timeOut);
}
});
}
}
}
// from cache
else {
callback(userArray);
// continue to display the hoover card
// 600ms before cards appear feels pretty good
// but this can be tweaked if cards appear to fast/slow
callback(userArray,600);
}
}
}