diff --git a/actions/all.php b/actions/all.php index dc08592faf..12397b4b18 100644 --- a/actions/all.php +++ b/actions/all.php @@ -163,7 +163,7 @@ class AllAction extends ProfileAction function showContent() { if (Event::handle('StartShowAllContent', array($this))) { - $nl = new NoticeList($this->notice, $this); + $nl = new ThreadedNoticeList($this->notice, $this); $cnt = $nl->show(); diff --git a/actions/public.php b/actions/public.php index 5fc547feaf..727c76d528 100644 --- a/actions/public.php +++ b/actions/public.php @@ -212,7 +212,7 @@ class PublicAction extends Action function showContent() { - $nl = new NoticeList($this->notice, $this); + $nl = new ThreadedNoticeList($this->notice, $this); $cnt = $nl->show(); diff --git a/lib/threadednoticelist.php b/lib/threadednoticelist.php new file mode 100644 index 0000000000..1af778721d --- /dev/null +++ b/lib/threadednoticelist.php @@ -0,0 +1,175 @@ +. + * + * @category UI + * @package StatusNet + * @author Brion Vibber + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://status.net/ + */ + +if (!defined('STATUSNET') && !defined('LACONICA')) { + exit(1); +} + +/** + * widget for displaying a list of notices + * + * There are a number of actions that display a list of notices, in + * reverse chronological order. This widget abstracts out most of the + * code for UI for notice lists. It's overridden to hide some + * data for e.g. the profile page. + * + * @category UI + * @package StatusNet + * @author Evan Prodromou + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://status.net/ + * @see Notice + * @see NoticeListItem + * @see ProfileNoticeList + */ + +class ThreadedNoticeList extends NoticeList +{ + /** + * show the list of notices + * + * "Uses up" the stream by looping through it. So, probably can't + * be called twice on the same list. + * + * @return int count of notices listed. + */ + + function show() + { + $this->out->elementStart('div', array('id' =>'notices_primary')); + $this->out->element('h2', null, _('Notices')); + $this->out->elementStart('ol', array('class' => 'notices xoxo')); + + $cnt = 0; + $conversations = array(); + while ($this->notice->fetch() && $cnt <= NOTICES_PER_PAGE) { + $convo = $this->notice->conversation; + if (!empty($conversations[$convo])) { + // Seen this convo already -- skip! + continue; + } + $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); + + $cnt++; + + if ($cnt > NOTICES_PER_PAGE) { + break; + } + + try { + $item = $this->newListItem($notice); + $item->show(); + } catch (Exception $e) { + // we log exceptions and continue + common_log(LOG_ERR, $e->getMessage()); + continue; + } + } + + $this->out->elementEnd('ol'); + $this->out->elementEnd('div'); + + return $cnt; + } + + /** + * returns a new list item for the current notice + * + * Recipe (factory?) method; overridden by sub-classes to give + * a different list item class. + * + * @param Notice $notice the current notice + * + * @return NoticeListItem a list item for displaying the notice + */ + + function newListItem($notice) + { + return new ThreadedNoticeListItem($notice, $this->out); + } +} + +/** + * widget for displaying a single notice + * + * This widget has the core smarts for showing a single notice: what to display, + * where, and under which circumstances. Its key method is show(); this is a recipe + * that calls all the other show*() methods to build up a single notice. The + * ProfileNoticeListItem subclass, for example, overrides showAuthor() to skip + * author info (since that's implicit by the data in the page). + * + * @category UI + * @package StatusNet + * @author Evan Prodromou + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://status.net/ + * @see NoticeList + * @see ProfileNoticeListItem + */ + +class ThreadedNoticeListItem extends NoticeListItem +{ + /** + * finish the notice + * + * Close the last elements in the notice list item + * + * @return void + */ + + function showEnd() + { + $notice = Notice::conversationStream($this->notice->conversation); + + $this->out->elementStart('ul', 'notices threaded-notices xoxo'); + while ($notice->fetch()) { + if ($notice->id == $this->notice->id) { + // Skip! + continue; + } + $this->out->elementStart('li'); + $item = new NoticeListItem($notice, $this->out); + $item->show(); + $this->out->elementEnd('li'); + } + $this->out->elementEnd('ul'); + + parent::showEnd(); + } +}