Merge remote-tracking branch 'gitorious/1.0.x' into 1.0.x

This commit is contained in:
Evan Prodromou 2011-04-15 17:55:43 -04:00
commit 0925b96840
32 changed files with 270 additions and 188 deletions

View File

@ -189,7 +189,7 @@ class ApiListsAction extends ApiBareAuthAction
// there is no argument named count // there is no argument named count
$count = 20; $count = 20;
$profile = $this->user->getProfile(); $profile = $this->user->getProfile();
$fn = array($profile, 'getOwnedTags'); $fn = array($profile, 'getLists');
list($this->lists, list($this->lists,
$this->next_cursor, $this->next_cursor,

View File

@ -47,12 +47,12 @@ class EditpeopletagAction extends OwnerDesignAction
function title() function title()
{ {
if ($_SERVER['REQUEST_METHOD'] == 'POST' && $this->boolean('delete')) { if ($_SERVER['REQUEST_METHOD'] == 'POST' && $this->boolean('delete')) {
// TRANS: Title for edit people tag page after deleting a tag. // TRANS: Title for edit list page after deleting a tag.
// TRANS: %s is a tag. // TRANS: %s is a list.
return sprintf(_('Delete %s list'), $this->peopletag->tag); return sprintf(_('Delete %s list'), $this->peopletag->tag);
} }
// TRANS: Title for edit people tag page. // TRANS: Title for edit list page.
// TRANS: %s is a tag. // TRANS: %s is a list.
return sprintf(_('Edit list %s'), $this->peopletag->tag); return sprintf(_('Edit list %s'), $this->peopletag->tag);
} }
@ -105,7 +105,7 @@ class EditpeopletagAction extends OwnerDesignAction
} }
if (!$this->peopletag) { if (!$this->peopletag) {
// TRANS: Client error displayed when referring to a non-exsting people tag. // TRANS: Client error displayed when referring to a non-exsting list.
$this->clientError(_('No such list.'), 404); $this->clientError(_('No such list.'), 404);
return false; return false;
} }
@ -215,7 +215,7 @@ class EditpeopletagAction extends OwnerDesignAction
$this->element('p', 'instructions', $this->confirm); $this->element('p', 'instructions', $this->confirm);
} else { } else {
$this->element('p', 'instructions', $this->element('p', 'instructions',
// TRANS: Form instruction for edit people tag form. // TRANS: Form instruction for edit list form.
_('Use this form to edit the list.')); _('Use this form to edit the list.'));
} }
} }
@ -293,7 +293,7 @@ class EditpeopletagAction extends OwnerDesignAction
if (!$result) { if (!$result) {
common_log_db_error($this->group, 'UPDATE', __FILE__); common_log_db_error($this->group, 'UPDATE', __FILE__);
// TRANS: TRANS: Server error displayed when updating a people tag fails. // TRANS: TRANS: Server error displayed when updating a list fails.
$this->serverError(_('Could not update list.')); $this->serverError(_('Could not update list.'));
} }

View File

@ -70,7 +70,7 @@ class PeopletagautocompleteAction extends Action
} }
$profile = $this->user->getProfile(); $profile = $this->user->getProfile();
$tags = $profile->getOwnedTags(common_current_user()); $tags = $profile->getLists(common_current_user());
$this->tags = array(); $this->tags = array();
while ($tags->fetch()) { while ($tags->fetch()) {
@ -88,7 +88,7 @@ class PeopletagautocompleteAction extends Action
$this->tags[] = $arr; $this->tags[] = $arr;
} }
$tags->free(); $tags = NULL;
return true; return true;
} }

View File

@ -92,7 +92,7 @@ class PeopletaggedAction extends OwnerDesignAction
$this->peopletag = Profile_list::pkeyGet(array('tagger' => $user->id, 'tag' => $tag)); $this->peopletag = Profile_list::pkeyGet(array('tagger' => $user->id, 'tag' => $tag));
if (!$this->peopletag) { if (!$this->peopletag) {
// TRANS: Client error displayed when referring to non-existing people tag. // TRANS: Client error displayed when referring to a non-existing list.
$this->clientError(_('No such list.'), 404); $this->clientError(_('No such list.'), 404);
return false; return false;
} }
@ -103,13 +103,13 @@ class PeopletaggedAction extends OwnerDesignAction
function title() function title()
{ {
if ($this->page == 1) { if ($this->page == 1) {
// TRANS: Title for list of people tagged by the user with a tag. // TRANS: Title for list of people listed by the user.
// TRANS: %1$s is a tag, %2$s is a username. // TRANS: %1$s is a list, %2$s is a username.
return sprintf(_('People listed in %1$s by %2$s'), return sprintf(_('People listed in %1$s by %2$s'),
$this->peopletag->tag, $this->tagger->nickname); $this->peopletag->tag, $this->tagger->nickname);
} else { } else {
// TRANS: Title for list of people tagged by the user with a tag. // TRANS: Title for list of people listed by the user.
// TRANS: %1$s is a tag, %2$s is a username, %2$s is a page number. // TRANS: %1$s is a list, %2$s is a username, %2$s is a page number.
return sprintf(_('People listed in %1$s by %2$s, page %3$d'), return sprintf(_('People listed in %1$s by %2$s, page %3$d'),
$this->peopletag->tag, $this->user->nickname, $this->peopletag->tag, $this->user->nickname,
$this->page); $this->page);

View File

@ -114,7 +114,7 @@ class PeopletagsbyuserAction extends OwnerDesignAction
$user = common_current_user(); $user = common_current_user();
if ($this->arg('public')) { if ($this->arg('public')) {
$this->tags = $this->tagger->getOwnedTags(false, $offset, $limit); $this->tags = $this->tagger->getLists(false, $offset, $limit);
} else if ($this->arg('private')) { } else if ($this->arg('private')) {
if (empty($user)) { if (empty($user)) {
// TRANS: Error message displayed when trying to perform an action that requires a logged in user. // TRANS: Error message displayed when trying to perform an action that requires a logged in user.
@ -128,7 +128,7 @@ class PeopletagsbyuserAction extends OwnerDesignAction
$this->clientError(_('You cannot view others\' private lists'), 403); $this->clientError(_('You cannot view others\' private lists'), 403);
} }
} else { } else {
$this->tags = $this->tagger->getOwnedTags(common_current_user(), $offset, $limit); $this->tags = $this->tagger->getLists(common_current_user(), $offset, $limit);
} }
return true; return true;
} }

View File

@ -102,7 +102,7 @@ class PeopletagsforuserAction extends OwnerDesignAction
function showAnonymousMessage() function showAnonymousMessage()
{ {
$notice = $notice =
// TRANS: Message displayed for anonymous users on page that displays people tags for a user. // TRANS: Message displayed for anonymous users on page that displays lists for a user.
// TRANS: This message contains Markdown links in the form [description](links). // TRANS: This message contains Markdown links in the form [description](links).
// TRANS: %s is a tagger nickname. // TRANS: %s is a tagger nickname.
sprintf(_('These are lists for **%s**. ' . sprintf(_('These are lists for **%s**. ' .
@ -138,7 +138,7 @@ class PeopletagsforuserAction extends OwnerDesignAction
function showEmptyListMessage() function showEmptyListMessage()
{ {
// TRANS: Message displayed on page that displays people tags for a user when there are none. // TRANS: Message displayed on page that displays lists for a user when there are none.
// TRANS: This message contains Markdown links in the form [description](links). // TRANS: This message contains Markdown links in the form [description](links).
// TRANS: %s is a tagger nickname. // TRANS: %s is a tagger nickname.
$message = sprintf(_('%s has not been [listed](%%%%doc.lists%%%%) by anyone yet.'), $this->tagged->nickname); $message = sprintf(_('%s has not been [listed](%%%%doc.lists%%%%) by anyone yet.'), $this->tagged->nickname);

View File

@ -46,11 +46,11 @@ class PeopletagsubscriptionsAction extends OwnerDesignAction
function title() function title()
{ {
if ($this->page == 1) { if ($this->page == 1) {
// TRANS: Title for page that displays people tags subscribed to by a user. // TRANS: Title for page that displays lists subscribed to by a user.
// TRANS: %s is a profile nickname. // TRANS: %s is a profile nickname.
return sprintf(_('Lists subscribed to by %s'), $this->profile->nickname); return sprintf(_('Lists subscribed to by %s'), $this->profile->nickname);
} else { } else {
// TRANS: Title for page that displays people tags subscribed to by a user. // TRANS: Title for page that displays lists subscribed to by a user.
// TRANS: %1$s is a profile nickname, %2$d is a page number. // TRANS: %1$s is a profile nickname, %2$d is a page number.
return sprintf(_('Lists subscribed to by %1$s, page %2$d'), $this->profile->nickname, $this->page); return sprintf(_('Lists subscribed to by %1$s, page %2$d'), $this->profile->nickname, $this->page);
} }
@ -104,7 +104,7 @@ class PeopletagsubscriptionsAction extends OwnerDesignAction
function showAnonymousMessage() function showAnonymousMessage()
{ {
$notice = $notice =
// TRANS: Message displayed for anonymous users on page that displays people tags subscribed to by a user. // TRANS: Message displayed for anonymous users on page that displays lists subscribed to by a user.
// TRANS: This message contains Markdown links in the form [description](links). // TRANS: This message contains Markdown links in the form [description](links).
// TRANS: %s is a profile nickname. // TRANS: %s is a profile nickname.
sprintf(_('These are lists subscribed to by **%s**. ' . sprintf(_('These are lists subscribed to by **%s**. ' .

View File

@ -606,7 +606,6 @@ class RegisterAction extends Action
function showSuccessContent() function showSuccessContent()
{ {
if (Event::handle('onStartRegisterSuccess', array($this))) { if (Event::handle('onStartRegisterSuccess', array($this))) {
$nickname = $this->arg('nickname'); $nickname = $this->arg('nickname');
$profileurl = common_local_url('showstream', $profileurl = common_local_url('showstream',

View File

@ -120,7 +120,7 @@ class ShowprofiletagAction extends Action
{ {
if ($this->page > 1) { if ($this->page > 1) {
if($this->peopletag->private) { if($this->peopletag->private) {
// TRANS: Title for private people tag timeline. // TRANS: Title for private list timeline.
// TRANS: %1$s is a people tag, %2$s is a page number. // TRANS: %1$s is a people tag, %2$s is a page number.
return sprintf(_('Private timeline for %1$s list by you, page %2$d'), return sprintf(_('Private timeline for %1$s list by you, page %2$d'),
$this->peopletag->tag, $this->page); $this->peopletag->tag, $this->page);
@ -128,13 +128,13 @@ class ShowprofiletagAction extends Action
$current = common_current_user(); $current = common_current_user();
if (!empty($current) && $current->id == $this->peopletag->tagger) { if (!empty($current) && $current->id == $this->peopletag->tagger) {
// TRANS: Title for public people tag timeline where the viewer is the tagger. // TRANS: Title for public list timeline where the viewer is the tagger.
// TRANS: %1$s is a people tag, %2$s is a page number. // TRANS: %1$s is a people tag, %2$s is a page number.
return sprintf(_('Timeline for %1$s list by you, page %2$d'), return sprintf(_('Timeline for %1$s list by you, page %2$d'),
$this->peopletag->tag, $this->page); $this->peopletag->tag, $this->page);
} }
// TRANS: Title for private people tag timeline. // TRANS: Title for private list timeline.
// TRANS: %1$s is a people tag, %2$s is the tagger's nickname, %3$d is a page number. // TRANS: %1$s is a people tag, %2$s is the tagger's nickname, %3$d is a page number.
return sprintf(_('Timeline for %1$s list by %2$s, page %3$d'), return sprintf(_('Timeline for %1$s list by %2$s, page %3$d'),
$this->peopletag->tag, $this->peopletag->tag,
@ -143,22 +143,22 @@ class ShowprofiletagAction extends Action
); );
} else { } else {
if($this->peopletag->private) { if($this->peopletag->private) {
// TRANS: Title for private people tag timeline. // TRANS: Title for private list timeline.
// TRANS: %s is a people tag. // TRANS: %s is a list.
return sprintf(_('Private timeline of %s list by you'), return sprintf(_('Private timeline of %s list by you'),
$this->peopletag->tag); $this->peopletag->tag);
} }
$current = common_current_user(); $current = common_current_user();
if (!empty($current) && $current->id == $this->peopletag->tagger) { if (!empty($current) && $current->id == $this->peopletag->tagger) {
// TRANS: Title for public people tag timeline where the viewer is the tagger. // TRANS: Title for public list timeline where the viewer is the tagger.
// TRANS: %s is a people tag. // TRANS: %s is a list.
return sprintf(_('Timeline for %s list by you'), return sprintf(_('Timeline for %s list by you'),
$this->peopletag->tag); $this->peopletag->tag);
} }
// TRANS: Title for private people tag timeline. // TRANS: Title for private list timeline.
// TRANS: %1$s is a people tag, %2$s is the tagger's nickname. // TRANS: %1$s is a list, %2$s is the tagger's nickname.
return sprintf(_('Timeline for %1$s list by %2$s'), return sprintf(_('Timeline for %1$s list by %2$s'),
$this->peopletag->tag, $this->peopletag->tag,
$this->tagger->nickname $this->tagger->nickname
@ -189,7 +189,7 @@ class ShowprofiletagAction extends Action
) )
), ),
// TRANS: Feed title. // TRANS: Feed title.
// TRANS: %1$s is a people tag, %2$s is tagger's nickname. // TRANS: %1$s is a list, %2$s is tagger's nickname.
sprintf(_('Feed for %1$s list by %2$s (Atom)'), sprintf(_('Feed for %1$s list by %2$s (Atom)'),
$this->peopletag->tag, $this->tagger->nickname $this->peopletag->tag, $this->tagger->nickname
) )
@ -205,8 +205,8 @@ class ShowprofiletagAction extends Action
function showEmptyListMessage() function showEmptyListMessage()
{ {
// TRANS: Empty list message for people tag timeline. // TRANS: Empty list message for list timeline.
// TRANS: %1$s is a people tag, %2$s is a tagger's nickname. // TRANS: %1$s is a list, %2$s is a tagger's nickname.
$message = sprintf(_('This is the timeline for %1$s list by %2$s but no one has posted anything yet.'), $message = sprintf(_('This is the timeline for %1$s list by %2$s but no one has posted anything yet.'),
$this->peopletag->tag, $this->peopletag->tag,
$this->tagger->nickname) . ' '; $this->tagger->nickname) . ' ';
@ -287,20 +287,8 @@ class ShowprofiletagAction extends Action
if (Event::handle('StartShowTaggedProfilesMiniList', array($this))) { if (Event::handle('StartShowTaggedProfilesMiniList', array($this))) {
$title = ''; $title = '';
$current = common_current_user(); // TRANS: Header on show list page.
if(!empty($current) && $this->peopletag->tagger == $current->id) { $this->element('h2', null, _('Listed'));
// TRANS: Header on show profile tag page.
// TRANS: %s is a people tag.
$title = sprintf(_('Listed'), $this->peopletag->tag);
} else {
// TRANS: Header on show profile tag page.
// TRANS: %1$s is a people tag, %2$s is a tagger's nickname.
$title = sprintf(_('Listed'),
$this->peopletag->tag,
$this->tagger->nickname);
}
$this->element('h2', null, $title);
$cnt = 0; $cnt = 0;
@ -308,7 +296,7 @@ class ShowprofiletagAction extends Action
$pml = new ProfileMiniList($profile, $this); $pml = new ProfileMiniList($profile, $this);
$cnt = $pml->show(); $cnt = $pml->show();
if ($cnt == 0) { if ($cnt == 0) {
// TRANS: Content of "People tagged x by a user" if there are no tagged users. // TRANS: Content of "Listed" page if there are no listed users.
$this->element('p', null, _('(None)')); $this->element('p', null, _('(None)'));
} }
} }

View File

@ -227,8 +227,8 @@ class SubscriptionsListItem extends SubscriptionListItem
} }
$this->out->element('input', $attrs); $this->out->element('input', $attrs);
// TRANS: Checkbox label for enabling Jabber messages for a profile in a subscriptions list. // TRANS: Checkbox label for enabling IM messages for a profile in a subscriptions list.
$this->out->element('label', array('for' => 'jabber-'.$this->profile->id), _('IM')); $this->out->element('label', array('for' => 'jabber-'.$this->profile->id), _m('LABEL','IM'));
} else { } else {
$this->out->hidden('jabber', $sub->jabber); $this->out->hidden('jabber', $sub->jabber);
} }

View File

@ -321,36 +321,66 @@ class Profile extends Memcached_DataObject
return false; return false;
} }
function getOwnedTags($auth_user, $offset=0, $limit=null, $since_id=0, $max_id=0) function getLists($auth_user, $offset=0, $limit=null, $since_id=0, $max_id=0)
{ {
$tags = new Profile_list(); $ids = array();
$tags->tagger = $this->id;
if (($auth_user instanceof User || $auth_user instanceof Profile) && $keypart = sprintf('profile:lists:%d', $this->id);
$auth_user->id === $this->id) {
// no condition, get both private and public tags $idstr = self::cacheGet($keypart);
if ($idstr !== false) {
$ids = explode(',', $idstr);
} else { } else {
$tags->private = false; $list = new Profile_list();
} $list->selectAdd();
$list->selectAdd('id');
$tags->selectAdd('id as "cursor"'); $list->tagger = $this->id;
$list->selectAdd('id as "cursor"');
if ($since_id>0) { if ($since_id>0) {
$tags->whereAdd('id > '.$since_id); $list->whereAdd('id > '.$since_id);
} }
if ($max_id>0) { if ($max_id>0) {
$tags->whereAdd('id <= '.$max_id); $list->whereAdd('id <= '.$max_id);
} }
if($offset>=0 && !is_null($limit)) { if($offset>=0 && !is_null($limit)) {
$tags->limit($offset, $limit); $list->limit($offset, $limit);
} }
$tags->orderBy('id DESC'); $list->orderBy('id DESC');
$tags->find();
return $tags; if ($list->find()) {
while ($list->fetch()) {
$ids[] = $list->id;
}
}
self::cacheSet($keypart, implode(',', $ids));
}
$showPrivate = (($auth_user instanceof User ||
$auth_user instanceof Profile) &&
$auth_user->id === $this->id);
$lists = array();
foreach ($ids as $id) {
$list = Profile_list::staticGet('id', $id);
if (!empty($list) &&
($showPrivate || !$list->private)) {
if (!isset($list->cursor)) {
$list->cursor = $list->id;
}
$lists[] = $list;
}
}
return new ArrayWrapper($lists);
} }
function getOtherTags($auth_user=null, $offset=0, $limit=null, $since_id=0, $max_id=0) function getOtherTags($auth_user=null, $offset=0, $limit=null, $since_id=0, $max_id=0)
@ -1323,42 +1353,4 @@ class Profile extends Memcached_DataObject
} }
return $profile; return $profile;
} }
function getLists()
{
$ids = array();
$keypart = sprintf('profile:lists:%d', $this->id);
$idstr = self::cacheGet($keypart);
if ($idstr !== false) {
$ids = explode(',', $idstr);
} else {
$list = new Profile_list();
$list->selectAdd();
$list->selectAdd('id');
$list->tagger = $this->id;
if ($list->find()) {
while ($list->fetch()) {
$ids[] = $list->id;
}
}
self::cacheSet($keypart, implode(',', $ids));
}
$lists = array();
foreach ($ids as $id) {
$list = Profile_list::staticGet('id', $id);
if (!empty($list) &&
($showPrivate || !$list->private)) {
$lists[] = $list;
}
}
return new ArrayWrapper($lists);
}
} }

View File

@ -28,8 +28,9 @@ Here are some documents that you might find helpful in understanding
* [Contact](%%doc.contact%%) - who to contact with questions about the service * [Contact](%%doc.contact%%) - who to contact with questions about the service
* [IM](%%doc.im%%) - using the instant-message (IM) features of %%site.name%% * [IM](%%doc.im%%) - using the instant-message (IM) features of %%site.name%%
* [SMS](%%doc.sms%%) - tying your cellphone to %%site.name%% * [SMS](%%doc.sms%%) - tying your cellphone to %%site.name%%
* [tags](%%doc.tags%%) - different ways to use tagging * [Tags](%%doc.tags%%) - different ways to use tagging
* [Groups](%%doc.groups%%) - joining together in groups * [Groups](%%doc.groups%%) - joining together in groups
* [Lists](%%doc.lists%%) - organize your contacts
* [OpenMicroBlogging](%%doc.openmublog%%) - subscribing to remote users * [OpenMicroBlogging](%%doc.openmublog%%) - subscribing to remote users
* [Privacy](%%doc.privacy%%) - %%site.name%%'s privacy policy * [Privacy](%%doc.privacy%%) - %%site.name%%'s privacy policy
* [Source](%%doc.source%%) - How to get the StatusNet source code * [Source](%%doc.source%%) - How to get the StatusNet source code

73
doc-src/lists Normal file
View File

@ -0,0 +1,73 @@
<!-- Copyright 2008-2010 StatusNet Inc. and contributors. -->
<!-- Document licensed under Creative Commons Attribution 3.0 Unported. See -->
<!-- http://creativecommons.org/licenses/by/3.0/ for details. -->
%%site.name%% supports
[tags](http://en.wikipedia.org/wiki/Tag_(metadata)) to help you
organize your activities here. You can use tags for people and for
notices.
Tagging a notice
----------------
You can tag a notice using a *hashtag*; a # character followed by
letters and numbers as well as '.', '-', and '_'. Note that accented
latin characters are not supported, and non-roman scripts are right out.
The HTML for the notice will link to a stream of all the other notices
with that tag. This can be a great way to keep track of a conversation.
The most popular current tags on the site can be found in the [public
tag cloud](%%action.publictagcloud%%). Their size shows their
popularity and recency.
Tagging yourself
----------------
You can also add tags for yourself on your [profile
settings](%%action.profilesettings%%) page or by using the edit tags
button on your profile page. Use single words to
describe yourself, your experiences and your interest. The tags will
become links on your profile page to a list of all the users on the
site who use that same tag. It can be a nice way to find people who
are related to you geographically or who have a common interest.
Tagging others
--------------
You can also tag other users by using the edit tags button next to
their profile. Such tags are called *people tags*. Once you have
created a people tag, you can add or remove users from it using the
tag's edit form. This makes it easy to organize your subscriptions
into groups and sort through them separately. Also, it will let
you create custom lists of people that others can subscribe to.
You can also send a notice "to the attention of" your subscribers
whom you've marked with a particular tag (note: *not* people who've
marked themselves with that tag). "@#family hello" will send a
notice to all your subscribers you've marked with the tag 'family'.
Private and public people tags
------------------------------
A private people tag is only visible to the creator, it cannot be
subscribed to, but the timeline can be viewed. To create a new
private prepend a '.' to the tag in the tags editing box. To set
an existing public tag as private or vice-versa, go to the tag's
edit page.
The most used public tags are displayed in the
[public people tag cloud](%%action.publicpeopletagcloud%%). Their
size shows their frequency of use.
Remote people tags
------------------
You can even [tag remote users](%%action.profilesettings%%). Just
enter the remote profile's URI and click on the "Fetch" button to
fetch the profile, you can then add tags and save them.
Subscribing to the timeline of a people tag on another server also
works. Just copy the URL of the people tag's timeline page to the
[OStatus subscription](%%action.ostatussub%%) form.

View File

@ -44,7 +44,6 @@ define('GROUPS_PER_MINILIST', 8);
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/ * @link http://status.net/
*/ */
class GroupMiniList extends GroupList class GroupMiniList extends GroupList
{ {
function show() function show()

View File

@ -44,7 +44,6 @@ if (!defined('STATUSNET')) {
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
* @link http://status.net/ * @link http://status.net/
*/ */
class InviteButtonSection extends Section class InviteButtonSection extends Section
{ {
function showTitle() function showTitle()
@ -57,7 +56,8 @@ class InviteButtonSection extends Section
$this->out->element('a', $this->out->element('a',
array('href' => common_local_url('invite'), array('href' => common_local_url('invite'),
'class' => 'invite_button'), 'class' => 'invite_button'),
_('Invite more colleagues')); // TRANS: Button text for inviting more users to the StatusNet instance.
_m('BUTTON','Invite more colleagues'));
return false; return false;
} }
} }

View File

@ -51,7 +51,7 @@ class ListsNav extends Menu
$user = common_current_user(); $user = common_current_user();
$this->lists = $profile->getOwnedTags($user); $this->lists = $profile->getLists($user);
} }
function show() function show()

View File

@ -105,8 +105,8 @@ class PeopletagEditForm extends Form
*/ */
function formLegend() function formLegend()
{ {
// TRANS: Form legend for people tag edit form. // TRANS: Form legend for list edit form.
// TRANS: %s is a people tag. // TRANS: %s is a list.
$this->out->element('legend', null, sprintf(_('Edit list %s'), $this->peopletag->tag)); $this->out->element('legend', null, sprintf(_('Edit list %s'), $this->peopletag->tag));
} }
@ -137,21 +137,21 @@ class PeopletagEditForm extends Form
$this->out->elementStart('li'); $this->out->elementStart('li');
$desclimit = Profile_list::maxDescription(); $desclimit = Profile_list::maxDescription();
if ($desclimit == 0) { if ($desclimit == 0) {
// TRANS: Field title for description of people tag. // TRANS: Field title for description of list.
$descinstr = _('Describe the list or topic.'); $descinstr = _('Describe the list or topic.');
} else { } else {
// TRANS: Field title for description of people tag. // TRANS: Field title for description of list.
// TRANS: %d is the maximum number of characters for the description. // TRANS: %d is the maximum number of characters for the description.
$descinstr = sprintf(_m('Describe the list or topic in %d character.', $descinstr = sprintf(_m('Describe the list or topic in %d character.',
'Describe the list or topic in %d characters.', 'Describe the list or topic in %d characters.',
$desclimit), $desclimit),
$desclimit); $desclimit);
} }
// TRANS: Field label for description of people tag. // TRANS: Field label for description of list.
$this->out->textarea('description', _('Description'), $this->out->textarea('description', _('Description'),
($this->out->arg('description')) ? $this->out->arg('description') : $description, ($this->out->arg('description')) ? $this->out->arg('description') : $description,
$descinstr); $descinstr);
// TRANS: Checkbox label to mark a people tag private. // TRANS: Checkbox label to mark a list private.
$this->out->checkbox('private', _('Private'), $private); $this->out->checkbox('private', _('Private'), $private);
$this->out->elementEnd('li'); $this->out->elementEnd('li');
$this->out->elementEnd('ul'); $this->out->elementEnd('ul');
@ -167,11 +167,11 @@ class PeopletagEditForm extends Form
// TRANS: Button text to save a people tag. // TRANS: Button text to save a people tag.
$this->out->submit('submit', _('Save')); $this->out->submit('submit', _('Save'));
$this->out->submit('form_action-yes', $this->out->submit('form_action-yes',
// TRANS: Button text to delete a people tag. // TRANS: Button text to delete a list.
_m('BUTTON','Delete'), _m('BUTTON','Delete'),
'submit', 'submit',
'delete', 'delete',
// TRANS: Button title to delete a people tag. // TRANS: Button title to delete a list.
_('Delete this list.')); _('Delete this list.'));
} }

View File

@ -103,10 +103,10 @@ class PeopletagGroupNav extends Widget
// People tag timeline // People tag timeline
$this->out->menuItem(common_local_url('showprofiletag', array('tagger' => $user_profile->nickname, $this->out->menuItem(common_local_url('showprofiletag', array('tagger' => $user_profile->nickname,
'tag' => $tag->tag)), 'tag' => $tag->tag)),
// TRANS: Menu item in people tag navigation panel. // TRANS: Menu item in list navigation panel.
_m('MENU','List'), _m('MENU','List'),
// TRANS: Menu item title in people tag navigation panel. // TRANS: Menu item title in list navigation panel.
// TRANS: %1$s is a tag, %2$s is a nickname. // TRANS: %1$s is a list, %2$s is a nickname.
sprintf(_('%1$s list by %2$s.'), $tag->tag, sprintf(_('%1$s list by %2$s.'), $tag->tag,
(($user_profile && $user_profile->fullname) ? $user_profile->fullname : $nickname)), (($user_profile && $user_profile->fullname) ? $user_profile->fullname : $nickname)),
$action == 'showprofiletag', 'nav_timeline_peopletag'); $action == 'showprofiletag', 'nav_timeline_peopletag');
@ -114,10 +114,10 @@ class PeopletagGroupNav extends Widget
// Tagged // Tagged
$this->out->menuItem(common_local_url('peopletagged', array('tagger' => $user->nickname, $this->out->menuItem(common_local_url('peopletagged', array('tagger' => $user->nickname,
'tag' => $tag->tag)), 'tag' => $tag->tag)),
// TRANS: Menu item in people tag navigation panel. // TRANS: Menu item in list navigation panel.
_m('MENU','Listed'), _m('MENU','Listed'),
// TRANS: Menu item title in people tag navigation panel. // TRANS: Menu item title in list navigation panel.
// TRANS: %1$s is a tag, %2$s is a nickname. // TRANS: %1$s is a list, %2$s is a nickname.
sprintf(_('%1$s list by %2$s.'), $tag->tag, sprintf(_('%1$s list by %2$s.'), $tag->tag,
(($user_profile && $user_profile->fullname) ? $user_profile->fullname : $nickname)), (($user_profile && $user_profile->fullname) ? $user_profile->fullname : $nickname)),
$action == 'peopletagged', 'nav_peopletag_tagged'); $action == 'peopletagged', 'nav_peopletag_tagged');
@ -125,10 +125,10 @@ class PeopletagGroupNav extends Widget
// Subscribers // Subscribers
$this->out->menuItem(common_local_url('peopletagsubscribers', array('tagger' => $user->nickname, $this->out->menuItem(common_local_url('peopletagsubscribers', array('tagger' => $user->nickname,
'tag' => $tag->tag)), 'tag' => $tag->tag)),
// TRANS: Menu item in people tag navigation panel. // TRANS: Menu item in list navigation panel.
_m('MENU','Subscribers'), _m('MENU','Subscribers'),
// TRANS: Menu item title in people tag navigation panel. // TRANS: Menu item title in list navigation panel.
// TRANS: %1$s is a tag, %2$s is a nickname. // TRANS: %1$s is a list, %2$s is a nickname.
sprintf(_('Subscribers to %1$s list by %2$s.'), $tag->tag, sprintf(_('Subscribers to %1$s list by %2$s.'), $tag->tag,
(($user_profile && $user_profile->fullname) ? $user_profile->fullname : $nickname)), (($user_profile && $user_profile->fullname) ? $user_profile->fullname : $nickname)),
$action == 'peopletagsubscribers', 'nav_peopletag_subscribers'); $action == 'peopletagsubscribers', 'nav_peopletag_subscribers');
@ -140,8 +140,8 @@ class PeopletagGroupNav extends Widget
'tag' => $tag->tag)), 'tag' => $tag->tag)),
// TRANS: Menu item in people tag navigation panel. // TRANS: Menu item in people tag navigation panel.
_m('MENU','Edit'), _m('MENU','Edit'),
// TRANS: Menu item title in people tag navigation panel. // TRANS: Menu item title in list navigation panel.
// TRANS: %s is a tag. // TRANS: %s is a list.
sprintf(_('Edit %s list by you.'), $tag->tag, sprintf(_('Edit %s list by you.'), $tag->tag,
(($user_profile && $user_profile->fullname) ? $user_profile->fullname : $nickname)), (($user_profile && $user_profile->fullname) ? $user_profile->fullname : $nickname)),
$action == 'editpeopletag', 'nav_peopletag_edit'); $action == 'editpeopletag', 'nav_peopletag_edit');

View File

@ -192,9 +192,9 @@ class PeopletagListItem extends Widget
$this->out->element('a', array('href' => $this->out->element('a', array('href' =>
common_local_url('editpeopletag', array('tagger' => $this->profile->nickname, common_local_url('editpeopletag', array('tagger' => $this->profile->nickname,
'tag' => $this->peopletag->tag)), 'tag' => $this->peopletag->tag)),
// TRANS: Title for link to edit people tag settings. // TRANS: Title for link to edit list settings.
'title' => _('Edit list settings.')), 'title' => _('Edit list settings.')),
// TRANS: Text for link to edit people tag settings. // TRANS: Text for link to edit list settings.
_('Edit')); _('Edit'));
$this->out->elementEnd('li'); $this->out->elementEnd('li');
} }

View File

@ -78,7 +78,7 @@ class PeopletagNav extends Menu
_m('MENU','List Subscriptions'), _m('MENU','List Subscriptions'),
// TRANS: Tooltip for menu item in the group navigation page. // TRANS: Tooltip for menu item in the group navigation page.
// TRANS: %s is the nickname of the group. // TRANS: %s is the nickname of the group.
sprintf(_m('TOOLTIP','Lists subscribed to by %s'), $nickname), sprintf(_m('TOOLTIP','Lists subscribed to by %s.'), $nickname),
$action_name == 'peopletagsubscriptions', $action_name == 'peopletagsubscriptions',
'nav_list_group'); 'nav_list_group');
$this->out->menuItem(common_local_url('peopletagsforuser', array('nickname' => $this->out->menuItem(common_local_url('peopletagsforuser', array('nickname' =>
@ -87,7 +87,7 @@ class PeopletagNav extends Menu
sprintf(_m('MENU','Lists with %s'), $nickname), sprintf(_m('MENU','Lists with %s'), $nickname),
// TRANS: Tooltip for menu item in the group navigation page. // TRANS: Tooltip for menu item in the group navigation page.
// TRANS: %s is the nickname of the group. // TRANS: %s is the nickname of the group.
sprintf(_m('TOOLTIP','Lists with %s'), $nickname), sprintf(_m('TOOLTIP','Lists with %s.'), $nickname),
$action_name == 'peopletagsforuser', $action_name == 'peopletagsforuser',
'nav_lists_with'); 'nav_lists_with');
$this->out->menuItem(common_local_url('peopletagsbyuser', array('nickname' => $this->out->menuItem(common_local_url('peopletagsbyuser', array('nickname' =>
@ -96,7 +96,7 @@ class PeopletagNav extends Menu
sprintf(_m('MENU','Lists by %s'), $nickname), sprintf(_m('MENU','Lists by %s'), $nickname),
// TRANS: Tooltip for menu item in the group navigation page. // TRANS: Tooltip for menu item in the group navigation page.
// TRANS: %s is the nickname of the group. // TRANS: %s is the nickname of the group.
sprintf(_m('TOOLTIP','Lists by %s'), $nickname), sprintf(_m('TOOLTIP','Lists by %s.'), $nickname),
$action_name == 'peopletagsbyuser', $action_name == 'peopletagsbyuser',
'nav_lists_by'); 'nav_lists_by');
Event::handle('EndGroupGroupNav', array($this)); Event::handle('EndGroupGroupNav', array($this));

View File

@ -65,8 +65,8 @@ class PeopletagsBySubsSection extends PeopletagSection
function title() function title()
{ {
// TRANS: Title for section contaning people tags with the most subscribers. // TRANS: Title for section contaning lists with the most subscribers.
return _('Lists with most subscribers'); return _('Popular lists');
} }
function divId() function divId()

View File

@ -83,7 +83,6 @@ class PeopletagSection extends Section
class PeopletagSectionItem extends PeopletagListItem class PeopletagSectionItem extends PeopletagListItem
{ {
function showStart() function showStart()
{ {
} }
@ -121,8 +120,8 @@ class PeopletagSectionItem extends PeopletagListItem
function showTag() function showTag()
{ {
// TRANS: Tag summary. %1$d is the number of users tagged with the tag, // TRANS: List summary. %1$d is the number of users in the list,
// TRANS: %2$d is the number of subscribers to the tag. // TRANS: %2$d is the number of subscribers to the list.
$title = sprintf(_('Listed: %1$d Subscribers: %2$d'), $title = sprintf(_('Listed: %1$d Subscribers: %2$d'),
$this->peopletag->taggedCount(), $this->peopletag->taggedCount(),
$this->peopletag->subscriberCount()); $this->peopletag->subscriberCount());

View File

@ -67,8 +67,7 @@ class PeopletagsForUserSection extends PeopletagSection
if (!empty($user) && $this->profile->id == $user->id) { if (!empty($user) && $this->profile->id == $user->id) {
return sprintf(_('Lists with you')); return sprintf(_('Lists with you'));
} }
// TRANS: Title for page that displays // TRANS: Title for page that displays which people tags a user has been tagged with.
// which people tags a user has been tagged with.
// TRANS: %s is a profile name. // TRANS: %s is a profile name.
return sprintf(_('Lists with %s'), $this->profile->getBestName()); return sprintf(_('Lists with %s'), $this->profile->getBestName());
} }

View File

@ -62,7 +62,7 @@ class PeopletagSubscriptionsSection extends PeopletagSection
function title() function title()
{ {
// TRANS: Title for page that displays people tags a user has subscribed to. // TRANS: Title for page that displays lists a user has subscribed to.
return _('List subscriptions'); return _('List subscriptions');
} }

View File

@ -52,8 +52,8 @@ class PersonalTagCloudSection extends TagCloudSection
function title() function title()
{ {
// TRANS: Title for personal tag cloud section. %s is a user nickname. // TRANS: Title for personal tag cloud section.
return sprintf(_('Tags'), $this->user->nickname); return _m('TITLE','Tags');
} }
function getTags() function getTags()

View File

@ -279,9 +279,8 @@ class ProfileAction extends OwnerDesignAction
function showLists() function showLists()
{ {
$cur = common_current_user(); $cur = common_current_user();
$showPrivate = (!empty($cur) && $cur->id == $this->profile->id);
$lists = $this->profile->getLists($showPrivate); $lists = $this->profile->getLists($cur);
if ($lists->N > 0) { if ($lists->N > 0) {
$this->elementStart('div', array('id' => 'entity_lists', $this->elementStart('div', array('id' => 'entity_lists',
@ -293,9 +292,9 @@ class ProfileAction extends OwnerDesignAction
array('nickname' => $this->profile->nickname)); array('nickname' => $this->profile->nickname));
$this->elementStart('h2'); $this->elementStart('h2');
// TRANS: H2 text for user list membership statistics.
$this->element('a', $this->element('a',
array('href' => $url), array('href' => $url),
// TRANS: H2 text for user list membership statistics.
_('Lists')); _('Lists'));
$this->text(' '); $this->text(' ');
$this->text($lists->N); $this->text($lists->N);

View File

@ -145,7 +145,7 @@ class SubGroupNav extends Menu
// TRANS: Menu item in local navigation menu. // TRANS: Menu item in local navigation menu.
_m('MENU','Invite'), _m('MENU','Invite'),
// TRANS: Menu item title in local navigation menu. // TRANS: Menu item title in local navigation menu.
// TRANS: %s is a user nickname. // TRANS: %s is the StatusNet sitename.
sprintf(_('Invite friends and colleagues to join you on %s.'), sprintf(_('Invite friends and colleagues to join you on %s.'),
common_config('site', 'name')), common_config('site', 'name')),
$action == 'invite', $action == 'invite',

View File

@ -91,17 +91,23 @@ class GroupdirectoryAction extends Action
if ($this->filter == 'all') { if ($this->filter == 'all') {
if ($this->page != 1) { if ($this->page != 1) {
// TRANS: Title for group directory page. %d is a page number.
return(sprintf(_m('Group Directory, page %d'), $this->page)); return(sprintf(_m('Group Directory, page %d'), $this->page));
} }
// TRANS: Title for group directory page.
return _m('Group directory'); return _m('Group directory');
} else if ($this->page == 1) { } else if ($this->page == 1) {
return sprintf( return sprintf(
// TRANS: Title for group directory page when it is filtered.
// TRANS: %s is the filter string.
_m('Group directory - %s'), _m('Group directory - %s'),
strtoupper($this->filter) strtoupper($this->filter)
); );
} else { } else {
return sprintf( return sprintf(
_m('Group directory - %s, page %d'), // TRANS: Title for group directory page when it is filtered.
// TRANS: %1$s is the filter string, %2$d is a page number.
_m('Group directory - %1$s, page %2$d'),
strtoupper($this->filter), strtoupper($this->filter),
$this->page $this->page
); );
@ -115,19 +121,11 @@ class GroupdirectoryAction extends Action
*/ */
function getInstructions() function getInstructions()
{ {
// TRANS: Page notice for groups directory. // TRANS: Page instructions.
// TRANS: %%site.name%% is the name of the StatusNet site. return _m("After you join a group you can send messages to all other members\n".
// TRANS: %%action.newgroup%% is a URL. Do not change it. "using the syntax \"!groupname\".\n\n".
// TRANS: This message contains Markdown links in the form [link text](link). "Browse groups, or search for groups on by their name, location or topic.\n".
$instructions = <<< END_OF_INSTRUCTIONS "Separate the terms by spaces; they must be three characters or more.\n");
After you join a group you can send messages to all other members
using the syntax "!groupname".
Browse groups, or search for groups on by their name, location or topic.
Separate the terms by spaces; they must be three characters or more.
END_OF_INSTRUCTIONS;
return _m($instructions);
} }
/** /**
@ -217,7 +215,7 @@ END_OF_INSTRUCTIONS;
'href' => common_local_url('newgroup'), 'href' => common_local_url('newgroup'),
'class' => 'more'), 'class' => 'more'),
// TRANS: Link to create a new group on the group list page. // TRANS: Link to create a new group on the group list page.
_('Create a new group') _m('Create a new group')
); );
$this->elementEnd('p'); $this->elementEnd('p');
} }
@ -226,6 +224,7 @@ END_OF_INSTRUCTIONS;
$this->elementStart('div', array('id' => 'profile_directory')); $this->elementStart('div', array('id' => 'profile_directory'));
// @todo FIXME: Does "All" need i18n here?
$alphaNav = new AlphaNav($this, false, false, array('0-9', 'All')); $alphaNav = new AlphaNav($this, false, false, array('0-9', 'All'));
$alphaNav->show(); $alphaNav->show();
@ -280,12 +279,15 @@ END_OF_INSTRUCTIONS;
$this->elementStart('fieldset'); $this->elementStart('fieldset');
// TRANS: Fieldset legend.
$this->element('legend', null, _m('Search groups')); $this->element('legend', null, _m('Search groups'));
$this->elementStart('ul', 'form_data'); $this->elementStart('ul', 'form_data');
$this->elementStart('li'); $this->elementStart('li');
// TRANS: Field label for input of one or more keywords.
$this->input('q', _m('Keyword(s)'), $this->q); $this->input('q', _m('Keyword(s)'), $this->q);
// TRANS: Button text for searching group directory.
$this->submit('search', _m('BUTTON','Search')); $this->submit('search', _m('BUTTON','Search'));
$this->elementEnd('li'); $this->elementEnd('li');
$this->elementEnd('ul'); $this->elementEnd('ul');
@ -401,19 +403,20 @@ GROUP_QUERY_END;
'p', 'p',
'error', 'error',
sprintf( sprintf(
_m('No groups starting with %s'), // TRANS: Empty list message for searching group directory.
// TRANS: %s is the search string.
_m('No groups starting with %s.'),
$this->filter $this->filter
) )
); );
} else { } else {
// TRANS: Empty list message for searching group directory.
$this->element('p', 'error', _m('No results.')); $this->element('p', 'error', _m('No results.'));
$message = _m(<<<E_O_T // TRANS: Help text for searching group directory.
* Make sure all words are spelled correctly. $message = _m("* Make sure all words are spelled correctly.\n".
* Try different keywords. "* Try different keywords.\n".
* Try more general keywords. "* Try more general keywords.\n".
* Try fewer keywords. "* Try fewer keywords.");
E_O_T
);
$this->elementStart('div', 'help instructions'); $this->elementStart('div', 'help instructions');
$this->raw(common_markup_to_html($message)); $this->raw(common_markup_to_html($message));
$this->elementEnd('div'); $this->elementEnd('div');
@ -427,5 +430,4 @@ E_O_T
$gbm = new GroupsByMembersSection($this); $gbm = new GroupsByMembersSection($this);
$gbm->show(); $gbm->show();
} }
} }

View File

@ -1,5 +1,4 @@
<?php <?php
/** /**
* StatusNet, the distributed open-source microblogging tool * StatusNet, the distributed open-source microblogging tool
* *
@ -43,7 +42,6 @@ require_once INSTALLDIR . '/lib/subscriptionlist.php';
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/ * @link http://status.net/
*/ */
class SortableGroupList extends SortableSubscriptionList class SortableGroupList extends SortableSubscriptionList
{ {
/** Owner of this list */ /** Owner of this list */
@ -63,12 +61,13 @@ class SortableGroupList extends SortableSubscriptionList
$this->out->elementStart('tr'); $this->out->elementStart('tr');
$tableHeaders = array( $tableHeaders = array(
// TRANS: Column header in table for user nickname.
'nickname' => _m('Nickname'), 'nickname' => _m('Nickname'),
// TRANS: Column header in table for timestamp when user was created.
'created' => _m('Created') 'created' => _m('Created')
); );
foreach ($tableHeaders as $id => $label) { foreach ($tableHeaders as $id => $label) {
$attrs = array('id' => $id); $attrs = array('id' => $id);
$current = (!empty($this->action->sort) && $this->action->sort == $id); $current = (!empty($this->action->sort) && $this->action->sort == $id);
@ -110,6 +109,7 @@ class SortableGroupList extends SortableSubscriptionList
$this->out->elementEnd('th'); $this->out->elementEnd('th');
} }
// TRANS: Column header in table for members of a group.
$this->out->element('th', array('id' => 'Members'), _m('Members')); $this->out->element('th', array('id' => 'Members'), _m('Members'));
$this->out->element('th', array('id' => 'controls'), null); $this->out->element('th', array('id' => 'controls'), null);
@ -245,6 +245,7 @@ class SortableGroupListItem extends SortableSubscriptionListItem
function showCreatedDate() function showCreatedDate()
{ {
$this->out->elementStart('td', 'entry_created'); $this->out->elementStart('td', 'entry_created');
// @todo FIXME: Should we provide i18n for timestamps in core?
$this->out->raw(date('j M Y', strtotime($this->profile->created))); $this->out->raw(date('j M Y', strtotime($this->profile->created)));
$this->out->elementEnd('td'); $this->out->elementEnd('td');
} }
@ -267,5 +268,4 @@ class SortableGroupListItem extends SortableSubscriptionListItem
} }
} }
} }

View File

@ -854,7 +854,7 @@ class OStatusPlugin extends Plugin
$oprofile = Ostatus_profile::staticGet('peopletag_id', $peopletag->id); $oprofile = Ostatus_profile::staticGet('peopletag_id', $peopletag->id);
if ($oprofile) { if ($oprofile) {
if (!$oprofile->subscribe()) { if (!$oprofile->subscribe()) {
// TRANS: Exception thrown when setup of remote people tag subscription fails. // TRANS: Exception thrown when setup of remote list subscription fails.
throw new Exception(_m('Could not set up remote list subscription.')); throw new Exception(_m('Could not set up remote list subscription.'));
} }
@ -875,7 +875,7 @@ class OStatusPlugin extends Plugin
// TRANS: Title for remote follow list. // TRANS: Title for remote follow list.
$act->title = _m('TITLE','Follow list'); $act->title = _m('TITLE','Follow list');
// TRANS: Success message for remote list follow through OStatus. // TRANS: Success message for remote list follow through OStatus.
// TRANS: %1$s is the subscriber name, %2$s the prople tag, %3$s is the tagger's name. // TRANS: %1$s is the subscriber name, %2$s is the list, %3$s is the tagger's name.
$act->content = sprintf(_m("%1$s is now following people listed in %2$s by %3$s."), $act->content = sprintf(_m("%1$s is now following people listed in %2$s by %3$s."),
$sub->getBestName(), $sub->getBestName(),
$oprofile->getBestName(), $oprofile->getBestName(),

View File

@ -169,6 +169,7 @@ class OStatusPeopletagAction extends OStatusSubAction
function getInstructions() function getInstructions()
{ {
// TRANS: Instructions for OStatus list subscription form.
return _m('You can subscribe to lists from other supported sites. Paste the lists\'s URI below:'); return _m('You can subscribe to lists from other supported sites. Paste the lists\'s URI below:');
} }

View File

@ -588,6 +588,36 @@ address {
-webkit-box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.5); -webkit-box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.5);
} }
.invite_button {
height: 2.1em;
line-height: 2.1em;
display: block;
text-align: center;
color:#fff;
font-weight: bold;
text-transform: uppercase;
font-size: 1.2em;
text-shadow: 0px -1px 0px rgba(0, 0, 0, 0.2);
border: 1px solid #d7621c;
border-radius: 4px;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
background: #FB6104;
background: -moz-linear-gradient(top, #ff9d63 , #FB6104);
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ff9d63), color-stop(100%,#FB6104));
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ff9d63', endColorstr='#FB6104',GradientType=0 );
}
.invite_button:hover {
color: #fff;
text-decoration: none;
text-shadow: 0px -1px 0px rgba(0, 0, 0, 0.6);
background: #ff9d63;
background: -moz-linear-gradient(top, #FB6104 , #fc8035);
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#FB6104), color-stop(100%,#fc8035));
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#FB6104', endColorstr='#fc8035',GradientType=0 );
}
#content h1 { #content h1 {
border-bottom: 3px solid #A6ADBF; border-bottom: 3px solid #A6ADBF;
color: #A6ADBF; color: #A6ADBF;