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
This commit is contained in:
Evan Prodromou 2008-09-16 15:53:46 -04:00
parent d57b39e8a5
commit 7416e50daa
9 changed files with 434 additions and 70 deletions

50
actions/inbox.php Normal file
View File

@ -0,0 +1,50 @@
<?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.'/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();
}
}

50
actions/outbox.php Normal file
View File

@ -0,0 +1,50 @@
<?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.'/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();
}
}

View File

@ -26,4 +26,12 @@ class Message extends DB_DataObject
/* the code above is auto generated do not remove the tag below */ /* the code above is auto generated do not remove the tag below */
###END_AUTOCODE ###END_AUTOCODE
function getFrom() {
return Profile::staticGet('id', $this->from_profile);
}
function getTo() {
return Profile::staticGet('id', $this->to_profile);
}
} }

View File

@ -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+)/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+)/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+)/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] RewriteRule ^(\w+)$ index.php?action=showstream&nickname=$1 [L,QSA]

159
lib/mailbox.php Normal file
View File

@ -0,0 +1,159 @@
<?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.'/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');
}
}

110
lib/personal.php Normal file
View File

@ -0,0 +1,110 @@
<?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); }
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;
}
}

View File

@ -19,54 +19,9 @@
if (!defined('LACONICA')) { exit(1); } if (!defined('LACONICA')) { exit(1); }
class StreamAction extends Action { require_once(INSTALLDIR.'/lib/personal.php');
function is_readonly() { class StreamAction extends PersonalAction {
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');
}
function show_notice($notice) { function show_notice($notice) {
global $config; global $config;
@ -148,27 +103,4 @@ class StreamAction extends Action {
common_element_end('p'); common_element_end('p');
common_element_end('li'); 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;
}
} }

View File

@ -869,6 +869,8 @@ function common_fancy_url($action, $args=NULL) {
case 'subscribers': case 'subscribers':
case 'all': case 'all':
case 'replies': case 'replies':
case 'inbox':
case 'outbox':
if ($args && isset($args['page'])) { if ($args && isset($args['page'])) {
return common_path($args['nickname'].'/'.$action.'?page=' . $args['page']); return common_path($args['nickname'].'/'.$action.'?page=' . $args['page']);
} else { } else {

View File

@ -714,3 +714,54 @@ font-size: 80%;
p.tagcloud a.smallest { p.tagcloud a.smallest {
font-size: 60%; 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;
}