diff --git a/QvitterPlugin.php b/QvitterPlugin.php index e11b8f8..c3c9bf8 100644 --- a/QvitterPlugin.php +++ b/QvitterPlugin.php @@ -528,16 +528,16 @@ class QvitterPlugin extends Plugin { $oembed = File_oembed::getKV('file_id',$attachment->id); if($oembed instanceof File_oembed) { $oembed_html = str_replace('<!--//-->','',$oembed->html); // trash left of wordpress' javascript after htmLawed removed the tags - if($oembed->provider == 'Twitter' && strstr($oembed_html, '>— '.$oembed->author_name)) { - $oembed_html = substr($oembed_html,0,strpos($oembed_html, '>— '.$oembed->author_name)+1); // remove user data from twitter oembed html (we have it in ) - $twitter_username = substr($oembed->html,strpos($oembed->html, '>— '.$oembed->author_name)+strlen('>— '.$oembed->author_name)); + if($oembed->provider == 'Twitter' && strstr($oembed_html, '>— '.$oembed->author_name)) { + $oembed_html = substr($oembed_html,0,strpos($oembed_html, '>— '.$oembed->author_name)+1); // remove user data from twitter oembed html (we have it in ) + $twitter_username = substr($oembed->html,strpos($oembed->html, '>— '.$oembed->author_name)+strlen('>— '.$oembed->author_name)); $twitter_username = substr($twitter_username, strpos($twitter_username,'(@')+1); $twitter_username = substr($twitter_username, 0,strpos($twitter_username,')')); $oembed->title = $twitter_username; } $oembed_html = str_replace('…','...',$oembed_html); // ellipsis is sometimes stored as html in db, for some reason - $oembed_html = mb_substr(trim(strip_tags(html_entity_decode($oembed_html,ENT_QUOTES))),0,250); // sometimes we have html charachters that we want to decode and then strip - $oembed_title = trim(strip_tags(html_entity_decode($oembed->title,ENT_QUOTES))); + $oembed_html = mb_substr(trim(strip_tags($oembed_html)),0,250); + $oembed_title = trim(strip_tags(html_entity_decode($oembed->title,ENT_QUOTES))); // sometimes we have html charachters that we want to decode and then strip $oembed_provider = trim(strip_tags(html_entity_decode($oembed->provider,ENT_QUOTES))); $oembed_author_name = trim(strip_tags(html_entity_decode($oembed->author_name,ENT_QUOTES))); $attachment_url_to_id[$enclosure_o->url]['oembed'] = array( @@ -703,11 +703,33 @@ class QvitterPlugin extends Plugin { // reply-to profile url try { $reply = $notice->getParent(); - $twitter_status['in_reply_to_profileurl'] = $reply->getProfile()->getUrl(); + $reply_profile = $reply->getProfile(); + $twitter_status['in_reply_to_profileurl'] = $reply_profile->getUrl(); + $twitter_status['in_reply_to_ostatus_uri'] = $reply_profile->getUri(); } catch (ServerException $e) { $twitter_status['in_reply_to_profileurl'] = null; + $twitter_status['in_reply_to_ostatus_uri'] = null; } + // attentions + try { + $attentions = $notice->getAttentionProfiles(); + $attentions_array = array(); + foreach ($attentions as $attn) { + if(!$attn->isGroup()) { + $attentions_array[] = array( + 'id' => $attn->getID(), + 'screen_name' => $attn->getNickname(), + 'fullname' => $attn->getStreamName(), + 'profileurl' => $attn->getUrl(), + 'ostatus_uri' => $attn->getUri(), + ); + } + } + $twitter_status['attentions'] = $attentions_array; + } catch (Exception $e) { + // + } // fave number $faves = Fave::byNotice($notice); diff --git a/actions/apiqvitterblocks.php b/actions/apiqvitterblocks.php index ebeed52..f6d7bb2 100644 --- a/actions/apiqvitterblocks.php +++ b/actions/apiqvitterblocks.php @@ -109,14 +109,18 @@ class ApiQvitterBlocksAction extends ApiPrivateAuthAction $blocks = QvitterBlocked::getBlocked($this->target->id, $offset, $limit); - $profiles = array(); + if($blocks) { + $profiles = array(); - while ($blocks->fetch()) { - $this_profile_block = clone($blocks); - $profiles[] = $this->getTargetProfile($this_profile_block->blocked); + while ($blocks->fetch()) { + $this_profile_block = clone($blocks); + $profiles[] = $this->getTargetProfile($this_profile_block->blocked); + } + return $profiles; + } else { + return false; } - return $profiles; } /** diff --git a/actions/qvitter.php b/actions/qvitter.php index 19d131d..672a655 100644 --- a/actions/qvitter.php +++ b/actions/qvitter.php @@ -158,6 +158,17 @@ class QvitterAction extends ApiAction print ' '."\n"; print ' '."\n"; + // rel="me" for the IndieWeb audience + $relMes = array( + ['href' => $user->getProfile()->getHomepage(), + 'text' => _('Homepage'), + 'image' => null], + ); + Event::handle('OtherAccountProfiles', array($user->getProfile(), &$relMes)); + foreach ($relMes as $relMe) { + print ' '."\n"; + } + // maybe openid if (array_key_exists('OpenID', StatusNet::getActivePlugins())) { print ' '."\n"; diff --git a/classes/QvitterBlocked.php b/classes/QvitterBlocked.php index a3cbc58..39f8b51 100644 --- a/classes/QvitterBlocked.php +++ b/classes/QvitterBlocked.php @@ -49,7 +49,12 @@ class QvitterBlocked extends Profile_block public static function getBlocked($profile_id, $offset = 0, $limit = PROFILES_PER_PAGE) { $ids = self::getBlockedIDs($profile_id, $offset, $limit); - return Profile_block::listFind('blocked', $ids); + try { + $blocked = Profile_block::listFind('blocked', $ids); + return $blocked; + } catch(NoResultException $e) { + return false; + } } diff --git a/css/qvitter.css b/css/qvitter.css index 481f634..f05eca6 100644 --- a/css/qvitter.css +++ b/css/qvitter.css @@ -3218,7 +3218,8 @@ ul.stats .avatar-row .avatar { .permalink-link { color: #999999 !important; } -.permalink-link:hover { +.permalink-link:hover, +.longdate a:hover { text-decoration:underline; } diff --git a/js/dom-functions.js b/js/dom-functions.js index 4aab788..d0edece 100644 --- a/js/dom-functions.js +++ b/js/dom-functions.js @@ -1224,8 +1224,6 @@ function expand_queet(q,doScrolling) { if($.inArray(attachment_mimetype, ['video/mp4', 'video/ogg', 'video/quicktime', 'video/webm']) >=0) { if(q.children('.queet').find('.expanded-content').children('.media').children('video').children('source[href="' + attachment_title + '"]').length < 1) { // not if already showed - console.log('video!'); - // local attachment with a thumbnail var attachment_poster = ''; if(typeof this.thumb_url != 'undefined') { @@ -1337,32 +1335,40 @@ function replyFormHtml(streamItem,qid) { var cachedText = encodeURIComponent(data); } + // object with ostatus-uri as key to avoid duplicates var screenNamesToAdd = {}; - // add the screen name to the one we're replying to (if it's not me) - if(!thisIsALinkToMyProfile(q.find('.account-group').attr('href'))) { - var replyToScreenName = q.find('.account-group span.screen-name').html().replace('@',''); - screenNamesToAdd[q.find('.account-group').attr('href')] = replyToScreenName; + // add the screen name to the one we're replying to first (if it's not me) + if(!thisIsALinkToMyProfile(streamItem.attr('data-user-profile-url')) && typeof streamItem.attr('data-user-ostatus-uri') != 'undefined') { + screenNamesToAdd[streamItem.attr('data-user-ostatus-uri')] = streamItem.attr('data-user-screen-name'); } - // add the screen name to the one who the one we're replying to is replying to (if it's not me) - if(q.find('i.addressees > span.reply-to').length > 0 - && !thisIsALinkToMyProfile(q.find('i.addressees > span.reply-to > a').attr('href'))) { - var replyToScreenName = q.find('i.addressees > span.reply-to > a').html().replace('@',''); - if(typeof screenNamesToAdd[q.find('i.addressees > span.reply-to > a').attr('href')] == 'undefined') { - screenNamesToAdd[q.find('i.addressees > span.reply-to > a').attr('href')] = replyToScreenName; - } + // old style notice (probably cached, this can be removed later) + else if (typeof streamItem.attr('data-user-ostatus-uri') == 'undefined') { + screenNamesToAdd[q.find('.account-group').attr('href')] = q.find('.screen-name').text().replace('@',''); } - // get all other mentions (if it's not me) - $.each(q.find('.queet-text').find('.mention'),function(key,obj){ - if(!thisIsALinkToMyProfile($(obj).attr('href'))) { - if(typeof screenNamesToAdd[$(obj).attr('href')] == 'undefined') { - var thisMention = $(obj).html().replace('@',''); - screenNamesToAdd[$(obj).attr('href')] = thisMention; - } + // add the rest of the attentions (not me) + if(q.children('script.attentions-json').length > 0 + && q.children('script.attentions-json').text() != 'undefined') { + try { + var attentionsParsed = JSON.parse(q.children('script.attentions-json').text()); } - }); + catch(e) { + var attentionsParsed = false; + console.log('could not parse attentions json: ' + e); + console.log("attentions-json: " + q.children('script.attentions-json').text()); + } + + if(attentionsParsed !== false) { + $.each(attentionsParsed, function() { + if(!thisIsALinkToMyProfile(this.profileurl) + && typeof screenNamesToAdd[this.ostatus_uri] == 'undefined') { + screenNamesToAdd[this.ostatus_uri] = this.screen_name; + } + }); + } + } // build reply/rant strings var repliesText = ''; @@ -2035,8 +2041,19 @@ function buildQueetHtml(obj, idInStream, extraClasses, requeeted_by, isConversat // reply-to html var reply_to_html = ''; - if(obj.in_reply_to_screen_name !== null && obj.in_reply_to_profileurl !== null && obj.in_reply_to_screen_name != obj.user.screen_name) { - reply_to_html = ''; + var qSource = '' + getHost(obj.external_url) + ''; + } + else { + var qSource = obj.source; } var queetTime = parseTwitterDate(obj.created_at); var queetHtml = '
'; + if(obj.in_reply_to_screen_name !== null + && obj.in_reply_to_profileurl !== null + && obj.in_reply_to_profileurl != obj.user.statusnet_profile_url) { + var replyToProfileurl = obj.in_reply_to_profileurl; + var replyToScreenName = obj.in_reply_to_screen_name; + } + // if we don't have a reply-to, we might have attentions, in that case use the first one as reply + else if(typeof obj.attentions != 'undefined' && typeof obj.attentions[0] != 'undefined') { + var replyToProfileurl = obj.attentions[0].profileurl; + var replyToScreenName = obj.attentions[0].screen_name; + } + if(typeof replyToProfileurl != 'undefined' && typeof replyToScreenName != 'undefined') { + reply_to_html = ' '; } // in-groups html @@ -2092,26 +2109,37 @@ function buildQueetHtml(obj, idInStream, extraClasses, requeeted_by, isConversat statusnetHTML = statusnetHTML.slice(0,-4); } + // external var ostatusHtml = ''; - if(obj.is_local === false) { + if(obj.user.is_local === false) { ostatusHtml = '