From 7416e50daa6f792f73e47141fa7ac3bfc843b1e0 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Tue, 16 Sep 2008 15:53:46 -0400 Subject: [PATCH] inbox and outbox for direct messages Added an inbox and outbox for direct messages. Factored common code to mailbox.php. Factored common code with stream.php to personal.php. darcs-hash:20080916195346-84dde-b5c846f713a970c41fd1b0671cb333e91f3cb920.gz --- actions/inbox.php | 50 ++++++++++++ actions/outbox.php | 50 ++++++++++++ classes/Message.php | 8 ++ htaccess.sample | 2 + lib/mailbox.php | 159 +++++++++++++++++++++++++++++++++++++++ lib/personal.php | 110 +++++++++++++++++++++++++++ lib/stream.php | 72 +----------------- lib/util.php | 2 + theme/stoica/display.css | 51 +++++++++++++ 9 files changed, 434 insertions(+), 70 deletions(-) create mode 100644 actions/inbox.php create mode 100644 actions/outbox.php create mode 100644 lib/mailbox.php create mode 100644 lib/personal.php diff --git a/actions/inbox.php b/actions/inbox.php new file mode 100644 index 0000000000..73155efd7a --- /dev/null +++ b/actions/inbox.php @@ -0,0 +1,50 @@ +. + */ + +if (!defined('LACONICA')) { exit(1); } + +require_once(INSTALLDIR.'/lib/mailbox.php'); + +class InboxAction extends MailboxAction { + + function get_title($user, $page) { + if ($page > 1) { + $title = sprintf(_("Inbox for %s - page %d"), $user->nickname, $page); + } else { + $title = sprintf(_("Inbox for %s"), $user->nickname); + } + } + + function get_messages($user, $page) { + $message = new Message(); + $message->to_profile = $user->id; + $message->orderBy('created DESC, id DESC'); + $message->limit((($page-1)*MESSAGES_PER_PAGE), MESSAGES_PER_PAGE + 1); + + if ($message->find()) { + return $message; + } else { + return NULL; + } + } + + function get_message_profile($message) { + return $message->getFrom(); + } +} diff --git a/actions/outbox.php b/actions/outbox.php new file mode 100644 index 0000000000..b09cd20327 --- /dev/null +++ b/actions/outbox.php @@ -0,0 +1,50 @@ +. + */ + +if (!defined('LACONICA')) { exit(1); } + +require_once(INSTALLDIR.'/lib/mailbox.php'); + +class OutboxAction extends MailboxAction { + + function get_title($user, $page) { + if ($page > 1) { + $title = sprintf(_("Outbox for %s - page %d"), $user->nickname, $page); + } else { + $title = sprintf(_("Outbox for %s"), $user->nickname); + } + } + + function get_messages($user, $page) { + $message = new Message(); + $message->from_profile = $user->id; + $message->orderBy('created DESC, id DESC'); + $message->limit((($page-1)*MESSAGES_PER_PAGE), MESSAGES_PER_PAGE + 1); + + if ($message->find()) { + return $message; + } else { + return NULL; + } + } + + function get_message_profile($message) { + return $message->getTo(); + } +} diff --git a/classes/Message.php b/classes/Message.php index 3f01e3c832..93ec419d49 100644 --- a/classes/Message.php +++ b/classes/Message.php @@ -26,4 +26,12 @@ class Message extends DB_DataObject /* the code above is auto generated do not remove the tag below */ ###END_AUTOCODE + + function getFrom() { + return Profile::staticGet('id', $this->from_profile); + } + + function getTo() { + return Profile::staticGet('id', $this->to_profile); + } } diff --git a/htaccess.sample b/htaccess.sample index 30f1bb5318..364c35b079 100644 --- a/htaccess.sample +++ b/htaccess.sample @@ -71,6 +71,8 @@ RewriteRule ^(\w+)/replies$ index.php?action=replies&nickname=$1 [L,QSA] RewriteRule ^(\w+)/replies/rss$ index.php?action=repliesrss&nickname=$1 [L,QSA] RewriteRule ^(\w+)/avatar/(original|96|48|24)$ index.php?action=avatarbynickname&nickname=$1&size=$2 [L,QSA] RewriteRule ^(\w+)/favorites$ index.php?action=showfavorites&nickname=$1 [L,QSA] +RewriteRule ^(\w+)/inbox$ index.php?action=inbox&nickname=$1 [L,QSA] +RewriteRule ^(\w+)/outbox$ index.php?action=outbox&nickname=$1 [L,QSA] RewriteRule ^(\w+)$ index.php?action=showstream&nickname=$1 [L,QSA] diff --git a/lib/mailbox.php b/lib/mailbox.php new file mode 100644 index 0000000000..5ad63cbaa1 --- /dev/null +++ b/lib/mailbox.php @@ -0,0 +1,159 @@ +. + */ + +if (!defined('LACONICA')) { exit(1); } + +require_once(INSTALLDIR.'/lib/personal.php'); + +define('MESSAGES_PER_PAGE', 20); + +class MailboxAction extends PersonalAction { + + function handle($args) { + + parent::handle($args); + + $nickname = common_canonical_nickname($this->arg('nickname')); + $user = User::staticGet('nickname', $nickname); + + if (!$user) { + $this->client_error(_('No such user.'), 404); + return; + } + + $cur = common_current_user(); + + if (!$cur || $cur->id != $user->id) { + $this->client_error(_('Only the user can read their own mailboxes.'), 403); + return; + } + + $profile = $user->getProfile(); + + if (!$profile) { + $this->server_error(_('User has no profile.')); + return; + } + + $page = $this->trimmed('page'); + + if (!$page) { + $page = 1; + } + + $this->show_page($user, $page); + } + + function get_title($user, $page) { + return ''; + } + + function show_page($user, $page) { + + common_show_header($this->get_title(), + NULL, $user, + array($this, 'show_top')); + + $this->show_box($user, $page); + + common_show_footer(); + } + + function show_box($user, $page) { + + $message = $this->get_messages($user, $page); + + if ($message) { + + $cnt = 0; + common_element_start('ul', array('id' => 'messages')); + + while ($message->fetch() && $cnt <= MESSAGES_PER_PAGE) { + $cnt++; + + if ($cnt > MESSAGES_PER_PAGE) { + break; + } + + $this->show_message($message); + } + + common_element_end('ul'); + + common_pagination($page > 1, $cnt > MESSAGES_PER_PAGE, + $page, $this->trimmed('action'), + array('nickname' => $user->nickname)); + + $message->free(); + unset($message); + } + } + + # returns the profile we want to show with the message + + function get_message_profile($message) { + return NULL; + } + + function show_message($message) { + + common_element_start('li', array('class' => 'message_single', + 'id' => 'message-' . $message->id)); + + $profile = $this->get_message_profile($message); + + $avatar = $profile->getAvatar(AVATAR_STREAM_SIZE); + common_element_start('a', array('href' => $profile->profileurl)); + common_element('img', array('src' => ($avatar) ? common_avatar_display_url($avatar) : 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($message->rendered); + common_element_end('p'); + + $messageurl = common_local_url('showmessage', array('message' => $message->id)); + + # XXX: we need to figure this out better. Is this right? + if (strcmp($message->uri, $messageurl) != 0 && preg_match('/^http/', $message->uri)) { + $messageurl = $message->uri; + } + common_element_start('p', 'time'); + common_element('a', array('class' => 'permalink', + 'href' => $messageurl, + 'title' => common_exact_date($message->created)), + common_date_string($message->created)); + if ($message->source) { + common_text(_(' from ')); + $this->source_link($message->source); + } + + common_element_end('p'); + + common_element_end('li'); + } +} diff --git a/lib/personal.php b/lib/personal.php new file mode 100644 index 0000000000..248b4cc6bb --- /dev/null +++ b/lib/personal.php @@ -0,0 +1,110 @@ +. + */ + +if (!defined('LACONICA')) { exit(1); } + +class PersonalAction extends Action { + + function is_readonly() { + return true; + } + + function handle($args) { + parent::handle($args); + common_set_returnto($this->self_url()); + } + + function views_menu() { + + $user = NULL; + $action = $this->trimmed('action'); + $nickname = $this->trimmed('nickname'); + + if ($nickname) { + $user = User::staticGet('nickname', $nickname); + $user_profile = $user->getProfile(); + } else { + $user_profile = false; + } + + common_element_start('ul', array('id' => 'nav_views')); + + common_menu_item(common_local_url('all', array('nickname' => + $nickname)), + _('Personal'), + sprintf(_('%s and friends'), (($user_profile && $user_profile->fullname) ? $user_profile->fullname : $nickname)), + $action == 'all'); + common_menu_item(common_local_url('replies', array('nickname' => + $nickname)), + _('Replies'), + sprintf(_('Replies to %s'), (($user_profile && $user_profile->fullname) ? $user_profile->fullname : $nickname)), + $action == 'replies'); + common_menu_item(common_local_url('showstream', array('nickname' => + $nickname)), + _('Profile'), + ($user_profile && $user_profile->fullname) ? $user_profile->fullname : $nickname, + $action == 'showstream'); + common_menu_item(common_local_url('showfavorites', array('nickname' => + $nickname)), + _('Favorites'), + sprintf(_('%s\'s favorite notices'), ($user_profile) ? $user_profile->getBestName() : _('User')), + $action == 'showfavorites'); + + $cur = common_current_user(); + + if ($cur && $cur->id == $user->id) { + + common_menu_item(common_local_url('inbox', array('nickname' => + $nickname)), + _('Inbox'), + _('Your incoming messages'), + $action == 'inbox'); + common_menu_item(common_local_url('outbox', array('nickname' => + $nickname)), + _('Outbox'), + _('Your sent messages'), + $action == 'outbox'); + } + + common_element_end('ul'); + } + + function source_link($source) { + $source_name = _($source); + switch ($source) { + case 'web': + case 'xmpp': + case 'mail': + case 'omb': + case 'api': + common_element('span', 'noticesource', $source_name); + break; + default: + $ns = Notice_source::staticGet($source); + if ($ns) { + common_element('a', array('href' => $ns->url), + $ns->name); + } else { + common_element('span', 'noticesource', $source_name); + } + break; + } + return; + } +} \ No newline at end of file diff --git a/lib/stream.php b/lib/stream.php index f41c125ca0..8a2c1e9b08 100644 --- a/lib/stream.php +++ b/lib/stream.php @@ -19,54 +19,9 @@ if (!defined('LACONICA')) { exit(1); } -class StreamAction extends Action { +require_once(INSTALLDIR.'/lib/personal.php'); - function is_readonly() { - return true; - } - - function handle($args) { - parent::handle($args); - common_set_returnto($this->self_url()); - } - - function views_menu() { - - $user = NULL; - $action = $this->trimmed('action'); - $nickname = $this->trimmed('nickname'); - - if ($nickname) { - $user = User::staticGet('nickname', $nickname); - $user_profile = $user->getProfile(); - } else { - $user_profile = false; - } - - common_element_start('ul', array('id' => 'nav_views')); - - common_menu_item(common_local_url('all', array('nickname' => - $nickname)), - _('Personal'), - sprintf(_('%s and friends'), (($user_profile && $user_profile->fullname) ? $user_profile->fullname : $nickname)), - $action == 'all'); - common_menu_item(common_local_url('replies', array('nickname' => - $nickname)), - _('Replies'), - sprintf(_('Replies to %s'), (($user_profile && $user_profile->fullname) ? $user_profile->fullname : $nickname)), - $action == 'replies'); - common_menu_item(common_local_url('showstream', array('nickname' => - $nickname)), - _('Profile'), - ($user_profile && $user_profile->fullname) ? $user_profile->fullname : $nickname, - $action == 'showstream'); - common_menu_item(common_local_url('showfavorites', array('nickname' => - $nickname)), - _('Favorites'), - sprintf(_('%s\'s favorite notices'), ($user_profile) ? $user_profile->getBestName() : _('User')), - $action == 'showfavorites'); - common_element_end('ul'); - } +class StreamAction extends PersonalAction { function show_notice($notice) { global $config; @@ -148,27 +103,4 @@ class StreamAction extends Action { common_element_end('p'); common_element_end('li'); } - - function source_link($source) { - $source_name = _($source); - switch ($source) { - case 'web': - case 'xmpp': - case 'mail': - case 'omb': - case 'api': - common_element('span', 'noticesource', $source_name); - break; - default: - $ns = Notice_source::staticGet($source); - if ($ns) { - common_element('a', array('href' => $ns->url), - $ns->name); - } else { - common_element('span', 'noticesource', $source_name); - } - break; - } - return; - } } diff --git a/lib/util.php b/lib/util.php index 55fb124f8a..f0aabfa29d 100644 --- a/lib/util.php +++ b/lib/util.php @@ -869,6 +869,8 @@ function common_fancy_url($action, $args=NULL) { case 'subscribers': case 'all': case 'replies': + case 'inbox': + case 'outbox': if ($args && isset($args['page'])) { return common_path($args['nickname'].'/'.$action.'?page=' . $args['page']); } else { diff --git a/theme/stoica/display.css b/theme/stoica/display.css index a6de393bf3..c35ee56a5e 100644 --- a/theme/stoica/display.css +++ b/theme/stoica/display.css @@ -714,3 +714,54 @@ font-size: 80%; p.tagcloud a.smallest { font-size: 60%; } + +/* ----- Mailbox ----- */ + +#messages { + clear: both; + margin: 0 auto; + padding: 0; + list-style-type: none; + width: 540px; + border-top: 1px solid #D8E2D7; + } + +#messages a:hover { + text-decoration: underline; + } + +.message_single { + clear: both; + display: block; + margin: 0; + padding: 5px 5px 5px 0; + min-height: 48px; + font-family: Georgia, "Times New Roman", Times, serif; + font-size: 13px; + line-height: 16px; + border-bottom: 1px solid #D8E2D7; + } +.message_single:hover { + background-color: #F3F8EA; + } +.message_single p { + display: inline; + margin: 0; + padding: 0; + } + +.avatar.stream { + float: left; + margin: 0 10px 0 0; + } + +p.time { + display: block; + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 10px; + line-height: 15px; + } + +p.time a { + color: #91AA9D; + }