]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
First pass at replies support http://laconi.ca/PITS/00080
authormatthew.gregg <matthew.gregg@gmail.com>
Mon, 23 Jun 2008 03:08:37 +0000 (23:08 -0400)
committermatthew.gregg <matthew.gregg@gmail.com>
Mon, 23 Jun 2008 03:08:37 +0000 (23:08 -0400)
Doesn't handle a reply to a user that has never updated.

darcs-hash:20080623030837-982e4-532ccd8899fd8be00575f8840da0defb44cd56f8.gz

actions/newnotice.php
actions/replies.php [new file with mode: 0644]
classes/User.php
db/laconica.sql
lib/stream.php
lib/util.php

index 64fe2494b8f11845675e086d364910e656e8c9a5..9aaf4b4d3bcd7665bf064a097a976cad93c8cf73 100644 (file)
@@ -36,6 +36,12 @@ class NewnoticeAction extends Action {
 
        function save_new_notice() {
 
+                #remember the current notice
+                $current_notice = DB_DataObject::factory('notice');
+                $current_notice->limit(1);
+                $current_notice->orderBy('created DESC');
+                $current_notice->find(1);
+
                $user = common_current_user();
                assert($user); # XXX: maybe an error instead...
                $notice = DB_DataObject::factory('notice');
@@ -67,7 +73,7 @@ class NewnoticeAction extends Action {
                        common_server_error(_t('Problem saving notice.'));
                        return;
                }
-
+               
                common_broadcast_notice($notice);
                $returnto = $this->trimmed('returnto');
                if ($returnto) {
diff --git a/actions/replies.php b/actions/replies.php
new file mode 100644 (file)
index 0000000..14f19cd
--- /dev/null
@@ -0,0 +1,103 @@
+<?php
+/*
+ * Laconica - a distributed open-source microblogging tool
+ * Copyright (C) 2008, Controlez-Vous, 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('LACONICA')) { exit(1); }
+
+require_once(INSTALLDIR.'/actions/showstream.php');
+
+class RepliesAction extends StreamAction {
+
+       function handle($args) {
+
+               parent::handle($args);
+
+               $nickname = common_canonical_nickname($this->arg('nickname'));
+               $user = User::staticGet('nickname', $nickname);
+
+               if (!$user) {
+                       $this->no_such_user();
+                       return;
+               }
+
+               $profile = $user->getProfile();
+
+               if (!$profile) {
+                       common_server_error(_t('User record exists without profile.'));
+                       return;
+               }
+
+               # Looks like we're good; show the header
+
+               common_show_header($profile->nickname . _t(" and friends"),
+                                                  array($this, 'show_header'), $user,
+                                                  array($this, 'show_top'));
+               
+               $this->show_replies($profile);
+               
+               common_show_footer();
+       }
+       
+       function show_header($user) {
+               common_element('link', array('rel' => 'alternate',
+                                                                        'href' => common_local_url('allrss', array('nickname' =>
+                                                                                                                                                          $user->nickname)),
+                                                                        'type' => 'application/rss+xml',
+                                                                        'title' => _t('Feed for friends of ') . $user->nickname));
+       }
+
+       function show_top($user) {
+               $cur = common_current_user();
+               
+               $this->views_menu();
+       }
+       
+       function show_replies($profile) {
+
+               $reply = DB_DataObject::factory('reply');
+
+                $reply->user_id = $profile->id;
+
+               $reply->orderBy('created DESC');
+
+               $page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
+
+               $reply->limit((($page-1)*NOTICES_PER_PAGE), NOTICES_PER_PAGE + 1);
+
+               $cnt = $reply->find();
+
+               if ($cnt > 0) {
+                       common_element_start('ul', array('id' => 'replies'));
+                       for ($i = 0; $i < min($cnt, REPLIES_PER_PAGE); $i++) {
+                               if ($reply->fetch()) {
+                                        $notice = DB_DataObject::factory('notice');
+                                        $notice->id = $reply->notice_id;
+                                        $notice->find(1);
+                                       $this->show_reply($notice, $reply->replied_id);
+                               } else {
+                                       // shouldn't happen!
+                                       break;
+                               }
+                       }
+                       common_element_end('ul');
+               }
+               
+               common_pagination($page > 1, $cnt > REPLIES_PER_PAGE,
+                                                 $page, 'all', array('nickname' => $profile->nickname));
+       }
+}
index 370dad82f797e24b43aa8c5f7f8ba652470ceba3..b22e486f38fe0cdda1c9b2861f532624d35f8f92 100644 (file)
@@ -94,4 +94,18 @@ class User extends DB_DataObject
                $merged = array_merge($blacklist, common_config('nickname', 'blacklist'));
                return !in_array($nickname, $merged);
        }
+
+        function getCurrentNotice() {
+                $notice = DB_DataObject::factory('notice');
+                $profile = $this->getProfile();
+                $notice->profile_id = $profile->id;
+                $notice->limit(1);
+                $notice->orderBy('created DESC');
+                if ($notice->find()) {
+                        $notice->fetch();
+                        return $notice;
+                }
+                return NULL;
+        }
+
 }
index 6db9b6cf6bfc4265038bd05d2f26b09d742482a6..af94e3b61bc76fee05dbb68283c807b430239b2e 100644 (file)
@@ -92,6 +92,19 @@ create table notice (
     index notice_profile_id_idx (profile_id)
 ) ENGINE=InnoDB;
 
+create table reply (
+    id integer auto_increment primary key comment 'unique identifier',
+    notice_id integer comment 'foreign key to notice table',
+    user_id integer comment 'foreign key to user table',
+    replied_id integer comment 'foreign key to notice table',
+    created datetime not null comment 'date this reply was created',
+
+    index notice_id_idx (notice_id),
+    index user_id_idx (user_id),
+    index replied_id_idx (replied_id)
+
+) ENGINE=InnoDB;
+
 /* tables for OAuth */
 
 create table consumer (
index a37e4dfa32f9fa7ce13c6a5cfb3979704010616d..6bba0eace3bca74a623b0dfc574f10109f356dac 100644 (file)
@@ -20,6 +20,7 @@
 if (!defined('LACONICA')) { exit(1); }
 
 define('NOTICES_PER_PAGE', 20);
+define('REPLIES_PER_PAGE', 20);
 
 class StreamAction extends Action {
 
@@ -44,6 +45,11 @@ class StreamAction extends Action {
                                                 _t('Personal'),
                                                 (($user && $user->fullname) ? $user->fullname : $nickname) . _t(' and friends'),
                                                 $action == 'all');
+               common_menu_item(common_local_url('replies', array('nickname' =>
+                                                                                                                         $nickname)),
+                                                _t('Replies'),  
+                                                ($user && $user->fullname) ? $user->fullname : $nickname,
+                                                $action == 'replies');
                common_menu_item(common_local_url('showstream', array('nickname' =>
                                                                                                                          $nickname)),
                                                 _t('Profile'),
@@ -84,4 +90,40 @@ class StreamAction extends Action {
                common_element_end('p');
                common_element_end('li');
        }
+
+       function show_reply($notice, $replied_id) {
+               global $config;
+               $profile = $notice->getProfile();
+               # XXX: RDFa
+               common_element_start('li', array('class' => 'notice_single',
+                                                                                 'id' => 'notice-' . $notice->id));
+               $avatar = $profile->getAvatar(AVATAR_STREAM_SIZE);
+               common_element_start('a', array('href' => $profile->profileurl));
+               common_element('img', array('src' => ($avatar) ? $avatar->url : common_default_avatar(AVATAR_STREAM_SIZE),
+                                                                       'class' => 'avatar stream',
+                                                                       'width' => AVATAR_STREAM_SIZE,
+                                                                       'height' => AVATAR_STREAM_SIZE,
+                                                                       'alt' =>
+                                                                       ($profile->fullname) ? $profile->fullname :
+                                                                       $profile->nickname));
+               common_element_end('a');
+               common_element('a', array('href' => $profile->profileurl,
+                                                                 'class' => 'nickname'),
+                                          $profile->nickname);
+               # FIXME: URL, image, video, audio
+               common_element_start('p', array('class' => 'content'));
+               common_raw(common_render_content($notice->content, $notice));
+               common_element_end('p');
+               $replyurl = common_local_url('shownotice', array('notice' => $replied_id));
+               $noticeurl = common_local_url('shownotice', array('notice' => $notice->id));
+               common_element_start('p', 'time');
+               common_element('a', array('class' => 'notice',
+                                                                 'href' => $noticeurl),
+                                          common_date_string($notice->created));
+               common_element('a', array('class' => 'notice',
+                                                                 'href' => $replyurl),
+                                          " in reply to ".$profile->nickname );
+               common_element_end('p');
+               common_element_end('li');
+       }
 }
index 4b781c0a89af2b632e181354c4530858433fe238..0aa1bd53ec770cb06f456c80f2cdb865302b590c 100644 (file)
@@ -808,6 +808,38 @@ function common_redirect($url, $code=307) {
        common_end_xml();
 }
 
+function common_save_replies($notice) {
+        # extract all @messages
+        preg_match_all('/(?:^|\s)@([a-z0-9]{1,64})/', $notice->content, $match);
+        $current_user = common_current_user();
+        $sender = $current_user->getProfile();
+        #store replied only for first @ (what user/notice what the reply directed, we assume first @ is it)
+        $reply_for = User::staticGet('nickname', $match[1][0]);
+        for ($i=0; $i<count($match[1]); $i++) {
+                $nickname = $match[1][$i];
+                #don't reply to myself
+                if ($sender->nickname == $nickname) {
+                    continue;
+                }
+                $reply = DB_DataObject::factory('reply');
+                $reply->notice_id = $notice->id;
+                $recipient_user = User::staticGet('nickname', $nickname);
+                #if recipient doesn't exist, skip
+                if (!$recipient_user) {
+                      continue;
+                }
+                $reply->user_id = $recipient_user->id;
+                $reply->created = DB_DataObject_Cast::dateTime();
+                $recipient_notice = $reply_for->getCurrentNotice();
+                $reply->replied_id = $recipient_notice->id;
+                $id = $reply->insert();
+                if (!$id) {
+                    common_server_error(_t('Problem saving reply.'));
+                    return;
+                }
+        }
+}
+
 function common_broadcast_notice($notice, $remote=false) {
        if (common_config('queue', 'enabled')) {
                # Do it later!