Merge branch '1.0.x' of git://gitorious.org/statusnet/mainline into 1.0.x

This commit is contained in:
Siebrand Mazeland 2011-03-18 16:09:27 +01:00
commit b7178d2197
14 changed files with 452 additions and 34 deletions

View 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
}
}

View File

@ -44,6 +44,7 @@ class Fave extends Memcached_DataObject
common_log_db_error($fave, 'INSERT', __FILE__); common_log_db_error($fave, 'INSERT', __FILE__);
return false; return false;
} }
self::blow('fave:by_notice:%d', $fave->notice_id);
Event::handle('EndFavorNotice', array($profile, $notice)); Event::handle('EndFavorNotice', array($profile, $notice));
} }
@ -61,6 +62,7 @@ class Fave extends Memcached_DataObject
if (Event::handle('StartDisfavorNotice', array($profile, $notice, &$result))) { if (Event::handle('StartDisfavorNotice', array($profile, $notice, &$result))) {
$result = parent::delete(); $result = parent::delete();
self::blow('fave:by_notice:%d', $this->notice_id);
if ($result) { if ($result) {
Event::handle('EndDisfavorNotice', array($profile, $notice)); Event::handle('EndDisfavorNotice', array($profile, $notice));
@ -208,4 +210,31 @@ class Fave extends Memcached_DataObject
return $fav; 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;
}
} }

View File

@ -496,6 +496,13 @@ class Notice extends Memcached_DataObject
if ($this->isPublic()) { if ($this->isPublic()) {
self::blow('public;last'); 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 /** save all urls in the notice to the db
@ -774,6 +781,35 @@ class Notice extends Memcached_DataObject
return false; 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 * Pull up a full list of local recipients who will be getting
* this notice in their inbox. Results will be cached, so don't * this notice in their inbox. Results will be cached, so don't

View File

@ -412,16 +412,20 @@ var SN = { // StatusNet
var replyItem = form.closest('li.notice-reply'); var replyItem = form.closest('li.notice-reply');
if (replyItem.length > 0) { 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'); var id = $(notice).attr('id');
if ($("#"+id).length == 0) { if ($("#"+id).length == 0) {
var parentNotice = replyItem.closest('li.notice'); $(notice).insertBefore(placeholder);
replyItem.replaceWith(notice);
SN.U.NoticeInlineReplyPlaceholder(parentNotice);
} else { } else {
// Realtime came through before us... // Realtime came through before us...
replyItem.remove();
} }
// ...and show the placeholder form.
placeholder.show();
} else if (notices.length > 0 && SN.U.belongsOnTimeline(notice)) { } else if (notices.length > 0 && SN.U.belongsOnTimeline(notice)) {
// Not a reply. If on our timeline, show it at the top! // Not a reply. If on our timeline, show it at the top!
@ -604,8 +608,8 @@ var SN = { // StatusNet
// Update the existing form... // Update the existing form...
nextStep(); nextStep();
} else { } else {
// Remove placeholder if any // Hide the placeholder...
list.find('li.notice-reply-placeholder').remove(); var placeholder = list.find('li.notice-reply-placeholder').hide();
// Create the reply form entry at the end // Create the reply form entry at the end
var replyItem = $('li.notice-reply', list); var replyItem = $('li.notice-reply', list);
@ -615,7 +619,7 @@ var SN = { // StatusNet
var intermediateStep = function(formMaster) { var intermediateStep = function(formMaster) {
var formEl = document._importNode(formMaster, true); var formEl = document._importNode(formMaster, true);
replyItem.append(formEl); replyItem.append(formEl);
list.append(replyItem); list.append(replyItem); // *after* the placeholder
var form = replyForm = $(formEl); var form = replyForm = $(formEl);
SN.Init.NoticeFormSetup(form); SN.Init.NoticeFormSetup(form);
@ -662,6 +666,18 @@ var SN = { // StatusNet
SN.U.NoticeInlineReplyTrigger(notice); SN.U.NoticeInlineReplyTrigger(notice);
return false; 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')) { if (cur == '' || cur == textarea.data('initialText')) {
var parentNotice = replyItem.closest('li.notice'); var parentNotice = replyItem.closest('li.notice');
replyItem.remove(); replyItem.remove();
SN.U.NoticeInlineReplyPlaceholder(parentNotice); parentNotice.find('li.notice-reply-placeholder').show();
} }
} }
}); });

2
js/util.min.js vendored

File diff suppressed because one or more lines are too long

View File

@ -100,10 +100,12 @@ class Action extends HTMLOutputter // lawsuit
{ {
if (Event::handle('StartShowHTML', array($this))) { if (Event::handle('StartShowHTML', array($this))) {
$this->startHTML(); $this->startHTML();
$this->flush();
Event::handle('EndShowHTML', array($this)); Event::handle('EndShowHTML', array($this));
} }
if (Event::handle('StartShowHead', array($this))) { if (Event::handle('StartShowHead', array($this))) {
$this->showHead(); $this->showHead();
$this->flush();
Event::handle('EndShowHead', array($this)); Event::handle('EndShowHead', array($this));
} }
if (Event::handle('StartShowBody', array($this))) { if (Event::handle('StartShowBody', array($this))) {
@ -471,11 +473,14 @@ class Action extends HTMLOutputter // lawsuit
$this->elementStart('div', array('id' => 'wrap')); $this->elementStart('div', array('id' => 'wrap'));
if (Event::handle('StartShowHeader', array($this))) { if (Event::handle('StartShowHeader', array($this))) {
$this->showHeader(); $this->showHeader();
$this->flush();
Event::handle('EndShowHeader', array($this)); Event::handle('EndShowHeader', array($this));
} }
$this->showCore(); $this->showCore();
$this->flush();
if (Event::handle('StartShowFooter', array($this))) { if (Event::handle('StartShowFooter', array($this))) {
$this->showFooter(); $this->showFooter();
$this->flush();
Event::handle('EndShowFooter', array($this)); Event::handle('EndShowFooter', array($this));
} }
$this->elementEnd('div'); $this->elementEnd('div');
@ -695,14 +700,17 @@ class Action extends HTMLOutputter // lawsuit
$this->elementStart('div', array('id' => 'site_nav_local_views_wrapper')); $this->elementStart('div', array('id' => 'site_nav_local_views_wrapper'));
if (Event::handle('StartShowLocalNavBlock', array($this))) { if (Event::handle('StartShowLocalNavBlock', array($this))) {
$this->showLocalNavBlock(); $this->showLocalNavBlock();
$this->flush();
Event::handle('EndShowLocalNavBlock', array($this)); Event::handle('EndShowLocalNavBlock', array($this));
} }
if (Event::handle('StartShowContentBlock', array($this))) { if (Event::handle('StartShowContentBlock', array($this))) {
$this->showContentBlock(); $this->showContentBlock();
$this->flush();
Event::handle('EndShowContentBlock', array($this)); Event::handle('EndShowContentBlock', array($this));
} }
if (Event::handle('StartShowAside', array($this))) { if (Event::handle('StartShowAside', array($this))) {
$this->showAside(); $this->showAside();
$this->flush();
Event::handle('EndShowAside', array($this)); Event::handle('EndShowAside', array($this));
} }
$this->elementEnd('div'); $this->elementEnd('div');

View File

@ -333,6 +333,9 @@ class Router
$m->connect('conversation/:id', $m->connect('conversation/:id',
array('action' => 'conversation'), array('action' => 'conversation'),
array('id' => '[0-9]+')); 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', array('action' => 'newmessage'));
$m->connect('message/new?to=:to', array('action' => 'newmessage'), array('to' => Nickname::DISPLAY_FMT)); $m->connect('message/new?to=:to', array('action' => 'newmessage'), array('to' => Nickname::DISPLAY_FMT));

View File

@ -75,7 +75,15 @@ class ThreadedNoticeList extends NoticeList
break; 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])) { if (!empty($conversations[$convo])) {
// Seen this convo already -- skip! // Seen this convo already -- skip!
continue; continue;
@ -83,14 +91,10 @@ class ThreadedNoticeList extends NoticeList
$conversations[$convo] = true; $conversations[$convo] = true;
// Get the convo's root notice // Get the convo's root notice
// @fixme stream goes in wrong direction, this needs sane caching $root = $notice->conversationRoot();
//$notice = Notice::conversationStream($convo, 0, 1); if ($root) {
//$notice->fetch(); $notice = $root;
$notice = new Notice(); }
$notice->conversation = $this->notice->conversation;
$notice->orderBy('CREATED');
$notice->limit(1);
$notice->find(true);
try { try {
$item = $this->newListItem($notice); $item = $this->newListItem($notice);
@ -145,7 +149,10 @@ class ThreadedNoticeList extends NoticeList
class ThreadedNoticeListItem extends NoticeListItem class ThreadedNoticeListItem extends NoticeListItem
{ {
const INITIAL_ITEMS = 3; function initialItems()
{
return 3;
}
function showContext() function showContext()
{ {
@ -162,8 +169,9 @@ class ThreadedNoticeListItem extends NoticeListItem
function showEnd() function showEnd()
{ {
$max = $this->initialItems();
if (!$this->repeat) { 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(); $notices = array();
$cnt = 0; $cnt = 0;
$moreCutoff = null; $moreCutoff = null;
@ -173,7 +181,7 @@ class ThreadedNoticeListItem extends NoticeListItem
continue; continue;
} }
$cnt++; $cnt++;
if ($cnt > self::INITIAL_ITEMS) { if ($cnt > $max) {
// boo-yah // boo-yah
$moreCutoff = clone($notice); $moreCutoff = clone($notice);
break; break;
@ -181,8 +189,15 @@ class ThreadedNoticeListItem extends NoticeListItem
$notices[] = clone($notice); // *grumble* inefficient as hell $notices[] = clone($notice); // *grumble* inefficient as hell
} }
$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 ($notices) {
$this->out->elementStart('ul', 'notices threaded-replies xoxo');
if ($moreCutoff) { if ($moreCutoff) {
$item = new ThreadedNoticeListMoreItem($moreCutoff, $this->out); $item = new ThreadedNoticeListMoreItem($moreCutoff, $this->out);
$item->show(); $item->show();
@ -191,14 +206,16 @@ class ThreadedNoticeListItem extends NoticeListItem
$item = new ThreadedNoticeListSubItem($notice, $this->out); $item = new ThreadedNoticeListSubItem($notice, $this->out);
$item->show(); $item->show();
} }
}
if ($notices || $hasFaves || $hasRepeats) {
// @fixme do a proper can-post check that's consistent // @fixme do a proper can-post check that's consistent
// with the JS side // with the JS side
if (common_current_user()) { if (common_current_user()) {
$item = new ThreadedNoticeListReplyItem($notice, $this->out); $item = new ThreadedNoticeListReplyItem($this->notice, $this->out);
$item->show(); $item->show();
} }
$this->out->elementEnd('ul');
} }
$this->out->elementEnd('ul');
} }
parent::showEnd(); 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() function showMiniForm()
{ {
$id = $this->notice->conversation; $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 = new Notice();
$notice->conversation = $id; $notice->conversation = $id;
@ -316,4 +340,155 @@ class ThreadedNoticeListReplyItem extends NoticeListItem
$this->out->element('input', array('class' => 'placeholder', $this->out->element('input', array('class' => 'placeholder',
'value' => _('Write a reply...'))); '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');
}
}

View File

@ -242,4 +242,15 @@ class XMLOutputter
{ {
$this->xw->writeComment($txt); $this->xw->writeComment($txt);
} }
/**
* Flush output buffers
*
* @return void
*/
function flush()
{
$this->xw->flush();
}
} }

View File

@ -2995,8 +2995,37 @@ X-OIM-Sequence-Num: 1
// no ticket found! // no ticket found!
if (count($matches) == 0) { if (count($matches) == 0) {
$this->debug_message('*** Could not get passport ticket!'); // Since 2011/2/15, the return value will be Compact2, not PPToken2
return false;
// 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)); //$this->debug_message(var_export($matches, true));

View File

@ -267,7 +267,7 @@ class PollPlugin extends MicroAppPlugin
{ {
$object = new ActivityObject(); $object = new ActivityObject();
$object->id = $notice->uri; $object->id = $notice->uri;
$object->type = self::POLL_OBJECT; $object->type = self::POLL_RESPONSE_OBJECT;
$object->title = $notice->content; $object->title = $notice->content;
$object->summary = $notice->content; $object->summary = $notice->content;
$object->link = $notice->bestUrl(); $object->link = $notice->bestUrl();
@ -290,7 +290,7 @@ class PollPlugin extends MicroAppPlugin
{ {
$object = new ActivityObject(); $object = new ActivityObject();
$object->id = $notice->uri; $object->id = $notice->uri;
$object->type = self::POLL_RESPONSE_OBJECT; $object->type = self::POLL_OBJECT;
$object->title = $notice->content; $object->title = $notice->content;
$object->summary = $notice->content; $object->summary = $notice->content;
$object->link = $notice->bestUrl(); $object->link = $notice->bestUrl();

View File

@ -155,6 +155,10 @@ RealtimeUpdate = {
} }
RealtimeUpdate.makeNoticeItem(data, function(noticeItem) { 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 noticeItemID = $(noticeItem).attr('id');
var list = $("#notices_primary .notices:first") var list = $("#notices_primary .notices:first")
@ -177,6 +181,7 @@ RealtimeUpdate = {
if (list.length == 0) { if (list.length == 0) {
list = $('<ul class="notices threaded-replies xoxo"></ul>'); list = $('<ul class="notices threaded-replies xoxo"></ul>');
parent.append(list); parent.append(list);
SN.U.NoticeInlineReplyPlaceholder(parent);
} }
prepend = false; prepend = false;
} }
@ -191,7 +196,6 @@ RealtimeUpdate = {
newNotice.insertBefore(placeholder) newNotice.insertBefore(placeholder)
} else { } else {
newNotice.appendTo(list); newNotice.appendTo(list);
SN.U.NoticeInlineReplyPlaceholder(parent);
} }
} }
newNotice.css({display:"none"}).fadeIn(1000); newNotice.css({display:"none"}).fadeIn(1000);

File diff suppressed because one or more lines are too long

View File

@ -577,7 +577,8 @@ div.entry-content a.response:after {
font-size: 1em; font-size: 1em;
} }
#content .notice .threaded-replies .notice { #content .notice .threaded-replies .notice,
#content .notice .threaded-replies .notice-data {
width: 440px; width: 440px;
min-height: 1px; min-height: 1px;
padding-bottom: 14px; padding-bottom: 14px;