forked from GNUsocial/gnu-social
Merge branch '1.0.x' of git://gitorious.org/statusnet/mainline into 1.0.x
This commit is contained in:
commit
b7178d2197
106
actions/conversationreplies.php
Normal file
106
actions/conversationreplies.php
Normal file
@ -0,0 +1,106 @@
|
||||
<?php
|
||||
/**
|
||||
* Display a conversation in the browser
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Action
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://status.net/
|
||||
*
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2009, StatusNet, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// XXX: not sure how to do paging yet,
|
||||
// so set a 60-notice limit
|
||||
|
||||
require_once INSTALLDIR.'/lib/noticelist.php';
|
||||
|
||||
/**
|
||||
* Conversation tree in the browser
|
||||
*
|
||||
* @category Action
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://status.net/
|
||||
*/
|
||||
class ConversationRepliesAction extends ConversationAction
|
||||
{
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
if ($this->boolean('ajax')) {
|
||||
$this->showAjax();
|
||||
} else {
|
||||
parent::handle($args);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show content.
|
||||
*
|
||||
* Display a hierarchical unordered list in the content area.
|
||||
* Uses ConversationTree to do most of the heavy lifting.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function showContent()
|
||||
{
|
||||
$notices = Notice::conversationStream($this->id, null, null);
|
||||
|
||||
$ct = new FullThreadedNoticeList($notices, $this);
|
||||
|
||||
$cnt = $ct->show();
|
||||
}
|
||||
|
||||
function showAjax()
|
||||
{
|
||||
header('Content-Type: text/xml;charset=utf-8');
|
||||
$this->xw->startDocument('1.0', 'UTF-8');
|
||||
$this->elementStart('html');
|
||||
$this->elementStart('head');
|
||||
$this->element('title', null, _('Notice'));
|
||||
$this->elementEnd('head');
|
||||
$this->elementStart('body');
|
||||
$this->showContent();
|
||||
$this->elementEnd('body');
|
||||
$this->elementEnd('html');
|
||||
}
|
||||
}
|
||||
|
||||
class FullThreadedNoticeList extends ThreadedNoticeList
|
||||
{
|
||||
function newListItem($notice)
|
||||
{
|
||||
return new FullThreadedNoticeListItem($notice, $this->out);
|
||||
}
|
||||
}
|
||||
|
||||
class FullThreadedNoticeListItem extends ThreadedNoticeListItem
|
||||
{
|
||||
function initialItems()
|
||||
{
|
||||
return 1000; // @fixme
|
||||
}
|
||||
}
|
@ -44,6 +44,7 @@ class Fave extends Memcached_DataObject
|
||||
common_log_db_error($fave, 'INSERT', __FILE__);
|
||||
return false;
|
||||
}
|
||||
self::blow('fave:by_notice:%d', $fave->notice_id);
|
||||
|
||||
Event::handle('EndFavorNotice', array($profile, $notice));
|
||||
}
|
||||
@ -61,6 +62,7 @@ class Fave extends Memcached_DataObject
|
||||
if (Event::handle('StartDisfavorNotice', array($profile, $notice, &$result))) {
|
||||
|
||||
$result = parent::delete();
|
||||
self::blow('fave:by_notice:%d', $this->notice_id);
|
||||
|
||||
if ($result) {
|
||||
Event::handle('EndDisfavorNotice', array($profile, $notice));
|
||||
@ -208,4 +210,31 @@ class Fave extends Memcached_DataObject
|
||||
|
||||
return $fav;
|
||||
}
|
||||
|
||||
/**
|
||||
* Grab a list of profile who have favored this notice.
|
||||
*
|
||||
* @return ArrayWrapper masquerading as a Fave
|
||||
*/
|
||||
static function byNotice($noticeId)
|
||||
{
|
||||
$c = self::memcache();
|
||||
$key = Cache::key('fave:by_notice:' . $noticeId);
|
||||
|
||||
$wrapper = $c->get($key);
|
||||
if (!$wrapper) {
|
||||
// @fixme caching & scalability!
|
||||
$fave = new Fave();
|
||||
$fave->notice_id = $noticeId;
|
||||
$fave->find();
|
||||
|
||||
$list = array();
|
||||
while ($fave->fetch()) {
|
||||
$list[] = clone($fave);
|
||||
}
|
||||
$wrapper = new ArrayWrapper($list);
|
||||
$c->set($key, $wrapper);
|
||||
}
|
||||
return $wrapper;
|
||||
}
|
||||
}
|
||||
|
@ -496,6 +496,13 @@ class Notice extends Memcached_DataObject
|
||||
if ($this->isPublic()) {
|
||||
self::blow('public;last');
|
||||
}
|
||||
|
||||
self::blow('fave:by_notice', $this->id);
|
||||
|
||||
if ($this->conversation) {
|
||||
// In case we're the first, will need to calc a new root.
|
||||
self::blow('notice:conversation_root:%d', $this->conversation);
|
||||
}
|
||||
}
|
||||
|
||||
/** save all urls in the notice to the db
|
||||
@ -774,6 +781,35 @@ class Notice extends Memcached_DataObject
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Grab the earliest notice from this conversation.
|
||||
*
|
||||
* @return Notice or null
|
||||
*/
|
||||
function conversationRoot()
|
||||
{
|
||||
if (!empty($this->conversation)) {
|
||||
$c = self::memcache();
|
||||
|
||||
$key = Cache::key('notice:conversation_root:' . $this->conversation);
|
||||
$notice = $c->get($key);
|
||||
if ($notice) {
|
||||
return $notice;
|
||||
}
|
||||
|
||||
$notice = new Notice();
|
||||
$notice->conversation = $this->conversation;
|
||||
$notice->orderBy('CREATED');
|
||||
$notice->limit(1);
|
||||
$notice->find(true);
|
||||
|
||||
if ($notice->N) {
|
||||
$c->set($key, $notice);
|
||||
return $notice;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* Pull up a full list of local recipients who will be getting
|
||||
* this notice in their inbox. Results will be cached, so don't
|
||||
|
34
js/util.js
34
js/util.js
@ -412,16 +412,20 @@ var SN = { // StatusNet
|
||||
var replyItem = form.closest('li.notice-reply');
|
||||
|
||||
if (replyItem.length > 0) {
|
||||
// If this is an inline reply, insert it in place.
|
||||
// If this is an inline reply, remove the form...
|
||||
var list = form.closest('.threaded-replies');
|
||||
var placeholder = list.find('.notice-reply-placeholder');
|
||||
replyItem.remove();
|
||||
|
||||
var id = $(notice).attr('id');
|
||||
if ($("#"+id).length == 0) {
|
||||
var parentNotice = replyItem.closest('li.notice');
|
||||
replyItem.replaceWith(notice);
|
||||
SN.U.NoticeInlineReplyPlaceholder(parentNotice);
|
||||
$(notice).insertBefore(placeholder);
|
||||
} else {
|
||||
// Realtime came through before us...
|
||||
replyItem.remove();
|
||||
}
|
||||
|
||||
// ...and show the placeholder form.
|
||||
placeholder.show();
|
||||
} else if (notices.length > 0 && SN.U.belongsOnTimeline(notice)) {
|
||||
// Not a reply. If on our timeline, show it at the top!
|
||||
|
||||
@ -604,8 +608,8 @@ var SN = { // StatusNet
|
||||
// Update the existing form...
|
||||
nextStep();
|
||||
} else {
|
||||
// Remove placeholder if any
|
||||
list.find('li.notice-reply-placeholder').remove();
|
||||
// Hide the placeholder...
|
||||
var placeholder = list.find('li.notice-reply-placeholder').hide();
|
||||
|
||||
// Create the reply form entry at the end
|
||||
var replyItem = $('li.notice-reply', list);
|
||||
@ -615,7 +619,7 @@ var SN = { // StatusNet
|
||||
var intermediateStep = function(formMaster) {
|
||||
var formEl = document._importNode(formMaster, true);
|
||||
replyItem.append(formEl);
|
||||
list.append(replyItem);
|
||||
list.append(replyItem); // *after* the placeholder
|
||||
|
||||
var form = replyForm = $(formEl);
|
||||
SN.Init.NoticeFormSetup(form);
|
||||
@ -662,6 +666,18 @@ var SN = { // StatusNet
|
||||
SN.U.NoticeInlineReplyTrigger(notice);
|
||||
return false;
|
||||
});
|
||||
$('li.notice-reply-comments a')
|
||||
.live('click', function() {
|
||||
var url = $(this).attr('href');
|
||||
var area = $(this).closest('.threaded-replies');
|
||||
$.get(url, {ajax: 1}, function(data, textStatus, xhr) {
|
||||
var replies = $('.threaded-replies', data);
|
||||
if (replies.length) {
|
||||
area.replaceWith(document._importNode(replies[0], true));
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
@ -1360,7 +1376,7 @@ var SN = { // StatusNet
|
||||
if (cur == '' || cur == textarea.data('initialText')) {
|
||||
var parentNotice = replyItem.closest('li.notice');
|
||||
replyItem.remove();
|
||||
SN.U.NoticeInlineReplyPlaceholder(parentNotice);
|
||||
parentNotice.find('li.notice-reply-placeholder').show();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
2
js/util.min.js
vendored
2
js/util.min.js
vendored
File diff suppressed because one or more lines are too long
@ -100,10 +100,12 @@ class Action extends HTMLOutputter // lawsuit
|
||||
{
|
||||
if (Event::handle('StartShowHTML', array($this))) {
|
||||
$this->startHTML();
|
||||
$this->flush();
|
||||
Event::handle('EndShowHTML', array($this));
|
||||
}
|
||||
if (Event::handle('StartShowHead', array($this))) {
|
||||
$this->showHead();
|
||||
$this->flush();
|
||||
Event::handle('EndShowHead', array($this));
|
||||
}
|
||||
if (Event::handle('StartShowBody', array($this))) {
|
||||
@ -471,11 +473,14 @@ class Action extends HTMLOutputter // lawsuit
|
||||
$this->elementStart('div', array('id' => 'wrap'));
|
||||
if (Event::handle('StartShowHeader', array($this))) {
|
||||
$this->showHeader();
|
||||
$this->flush();
|
||||
Event::handle('EndShowHeader', array($this));
|
||||
}
|
||||
$this->showCore();
|
||||
$this->flush();
|
||||
if (Event::handle('StartShowFooter', array($this))) {
|
||||
$this->showFooter();
|
||||
$this->flush();
|
||||
Event::handle('EndShowFooter', array($this));
|
||||
}
|
||||
$this->elementEnd('div');
|
||||
@ -695,14 +700,17 @@ class Action extends HTMLOutputter // lawsuit
|
||||
$this->elementStart('div', array('id' => 'site_nav_local_views_wrapper'));
|
||||
if (Event::handle('StartShowLocalNavBlock', array($this))) {
|
||||
$this->showLocalNavBlock();
|
||||
$this->flush();
|
||||
Event::handle('EndShowLocalNavBlock', array($this));
|
||||
}
|
||||
if (Event::handle('StartShowContentBlock', array($this))) {
|
||||
$this->showContentBlock();
|
||||
$this->flush();
|
||||
Event::handle('EndShowContentBlock', array($this));
|
||||
}
|
||||
if (Event::handle('StartShowAside', array($this))) {
|
||||
$this->showAside();
|
||||
$this->flush();
|
||||
Event::handle('EndShowAside', array($this));
|
||||
}
|
||||
$this->elementEnd('div');
|
||||
|
@ -333,6 +333,9 @@ class Router
|
||||
$m->connect('conversation/:id',
|
||||
array('action' => 'conversation'),
|
||||
array('id' => '[0-9]+'));
|
||||
$m->connect('conversation/:id/replies',
|
||||
array('action' => 'conversationreplies'),
|
||||
array('id' => '[0-9]+'));
|
||||
|
||||
$m->connect('message/new', array('action' => 'newmessage'));
|
||||
$m->connect('message/new?to=:to', array('action' => 'newmessage'), array('to' => Nickname::DISPLAY_FMT));
|
||||
|
@ -75,7 +75,15 @@ class ThreadedNoticeList extends NoticeList
|
||||
break;
|
||||
}
|
||||
|
||||
$convo = $this->notice->conversation;
|
||||
// Collapse repeats into their originals...
|
||||
$notice = $this->notice;
|
||||
if ($notice->repeat_of) {
|
||||
$orig = Notice::staticGet('id', $notice->repeat_of);
|
||||
if ($orig) {
|
||||
$notice = $orig;
|
||||
}
|
||||
}
|
||||
$convo = $notice->conversation;
|
||||
if (!empty($conversations[$convo])) {
|
||||
// Seen this convo already -- skip!
|
||||
continue;
|
||||
@ -83,14 +91,10 @@ class ThreadedNoticeList extends NoticeList
|
||||
$conversations[$convo] = true;
|
||||
|
||||
// Get the convo's root notice
|
||||
// @fixme stream goes in wrong direction, this needs sane caching
|
||||
//$notice = Notice::conversationStream($convo, 0, 1);
|
||||
//$notice->fetch();
|
||||
$notice = new Notice();
|
||||
$notice->conversation = $this->notice->conversation;
|
||||
$notice->orderBy('CREATED');
|
||||
$notice->limit(1);
|
||||
$notice->find(true);
|
||||
$root = $notice->conversationRoot();
|
||||
if ($root) {
|
||||
$notice = $root;
|
||||
}
|
||||
|
||||
try {
|
||||
$item = $this->newListItem($notice);
|
||||
@ -145,7 +149,10 @@ class ThreadedNoticeList extends NoticeList
|
||||
|
||||
class ThreadedNoticeListItem extends NoticeListItem
|
||||
{
|
||||
const INITIAL_ITEMS = 3;
|
||||
function initialItems()
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
function showContext()
|
||||
{
|
||||
@ -162,8 +169,9 @@ class ThreadedNoticeListItem extends NoticeListItem
|
||||
|
||||
function showEnd()
|
||||
{
|
||||
$max = $this->initialItems();
|
||||
if (!$this->repeat) {
|
||||
$notice = Notice::conversationStream($this->notice->conversation, 0, self::INITIAL_ITEMS + 2);
|
||||
$notice = Notice::conversationStream($this->notice->conversation, 0, $max + 2);
|
||||
$notices = array();
|
||||
$cnt = 0;
|
||||
$moreCutoff = null;
|
||||
@ -173,7 +181,7 @@ class ThreadedNoticeListItem extends NoticeListItem
|
||||
continue;
|
||||
}
|
||||
$cnt++;
|
||||
if ($cnt > self::INITIAL_ITEMS) {
|
||||
if ($cnt > $max) {
|
||||
// boo-yah
|
||||
$moreCutoff = clone($notice);
|
||||
break;
|
||||
@ -181,8 +189,15 @@ class ThreadedNoticeListItem extends NoticeListItem
|
||||
$notices[] = clone($notice); // *grumble* inefficient as hell
|
||||
}
|
||||
|
||||
if ($notices) {
|
||||
$this->out->elementStart('ul', 'notices threaded-replies xoxo');
|
||||
|
||||
$item = new ThreadedNoticeListFavesItem($this->notice, $this->out);
|
||||
$hasFaves = $item->show();
|
||||
|
||||
$item = new ThreadedNoticeListRepeatsItem($this->notice, $this->out);
|
||||
$hasRepeats = $item->show();
|
||||
|
||||
if ($notices) {
|
||||
if ($moreCutoff) {
|
||||
$item = new ThreadedNoticeListMoreItem($moreCutoff, $this->out);
|
||||
$item->show();
|
||||
@ -191,14 +206,16 @@ class ThreadedNoticeListItem extends NoticeListItem
|
||||
$item = new ThreadedNoticeListSubItem($notice, $this->out);
|
||||
$item->show();
|
||||
}
|
||||
}
|
||||
if ($notices || $hasFaves || $hasRepeats) {
|
||||
// @fixme do a proper can-post check that's consistent
|
||||
// with the JS side
|
||||
if (common_current_user()) {
|
||||
$item = new ThreadedNoticeListReplyItem($notice, $this->out);
|
||||
$item = new ThreadedNoticeListReplyItem($this->notice, $this->out);
|
||||
$item->show();
|
||||
}
|
||||
$this->out->elementEnd('ul');
|
||||
}
|
||||
$this->out->elementEnd('ul');
|
||||
}
|
||||
|
||||
parent::showEnd();
|
||||
@ -227,6 +244,13 @@ class ThreadedNoticeListSubItem extends NoticeListItem
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
function showEnd()
|
||||
{
|
||||
$item = new ThreadedNoticeListInlineFavesItem($this->notice, $this->out);
|
||||
$hasFaves = $item->show();
|
||||
parent::showEnd();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -265,7 +289,7 @@ class ThreadedNoticeListMoreItem extends NoticeListItem
|
||||
function showMiniForm()
|
||||
{
|
||||
$id = $this->notice->conversation;
|
||||
$url = common_local_url('conversation', array('id' => $id)) . '#notice-' . $this->notice->id;
|
||||
$url = common_local_url('conversationreplies', array('id' => $id));
|
||||
|
||||
$notice = new Notice();
|
||||
$notice->conversation = $id;
|
||||
@ -317,3 +341,154 @@ class ThreadedNoticeListReplyItem extends NoticeListItem
|
||||
'value' => _('Write a reply...')));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Placeholder for showing faves...
|
||||
*/
|
||||
abstract class NoticeListActorsItem extends NoticeListItem
|
||||
{
|
||||
/**
|
||||
* @return array of profile IDs
|
||||
*/
|
||||
abstract function getProfiles();
|
||||
|
||||
abstract function getListMessage($count, $you);
|
||||
|
||||
function show()
|
||||
{
|
||||
$links = array();
|
||||
$you = false;
|
||||
$cur = common_current_user();
|
||||
foreach ($this->getProfiles() as $id) {
|
||||
if ($cur && $cur->id == $id) {
|
||||
$you = true;
|
||||
array_unshift($links, _m('FAVELIST', 'You'));
|
||||
} else {
|
||||
$profile = Profile::staticGet('id', $id);
|
||||
if ($profile) {
|
||||
$links[] = sprintf('<a href="%s" title="%s">%s</a>',
|
||||
htmlspecialchars($profile->profileurl),
|
||||
htmlspecialchars($profile->getBestName()),
|
||||
htmlspecialchars($profile->nickname));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($links) {
|
||||
$count = count($links);
|
||||
$msg = $this->getListMessage($count, $you);
|
||||
$out = sprintf($msg, $this->magicList($links));
|
||||
|
||||
$this->showStart();
|
||||
$this->out->raw($out);
|
||||
$this->showEnd();
|
||||
return $count;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
function magicList($items)
|
||||
{
|
||||
if (count($items) == 0) {
|
||||
return '';
|
||||
} else if (count($items) == 1) {
|
||||
return $items[0];
|
||||
} else {
|
||||
$first = array_slice($items, 0, -1);
|
||||
$last = array_slice($items, -1, 1);
|
||||
// TRANS For building a list such as "You, bob, mary and 5 others have favored this notice".
|
||||
return sprintf(_m('FAVELIST', '%1$s and %2$s'), implode(', ', $first), implode(', ', $last));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Placeholder for showing faves...
|
||||
*/
|
||||
class ThreadedNoticeListFavesItem extends NoticeListActorsItem
|
||||
{
|
||||
function getProfiles()
|
||||
{
|
||||
$fave = Fave::byNotice($this->notice->id);
|
||||
$profiles = array();
|
||||
while ($fave->fetch()) {
|
||||
$profiles[] = $fave->user_id;
|
||||
}
|
||||
return $profiles;
|
||||
}
|
||||
|
||||
function getListMessage($count, $you)
|
||||
{
|
||||
if ($count == 1 && $you) {
|
||||
// darn first person being different from third person!
|
||||
return _m('FAVELIST', 'You have favored this notice.');
|
||||
} else {
|
||||
// if 'you' is the first item,
|
||||
return _m('FAVELIST', '%1$s has favored this notice.', '%1$s have favored this notice.', $count);
|
||||
}
|
||||
}
|
||||
|
||||
function showStart()
|
||||
{
|
||||
$this->out->elementStart('li', array('class' => 'notice-data notice-faves'));
|
||||
}
|
||||
|
||||
function showEnd()
|
||||
{
|
||||
$this->out->elementEnd('li');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ThreadedNoticeListInlineFavesItem extends ThreadedNoticeListFavesItem
|
||||
{
|
||||
function showStart()
|
||||
{
|
||||
$this->out->elementStart('div', array('class' => 'entry-content notice-faves'));
|
||||
}
|
||||
|
||||
function showEnd()
|
||||
{
|
||||
$this->out->elementEnd('div');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Placeholder for showing faves...
|
||||
*/
|
||||
class ThreadedNoticeListRepeatsItem extends NoticeListActorsItem
|
||||
{
|
||||
function getProfiles()
|
||||
{
|
||||
$rep = $this->notice->repeatStream();
|
||||
|
||||
$profiles = array();
|
||||
while ($rep->fetch()) {
|
||||
$profiles[] = $rep->profile_id;
|
||||
}
|
||||
return $profiles;
|
||||
}
|
||||
|
||||
function getListMessage($count, $you)
|
||||
{
|
||||
if ($count == 1 && $you) {
|
||||
// darn first person being different from third person!
|
||||
return _m('REPEATLIST', 'You have repeated this notice.');
|
||||
} else {
|
||||
// if 'you' is the first item,
|
||||
return _m('REPEATLIST', '%1$s has repeated this notice.', '%1$s have repeated this notice.', $count);
|
||||
}
|
||||
}
|
||||
|
||||
function showStart()
|
||||
{
|
||||
$this->out->elementStart('li', array('class' => 'notice-data notice-repeats'));
|
||||
}
|
||||
|
||||
function showEnd()
|
||||
{
|
||||
$this->out->elementEnd('li');
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -242,4 +242,15 @@ class XMLOutputter
|
||||
{
|
||||
$this->xw->writeComment($txt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush output buffers
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function flush()
|
||||
{
|
||||
$this->xw->flush();
|
||||
}
|
||||
}
|
||||
|
@ -2995,9 +2995,38 @@ X-OIM-Sequence-Num: 1
|
||||
|
||||
// no ticket found!
|
||||
if (count($matches) == 0) {
|
||||
$this->debug_message('*** Could not get passport ticket!');
|
||||
// Since 2011/2/15, the return value will be Compact2, not PPToken2
|
||||
|
||||
// we need ticket and secret code
|
||||
// RST1: messengerclear.live.com
|
||||
// <wsse:BinarySecurityToken Id="Compact1">t=tick&p=</wsse:BinarySecurityToken>
|
||||
// <wst:BinarySecret>binary secret</wst:BinarySecret>
|
||||
// RST2: messenger.msn.com
|
||||
// <wsse:BinarySecurityToken Id="PPToken2">t=tick</wsse:BinarySecurityToken>
|
||||
// RST3: contacts.msn.com
|
||||
// <wsse:BinarySecurityToken Id="Compact3">t=tick&p=</wsse:BinarySecurityToken>
|
||||
// RST4: messengersecure.live.com
|
||||
// <wsse:BinarySecurityToken Id="Compact4">t=tick&p=</wsse:BinarySecurityToken>
|
||||
// RST5: spaces.live.com
|
||||
// <wsse:BinarySecurityToken Id="Compact5">t=tick&p=</wsse:BinarySecurityToken>
|
||||
// RST6: storage.msn.com
|
||||
// <wsse:BinarySecurityToken Id="Compact6">t=tick&p=</wsse:BinarySecurityToken>
|
||||
preg_match("#".
|
||||
"<wsse\:BinarySecurityToken Id=\"Compact1\">(.*)</wsse\:BinarySecurityToken>(.*)".
|
||||
"<wst\:BinarySecret>(.*)</wst\:BinarySecret>(.*)".
|
||||
"<wsse\:BinarySecurityToken Id=\"Compact2\">(.*)</wsse\:BinarySecurityToken>(.*)".
|
||||
"<wsse\:BinarySecurityToken Id=\"Compact3\">(.*)</wsse\:BinarySecurityToken>(.*)".
|
||||
"<wsse\:BinarySecurityToken Id=\"Compact4\">(.*)</wsse\:BinarySecurityToken>(.*)".
|
||||
"<wsse\:BinarySecurityToken Id=\"Compact5\">(.*)</wsse\:BinarySecurityToken>(.*)".
|
||||
"<wsse\:BinarySecurityToken Id=\"Compact6\">(.*)</wsse\:BinarySecurityToken>(.*)".
|
||||
"#",
|
||||
$data, $matches);
|
||||
// no ticket found!
|
||||
if (count($matches) == 0) {
|
||||
$this->debug_message("*** Can't get passport ticket!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//$this->debug_message(var_export($matches, true));
|
||||
// matches[0]: all data
|
||||
|
@ -267,7 +267,7 @@ class PollPlugin extends MicroAppPlugin
|
||||
{
|
||||
$object = new ActivityObject();
|
||||
$object->id = $notice->uri;
|
||||
$object->type = self::POLL_OBJECT;
|
||||
$object->type = self::POLL_RESPONSE_OBJECT;
|
||||
$object->title = $notice->content;
|
||||
$object->summary = $notice->content;
|
||||
$object->link = $notice->bestUrl();
|
||||
@ -290,7 +290,7 @@ class PollPlugin extends MicroAppPlugin
|
||||
{
|
||||
$object = new ActivityObject();
|
||||
$object->id = $notice->uri;
|
||||
$object->type = self::POLL_RESPONSE_OBJECT;
|
||||
$object->type = self::POLL_OBJECT;
|
||||
$object->title = $notice->content;
|
||||
$object->summary = $notice->content;
|
||||
$object->link = $notice->bestUrl();
|
||||
|
@ -155,6 +155,10 @@ RealtimeUpdate = {
|
||||
}
|
||||
|
||||
RealtimeUpdate.makeNoticeItem(data, function(noticeItem) {
|
||||
// Check again in case it got shown while we were waiting for data...
|
||||
if (RealtimeUpdate.isNoticeVisible(data.id)) {
|
||||
return;
|
||||
}
|
||||
var noticeItemID = $(noticeItem).attr('id');
|
||||
|
||||
var list = $("#notices_primary .notices:first")
|
||||
@ -177,6 +181,7 @@ RealtimeUpdate = {
|
||||
if (list.length == 0) {
|
||||
list = $('<ul class="notices threaded-replies xoxo"></ul>');
|
||||
parent.append(list);
|
||||
SN.U.NoticeInlineReplyPlaceholder(parent);
|
||||
}
|
||||
prepend = false;
|
||||
}
|
||||
@ -191,7 +196,6 @@ RealtimeUpdate = {
|
||||
newNotice.insertBefore(placeholder)
|
||||
} else {
|
||||
newNotice.appendTo(list);
|
||||
SN.U.NoticeInlineReplyPlaceholder(parent);
|
||||
}
|
||||
}
|
||||
newNotice.css({display:"none"}).fadeIn(1000);
|
||||
|
2
plugins/Realtime/realtimeupdate.min.js
vendored
2
plugins/Realtime/realtimeupdate.min.js
vendored
File diff suppressed because one or more lines are too long
@ -577,7 +577,8 @@ div.entry-content a.response:after {
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
#content .notice .threaded-replies .notice {
|
||||
#content .notice .threaded-replies .notice,
|
||||
#content .notice .threaded-replies .notice-data {
|
||||
width: 440px;
|
||||
min-height: 1px;
|
||||
padding-bottom: 14px;
|
||||
|
Loading…
Reference in New Issue
Block a user