diff --git a/js/ajax-functions.js b/js/ajax-functions.js index 07b6bb1..1f960aa 100644 --- a/js/ajax-functions.js +++ b/js/ajax-functions.js @@ -176,6 +176,7 @@ function getFromAPI(stream, actionOnSuccess) { data = convertEmptyObjectToEmptyArray(data); data = iterateRecursiveReplaceHtmlSpecialChars(data); searchForUserDataToCache(data); + updateUserDataInStream(); searchForUpdatedNoticeData(data); actionOnSuccess(data, userArray, request, url); @@ -450,6 +451,7 @@ function APIFollowOrUnfollowUser(followOrUnfollow,user_id,this_element,actionOnS data = convertEmptyObjectToEmptyArray(data); data = iterateRecursiveReplaceHtmlSpecialChars(data); searchForUserDataToCache(data); + updateUserDataInStream(); actionOnSuccess(data,this_element); } }); @@ -479,6 +481,7 @@ function APIJoinOrLeaveGroup(joinOrLeave,group_id,this_element,actionOnSuccess) data = convertEmptyObjectToEmptyArray(data); data = iterateRecursiveReplaceHtmlSpecialChars(data); searchForUserDataToCache(data); + updateUserDataInStream(); actionOnSuccess(data,this_element); } }); @@ -512,6 +515,7 @@ function postQueetToAPI(queetText_txt, in_reply_to_status_id, postToGroups, acti data = convertEmptyObjectToEmptyArray(data); data = iterateRecursiveReplaceHtmlSpecialChars(data); searchForUserDataToCache(data); + updateUserDataInStream(); searchForUpdatedNoticeData(data); actionOnSuccess(data); } @@ -543,6 +547,7 @@ function postActionToAPI(action, actionOnSuccess) { data = convertEmptyObjectToEmptyArray(data); data = iterateRecursiveReplaceHtmlSpecialChars(data); searchForUserDataToCache(data); + updateUserDataInStream(); searchForUpdatedNoticeData(data); actionOnSuccess(data); } diff --git a/js/dom-functions.js b/js/dom-functions.js index c0b0891..e4b4c7e 100644 --- a/js/dom-functions.js +++ b/js/dom-functions.js @@ -343,15 +343,15 @@ function buildProfileCard(data) { // full card html data.profileCardHtml = '\
\ -
\ +
\
\ \ - \ + \ \
\ -

' + data.name + '

\ +

' + data.name + '

\

\ - @' + data.screen_name + '\ + @' + data.screen_name + '\ ' + follows_you + '\

\

' + data.description + '

\ @@ -1576,8 +1576,8 @@ function addToFeed(feed, after, extraClasses) { ' + ostatusHtml + '\
\
\ -
' + obj.description + '
'; + var userHtml = '
' + followButton + '
' + obj.description + '
'; if(after) { $('#' + after).after(userHtml); @@ -1964,7 +1964,7 @@ function buildQueetHtml(obj, idInStream, extraClasses, requeeted_by, isConversat var queetHtml = '
\
\ - ' + '' + reply_to_html + in_groups_html + '' + '\ diff --git a/js/misc-functions.js b/js/misc-functions.js index 7248750..3e653f1 100644 --- a/js/misc-functions.js +++ b/js/misc-functions.js @@ -472,11 +472,10 @@ function userArrayCacheStore(data) { var instanceUrlWithoutProtocol = guessInstanceUrlWithoutProtocolFromProfileUrlAndNickname(data.statusnet_profile_url, data.screen_name); var key = instanceUrlWithoutProtocol + '/' + data.screen_name; - var dataProfileImageUrlWithoutProtocol = removeProtocolFromUrl(data.profile_image_url); - var siteInstanceURLWithoutProtocol = removeProtocolFromUrl(window.siteInstanceURL); + var localOrExternal = detectLocalOrExternalUserObject(data); // local - if(dataProfileImageUrlWithoutProtocol.substring(0,siteInstanceURLWithoutProtocol.length) == siteInstanceURLWithoutProtocol){ + if(localOrExternal == 'local'){ var dataToStore = {local:data,external:false}; } // external @@ -491,6 +490,7 @@ function userArrayCacheStore(data) { // store if(typeof window.userArrayCache[key] == 'undefined') { window.userArrayCache[key] = dataToStore; + window.userArrayCache[key].modified = Date.now(); // easy conversion between URI and statusnet_profile_url and the key we're using in window.userArrayCache window.convertUriToUserArrayCacheKey[dataToStore.local.ostatus_uri] = key; @@ -517,6 +517,10 @@ function userArrayCacheStore(data) { window.convertUriToUserArrayCacheKey[dataToStore.external.ostatus_uri] = key; window.convertStatusnetProfileUrlToUserArrayCacheKey[dataToStore.external.statusnet_profile_url] = key; } + // store the time when this record was modified + if(dataToStore.local || dataToStore.external) { + window.userArrayCache[key].modified = Date.now(); + } } } @@ -572,6 +576,23 @@ function userArrayCacheGetUserNicknameById(id) { } +/* · + · + · Detect if the supplied user object is from the local server or external + · + · · · · · · · · · */ + +function detectLocalOrExternalUserObject(userObject) { + var dataProfileImageUrlWithoutProtocol = removeProtocolFromUrl(userObject.profile_image_url); + var siteInstanceURLWithoutProtocol = removeProtocolFromUrl(window.siteInstanceURL); + if(dataProfileImageUrlWithoutProtocol.substring(0,siteInstanceURLWithoutProtocol.length) == siteInstanceURLWithoutProtocol){ + return 'local'; + } + else { + return 'external'; + } + } + /* · · @@ -647,6 +668,92 @@ function searchForUserDataToCache(obj) { } } + +/* · + · + · Updates user data loaded into the stream with the latest data from the user array cache + · This function should therefor always be invoked _after_ searchForUserDataToCache() + · + · · · · · · · · · · · · · */ + +function updateUserDataInStream() { + var timeNow = Date.now(); + $.each(window.userArrayCache,function(k,userArray){ + // if the cache record was updated the latest second, we assume this is brand new info that we haven't + // updated the stream with + if(typeof userArray.local != 'undefined' + && userArray.local !== false + && typeof userArray.modified != 'undefined' + && (timeNow-userArray.modified)<1000) { + + // profile size avatars (notices, users) + $.each($('img.avatar.profile-size[data-user-id="' + userArray.local.id + '"]'),function(){ + if($(this).attr('src') != userArray.local.profile_image_url_profile_size) { + $(this).attr('src',userArray.local.profile_image_url_profile_size); + } + }); + + // standard size avatars (notifications) + $.each($('img.avatar.standard-size[data-user-id="' + userArray.local.id + '"]'),function(){ + if($(this).attr('src') != userArray.local.profile_image_url) { + $(this).attr('src',userArray.local.profile_image_url); + } + }); + + // full names + $.each($('strong.name[data-user-id="' + userArray.local.id + '"],\ + .fullname[data-user-id="' + userArray.local.id + '"]'),function(){ + if($(this).html() != userArray.local.name) { + $(this).html(userArray.local.name); + } + }); + + // user/screen names + $.each($('.screen-name[data-user-id="' + userArray.local.id + '"]'),function(){ + if($(this).html().substring(1) != userArray.local.screen_name) { + $(this).html('@' + userArray.local.screen_name); + } + }); + + // profile urls + // try to find the last account group with this id, if the statusnet_profile_url seems to + // be changed we replace it wherever we can find it, even in list urls etc that starts with statusnet_profile_url + if($('a.account-group[data-user-id="' + userArray.local.id + '"]').last().attr('href') != userArray.local.statusnet_profile_url) { + var oldStatusnetProfileURL = $('a.account-group[data-user-id="' + userArray.local.id + '"]').last().attr('href'); + // all links with the exact statusnet_profile_url + $.each($('[href="' + oldStatusnetProfileURL + '"]'),function(){ + $(this).attr('href',userArray.local.statusnet_profile_url); + }); + // links starting with statusnet_profile_url + $.each($('[href*="' + oldStatusnetProfileURL + '/"]'),function(){ + $(this).attr('href',$(this).attr('href').replace(oldStatusnetProfileURL + '/',userArray.local.statusnet_profile_url + '/')); + }); + } + + // cover photos + $.each($('.profile-header-inner[data-user-id="' + userArray.local.id + '"]'),function(){ + if($(this).css('background-image') != 'url("' + userArray.local.cover_photo + '")') { + $(this).css('background-image','url("' + userArray.local.cover_photo + '")'); + } + }); + + // the window.following object might need updating also + if(typeof window.following != 'undefined' && typeof window.following[userArray.local.id] != 'undefined') { + if(window.following[userArray.local.id].avatar != userArray.local.profile_image_url) { + window.following[userArray.local.id].avatar = userArray.local.profile_image_url; + } + if(window.following[userArray.local.id].name != userArray.local.name) { + window.following[userArray.local.id].name = userArray.local.name; + } + if(window.following[userArray.local.id].username != userArray.local.screen_name) { + window.following[userArray.local.id].username = userArray.local.screen_name; + } + } + + } + }); + } + /* · · · Iterates recursively through an API response in search for updated notice data @@ -654,7 +761,6 @@ function searchForUserDataToCache(obj) { · · · · · · · · · · · · · · */ - window.knownDeletedNotices = new Object(); function searchForUpdatedNoticeData(obj) { for (var property in obj) { @@ -687,8 +793,6 @@ function searchForUpdatedNoticeData(obj) { var queetFoundInFeed = streamItemFoundInFeed.children('.queet'); var queetID = streamItemFoundInFeed.attr('data-quitter-id'); - // console.log(obj); - // sometimes activity notices don't get the is_activity flag set to true // maybe because they were in the process of being saved when // we first got them @@ -705,20 +809,6 @@ function searchForUpdatedNoticeData(obj) { } } - // avatar may have changed - if(typeof obj.user != 'undefined' - && typeof obj.user.profile_image_url_profile_size != 'undefined' - && queetFoundInFeed.find('.stream-item-header').find('img.avatar').src != obj.user.profile_image_url_profile_size) { - queetFoundInFeed.find('.stream-item-header').find('img.avatar').attr('src',obj.user.profile_image_url_profile_size); - } - - // name may have changed - if(typeof obj.user != 'undefined' - && typeof obj.user.name != 'undefined' - && queetFoundInFeed.find('.stream-item-header').find('strong.name').html() != obj.user.name) { - queetFoundInFeed.find('.stream-item-header').find('strong.name').html(obj.user.name); - } - // attachments might have been added/changed/have had time to be processed if(streamItemFoundInFeed.attr('data-attachments') != JSON.stringify(obj.attachments)) { streamItemFoundInFeed.attr('data-attachments',JSON.stringify(obj.attachments));