diff --git a/EVENTS.txt b/EVENTS.txt index aca9e8f73d..5bf6078a1c 100644 --- a/EVENTS.txt +++ b/EVENTS.txt @@ -1089,13 +1089,13 @@ EndGroupSave: After saving a group, aliases, and first member - $group: group that was saved StartInterpretCommand: Before running a command -- $cmd: First word in the string, 'foo' in 'foo argument' +- $cmd: First word in the string, 'foo' in 'foo argument' - $arg: Argument, if any, like 'argument' in 'foo argument' - $user: User who issued the command - &$result: Resulting command; you can set this! EndInterpretCommand: Before running a command -- $cmd: First word in the string, 'foo' in 'foo argument' +- $cmd: First word in the string, 'foo' in 'foo argument' - $arg: Argument, if any, like 'argument' in 'foo argument' - $user: User who issued the command - $result: Resulting command @@ -1111,7 +1111,7 @@ EndGroupActionsList: End the list of actions on a group profile page (before showSubscriptions(); + $ibs = new InviteButtonSection($this); + $ibs->show(); + $this->showSubscribers(); + $this->showGroups(); + $this->showLists(); + } + function showPageTitle() { $user = common_current_user(); diff --git a/actions/avatarsettings.php b/actions/avatarsettings.php index 7cc55e1e3f..ceab14a962 100644 --- a/actions/avatarsettings.php +++ b/actions/avatarsettings.php @@ -146,13 +146,15 @@ class AvatarsettingsAction extends SettingsAction // TRANS: Header on avatar upload page for thumbnail of to be used rendition of uploaded avatar (h2). $this->element('h2', null, _("Preview")); $this->elementStart('div', array('id'=>'avatar_preview_view')); - $this->element('img', array('src' => $original->url, + $this->element('img', array('src' => $avatar->url, 'width' => AVATAR_PROFILE_SIZE, 'height' => AVATAR_PROFILE_SIZE, 'alt' => $user->nickname)); $this->elementEnd('div'); - // TRANS: Button on avatar upload page to delete current avatar. - $this->submit('delete', _m('BUTTON','Delete')); + if (!empty($avatar->filename)) { + // TRANS: Button on avatar upload page to delete current avatar. + $this->submit('delete', _m('BUTTON','Delete')); + } $this->elementEnd('li'); } diff --git a/actions/editpeopletag.php b/actions/editpeopletag.php index 9d0548cb94..db34e485cc 100644 --- a/actions/editpeopletag.php +++ b/actions/editpeopletag.php @@ -49,11 +49,11 @@ class EditpeopletagAction extends OwnerDesignAction if ($_SERVER['REQUEST_METHOD'] == 'POST' && $this->boolean('delete')) { // TRANS: Title for edit people tag page after deleting a tag. // TRANS: %s is a tag. - return sprintf(_('Delete %s people tag'), $this->peopletag->tag); + return sprintf(_('Delete %s list'), $this->peopletag->tag); } // TRANS: Title for edit people tag page. // TRANS: %s is a tag. - return sprintf(_('Edit people tag %s'), $this->peopletag->tag); + return sprintf(_('Edit list %s'), $this->peopletag->tag); } /** @@ -106,7 +106,7 @@ class EditpeopletagAction extends OwnerDesignAction if (!$this->peopletag) { // TRANS: Client error displayed when referring to a non-exsting people tag. - $this->clientError(_('No such people tag.'), 404); + $this->clientError(_('No such list.'), 404); return false; } @@ -216,7 +216,7 @@ class EditpeopletagAction extends OwnerDesignAction } else { $this->element('p', 'instructions', // TRANS: Form instruction for edit people tag form. - _('Use this form to edit the people tag.')); + _('Use this form to edit the list.')); } } @@ -294,7 +294,7 @@ class EditpeopletagAction extends OwnerDesignAction if (!$result) { common_log_db_error($this->group, 'UPDATE', __FILE__); // TRANS: TRANS: Server error displayed when updating a people tag fails. - $this->serverError(_('Could not update people tag.')); + $this->serverError(_('Could not update list.')); } $this->peopletag->query('COMMIT'); diff --git a/actions/invite.php b/actions/invite.php index be2228e703..9522cac900 100644 --- a/actions/invite.php +++ b/actions/invite.php @@ -296,10 +296,4 @@ class InviteAction extends CurrentUserDesignAction mail_send($recipients, $headers, $body); } - - function showObjectNav() - { - $nav = new SubGroupNav($this, common_current_user()); - $nav->show(); - } } diff --git a/actions/peopletagged.php b/actions/peopletagged.php index 84356116cc..7ab16b6f87 100644 --- a/actions/peopletagged.php +++ b/actions/peopletagged.php @@ -93,7 +93,7 @@ class PeopletaggedAction extends OwnerDesignAction if (!$this->peopletag) { // TRANS: Client error displayed when referring to non-existing people tag. - $this->clientError(_('No such people tag.'), 404); + $this->clientError(_('No such list.'), 404); return false; } @@ -105,12 +105,12 @@ class PeopletaggedAction extends OwnerDesignAction if ($this->page == 1) { // TRANS: Title for list of people tagged by the user with a tag. // TRANS: %1$s is a tag, %2$s is a username. - return sprintf(_('People tagged %1$s by %2$s'), + return sprintf(_('People listed in %1$s by %2$s'), $this->peopletag->tag, $this->tagger->nickname); } else { // TRANS: Title for list of people tagged by the user with a tag. // TRANS: %1$s is a tag, %2$s is a username, %2$s is a page number. - return sprintf(_('People tagged %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->page); } diff --git a/actions/peopletagsbyuser.php b/actions/peopletagsbyuser.php index 42b728e1d8..7dc70058b2 100644 --- a/actions/peopletagsbyuser.php +++ b/actions/peopletagsbyuser.php @@ -2,7 +2,7 @@ /** * StatusNet, the distributed open-source microblogging tool * - * People tags by a user + * Lists by a user * * PHP version 5 * @@ -49,22 +49,22 @@ class PeopletagsbyuserAction extends OwnerDesignAction if ($this->page == 1) { if ($this->isOwner()) { if ($this->arg('private')) { - // TRANS: Title for people tags by a user page for a private tag. - return _('Private people tags by you'); + // TRANS: Title for lists by a user page for a private tag. + return _('Private lists by you'); } else if ($this->arg('public')) { - // TRANS: Title for people tags by a user page for a public tag. - return _('Public people tags by you'); + // TRANS: Title for lists by a user page for a public tag. + return _('Public lists by you'); } - // TRANS: Title for people tags by a user page. - return _('People tags by you'); + // TRANS: Title for lists by a user page. + return _('Lists by you'); } - // TRANS: Title for people tags by a user page. + // TRANS: Title for lists by a user page. // TRANS: %s is a user nickname. - return sprintf(_('People tags by %s'), $this->tagger->nickname); + return sprintf(_('Lists by %s'), $this->tagger->nickname); } else { - // TRANS: Title for people tags by a user page. + // TRANS: Title for lists by a user page. // TRANS: %1$s is a user nickname, %2$d is a page number. - return sprintf(_('People tags by %1$s, page %2$d'), $this->tagger->nickname, $this->page); + return sprintf(_('Lists by %1$s, page %2$d'), $this->tagger->nickname, $this->page); } } @@ -124,8 +124,8 @@ class PeopletagsbyuserAction extends OwnerDesignAction if ($this->isOwner()) { $this->tags = $this->tagger->getPrivateTags($offset, $limit); } else { - // TRANS: Client error displayed when trying view another user's private people tags. - $this->clientError(_('You cannot view others\' private people tags'), 403); + // TRANS: Client error displayed when trying view another user's private lists. + $this->clientError(_('You cannot view others\' private lists'), 403); } } else { $this->tags = $this->tagger->getOwnedTags(common_current_user(), $offset, $limit); @@ -160,8 +160,8 @@ class PeopletagsbyuserAction extends OwnerDesignAction array('href' => common_local_url('peopletagsforuser', array('nickname' => $this->user->nickname))), - // TRANS: Link text to show people tags for user %s. - sprintf(_('People tags for %s'), $this->tagger->nickname)); + // TRANS: Link text to show lists for user %s. + sprintf(_('Lists for %s'), $this->tagger->nickname)); $this->elementEnd('li'); if ($this->isOwner()) { @@ -204,11 +204,11 @@ class PeopletagsbyuserAction extends OwnerDesignAction function showAnonymousMessage() { $notice = - // TRANS: Message displayed for anonymous users on page that displays people tags by a user. + // TRANS: Message displayed for anonymous users on page that displays lists by a user. // TRANS: This message contains Markdown links in the form [description](links). // TRANS: %s is a tagger nickname. - sprintf(_('These are people tags created by **%s**. ' . - 'People tags are how you sort similar ' . + sprintf(_('These are lists created by **%s**. ' . + 'Lists are how you sort similar ' . 'people on %%%%site.name%%%%, a [micro-blogging]' . '(http://en.wikipedia.org/wiki/Micro-blogging) service ' . 'based on the Free Software [StatusNet](http://status.net/) tool. ' . @@ -259,17 +259,29 @@ class PeopletagsbyuserAction extends OwnerDesignAction return !empty($user) && $user->id == $this->tagger->id; } + function showObjectNav() + { + $nav = new PeopletagNav($this, $this->tagger); + $nav->show(); + } + function showEmptyListMessage() { - // TRANS: Message displayed on page that displays people tags by a user when there are none. + // TRANS: Message displayed on page that displays lists by a user when there are none. // TRANS: This message contains Markdown links in the form [description](links). // TRANS: %s is a tagger nickname. - $message = sprintf(_('%s has not created any [people tags](%%%%doc.tags%%%%) yet.'), $this->tagger->nickname); + $message = sprintf(_('%s has not created any [lists](%%%%doc.lists%%%%) yet.'), $this->tagger->nickname); $this->elementStart('div', 'guide'); $this->raw(common_markup_to_html($message)); $this->elementEnd('div'); } + function showProfileBlock() + { + $block = new AccountProfileBlock($this, $this->tagger); + $block->show(); + } + function showSections() { #TODO: tags with most subscribers diff --git a/actions/peopletagsforuser.php b/actions/peopletagsforuser.php index 789dcbe921..7f5c216070 100644 --- a/actions/peopletagsforuser.php +++ b/actions/peopletagsforuser.php @@ -47,10 +47,10 @@ class PeopletagsforuserAction extends OwnerDesignAction { if ($this->page == 1) { // Page title. %s is a tagged user's nickname. - return sprintf(_('People tags for %s'), $this->tagged->nickname); + return sprintf(_('Lists with %s in them'), $this->tagged->nickname); } else { // Page title. %1$s is a tagged user's nickname, %2$s is a page number. - return sprintf(_('People tags for %1$s, page %2$d'), $this->tagged->nickname, $this->page); + return sprintf(_('Lists with %1$s, page %2$d'), $this->tagged->nickname, $this->page); } } @@ -105,8 +105,8 @@ class PeopletagsforuserAction extends OwnerDesignAction // TRANS: Message displayed for anonymous users on page that displays people tags for a user. // TRANS: This message contains Markdown links in the form [description](links). // TRANS: %s is a tagger nickname. - sprintf(_('These are people tags for **%s**. ' . - 'People tags are how you sort similar ' . + sprintf(_('These are lists for **%s**. ' . + 'lists are how you sort similar ' . 'people on %%%%site.name%%%%, a [micro-blogging]' . '(http://en.wikipedia.org/wiki/Micro-blogging) service ' . 'based on the Free Software [StatusNet](http://status.net/) tool. ' . @@ -117,27 +117,6 @@ class PeopletagsforuserAction extends OwnerDesignAction $this->elementEnd('div'); } - function showPageNotice() - { - $this->elementStart('dl', 'filter_tags'); - $this->elementStart('dd', array('id' => 'filter_tags_for', - 'class' => 'child_1')); - - $user = common_current_user(); - // TRANS: Page notice. - $text = ($this->tagged->id == @$user->id) ? _('People tags by you') : - // TRANS: Page notice. %s is a tagger's nickname. - sprintf(_('People tags by %s'), $this->tagged->nickname); - $this->element('a', - array('href' => - common_local_url('peopletagsbyuser', - array('nickname' => $this->tagged->nickname))), - $text); - $this->elementEnd('dd'); - $this->elementEnd('dl'); - } - - function showContent() { #TODO: controls here. @@ -162,12 +141,24 @@ class PeopletagsforuserAction extends OwnerDesignAction // TRANS: Message displayed on page that displays people tags for a user when there are none. // TRANS: This message contains Markdown links in the form [description](links). // TRANS: %s is a tagger nickname. - $message = sprintf(_('%s has not been [tagged](%%%%doc.tags%%%%) by anyone yet.'), $this->tagged->nickname); + $message = sprintf(_('%s has not been [listed](%%%%doc.lists%%%%) by anyone yet.'), $this->tagged->nickname); $this->elementStart('div', 'guide'); $this->raw(common_markup_to_html($message)); $this->elementEnd('div'); } + function showObjectNav() + { + $nav = new PeopletagNav($this, $this->tagged); + $nav->show(); + } + + function showProfileBlock() + { + $block = new AccountProfileBlock($this, $this->tagged); + $block->show(); + } + function showSections() { #TODO: tags with most subscribers diff --git a/actions/peopletagsubscriptions.php b/actions/peopletagsubscriptions.php index 5eee82396d..3674cc1e76 100644 --- a/actions/peopletagsubscriptions.php +++ b/actions/peopletagsubscriptions.php @@ -48,11 +48,11 @@ class PeopletagsubscriptionsAction extends OwnerDesignAction if ($this->page == 1) { // TRANS: Title for page that displays people tags subscribed to by a user. // TRANS: %s is a profile nickname. - return sprintf(_('People tags subscriptions by %s'), $this->profile->nickname); + return sprintf(_('Lists subscribed to by %s'), $this->profile->nickname); } else { // TRANS: Title for page that displays people tags subscribed to by a user. // TRANS: %1$s is a profile nickname, %2$d is a page number. - return sprintf(_('People tags subscriptions 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); } } @@ -107,13 +107,13 @@ class PeopletagsubscriptionsAction extends OwnerDesignAction // TRANS: Message displayed for anonymous users on page that displays people tags subscribed to by a user. // TRANS: This message contains Markdown links in the form [description](links). // TRANS: %s is a profile nickname. - sprintf(_('These are people tags subscribed to by **%s**. ' . - 'People tags are how you sort similar ' . + sprintf(_('These are lists subscribed to by **%s**. ' . + 'Lists are how you sort similar ' . 'people on %%%%site.name%%%%, a [micro-blogging]' . '(http://en.wikipedia.org/wiki/Micro-blogging) service ' . 'based on the Free Software [StatusNet](http://status.net/) tool. ' . 'You can easily keep track of what they ' . - 'are doing by subscribing to the tag\'s timeline.' ), $this->profile->nickname); + 'are doing by subscribing to the list\'s timeline.' ), $this->profile->nickname); $this->elementStart('div', array('id' => 'anon_notice')); $this->raw(common_markup_to_html($notice)); $this->elementEnd('div'); @@ -133,6 +133,18 @@ class PeopletagsubscriptionsAction extends OwnerDesignAction $this->page, 'peopletagsubscriptions', array('nickname' => $this->profile->id)); } + function showObjectNav() + { + $nav = new PeopletagNav($this, $this->profile); + $nav->show(); + } + + function showProfileBlock() + { + $block = new AccountProfileBlock($this, $this->profile); + $block->show(); + } + function showSections() { #TODO: tags with most subscribers diff --git a/actions/public.php b/actions/public.php index 100f8d1194..d906d65501 100644 --- a/actions/public.php +++ b/actions/public.php @@ -222,14 +222,12 @@ class PublicAction extends Action function showSections() { - // $top = new TopPostersSection($this); - // $top->show(); $pop = new PopularNoticeSection($this); $pop->show(); + $ibs = new InviteButtonSection($this); + $ibs->show(); $gbp = new GroupsByMembersSection($this); $gbp->show(); - $ptp = new PeopletagsBySubsSection($this); - $ptp->show(); $feat = new FeaturedUsersSection($this); $feat->show(); } diff --git a/actions/register.php b/actions/register.php index e5f3ef1080..f4ad38ef7c 100644 --- a/actions/register.php +++ b/actions/register.php @@ -605,48 +605,53 @@ class RegisterAction extends Action */ function showSuccessContent() { - $nickname = $this->arg('nickname'); + if (Event::handle('onStartRegisterSuccess', array($this))) { - $profileurl = common_local_url('showstream', - array('nickname' => $nickname)); + $nickname = $this->arg('nickname'); - $this->elementStart('div', 'success'); - // TRANS: Text displayed after successful account registration. - // TRANS: %1$s is the registered nickname, %2$s is the profile URL. - // TRANS: This message contains Markdown links in the form [link text](link) - // TRANS: and variables in the form %%%%variable%%%%. Please mind the syntax. - $instr = sprintf(_('Congratulations, %1$s! And welcome to %%%%site.name%%%%. '. - 'From here, you may want to...'. "\n\n" . - '* Go to [your profile](%2$s) '. - 'and post your first message.' . "\n" . - '* Add a [Jabber/GTalk address]'. - '(%%%%action.imsettings%%%%) '. - 'so you can send notices '. - 'through instant messages.' . "\n" . - '* [Search for people](%%%%action.peoplesearch%%%%) '. - 'that you may know or '. - 'that share your interests. ' . "\n" . - '* Update your [profile settings]'. - '(%%%%action.profilesettings%%%%)'. - ' to tell others more about you. ' . "\n" . - '* Read over the [online docs](%%%%doc.help%%%%)'. - ' for features you may have missed. ' . "\n\n" . - 'Thanks for signing up and we hope '. - 'you enjoy using this service.'), - $nickname, $profileurl); + $profileurl = common_local_url('showstream', + array('nickname' => $nickname)); - $this->raw(common_markup_to_html($instr)); + $this->elementStart('div', 'success'); + // TRANS: Text displayed after successful account registration. + // TRANS: %1$s is the registered nickname, %2$s is the profile URL. + // TRANS: This message contains Markdown links in the form [link text](link) + // TRANS: and variables in the form %%%%variable%%%%. Please mind the syntax. + $instr = sprintf(_('Congratulations, %1$s! And welcome to %%%%site.name%%%%. '. + 'From here, you may want to...'. "\n\n" . + '* Go to [your profile](%2$s) '. + 'and post your first message.' . "\n" . + '* Add a [Jabber/GTalk address]'. + '(%%%%action.imsettings%%%%) '. + 'so you can send notices '. + 'through instant messages.' . "\n" . + '* [Search for people](%%%%action.peoplesearch%%%%) '. + 'that you may know or '. + 'that share your interests. ' . "\n" . + '* Update your [profile settings]'. + '(%%%%action.profilesettings%%%%)'. + ' to tell others more about you. ' . "\n" . + '* Read over the [online docs](%%%%doc.help%%%%)'. + ' for features you may have missed. ' . "\n\n" . + 'Thanks for signing up and we hope '. + 'you enjoy using this service.'), + $nickname, $profileurl); - $have_email = $this->trimmed('email'); - if ($have_email) { - // TRANS: Instruction text on how to deal with the e-mail address confirmation e-mail. - $emailinstr = _('(You should receive a message by email '. - 'momentarily, with ' . - 'instructions on how to confirm '. - 'your email address.)'); - $this->raw(common_markup_to_html($emailinstr)); + $this->raw(common_markup_to_html($instr)); + + $have_email = $this->trimmed('email'); + if ($have_email) { + // TRANS: Instruction text on how to deal with the e-mail address confirmation e-mail. + $emailinstr = _('(You should receive a message by email '. + 'momentarily, with ' . + 'instructions on how to confirm '. + 'your email address.)'); + $this->raw(common_markup_to_html($emailinstr)); + } + $this->elementEnd('div'); + + Event::handle('onEndRegisterSuccess', array($this)); } - $this->elementEnd('div'); } /** @@ -656,15 +661,23 @@ class RegisterAction extends Action */ function showLocalNav() { - $nav = new LoginGroupNav($this); - $nav->show(); - } - - function showNoticeForm() - { + if (common_logged_in()) { + parent::showLocalNav(); + } else { + $nav = new LoginGroupNav($this); + $nav->show(); + } } + /** + * Show a bit of login context + * + * @return nothing + */ function showProfileBlock() { + if (common_logged_in()) { + parent::showProfileBlock(); + } } } diff --git a/actions/showprofiletag.php b/actions/showprofiletag.php index 29ecf4788f..07603d5a4b 100644 --- a/actions/showprofiletag.php +++ b/actions/showprofiletag.php @@ -33,7 +33,7 @@ require_once INSTALLDIR.'/lib/feedlist.php'; class ShowprofiletagAction extends Action { - var $notice, $tagger, $peopletag; + var $notice, $tagger, $peopletag, $userProfile; function isReadOnly($args) { @@ -88,7 +88,12 @@ class ShowprofiletagAction extends Action } $this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1; - $this->notice = $this->peopletag->getNotices(($this->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1); + $this->userProfile = Profile::current(); + + $stream = new PeopletagNoticeStream($this->peopletag, $this->userProfile); + + $this->notice = $stream->getNotices(($this->page-1)*NOTICES_PER_PAGE, + NOTICES_PER_PAGE + 1); if ($this->page > 1 && $this->notice->N == 0) { // TRANS: Server error when page not found (404). @@ -117,7 +122,7 @@ class ShowprofiletagAction extends Action if($this->peopletag->private) { // TRANS: Title for private people tag timeline. // TRANS: %1$s is a people tag, %2$s is a page number. - return sprintf(_('Private timeline for people tagged %1$s by you, page %2$d'), + return sprintf(_('Private timeline for %1$s list by you, page %2$d'), $this->peopletag->tag, $this->page); } @@ -125,13 +130,13 @@ class ShowprofiletagAction extends Action if (!empty($current) && $current->id == $this->peopletag->tagger) { // TRANS: Title for public people tag timeline where the viewer is the tagger. // TRANS: %1$s is a people tag, %2$s is a page number. - return sprintf(_('Timeline for people tagged %1$s by you, page %2$d'), + return sprintf(_('Timeline for %1$s list by you, page %2$d'), $this->peopletag->tag, $this->page); } // TRANS: Title for private people tag timeline. // TRANS: %1$s is a people tag, %2$s is the tagger's nickname, %3$d is a page number. - return sprintf(_('Timeline for people tagged %1$s by %2$s, page %3$d'), + return sprintf(_('Timeline for %1$s list by %2$s, page %3$d'), $this->peopletag->tag, $this->tagger->nickname, $this->page @@ -140,7 +145,7 @@ class ShowprofiletagAction extends Action if($this->peopletag->private) { // TRANS: Title for private people tag timeline. // TRANS: %s is a people tag. - return sprintf(_('Private timeline of people tagged %s by you'), + return sprintf(_('Private timeline of %s list by you'), $this->peopletag->tag); } @@ -148,13 +153,13 @@ class ShowprofiletagAction extends Action if (!empty($current) && $current->id == $this->peopletag->tagger) { // TRANS: Title for public people tag timeline where the viewer is the tagger. // TRANS: %s is a people tag. - return sprintf(_('Timeline for people tagged %s by you'), + return sprintf(_('Timeline for %s list by you'), $this->peopletag->tag); } // TRANS: Title for private people tag timeline. // TRANS: %1$s is a people tag, %2$s is the tagger's nickname. - return sprintf(_('Timeline for people tagged %1$s by %2$s'), + return sprintf(_('Timeline for %1$s list by %2$s'), $this->peopletag->tag, $this->tagger->nickname ); @@ -185,7 +190,7 @@ class ShowprofiletagAction extends Action ), // TRANS: Feed title. // TRANS: %1$s is a people tag, %2$s is tagger's nickname. - sprintf(_('Feed for people tagged %1$s by %2$s (Atom)'), + sprintf(_('Feed for %1$s list by %2$s (Atom)'), $this->peopletag->tag, $this->tagger->nickname ) ) @@ -202,7 +207,7 @@ class ShowprofiletagAction extends Action { // TRANS: Empty list message for people tag timeline. // TRANS: %1$s is a people tag, %2$s is a tagger's nickname. - $message = sprintf(_('This is the timeline for people tagged %1$s 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->tagger->nickname) . ' '; @@ -239,7 +244,7 @@ class ShowprofiletagAction extends Action function showNotices() { if (Event::handle('StartShowProfileTagContent', array($this))) { - $nl = new NoticeList($this->notice, $this); + $nl = new ThreadedNoticeList($this->notice, $this, $this->userProfile); $cnt = $nl->show(); @@ -247,10 +252,12 @@ class ShowprofiletagAction extends Action $this->showEmptyListMessage(); } - $this->pagination( - $this->page > 1, $cnt > NOTICES_PER_PAGE, - $this->page, 'showprofiletag', array('tag' => $this->peopletag->tag, - 'tagger' => $this->tagger->nickname) + $this->pagination($this->page > 1, + $cnt > NOTICES_PER_PAGE, + $this->page, + 'showprofiletag', + array('tag' => $this->peopletag->tag, + 'tagger' => $this->tagger->nickname) ); Event::handle('EndShowProfileTagContent', array($this)); @@ -284,11 +291,11 @@ class ShowprofiletagAction extends Action if(!empty($current) && $this->peopletag->tagger == $current->id) { // TRANS: Header on show profile tag page. // TRANS: %s is a people tag. - $title = sprintf(_('People tagged %s by you'), $this->peopletag->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(_('People tagged %1$s by %2$s'), + $title = sprintf(_('Listed'), $this->peopletag->tag, $this->tagger->nickname); } diff --git a/actions/showstream.php b/actions/showstream.php index a2320909fc..fe819d30cf 100644 --- a/actions/showstream.php +++ b/actions/showstream.php @@ -103,12 +103,6 @@ class ShowstreamAction extends ProfileAction $this->showNotices(); } - function showObjectNav() - { - $nav = new SubGroupNav($this, $this->user); - $nav->show(); - } - function showProfileBlock() { $block = new AccountProfileBlock($this, $this->profile); diff --git a/actions/subscribers.php b/actions/subscribers.php index ad522a4bae..9e1fb4cf73 100644 --- a/actions/subscribers.php +++ b/actions/subscribers.php @@ -135,11 +135,6 @@ class SubscribersAction extends GalleryAction function showSections() { parent::showSections(); - $cloud = new SubscribersPeopleTagCloudSection($this); - $cloud->show(); - - $cloud2 = new SubscribersPeopleSelfTagCloudSection($this); - $cloud2->show(); } } diff --git a/actions/subscriptions.php b/actions/subscriptions.php index cfe2b5683a..9fc4656ac2 100644 --- a/actions/subscriptions.php +++ b/actions/subscriptions.php @@ -152,16 +152,6 @@ class SubscriptionsAction extends GalleryAction $this->elementEnd('div'); } - function showSections() - { - parent::showSections(); - $cloud = new SubscriptionsPeopleTagCloudSection($this); - $cloud->show(); - - $cloud2 = new SubscriptionsPeopleSelfTagCloudSection($this); - $cloud2->show(); - } - /** * Link to feeds of subscriptions * diff --git a/actions/tag.php b/actions/tag.php index 045fac97b5..f3514bef55 100644 --- a/actions/tag.php +++ b/actions/tag.php @@ -55,12 +55,6 @@ class TagAction extends Action return true; } - function showSections() - { - $pop = new PopularNoticeSection($this); - $pop->show(); - } - function title() { if ($this->page == 1) { diff --git a/actions/usergroups.php b/actions/usergroups.php index f9063d8867..ca95abddf5 100644 --- a/actions/usergroups.php +++ b/actions/usergroups.php @@ -45,7 +45,7 @@ require_once INSTALLDIR.'/lib/grouplist.php'; * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ -class UsergroupsAction extends OwnerDesignAction +class UsergroupsAction extends ProfileAction { var $page = null; var $profile = null; @@ -115,12 +115,6 @@ class UsergroupsAction extends OwnerDesignAction $this->showPage(); } - function showObjectNav() - { - $nav = new SubGroupNav($this, $this->user); - $nav->show(); - } - function showContent() { $this->elementStart('p', array('id' => 'new_group')); diff --git a/classes/Notice.php b/classes/Notice.php index 70036fa8fb..ada4d495d2 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -545,12 +545,6 @@ class Notice extends Memcached_DataObject $notice->saveKnownGroups($groups); - if (isset($peopletags)) { - $notice->saveProfileTags($peopletags); - } else { - $notice->saveProfileTags(); - } - if (isset($urls)) { $notice->saveKnownUrls($urls); } else { @@ -596,6 +590,11 @@ class Notice extends Memcached_DataObject if (!empty($profile)) { $profile->blowNoticeCount(); } + + $ptags = $this->getProfileTags(); + foreach ($ptags as $ptag) { + $ptag->blowNoticeStreamCache(); + } } /** @@ -618,6 +617,11 @@ class Notice extends Memcached_DataObject // In case we're the first, will need to calc a new root. self::blow('notice:conversation_root:%d', $this->conversation); } + + $ptags = $this->getProfileTags(); + foreach ($ptags as $ptag) { + $ptag->blowNoticeStreamCache(true); + } } /** save all urls in the notice to the db @@ -1030,34 +1034,14 @@ class Notice extends Memcached_DataObject function getProfileTags() { - // Don't save ptags for repeats, for now. + $profile = $this->getProfile(); + $list = $profile->getOtherTags($profile); + $ptags = array(); - if (!empty($this->repeat_of)) { - return array(); + while($list->fetch()) { + $ptags[] = clone($list); } - // XXX: cache me - - $ptags = array(); - - $ptagi = new Profile_tag_inbox(); - - $ptagi->selectAdd(); - $ptagi->selectAdd('profile_tag_id'); - - $ptagi->notice_id = $this->id; - - if ($ptagi->find()) { - while ($ptagi->fetch()) { - $profile_list = Profile_list::staticGet('id', $ptagi->profile_tag_id); - if ($profile_list) { - $ptags[] = $profile_list; - } - } - } - - $ptagi->free(); - return $ptags; } @@ -1173,72 +1157,6 @@ class Notice extends Memcached_DataObject return true; } - /** - * record targets into profile_tag_inbox. - * @return array of Profile_list objects - */ - function saveProfileTags($known=array()) - { - // Don't save ptags for repeats, for now - - if (!empty($this->repeat_of)) { - return array(); - } - - if (is_array($known)) { - $ptags = $known; - } else { - $ptags = array(); - } - - $ptag = new Profile_tag(); - $ptag->tagged = $this->profile_id; - - if($ptag->find()) { - while($ptag->fetch()) { - $plist = Profile_list::getByTaggerAndTag($ptag->tagger, $ptag->tag); - if (!empty($plist)) { - $ptags[] = clone($plist); - } - } - } - - foreach ($ptags as $target) { - $this->addToProfileTagInbox($target); - } - - return $ptags; - } - - function addToProfileTagInbox($plist) - { - $ptagi = Profile_tag_inbox::pkeyGet(array('profile_tag_id' => $plist->id, - 'notice_id' => $this->id)); - - if (empty($ptagi)) { - - $ptagi = new Profile_tag_inbox(); - - $ptagi->query('BEGIN'); - $ptagi->profile_tag_id = $plist->id; - $ptagi->notice_id = $this->id; - $ptagi->created = $this->created; - - $result = $ptagi->insert(); - if (!$result) { - common_log_db_error($ptagi, 'INSERT', __FILE__); - // TRANS: Server exception thrown when saving profile_tag inbox fails. - throw new ServerException(_('Problem saving profile_tag inbox.')); - } - - $ptagi->query('COMMIT'); - - self::blow('profile_tag:notice_ids:%d', $ptagi->profile_tag_id); - } - - return true; - } - /** * Save reply records indicating that this notice needs to be * delivered to the local users with the given URIs. diff --git a/classes/Profile.php b/classes/Profile.php index a47744a124..b9c50905a7 100644 --- a/classes/Profile.php +++ b/classes/Profile.php @@ -68,9 +68,17 @@ class Profile extends Memcached_DataObject if (is_null($height)) { $height = $width; } - return Avatar::pkeyGet(array('profile_id' => $this->id, - 'width' => $width, - 'height' => $height)); + + $avatar = null; + + if (Event::handle('StartProfileGetAvatar', array($this, $width, &$avatar))) { + $avatar = Avatar::pkeyGet(array('profile_id' => $this->id, + 'width' => $width, + 'height' => $height)); + Event::handle('EndProfileGetAvatar', array($this, $width, &$avatar)); + } + + return $avatar; } function getOriginalAvatar() @@ -1315,4 +1323,42 @@ class Profile extends Memcached_DataObject } 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); + } } diff --git a/classes/Profile_list.php b/classes/Profile_list.php index 4fd731c9b2..17c2ffd4f4 100644 --- a/classes/Profile_list.php +++ b/classes/Profile_list.php @@ -170,51 +170,6 @@ class Profile_list extends Memcached_DataObject return $stream->getNotices($offset, $limit, $since_id, $max_id); } - /** - * Query notices by users associated with this tag from the database. - * - * @param integer $offset offset - * @param integer $limit maximum no of results - * @param integer $since_id=null since this id - * @param integer $max_id=null maximum id in result - * - * @return array array of notice ids. - */ - - function _streamDirect($offset, $limit, $since_id, $max_id) - { - $inbox = new Profile_tag_inbox(); - - $inbox->profile_tag_id = $this->id; - - $inbox->selectAdd(); - $inbox->selectAdd('notice_id'); - - if ($since_id != 0) { - $inbox->whereAdd('notice_id > ' . $since_id); - } - - if ($max_id != 0) { - $inbox->whereAdd('notice_id <= ' . $max_id); - } - - $inbox->orderBy('notice_id DESC'); - - if (!is_null($offset)) { - $inbox->limit($offset, $limit); - } - - $ids = array(); - - if ($inbox->find()) { - while ($inbox->fetch()) { - $ids[] = $inbox->notice_id; - } - } - - return $ids; - } - /** * Get subscribers (local and remote) to this people tag * Order by reverse chronology @@ -371,6 +326,8 @@ class Profile_list extends Memcached_DataObject Profile_tag::cleanup($this); Profile_tag_subscription::cleanup($this); + self::blow('profile:lists:%d', $this->tagger); + return parent::delete(); } @@ -467,18 +424,24 @@ class Profile_list extends Memcached_DataObject function taggedCount($recount=false) { - if (!$recount) { - return $this->tagged_count; + $keypart = sprintf('profile_list:tagged_count:%d:%s', + $this->tagger, + $this->tag); + + $count = self::cacheGet($keypart); + + if ($count === false) { + $tags = new Profile_tag(); + + $tags->tag = $this->tag; + $tags->tagger = $this->tagger; + + $count = $tags->count('distinct tagged'); + + self::cacheSet($keypart, $count); } - $tags = new Profile_tag(); - $tags->tag = $this->tag; - $tags->tagger = $this->tagger; - $orig = clone($this); - $this->tagged_count = (int) $tags->count('distinct tagged'); - $this->update($orig); - - return $this->tagged_count; + return $count; } /** @@ -492,17 +455,38 @@ class Profile_list extends Memcached_DataObject function subscriberCount($recount=false) { - if ($recount) { - return $this->subscriber_count; + $keypart = sprintf('profile_list:subscriber_count:%d', + $this->id); + + $count = self::cacheGet($keypart); + + if ($count === false) { + + $sub = new Profile_tag_subscription(); + $sub->profile_tag_id = $this->id; + $count = (int) $sub->count('distinct profile_id'); + + self::cacheSet($keypart, $count); } - $sub = new Profile_tag_subscription(); - $sub->profile_tag_id = $this->id; - $orig = clone($this); - $this->subscriber_count = (int) $sub->count('distinct profile_id'); - $this->update($orig); + return $count; + } - return $this->subscriber_count; + /** + * get the cached number of profiles subscribed to this + * people tag, re-count if the argument is true. + * + * @param boolean $recount whether to ignore cache + * + * @return integer count + */ + + function blowNoticeStreamCache($all=false) + { + self::blow('profile_list:notice_ids:%d', $this->id); + if ($all) { + self::blow('profile_list:notice_ids:%d;last', $this->id); + } } /** @@ -928,4 +912,13 @@ class Profile_list extends Memcached_DataObject return new ArrayWrapper($wrapped); } } + + function insert() + { + $result = parent::insert(); + if ($result) { + self::blow('profile:lists:%d', $this->tagger); + } + return $result; + } } diff --git a/classes/Profile_tag.php b/classes/Profile_tag.php index d7841bd8ca..00585280d3 100644 --- a/classes/Profile_tag.php +++ b/classes/Profile_tag.php @@ -291,4 +291,26 @@ class Profile_tag extends Memcached_DataObject } return true; } + + function insert() + { + $result = parent::insert(); + if ($result) { + self::blow('profile_list:tagged_count:%d:%s', + $this->tagger, + $this->tag); + } + return $result; + } + + function delete() + { + $result = parent::delete(); + if ($result) { + self::blow('profile_list:tagged_count:%d:%s', + $this->tagger, + $this->tag); + } + return $result; + } } diff --git a/classes/Profile_tag_inbox.php b/classes/Profile_tag_inbox.php deleted file mode 100644 index dd517b3088..0000000000 --- a/classes/Profile_tag_inbox.php +++ /dev/null @@ -1,27 +0,0 @@ -profile_tag_id); + } + return $result; + } + + function delete() + { + $result = parent::delete(); + if ($result) { + self::blow('profile_list:subscriber_count:%d', + $this->profile_tag_id); + } + return $result; + } } diff --git a/classes/statusnet.ini b/classes/statusnet.ini index 05f339ca5a..bdf96c1ddc 100644 --- a/classes/statusnet.ini +++ b/classes/statusnet.ini @@ -480,15 +480,6 @@ id = U tagger = K tag = K -[profile_tag_inbox] -profile_tag_id = 129 -notice_id = 129 -created = 142 - -[profile_tag_inbox__keys] -profile_tag_id = K -notice_id = K - [profile_tag_subscription] profile_tag_id = 129 profile_id = 129 diff --git a/classes/statusnet.links.ini b/classes/statusnet.links.ini index 28bf03fd45..17a8c40085 100644 --- a/classes/statusnet.links.ini +++ b/classes/statusnet.links.ini @@ -11,6 +11,7 @@ id = profile:id [notice] profile_id = profile:id reply_to = notice:id +profile_id = profile_tag:tagged [reply] notice_id = notice:id @@ -67,10 +68,6 @@ tagged = profile:id [profile_list] tagger = profile:id -[profile_tag_inbox] -profile_tag_id = profile_list:id -notice_id = notice:id - [profile_tag_subscription] profile_tag_id = profile_list:id profile_id = profile:id diff --git a/lib/action.php b/lib/action.php index f626c04480..0234d2fa23 100644 --- a/lib/action.php +++ b/lib/action.php @@ -1354,13 +1354,16 @@ class Action extends HTMLOutputter // lawsuit * * @return nothing */ - function menuItem($url, $text, $title=null, $is_selected=false, $id=null) + function menuItem($url, $text, $title=null, $is_selected=false, $id=null, $class=null) { // Added @id to li for some control. // XXX: We might want to move this to htmloutputter.php $lattrs = array(); - if ($is_selected) { - $lattrs['class'] = 'current'; + if ($class !== null) { + $lattrs['class'] = $class; + if ($is_selected) { + $lattrs['class'] = trim('current ' . $lattrs['class']); + } } (is_null($id)) ? $lattrs : $lattrs['id'] = $id; diff --git a/lib/default.php b/lib/default.php index 11456ec4d0..c58db28f51 100644 --- a/lib/default.php +++ b/lib/default.php @@ -190,9 +190,9 @@ $default = 'user' => false, 'group' => false), 'emailpost' => - array('enabled' => true), + array('enabled' => false), 'sms' => - array('enabled' => true), + array('enabled' => false), 'twitterimport' => array('enabled' => false), 'integration' => diff --git a/lib/defaultlocalnav.php b/lib/defaultlocalnav.php index 84a6267ac9..ffef87480c 100644 --- a/lib/defaultlocalnav.php +++ b/lib/defaultlocalnav.php @@ -72,6 +72,14 @@ class DefaultLocalNav extends Menu } } + if (!empty($user)) { + $sn = new ListsNav($this->action, $user->getProfile()); + if ($sn->hasLists()) { + // TRANS: Menu item in default local navigation panel. + $this->submenu(_m('MENU', 'Lists'), $sn); + } + } + Event::handle('EndDefaultLocalNav', array($this, $user)); } diff --git a/lib/featureduserssection.php b/lib/featureduserssection.php index 8dacdc332d..1b0718a05f 100644 --- a/lib/featureduserssection.php +++ b/lib/featureduserssection.php @@ -42,6 +42,15 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { */ class FeaturedUsersSection extends ProfileSection { + function show() + { + $featured_nicks = common_config('nickname', 'featured'); + if (empty($featured_nicks)) { + return; + } + parent::show(); + } + function getProfiles() { $featured_nicks = common_config('nickname', 'featured'); diff --git a/lib/galleryaction.php b/lib/galleryaction.php index ac2feeeccf..bd7da195fa 100644 --- a/lib/galleryaction.php +++ b/lib/galleryaction.php @@ -28,7 +28,7 @@ require_once INSTALLDIR.'/lib/profilelist.php'; define('AVATARS_PER_PAGE', 80); // @todo FIXME: Class documentation missing. -class GalleryAction extends OwnerDesignAction +class GalleryAction extends ProfileAction { var $profile = null; var $page = null; @@ -97,12 +97,6 @@ class GalleryAction extends OwnerDesignAction $this->showPage(); } - function showObjectNav() - { - $nav = new SubGroupNav($this, $this->user); - $nav->show(); - } - function showContent() { $this->showTagsDropdown(); diff --git a/lib/groupminilist.php b/lib/groupminilist.php index dff81eff53..0a50f62b6e 100644 --- a/lib/groupminilist.php +++ b/lib/groupminilist.php @@ -33,7 +33,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { require_once INSTALLDIR.'/lib/grouplist.php'; -define('GROUPS_PER_MINILIST', 27); +define('GROUPS_PER_MINILIST', 8); /** * Widget to show a list of groups, good for sidebar diff --git a/lib/groupsbymemberssection.php b/lib/groupsbymemberssection.php index 5cf1a563c0..4cb8ed46f0 100644 --- a/lib/groupsbymemberssection.php +++ b/lib/groupsbymemberssection.php @@ -68,7 +68,7 @@ class GroupsByMembersSection extends GroupSection function title() { // TRANS: Title for groups with the most members section. - return _('Groups with most members'); + return _('Popular groups'); } function divId() diff --git a/lib/groupsbypostssection.php b/lib/groupsbypostssection.php index 50d60e87cb..c338ab7e97 100644 --- a/lib/groupsbypostssection.php +++ b/lib/groupsbypostssection.php @@ -68,7 +68,7 @@ class GroupsByPostsSection extends GroupSection function title() { // TRANS: Title for groups with the most posts section. - return _('Groups with most posts'); + return _('Active groups'); } function divId() diff --git a/lib/invitebuttonsection.php b/lib/invitebuttonsection.php new file mode 100644 index 0000000000..4812e47880 --- /dev/null +++ b/lib/invitebuttonsection.php @@ -0,0 +1,63 @@ +. + * + * @category Section + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +if (!defined('STATUSNET')) { + // This check helps protect against security problems; + // your code file can't be executed directly from the web. + exit(1); +} + +/** + * Invite button + * + * @category Section + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +class InviteButtonSection extends Section +{ + function showTitle() + { + return false; + } + + function showContent() + { + $this->out->element('a', + array('href' => common_local_url('invite'), + 'class' => 'invite_button'), + _('Invite more colleagues')); + return false; + } +} \ No newline at end of file diff --git a/lib/listsnav.php b/lib/listsnav.php new file mode 100644 index 0000000000..67d8941ba3 --- /dev/null +++ b/lib/listsnav.php @@ -0,0 +1,90 @@ +. + * + * @category Widget + * @package StatusNet + * @author Shashi Gowda + * @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); +} + +/** + * Peopletags a user has subscribed to + * + * @category Widget + * @package StatusNet + * @author Shashi Gowda + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://status.net/ + */ +class ListsNav extends Menu +{ + var $profile=null; + var $lists=null; + + function __construct($out, Profile $profile) + { + parent::__construct($out); + $this->profile = $profile; + + $user = common_current_user(); + + $this->lists = $profile->getOwnedTags($user); + } + + function show() + { + $action = $this->actionName; + + $this->out->elementStart('ul', array('class' => 'nav')); + + if (Event::handle('StartListsNav', array($this))) { + + while ($this->lists->fetch()) { + $mode = $this->lists->private ? 'private' : 'public'; + $this->out->menuItem(($this->lists->mainpage) ? + $this->lists->mainpage : + common_local_url('showprofiletag', + array('tagger' => $this->profile->nickname, + 'tag' => $this->lists->tag)), + $this->lists->tag, + '', + $action == 'showprofiletag' && + $this->action->arg('tagger') == $this->profile->nickname && + $this->action->arg('tag') == $this->lists->tag, + 'nav_timeline_list_'.$this->lists->id, + 'mode-' . $mode); + } + Event::handle('EndListsNav', array($this)); + } + + $this->out->elementEnd('ul'); + } + + function hasLists() + { + return (!empty($this->lists) && $this->lists->N > 0); + } +} diff --git a/lib/peopletageditform.php b/lib/peopletageditform.php index 27920008a8..9fb824bdbc 100644 --- a/lib/peopletageditform.php +++ b/lib/peopletageditform.php @@ -107,7 +107,7 @@ class PeopletagEditForm extends Form { // TRANS: Form legend for people tag edit form. // TRANS: %s is a people tag. - $this->out->element('legend', null, sprintf(_('Edit people tag %s'), $this->peopletag->tag)); + $this->out->element('legend', null, sprintf(_('Edit list %s'), $this->peopletag->tag)); } /** @@ -138,12 +138,12 @@ class PeopletagEditForm extends Form $desclimit = Profile_list::maxDescription(); if ($desclimit == 0) { // TRANS: Field title for description of people tag. - $descinstr = _('Describe the people tag or topic.'); + $descinstr = _('Describe the list or topic.'); } else { // TRANS: Field title for description of people tag. // TRANS: %d is the maximum number of characters for the description. - $descinstr = sprintf(_m('Describe the people tag or topic in %d character.', - 'Describe the people tag or topic in %d characters.', + $descinstr = sprintf(_m('Describe the list or topic in %d character.', + 'Describe the list or topic in %d characters.', $desclimit), $desclimit); } @@ -172,7 +172,7 @@ class PeopletagEditForm extends Form 'submit', 'delete', // TRANS: Button title to delete a people tag. - _('Delete this people tag.')); + _('Delete this list.')); } function showProfileList() diff --git a/lib/peopletaggroupnav.php b/lib/peopletaggroupnav.php index 5c95487247..a93499ce76 100644 --- a/lib/peopletaggroupnav.php +++ b/lib/peopletaggroupnav.php @@ -104,10 +104,10 @@ class PeopletagGroupNav extends Widget $this->out->menuItem(common_local_url('showprofiletag', array('tagger' => $user_profile->nickname, 'tag' => $tag->tag)), // TRANS: Menu item in people tag navigation panel. - _m('MENU','People tag'), + _m('MENU','List'), // TRANS: Menu item title in people tag navigation panel. // TRANS: %1$s is a tag, %2$s is a nickname. - sprintf(_('%1$s tag by %2$s.'), $tag->tag, + sprintf(_('%1$s list by %2$s.'), $tag->tag, (($user_profile && $user_profile->fullname) ? $user_profile->fullname : $nickname)), $action == 'showprofiletag', 'nav_timeline_peopletag'); @@ -115,10 +115,10 @@ class PeopletagGroupNav extends Widget $this->out->menuItem(common_local_url('peopletagged', array('tagger' => $user->nickname, 'tag' => $tag->tag)), // TRANS: Menu item in people tag navigation panel. - _m('MENU','Tagged'), + _m('MENU','Listed'), // TRANS: Menu item title in people tag navigation panel. // TRANS: %1$s is a tag, %2$s is a nickname. - sprintf(_('%1$s tag by %2$s.'), $tag->tag, + sprintf(_('%1$s list by %2$s.'), $tag->tag, (($user_profile && $user_profile->fullname) ? $user_profile->fullname : $nickname)), $action == 'peopletagged', 'nav_peopletag_tagged'); @@ -129,7 +129,7 @@ class PeopletagGroupNav extends Widget _m('MENU','Subscribers'), // TRANS: Menu item title in people tag navigation panel. // TRANS: %1$s is a tag, %2$s is a nickname. - sprintf(_('Subscribers to %1$s tag 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)), $action == 'peopletagsubscribers', 'nav_peopletag_subscribers'); @@ -142,7 +142,7 @@ class PeopletagGroupNav extends Widget _m('MENU','Edit'), // TRANS: Menu item title in people tag navigation panel. // TRANS: %s is a tag. - sprintf(_('Edit %s tag by you.'), $tag->tag, + sprintf(_('Edit %s list by you.'), $tag->tag, (($user_profile && $user_profile->fullname) ? $user_profile->fullname : $nickname)), $action == 'editpeopletag', 'nav_peopletag_edit'); } diff --git a/lib/peopletaglist.php b/lib/peopletaglist.php index 729ff8814e..10ebc8cb9e 100644 --- a/lib/peopletaglist.php +++ b/lib/peopletaglist.php @@ -193,7 +193,7 @@ class PeopletagListItem extends Widget common_local_url('editpeopletag', array('tagger' => $this->profile->nickname, 'tag' => $this->peopletag->tag)), // TRANS: Title for link to edit people tag settings. - 'title' => _('Edit people tag settings.')), + 'title' => _('Edit list settings.')), // TRANS: Text for link to edit people tag settings. _('Edit')); $this->out->elementEnd('li'); diff --git a/lib/peopletagnav.php b/lib/peopletagnav.php new file mode 100644 index 0000000000..cc03b59a35 --- /dev/null +++ b/lib/peopletagnav.php @@ -0,0 +1,106 @@ +. + * + * @category Action + * @package StatusNet + * @author Shashi Gowda + * @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); +} + +require_once INSTALLDIR.'/lib/widget.php'; + +/** + * Tabset for a group + * + * Shows a group of tabs for a particular user group + * + * @category Output + * @package StatusNet + * @author Shashi Gowda + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://status.net/ + * + * @see HTMLOutputter + */ +class PeopletagNav extends Menu +{ + var $group = null; + + /** + * Construction + * + * @param Action $action current action, used for output + */ + function __construct($action=null, $profile=null) + { + parent::__construct($action); + $this->profile = $profile; + } + + /** + * Show the menu + * + * @return void + */ + function show() + { + $action_name = $this->action->trimmed('action'); + $nickname = $this->profile->nickname; + + $this->out->elementStart('ul', array('class' => 'nav')); + if (Event::handle('StartPeopletagGroupNav', array($this))) { + $this->out->menuItem(common_local_url('peopletagsubscriptions', array('nickname' => + $nickname)), + // TRANS: Menu item in the group navigation page. + _m('MENU','List Subscriptions'), + // TRANS: Tooltip for menu item in the group navigation page. + // TRANS: %s is the nickname of the group. + sprintf(_m('TOOLTIP','Lists subscribed to by %s'), $nickname), + $action_name == 'peopletagsubscriptions', + 'nav_list_group'); + $this->out->menuItem(common_local_url('peopletagsforuser', array('nickname' => + $nickname)), + // TRANS: Menu item in the group navigation page. + sprintf(_m('MENU','Lists with %s'), $nickname), + // TRANS: Tooltip for menu item in the group navigation page. + // TRANS: %s is the nickname of the group. + sprintf(_m('TOOLTIP','Lists with %s'), $nickname), + $action_name == 'peopletagsforuser', + 'nav_lists_with'); + $this->out->menuItem(common_local_url('peopletagsbyuser', array('nickname' => + $nickname)), + // TRANS: Menu item in the group navigation page. + sprintf(_m('MENU','Lists by %s'), $nickname), + // TRANS: Tooltip for menu item in the group navigation page. + // TRANS: %s is the nickname of the group. + sprintf(_m('TOOLTIP','Lists by %s'), $nickname), + $action_name == 'peopletagsbyuser', + 'nav_lists_by'); + Event::handle('EndGroupGroupNav', array($this)); + } + $this->out->elementEnd('ul'); + } +} diff --git a/lib/peopletagnoticestream.php b/lib/peopletagnoticestream.php index 5eed25412f..f90255b111 100644 --- a/lib/peopletagnoticestream.php +++ b/lib/peopletagnoticestream.php @@ -53,7 +53,7 @@ class PeopletagNoticeStream extends ScopingNoticeStream $profile = Profile::current(); } parent::__construct(new CachingNoticeStream(new RawPeopletagNoticeStream($plist), - 'profile_tag:notice_ids:' . $plist->id), + 'profile_list:notice_ids:' . $plist->id), $profile); } } @@ -71,36 +71,54 @@ class PeopletagNoticeStream extends ScopingNoticeStream */ class RawPeopletagNoticeStream extends NoticeStream { - protected $profile_tag; + protected $profile_list; - function __construct($profile_tag) + function __construct($profile_list) { - $this->profile_tag = $profile_tag; + $this->profile_list = $profile_list; } + /** + * Query notices by users associated with this tag from the database. + * + * @param integer $offset offset + * @param integer $limit maximum no of results + * @param integer $since_id=null since this id + * @param integer $max_id=null maximum id in result + * + * @return array array of notice ids. + */ + function getNoticeIds($offset, $limit, $since_id, $max_id) { - $inbox = new Profile_tag_inbox(); + $notice = new Notice(); - $inbox->profile_tag_id = $this->profile_tag->id; + $notice->selectAdd(); + $notice->selectAdd('notice.id'); - $inbox->selectAdd(); - $inbox->selectAdd('notice_id'); + $ptag = new Profile_tag(); + $ptag->tag = $this->profile_list->tag; + $ptag->tagger = $this->profile_list->tagger; + $notice->joinAdd($ptag); - Notice::addWhereSinceId($inbox, $since_id, 'notice_id'); - Notice::addWhereMaxId($inbox, $max_id, 'notice_id'); + if ($since_id != 0) { + $notice->whereAdd('notice.id > ' . $since_id); + } - $inbox->orderBy('created DESC, notice_id DESC'); + if ($max_id != 0) { + $notice->whereAdd('notice.id <= ' . $max_id); + } + + $notice->orderBy('notice.id DESC'); if (!is_null($offset)) { - $inbox->limit($offset, $limit); + $notice->limit($offset, $limit); } $ids = array(); - - if ($inbox->find()) { - while ($inbox->fetch()) { - $ids[] = $inbox->notice_id; + if ($notice->find()) { + while ($notice->fetch()) { + $ids[] = $notice->id; } } diff --git a/lib/peopletags.php b/lib/peopletags.php index faf408c895..ec8c04241d 100644 --- a/lib/peopletags.php +++ b/lib/peopletags.php @@ -124,7 +124,7 @@ class PeopletagsWidget extends Widget function showEditTagForm($tags=null) { - $this->out->elementStart('span', 'form_tag_user_wrap'); + $this->out->elementStart('div', 'form_tag_user_wrap'); $this->out->elementStart('form', array('method' => 'post', 'class' => 'form_tag_user', 'name' => 'tagprofile', @@ -147,7 +147,7 @@ class PeopletagsWidget extends Widget $this->out->elementEnd('fieldset'); $this->out->elementEnd('form'); - $this->out->elementEnd('span'); + $this->out->elementEnd('div'); } function showEmptyList() diff --git a/lib/peopletagsbysubssection.php b/lib/peopletagsbysubssection.php index d67b7fb88d..e1e3251f84 100644 --- a/lib/peopletagsbysubssection.php +++ b/lib/peopletagsbysubssection.php @@ -66,7 +66,7 @@ class PeopletagsBySubsSection extends PeopletagSection function title() { // TRANS: Title for section contaning people tags with the most subscribers. - return _('People tags with most subscribers'); + return _('Lists with most subscribers'); } function divId() diff --git a/lib/peopletagsection.php b/lib/peopletagsection.php index 20358cb85d..a6c587e04e 100644 --- a/lib/peopletagsection.php +++ b/lib/peopletagsection.php @@ -83,6 +83,7 @@ class PeopletagSection extends Section class PeopletagSectionItem extends PeopletagListItem { + function showStart() { } @@ -104,10 +105,11 @@ class PeopletagSectionItem extends PeopletagListItem common_log(LOG_WARNING, "Trying to show missing peopletag; skipping."); return; } + $mode = ($this->peopletag->private) ? 'private' : 'public'; $this->out->elementStart('tr'); - $this->out->elementStart('td', 'peopletag'); + $this->out->elementStart('td', 'peopletag mode-' . $mode); $this->showPeopletag(); $this->out->elementEnd('td'); @@ -121,11 +123,12 @@ class PeopletagSectionItem extends PeopletagListItem { // TRANS: Tag summary. %1$d is the number of users tagged with the tag, // TRANS: %2$d is the number of subscribers to the tag. - $title = sprintf(_('Tagged: %1$d Subscribers: %2$d'), + $title = sprintf(_('Listed: %1$d Subscribers: %2$d'), $this->peopletag->taggedCount(), $this->peopletag->subscriberCount()); $this->out->elementStart('span', 'entry-title tag'); + $this->out->element('a', array('rel' => 'bookmark', 'href' => $this->url(), diff --git a/lib/peopletagsforusersection.php b/lib/peopletagsforusersection.php index fef469eb8d..9f7879d9e1 100644 --- a/lib/peopletagsforusersection.php +++ b/lib/peopletagsforusersection.php @@ -62,13 +62,15 @@ class PeopletagsForUserSection extends PeopletagSection function title() { - $name = $this->profile->getBestName(); - if ($this->profile->id == common_current_user()->id) { - $name = 'you'; + $user = common_current_user(); + + if (!empty($user) && $this->profile->id == $user->id) { + return sprintf(_('Lists with you')); } - // TRANS: Title for page that displays which people tags a user has been tagged with. + // TRANS: Title for page that displays + // which people tags a user has been tagged with. // TRANS: %s is a profile name. - return sprintf(_('People tags for %s'), $name); + return sprintf(_('Lists with %s'), $this->profile->getBestName()); } function link() diff --git a/lib/peopletagsubscriptionssection.php b/lib/peopletagsubscriptionssection.php index 2182a3d834..ab90f7eb75 100644 --- a/lib/peopletagsubscriptionssection.php +++ b/lib/peopletagsubscriptionssection.php @@ -42,27 +42,28 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { class PeopletagSubscriptionsSection extends PeopletagSection { var $profile=null; + var $ptags=null; function __construct($out, Profile $profile) { parent::__construct($out); $this->profile = $profile; + + $limit = PEOPLETAGS_PER_SECTION+1; + $offset = 0; + + $this->ptags = $this->profile->getTagSubscriptions($offset, $limit); } function getPeopletags() { - $limit = PEOPLETAGS_PER_SECTION+1; - $offset = 0; - - $ptags = $this->profile->getTagSubscriptions($offset, $limit); - - return $ptags; + return $this->ptags; } function title() { // TRANS: Title for page that displays people tags a user has subscribed to. - return _('People tag subscriptions'); + return _('List subscriptions'); } function link() diff --git a/lib/personalgroupnav.php b/lib/personalgroupnav.php index 3b3a87ff0d..d379dcf528 100644 --- a/lib/personalgroupnav.php +++ b/lib/personalgroupnav.php @@ -103,18 +103,6 @@ class PersonalGroupNav extends Menu // TRANS: Replaces %s in '%s\'s favorite notices'. (Yes, we know we need to fix this.) ($user_profile) ? $name : _m('FIXME','User')), $mine && $action =='showfavorites', 'nav_timeline_favorites'); - $this->out->menuItem(common_local_url('peopletagsbyuser', array('nickname' => - $nickname)), - // TRANS: Menu item in personal group navigation menu. - _m('MENU','People tags'), - // @todo i18n FIXME: Need to make this two messages. - // TRANS: Menu item title in personal group navigation menu. - // TRANS: %s is a username. - sprintf(_('People tags by %s'), - // TRANS: Replaces %s in 'People tags by %s'. (Yes, we know we need to fix this.) - ($user_profile) ? $name : _('User')), - in_array($action, array('peopletagsbyuser', 'peopletagsforuser')), - 'nav_timeline_peopletags'); $cur = common_current_user(); diff --git a/lib/personaltagcloudsection.php b/lib/personaltagcloudsection.php index fd10ba14d6..a86bb23e8d 100644 --- a/lib/personaltagcloudsection.php +++ b/lib/personaltagcloudsection.php @@ -53,7 +53,7 @@ class PersonalTagCloudSection extends TagCloudSection function title() { // TRANS: Title for personal tag cloud section. %s is a user nickname. - return sprintf(_('Tags in %s\'s notices'), $this->user->nickname); + return sprintf(_('Tags'), $this->user->nickname); } function getTags() diff --git a/lib/profileaction.php b/lib/profileaction.php index cd3f5bcde5..c919cb6bed 100644 --- a/lib/profileaction.php +++ b/lib/profileaction.php @@ -97,8 +97,7 @@ class ProfileAction extends OwnerDesignAction $this->showSubscriptions(); $this->showSubscribers(); $this->showGroups(); - $this->showPeopletagSubs(); - $this->showPeopletags(); + $this->showLists(); $this->showStatistics(); } @@ -126,7 +125,9 @@ class ProfileAction extends OwnerDesignAction if (Event::handle('StartShowSubscriptionsMiniList', array($this))) { $this->elementStart('h2'); // TRANS: H2 text for user subscription statistics. - $this->statsSectionLink('subscriptions', _('Subscriptions')); + $this->statsSectionLink('subscriptions', _('Following')); + $this->text(' '); + $this->text($this->profile->subscriptionCount()); $this->elementEnd('h2'); $cnt = 0; @@ -140,13 +141,6 @@ class ProfileAction extends OwnerDesignAction } } - if ($cnt > PROFILES_PER_MINILIST) { - $this->elementStart('p'); - // TRANS: Text for user subscription statistics if user has more subscriptions than displayed. - $this->statsSectionLink('subscriptions', _('All subscriptions'), 'more'); - $this->elementEnd('p'); - } - Event::handle('EndShowSubscriptionsMiniList', array($this)); } $this->elementEnd('div'); @@ -163,7 +157,9 @@ class ProfileAction extends OwnerDesignAction $this->elementStart('h2'); // TRANS: H2 text for user subscriber statistics. - $this->statsSectionLink('subscribers', _('Subscribers')); + $this->statsSectionLink('subscribers', _('Followers')); + $this->text(' '); + $this->text($this->profile->subscriberCount()); $this->elementEnd('h2'); $cnt = 0; @@ -177,45 +173,12 @@ class ProfileAction extends OwnerDesignAction } } - if ($cnt > PROFILES_PER_MINILIST) { - $this->elementStart('p'); - // TRANS: Text for user subscription statistics if user has more subscribers than displayed. - $this->statsSectionLink('subscribers', _('All subscribers'), 'more'); - $this->elementEnd('p'); - } - Event::handle('EndShowSubscribersMiniList', array($this)); } $this->elementEnd('div'); } - function showPeopletagSubs() - { - $user = common_current_user(); - if (!empty($user) && $this->profile->id == $user->id) { - if (Event::handle('StartShowPeopletagSubscriptionsSection', array($this))) { - - $profile = $user->getProfile(); - $section = new PeopletagSubscriptionsSection($this, $profile); - $section->show(); - - Event::handle('EndShowPeopletagSubscriptionsSection', array($this)); - } - } - } - - function showPeopletags() - { - if (Event::handle('StartShowPeopletagsSection', array($this))) { - - $section = new PeopletagsForUserSection($this, $this->profile); - $section->show(); - - Event::handle('EndShowPeopletagsSection', array($this)); - } - } - function showStatistics() { $notice_count = $this->profile->noticeCount(); @@ -247,27 +210,6 @@ class ProfileAction extends OwnerDesignAction 'label' => _('Member since'), 'value' => date('j M Y', strtotime($profile->created)) ), - array( - 'id' => 'subscriptions', - // TRANS: Label for user statistics. - 'label' => _('Subscriptions'), - 'link' => common_local_url('subscriptions', $actionParams), - 'value' => $profile->subscriptionCount(), - ), - array( - 'id' => 'subscribers', - // TRANS: Label for user statistics. - 'label' => _('Subscribers'), - 'link' => common_local_url('subscribers', $actionParams), - 'value' => $profile->subscriberCount(), - ), - array( - 'id' => 'groups', - // TRANS: Label for user statistics. - 'label' => _('Groups'), - 'link' => common_local_url('usergroups', $actionParams), - 'value' => $profile->getGroups()->N, - ), array( 'id' => 'notices', // TRANS: Label for user statistics. @@ -316,6 +258,8 @@ class ProfileAction extends OwnerDesignAction $this->elementStart('h2'); // TRANS: H2 text for user group membership statistics. $this->statsSectionLink('usergroups', _('Groups')); + $this->text(' '); + $this->text($this->profile->getGroups()->N); $this->elementEnd('h2'); if ($groups) { @@ -327,17 +271,66 @@ class ProfileAction extends OwnerDesignAction } } - if ($cnt > GROUPS_PER_MINILIST) { - $this->elementStart('p'); - // TRANS: Text for user group membership statistics if user has more subscriptions than displayed. - $this->statsSectionLink('usergroups', _('All groups'), 'more'); - $this->elementEnd('p'); - } - Event::handle('EndShowGroupsMiniList', array($this)); } $this->elementEnd('div'); } + + function showLists() + { + $cur = common_current_user(); + $showPrivate = (!empty($cur) && $cur->id == $this->profile->id); + + $lists = $this->profile->getLists($showPrivate); + + if ($lists->N > 0) { + $this->elementStart('div', array('id' => 'entity_lists', + 'class' => 'section')); + + if (Event::handle('StartShowListsMiniList', array($this))) { + + $url = common_local_url('peopletagsbyuser', + array('nickname' => $this->profile->nickname)); + + $this->elementStart('h2'); + // TRANS: H2 text for user list membership statistics. + $this->element('a', + array('href' => $url), + _('Lists')); + $this->text(' '); + $this->text($lists->N); + $this->elementEnd('h2'); + + $this->elementStart('ul'); + + + $first = true; + + while ($lists->fetch()) { + if (!empty($lists->mainpage)) { + $url = $lists->mainpage; + } else { + $url = common_local_url('showprofiletag', + array('tagger' => $this->profile->nickname, + 'tag' => $lists->tag)); + } + if (!$first) { + $this->text(', '); + } else { + $first = false; + } + + $this->element('a', array('href' => $url), + $lists->tag); + } + + $this->elementEnd('ul'); + + Event::handle('EndShowListsMiniList', array($this)); + } + $this->elementEnd('div'); + } + } } class SubscribersMiniList extends ProfileMiniList diff --git a/lib/profileminilist.php b/lib/profileminilist.php index a989534748..36bfad770c 100644 --- a/lib/profileminilist.php +++ b/lib/profileminilist.php @@ -33,7 +33,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { require_once INSTALLDIR.'/lib/profilelist.php'; -define('PROFILES_PER_MINILIST', 27); +define('PROFILES_PER_MINILIST', 8); /** * Widget to show a list of profiles, good for sidebar diff --git a/lib/publicgroupnav.php b/lib/publicgroupnav.php index 952ac809b1..77243fda7a 100644 --- a/lib/publicgroupnav.php +++ b/lib/publicgroupnav.php @@ -47,6 +47,9 @@ require_once INSTALLDIR.'/lib/widget.php'; */ class PublicGroupNav extends Menu { + + var $actionName = null; + /** * Show the menu * @@ -54,7 +57,7 @@ class PublicGroupNav extends Menu */ function show() { - $action_name = $this->action->trimmed('action'); + $this->actionName = $this->action->trimmed('action'); $this->action->elementStart('ul', array('class' => 'nav')); @@ -62,35 +65,29 @@ class PublicGroupNav extends Menu // TRANS: Menu item in search group navigation panel. $this->out->menuItem(common_local_url('public'), _m('MENU','Public'), // TRANS: Menu item title in search group navigation panel. - _('Public timeline'), $action_name == 'public', 'nav_timeline_public'); + _('Public timeline'), $this->actionName == 'public', 'nav_timeline_public'); // TRANS: Menu item in search group navigation panel. $this->out->menuItem(common_local_url('groups'), _m('MENU','Groups'), // TRANS: Menu item title in search group navigation panel. - _('User groups'), $action_name == 'groups', 'nav_groups'); + _('User groups'), $this->actionName == 'groups', 'nav_groups'); // TRANS: Menu item in search group navigation panel. $this->out->menuItem(common_local_url('publictagcloud'), _m('MENU','Recent tags'), // TRANS: Menu item title in search group navigation panel. - _('Recent tags'), $action_name == 'publictagcloud', 'nav_recent-tags'); - - // TRANS: Menu item in search group navigation panel. - $this->out->menuItem(common_local_url('publicpeopletagcloud'), _m('MENU','People tags'), - // TRANS: Menu item title in search group navigation panel. - _('People tags'), in_array($action_name, array('publicpeopletagcloud', - 'peopletag', 'selftag')), 'nav_people-tags'); + _('Recent tags'), $this->actionName == 'publictagcloud', 'nav_recent-tags'); if (count(common_config('nickname', 'featured')) > 0) { // TRANS: Menu item in search group navigation panel. $this->out->menuItem(common_local_url('featured'), _m('MENU','Featured'), // TRANS: Menu item title in search group navigation panel. - _('Featured users'), $action_name == 'featured', 'nav_featured'); + _('Featured users'), $this->actionName == 'featured', 'nav_featured'); } // TRANS: Menu item in search group navigation panel. $this->out->menuItem(common_local_url('favorited'), _m('MENU','Popular'), // TRANS: Menu item title in search group navigation panel. - _('Popular notices'), $action_name == 'favorited', 'nav_timeline_favorited'); + _('Popular notices'), $this->actionName == 'favorited', 'nav_timeline_favorited'); Event::handle('EndPublicGroupNav', array($this)); } diff --git a/lib/section.php b/lib/section.php index d77673898a..2d8d6f3673 100644 --- a/lib/section.php +++ b/lib/section.php @@ -61,6 +61,19 @@ class Section extends Widget array('id' => $this->divId(), 'class' => 'section')); + $this->showTitle(); + + $have_more = $this->showContent(); + + if ($have_more) { + $this->showMore(); + } + + $this->out->elementEnd('div'); + } + + function showTitle() + { $link = $this->link(); if (!empty($link)) { $this->out->elementStart('h2'); @@ -70,18 +83,15 @@ class Section extends Widget $this->out->element('h2', null, $this->title()); } + } - $have_more = $this->showContent(); - - if ($have_more) { - $this->out->elementStart('p'); - $this->out->element('a', array('href' => $this->moreUrl(), - 'class' => 'more'), - $this->moreTitle()); - $this->out->elementEnd('p'); - } - - $this->out->elementEnd('div'); + function showMore() + { + $this->out->elementStart('p'); + $this->out->element('a', array('href' => $this->moreUrl(), + 'class' => 'more'), + $this->moreTitle()); + $this->out->elementEnd('p'); } function divId() diff --git a/lib/subgroupnav.php b/lib/subgroupnav.php index 6ff3b4609c..49bd357f29 100644 --- a/lib/subgroupnav.php +++ b/lib/subgroupnav.php @@ -128,16 +128,16 @@ class SubGroupNav extends Menu $this->user->nickname), $action == 'usergroups', 'nav_usergroups'); - $this->out->menuItem(common_local_url('peopletagsbyuser', + $this->out->menuItem(common_local_url('peopletagsubscriptions', array('nickname' => $this->user->nickname)), // TRANS: Menu item title in local navigation menu. - _m('MENU','People tags'), + _m('MENU','Lists'), // TRANS: Menu item title in local navigation menu. // TRANS: %s is a user nickname. - sprintf(_('People tags by %s.'), + sprintf(_('List subscriptions by %s.'), $this->user->nickname), - in_array($action, array('peopletagsbyuser', 'peopletagsforuser')), + in_array($action, array('peopletagsbyuser', 'peopletagsubscriptions', 'peopletagsforuser')), 'nav_timeline_peopletags'); if (common_config('invite', 'enabled') && !is_null($cur) && $this->user->id === $cur->id) { diff --git a/lib/util.php b/lib/util.php index f4c9824fd5..13966b2dd6 100644 --- a/lib/util.php +++ b/lib/util.php @@ -1221,19 +1221,22 @@ function common_relative_profile($sender, $nickname, $dt=null) function common_local_url($action, $args=null, $params=null, $fragment=null, $addSession=true) { - $r = Router::get(); - $path = $r->build($action, $args, $params, $fragment); + if (Event::handle('StartLocalURL', array(&$action, &$params, &$fragment, &$addSession, &$url))) { + $r = Router::get(); + $path = $r->build($action, $args, $params, $fragment); - $ssl = common_is_sensitive($action); + $ssl = common_is_sensitive($action); - if (common_config('site','fancy')) { - $url = common_path(mb_substr($path, 1), $ssl, $addSession); - } else { - if (mb_strpos($path, '/index.php') === 0) { + if (common_config('site','fancy')) { $url = common_path(mb_substr($path, 1), $ssl, $addSession); } else { - $url = common_path('index.php'.$path, $ssl, $addSession); + if (mb_strpos($path, '/index.php') === 0) { + $url = common_path(mb_substr($path, 1), $ssl, $addSession); + } else { + $url = common_path('index.php'.$path, $ssl, $addSession); + } } + Event::handle('EndLocalURL', array(&$action, &$params, &$fragment, &$addSession, &$url)); } return $url; } diff --git a/plugins/Directory/DirectoryPlugin.php b/plugins/Directory/DirectoryPlugin.php index 4fe1eaec9e..ad7fc82049 100644 --- a/plugins/Directory/DirectoryPlugin.php +++ b/plugins/Directory/DirectoryPlugin.php @@ -85,6 +85,7 @@ class DirectoryPlugin extends Plugin switch ($cls) { case 'UserdirectoryAction': + case 'GroupdirectoryAction': include_once $dir . '/actions/' . strtolower(mb_substr($cls, 0, -6)) . '.php'; return false; @@ -93,6 +94,7 @@ class DirectoryPlugin extends Plugin . '/lib/' . strtolower($cls) . '.php'; return false; case 'SortableSubscriptionList': + case 'SortableGroupList': include_once $dir . '/lib/' . strtolower($cls) . '.php'; return false; @@ -111,6 +113,7 @@ class DirectoryPlugin extends Plugin */ function onRouterInitialized($m) { + $m->connect( 'directory/users', array('action' => 'userdirectory'), @@ -123,6 +126,54 @@ class DirectoryPlugin extends Plugin array('filter' => '([0-9a-zA-Z_]{1,64}|0-9)') ); + $m->connect( + 'groups/:filter', + array('action' => 'groupdirectory'), + array('filter' => '([0-9a-zA-Z_]{1,64}|0-9)') + ); + + return true; + } + + /** + * Hijack the routing (URL -> Action) for the normal directory page + * and substitute our group directory action + * + * @param string $path path to connect + * @param array $defaults path defaults + * @param array $rules path rules + * @param array $result unused + * + * @return boolean hook return + */ + function onStartConnectPath(&$path, &$defaults, &$rules, &$result) + { + if (in_array($path, array('group', 'group/', 'groups', 'groups/'))) { + $defaults['action'] = 'groupdirectory'; + return true; + } + return true; + } + + // The following three function are to replace the existing groups + // list page with the directory plugin's group directory page + + /** + * Hijack the mapping (Action -> URL) and return the URL to our + * group directory page instead of the normal groups page + * + * @param Action $action action to find a path for + * @param array $params parameters to pass to the action + * @param string $fragment any url fragement + * @param boolean $addSession whether to add session variable + * @param string $url resulting URL to local resource + * + * @return string the local URL + */ + function onEndLocalURL(&$action, &$params, &$fragment, &$addSession, &$url) { + if (in_array($action, array('group', 'group/', 'groups', 'groups/'))) { + $url = common_local_url('groupdirectory'); + } return true; } @@ -137,7 +188,7 @@ class DirectoryPlugin extends Plugin { if (in_array( $action->trimmed('action'), - array('userdirectory')) + array('userdirectory', 'groupdirectory')) ) { $action->cssLink($this->path('css/directory.css')); } @@ -145,6 +196,24 @@ class DirectoryPlugin extends Plugin return true; } + /** + * Fool the public nav into thinking it's on the regular + * group page when it's actually on our injected group + * directory page. This way "Groups" gets hilighted when + * when we're on the groups directory page. + * + * @param type $action the current action + * + * @return boolean hook flag + */ + function onStartPublicGroupNav($action) + { + if ($action->trimmed('action') == 'groupdirectory') { + $action->actionName = 'groups'; + } + return true; + } + /** * Modify the public local nav to add a link to the user directory * diff --git a/plugins/Directory/actions/groupdirectory.php b/plugins/Directory/actions/groupdirectory.php new file mode 100644 index 0000000000..4e8e422bf2 --- /dev/null +++ b/plugins/Directory/actions/groupdirectory.php @@ -0,0 +1,431 @@ +. + * + * @category Public + * @package StatusNet + * @author Zach Copley + * @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')) +{ + exit(1); +} + +require_once INSTALLDIR . '/lib/publicgroupnav.php'; + +/** + * Group directory + * + * @category Directory + * @package StatusNet + * @author Zach Copley + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://status.net/ + */ +class GroupdirectoryAction extends Action +{ + /** + * The page we're on + * + * @var integer + */ + public $page; + + /** + * What to filter the search results by + * + * @var string + */ + public $filter; + + /** + * Column to sort by + * + * @var string + */ + public $sort; + + /** + * How to order search results, ascending or descending + * + * @var string + */ + public $reverse; + + /** + * Query + * + * @var string + */ + public $q; + + /** + * Title of the page + * + * @return string Title of the page + */ + function title() + { + // @fixme: This looks kinda gross + + if ($this->filter == 'all') { + if ($this->page != 1) { + return(sprintf(_m('Group Directory, page %d'), $this->page)); + } + return _m('Group directory'); + } else if ($this->page == 1) { + return sprintf( + _m('Group directory - %s'), + strtoupper($this->filter) + ); + } else { + return sprintf( + _m('Group directory - %s, page %d'), + strtoupper($this->filter), + $this->page + ); + } + } + + /** + * Instructions for use + * + * @return instructions for use + */ + function getInstructions() + { + // TRANS: Page notice for groups directory. + // TRANS: %%site.name%% is the name of the StatusNet site. + // TRANS: %%action.newgroup%% is a URL. Do not change it. + // TRANS: This message contains Markdown links in the form [link text](link). + $instructions = <<< END_OF_INSTRUCTIONS +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); + } + + /** + * Is this page read-only? + * + * @return boolean true + */ + function isReadOnly($args) + { + return true; + } + + /** + * Take arguments for running + * + * @param array $args $_REQUEST args + * + * @return boolean success flag + */ + function prepare($args) + { + parent::prepare($args); + + $this->page = ($this->arg('page')) ? ($this->arg('page') + 0) : 1; + $this->filter = $this->arg('filter', 'all'); + $this->reverse = $this->boolean('reverse'); + $this->q = $this->trimmed('q'); + $this->sort = $this->arg('sort', 'nickname'); + + common_set_returnto($this->selfUrl()); + + return true; + } + + /** + * Handle request + * + * Shows the page + * + * @param array $args $_REQUEST args; handled in prepare() + * + * @return void + */ + function handle($args) + { + parent::handle($args); + $this->showPage(); + } + + /** + * Show the page notice + * + * Shows instructions for the page + * + * @return void + */ + function showPageNotice() + { + $instr = $this->getInstructions(); + $output = common_markup_to_html($instr); + + $this->elementStart('div', 'instructions'); + $this->raw($output); + $this->elementEnd('div'); + } + + + /** + * Content area + * + * Shows the groups + * + * @return void + */ + function showContent() + { + if (common_logged_in()) { + $this->elementStart( + 'p', + array( + 'id' => 'new_group' + ) + ); + $this->element( + 'a', + array( + 'href' => common_local_url('newgroup'), + 'class' => 'more'), + // TRANS: Link to create a new group on the group list page. + _('Create a new group') + ); + $this->elementEnd('p'); + } + + $this->showForm(); + + $this->elementStart('div', array('id' => 'profile_directory')); + + $alphaNav = new AlphaNav($this, false, false, array('0-9', 'All')); + $alphaNav->show(); + + $group = null; + $group = $this->getGroups(); + $cnt = 0; + + if (!empty($group)) { + $groupList = new SortableGroupList( + $group, + common_current_user(), + $this + ); + + $cnt = $groupList->show(); + $group->free(); + + if (0 == $cnt) { + $this->showEmptyListMessage(); + } + } + + $args = array(); + if (isset($this->q)) { + $args['q'] = $this->q; + } else { + $args['filter'] = $this->filter; + } + + $this->pagination( + $this->page > 1, + $cnt > PROFILES_PER_PAGE, + $this->page, + 'groupdirectory', + $args + ); + + $this->elementEnd('div'); + } + + function showForm($error=null) + { + $this->elementStart( + 'form', + array( + 'method' => 'get', + 'id' => 'form_search', + 'class' => 'form_settings', + 'action' => common_local_url('groupdirectory') + ) + ); + + $this->elementStart('fieldset'); + + $this->element('legend', null, _m('Search groups')); + $this->elementStart('ul', 'form_data'); + $this->elementStart('li'); + + $this->input('q', _m('Keyword(s)'), $this->q); + + $this->submit('search', _m('BUTTON','Search')); + $this->elementEnd('li'); + $this->elementEnd('ul'); + $this->elementEnd('fieldset'); + $this->elementEnd('form'); + } + + /* + * Get groups filtered by the current filter, sort key, + * sort order, and page + */ + function getGroups() + { + $group = new User_group(); + + $offset = ($this->page-1) * PROFILES_PER_PAGE; + $limit = PROFILES_PER_PAGE + 1; + + if (isset($this->q)) { + + $order = 'user_group.created ASC'; + + if ($this->sort == 'nickname') { + if ($this->reverse) { + $order = 'user_group.nickname DESC'; + } else { + $order = 'user_group.nickname ASC'; + } + } else { + if ($this->reverse) { + $order = 'user_group.created DESC'; + } + } + + $sql = <<< GROUP_QUERY_END +SELECT user_group.* +FROM user_group +JOIN local_group ON user_group.id = local_group.group_id +ORDER BY %s +LIMIT %d, %d +GROUP_QUERY_END; + + $cnt = 0; + $group->query(sprintf($sql, $order, $limit, $offset)); + $group->find(); + + } else { + // User is browsing via AlphaNav + $sort = $this->getSortKey(); + + $sql = <<< GROUP_QUERY_END +SELECT user_group.* +FROM user_group +JOIN local_group ON user_group.id = local_group.group_id +GROUP_QUERY_END; + + switch($this->filter) + { + case 'all': + // NOOP + break; + case '0-9': + $sql .= + ' AND LEFT(user_group.nickname, 1) BETWEEN \'0\' AND \'9\''; + break; + default: + $sql .= sprintf( + ' AND LEFT(LOWER(user_group.nickname), 1) = \'%s\'', + $this->filter + ); + } + + $sql .= sprintf( + ' ORDER BY user_group.%s %s, user_group.nickname ASC LIMIT %d, %d', + $sort, + $this->reverse ? 'DESC' : 'ASC', + $offset, + $limit + ); + + $group->query($sql); + } + + return $group; + } + + /** + * Filter the sort parameter + * + * @return string a column name for sorting + */ + function getSortKey() + { + switch ($this->sort) { + case 'nickname': + return $this->sort; + break; + case 'created': + return $this->sort; + break; + default: + return 'nickname'; + } + } + + /** + * Show a nice message when there's no search results + */ + function showEmptyListMessage() + { + if (!empty($this->filter) && ($this->filter != 'all')) { + $this->element( + 'p', + 'error', + sprintf( + _m('No groups starting with %s'), + $this->filter + ) + ); + } else { + $this->element('p', 'error', _m('No results.')); + $message = _m(<<elementStart('div', 'help instructions'); + $this->raw(common_markup_to_html($message)); + $this->elementEnd('div'); + } + } + + function showSections() + { + $gbp = new GroupsByPostsSection($this); + $gbp->show(); + $gbm = new GroupsByMembersSection($this); + $gbm->show(); + } + +} diff --git a/plugins/Directory/actions/userdirectory.php b/plugins/Directory/actions/userdirectory.php index 6532f03c02..b12d1171ea 100644 --- a/plugins/Directory/actions/userdirectory.php +++ b/plugins/Directory/actions/userdirectory.php @@ -199,7 +199,7 @@ class UserdirectoryAction extends Action { $this->showForm(); - $this->elementStart('div', array('id' => 'user_directory')); + $this->elementStart('div', array('id' => 'profile_directory')); $alphaNav = new AlphaNav($this, false, false, array('0-9', 'All')); $alphaNav->show(); diff --git a/plugins/Directory/css/directory.css b/plugins/Directory/css/directory.css index 14fd2ce23b..d49c28fe55 100644 --- a/plugins/Directory/css/directory.css +++ b/plugins/Directory/css/directory.css @@ -1,35 +1,35 @@ /* CSS file for the Directory plugin */ -div#user_directory div.alpha_nav { +div#profile_directory div.alpha_nav { overflow: hidden; width: 100%; text-align: center; } /* XXX: this needs serious CSS foo */ -div#user_directory div.alpha_nav > a { +div#profile_directory div.alpha_nav > a { border-left: 1px solid #000; padding-left: 2px; } -div#user_directory div.alpha_nav > a.first { +div#profile_directory div.alpha_nav > a.first { border-left: none; } -div#user_directory div.alpha_nav a:link { +div#profile_directory div.alpha_nav a:link { text-decoration: none; } -div#user_directory div.alpha_nav a:visited { +div#profile_directory div.alpha_nav a:visited { text-decoration: none; } -div#user_directory div.alpha_nav a:active { +div#profile_directory div.alpha_nav a:active { text-decoration: none; } -div#user_directory div.alpha_nav a:hover { +div#profile_directory div.alpha_nav a:hover { text-decoration: underline; color: blue; } -div#user_directory div.alpha_nav a.current { +div#profile_directory div.alpha_nav a.current { background-color:#9BB43E; } diff --git a/plugins/Directory/lib/alphanav.php b/plugins/Directory/lib/alphanav.php index 87e2f18f18..60a15ee942 100644 --- a/plugins/Directory/lib/alphanav.php +++ b/plugins/Directory/lib/alphanav.php @@ -108,10 +108,15 @@ class AlphaNav extends Widget $classes .= 'last '; // last filter in the list } - $href = common_local_url( - $actionName, - array('filter' => strtolower($filter)) - ); + // hack to get around $m->connect(array('action' => 'all, 'nickname' => $nickname)); + if (strtolower($filter) == 'all') { + $href = common_local_url($actionName); + } else { + $href = common_local_url( + $actionName, + array('filter' => strtolower($filter)) + ); + } $params = array('href' => $href); diff --git a/plugins/Directory/lib/sortablegrouplist.php b/plugins/Directory/lib/sortablegrouplist.php new file mode 100644 index 0000000000..2b51ef5655 --- /dev/null +++ b/plugins/Directory/lib/sortablegrouplist.php @@ -0,0 +1,271 @@ +. + * + * @category Public + * @package StatusNet + * @author Zach Copley + * @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')) { + exit(1); +} + +require_once INSTALLDIR . '/lib/subscriptionlist.php'; + +/** + * Widget to show a sortable list of subscriptions + * + * @category Public + * @package StatusNet + * @author Zach Copley + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://status.net/ + */ + +class SortableGroupList extends SortableSubscriptionList +{ + /** Owner of this list */ + var $owner = null; + + function __construct($profile, $owner=null, $action=null) + { + parent::__construct($profile, $owner, $action); + + $this->owner = $owner; + } + + function startList() + { + $this->out->elementStart('table', array('class' => 'profile_list xoxo')); + $this->out->elementStart('thead'); + $this->out->elementStart('tr'); + + $tableHeaders = array( + 'nickname' => _m('Nickname'), + 'created' => _m('Created') + ); + + foreach ($tableHeaders as $id => $label) { + + $attrs = array('id' => $id); + $current = (!empty($this->action->sort) && $this->action->sort == $id); + + if ($current || empty($this->action->sort) && $id == 'nickname') { + $attrs['class'] = 'current'; + } + + if ($current && $this->action->reverse) { + $attrs['class'] .= ' reverse'; + $attrs['class'] = trim($attrs['class']); + } + + $this->out->elementStart('th', $attrs); + + $linkAttrs = array(); + $params = array('sort' => $id); + + if (!empty($this->action->q)) { + $params['q'] = $this->action->q; + } + + if ($current && !$this->action->reverse) { + $params['reverse'] = 'true'; + } + + $args = array(); + + $filter = $this->action->arg('filter'); + + if (!empty($filter)) { + $args['filter'] = $filter; + } + + $linkAttrs['href'] = common_local_url( + $this->action->arg('action'), $args, $params + ); + + $this->out->element('a', $linkAttrs, $label); + $this->out->elementEnd('th'); + } + + $this->out->element('th', array('id' => 'Members'), _m('Members')); + $this->out->element('th', array('id' => 'controls'), null); + + $this->out->elementEnd('tr'); + $this->out->elementEnd('thead'); + + $this->out->elementStart('tbody'); + } + + function newListItem($profile, $odd) + { + return new SortableGroupListItem($profile, $this->owner, $this->action, $odd); + } +} + +class SortableGroupListItem extends SortableSubscriptionListItem +{ + /** Owner of this list */ + var $owner = null; + + function __construct($profile, $owner, $action, $alt) + { + parent::__construct($profile, $owner, $action, $alt); + + $this->alt = $alt; // is this row alternate? + $this->owner = $owner; + } + + function showHomepage() + { + if (!empty($this->profile->homepage)) { + $this->out->text(' '); + $aAttrs = $this->homepageAttributes(); + $this->out->elementStart('a', $aAttrs); + $this->out->raw($this->highlight($this->profile->homeUrl())); + $this->out->elementEnd('a'); + } + } + + function showAvatar() + { + $logo = ($this->profile->stream_logo) ? + $this->profile->stream_logo : User_group::defaultLogo(AVATAR_STREAM_SIZE); + + $this->out->elementStart( + 'a', + array( + 'href' => $this->profile->homeUrl(), + 'class' => 'url entry-title', + 'rel' => 'contact group' + ) + ); + $this->out->element( + 'img', + array( + 'src' => $logo, + 'class' => 'photo avatar', + 'width' => AVATAR_STREAM_SIZE, + 'height' => AVATAR_STREAM_SIZE, + 'alt' => ($this->profile->fullname) + ? $this->profile->fullname : $this->profile->nickname + ) + ); + + $this->out->text(' '); + $hasFN = ($this->profile->fullname) ? 'nickname' : 'fn org nickname'; + $this->out->elementStart('span', $hasFN); + $this->out->raw($this->highlight($this->profile->nickname)); + $this->out->elementEnd('span'); + $this->out->elementEnd('a'); + } + + function show() + { + if (Event::handle('StartProfileListItem', array($this))) { + $this->startItem(); + if (Event::handle('StartProfileListItemProfile', array($this))) { + $this->showProfile(); + Event::handle('EndProfileListItemProfile', array($this)); + } + + // XXX Add events? + $this->showCreatedDate(); + $this->showMemberCount(); + + if (Event::handle('StartProfileListItemActions', array($this))) { + $this->showActions(); + Event::handle('EndProfileListItemActions', array($this)); + } + $this->endItem(); + + Event::handle('EndProfileListItem', array($this)); + } + } + + function showActions() + { + $this->startActions(); + if (Event::handle('StartProfileListItemActionElements', array($this))) { + $this->showJoinButton(); + Event::handle('EndProfileListItemActionElements', array($this)); + } + $this->endActions(); + } + + function showJoinButton() + { + $user = $this->owner; + if ($user) { + + $this->out->elementStart('li', 'entity_subscribe'); + // XXX: special-case for user looking at own + // subscriptions page + if ($user->isMember($this->profile)) { + $lf = new LeaveForm($this->out, $this->profile); + $lf->show(); + } else if (!Group_block::isBlocked($this->profile, $user->getProfile())) { + $jf = new JoinForm($this->out, $this->profile); + $jf->show(); + } + + $this->out->elementEnd('li'); + } + } + + function showMemberCount() + { + $this->out->elementStart('td', 'entry_member_count'); + $this->out->raw($this->profile->getMemberCount()); + $this->out->elementEnd('td'); + } + + function showCreatedDate() + { + $this->out->elementStart('td', 'entry_created'); + $this->out->raw(date('j M Y', strtotime($this->profile->created))); + $this->out->elementEnd('td'); + } + + function showAdmins() + { + $this->out->elementStart('td', 'entry_admins'); + // @todo + $this->out->raw('gargargar'); + $this->out->elementEnd('td'); + } + + /** + * Only show the tags if we're logged in + */ + function showTags() + { + if (common_logged_in()) { + parent::showTags(); + } + + } + +} diff --git a/plugins/Gravatar/GravatarPlugin.php b/plugins/Gravatar/GravatarPlugin.php index 256f6b162a..bdb73f3433 100644 --- a/plugins/Gravatar/GravatarPlugin.php +++ b/plugins/Gravatar/GravatarPlugin.php @@ -1,7 +1,7 @@ getUser(); + if (!empty($user) && !empty($user->email)) { + // Fake one! + $avatar = new Avatar(); + $avatar->width = $avatar->height = $size; + $avatar->url = $this->gravatar_url($user->email, $size); + return false; + } + } + return true; } - function onStartAvatarFormData($action) - { - $user = common_current_user(); - $hasGravatar = $this->hasGravatar($user->id); - - if($hasGravatar) { - return false; - } - } - - function onEndAvatarFormData($action) - { - $user = common_current_user(); - $hasGravatar = $this->hasGravatar($user->id); - - if(!empty($user->email) && !$hasGravatar) { //and not gravatar already set - $action->elementStart('form', array('method' => 'post', - 'id' => 'form_settings_gravatar_add', - 'class' => 'form_settings', - 'action' => - common_local_url('avatarsettings'))); - $action->elementStart('fieldset', array('id' => 'settings_gravatar_add')); - // TRANS: Fieldset legend. Gravatar is an avatar service. - $action->element('legend', null, _m('Set Gravatar')); - $action->hidden('token', common_session_token()); - $action->element('p', 'form_guide', - // TRANS: Form guide. Gravatar is an avatar service. - _m('If you want to use your Gravatar image, click "Add".')); - $action->element('input', array('type' => 'submit', - 'id' => 'settings_gravatar_add_action-submit', - 'name' => 'add', - 'class' => 'submit', - // TRANS: Button text to add a Gravatar. Gravatar is an avatar service. - 'value' => _m('BUTTON','Add'))); - $action->elementEnd('fieldset'); - $action->elementEnd('form'); - } elseif($hasGravatar) { - $action->elementStart('form', array('method' => 'post', - 'id' => 'form_settings_gravatar_remove', - 'class' => 'form_settings', - 'action' => - common_local_url('avatarsettings'))); - $action->elementStart('fieldset', array('id' => 'settings_gravatar_remove')); - // TRANS: Fieldset legend. Gravatar is an avatar service. - $action->element('legend', null, _m('Remove Gravatar')); - $action->hidden('token', common_session_token()); - $action->element('p', 'form_guide', - // TRANS: Form guide. Gravatar is an avatar service. - _m('If you want to remove your Gravatar image, click "Remove".')); - $action->element('input', array('type' => 'submit', - 'id' => 'settings_gravatar_remove_action-submit', - 'name' => 'remove', - 'class' => 'submit', - // TRANS: Button text to remove a Gravatar. Gravatar is an avatar service. - 'value' => _m('Remove'))); - $action->elementEnd('fieldset'); - $action->elementEnd('form'); - } else { - $action->element('p', 'form_guide', - // TRANS: Form guide. Gravatar is an avatar service. - _m('To use a Gravatar first enter in an email address.')); - } - } - - function onStartAvatarSaveForm($action) - { - if ($action->arg('add')) { - $result = $this->gravatar_save(); - - if($result['success']===true) { - common_broadcast_profile(common_current_user()->getProfile()); - } - - $action->showForm($result['message'], $result['success']); - - return false; - } else if ($action->arg('remove')) { - $result = $this->gravatar_remove(); - - if($result['success']===true) { - common_broadcast_profile(common_current_user()->getProfile()); - } - - $action->showForm($result['message'], $result['success']); - - return false; - } else { - return true; - } - } - - function hasGravatar($id) { - $avatar = new Avatar(); - $avatar->profile_id = $id; - if ($avatar->find()) { - while ($avatar->fetch()) { - if($avatar->filename == null) { - return true; - } - } - } - return false; - } - - function gravatar_save() - { - $cur = common_current_user(); - - if(empty($cur->email)) { - // TRANS: Message displayed when no e-mail address was set when saving Gravatar setting. Gravatar is an avatar service. - return array('message' => _m('You do not have an email address set in your profile.'), - 'success' => false); - } - //Get rid of previous Avatar - $this->gravatar_remove(); - - foreach (array(AVATAR_PROFILE_SIZE, AVATAR_STREAM_SIZE, AVATAR_MINI_SIZE) as $size) { - $gravatar = new Avatar(); - $gravatar->profile_id = $cur->id; - $gravatar->width = $size; - $gravatar->height = $size; - $gravatar->original = false; //No file, so no original - $gravatar->mediatype = 'img';//XXX: Unsure what to put here - //$gravatar->filename = null;//No filename. Remote - $gravatar->url = $this->gravatar_url($cur->email, $size); - $gravatar->created = DB_DataObject_Cast::dateTime(); # current time - - if (!$gravatar->insert()) { - // TRANS: Message displayed when saving Gravatar setting fails. Gravatar is an avatar service. - return array('message' => _m('Failed to save Gravatar to the database.'), - 'success' => false); - } - } - // TRANS: Message displayed when Gravatar was added. Gravatar is an avatar service. - return array('message' => _m('Gravatar added.'), - 'success' => true); - } - - function gravatar_remove() - { - $user = common_current_user(); - $profile = $user->getProfile(); - - $avatar = $profile->getOriginalAvatar(); - if($avatar) $avatar->delete(); - $avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE); - if($avatar) $avatar->delete(); - $avatar = $profile->getAvatar(AVATAR_STREAM_SIZE); - if($avatar) $avatar->delete(); - $avatar = $profile->getAvatar(AVATAR_MINI_SIZE); - if($avatar) $avatar->delete(); - - // TRANS: Message displayed when Gravatar was removed. Gravatar is an avatar service. - return array('message' => _m('Gravatar removed.'), - 'success' => true); - } - function gravatar_url($email, $size) { $url = "https://secure.gravatar.com/avatar.php?gravatar_id=". @@ -205,7 +59,7 @@ class GravatarPlugin extends Plugin { $versions[] = array('name' => 'Gravatar', 'version' => STATUSNET_VERSION, - 'author' => 'Eric Helgeson', + 'author' => 'Eric Helgeson, Evan Prodromou', 'homepage' => 'http://status.net/wiki/Plugin:Gravatar', 'rawdescription' => // TRANS: Plugin decsription. diff --git a/plugins/OStatus/OStatusPlugin.php b/plugins/OStatus/OStatusPlugin.php index a74ce6201b..b0b67569c6 100644 --- a/plugins/OStatus/OStatusPlugin.php +++ b/plugins/OStatus/OStatusPlugin.php @@ -855,7 +855,7 @@ class OStatusPlugin extends Plugin if ($oprofile) { if (!$oprofile->subscribe()) { // TRANS: Exception thrown when setup of remote people tag subscription fails. - throw new Exception(_m('Could not set up remote people tag subscription.')); + throw new Exception(_m('Could not set up remote list subscription.')); } $sub = $user->getProfile(); @@ -876,7 +876,7 @@ class OStatusPlugin extends Plugin $act->title = _m('TITLE','Follow list'); // 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. - $act->content = sprintf(_m("%1$s is now following people tagged %2$s by %3$s."), + $act->content = sprintf(_m("%1$s is now following people listed in %2$s by %3$s."), $sub->getBestName(), $oprofile->getBestName(), $tagger->getBestName()); @@ -1000,7 +1000,7 @@ class OStatusPlugin extends Plugin common_date_iso8601(time())); $act->time = time(); $act->title = _m('TITLE','Tag'); - $act->content = sprintf(_m('%1$s tagged %2$s in the list %3$s.'), + $act->content = sprintf(_m('%1$s listed %2$s in the list %3$s.'), $tagger->getBestName(), $tagged->getBestName(), $plist->getBestName()); diff --git a/plugins/OStatus/actions/ostatuspeopletag.php b/plugins/OStatus/actions/ostatuspeopletag.php index 6d6199b811..1a8495ce21 100644 --- a/plugins/OStatus/actions/ostatuspeopletag.php +++ b/plugins/OStatus/actions/ostatuspeopletag.php @@ -169,7 +169,7 @@ class OStatusPeopletagAction extends OStatusSubAction function getInstructions() { - return _m('You can subscribe to people tags from other supported sites. Paste the tag\'s profile URI below:'); + return _m('You can subscribe to lists from other supported sites. Paste the lists\'s URI below:'); } function selfLink() diff --git a/plugins/OStatus/actions/peopletagsalmon.php b/plugins/OStatus/actions/peopletagsalmon.php index 21025f511e..a200ca9eef 100644 --- a/plugins/OStatus/actions/peopletagsalmon.php +++ b/plugins/OStatus/actions/peopletagsalmon.php @@ -42,13 +42,13 @@ class PeopletagsalmonAction extends SalmonAction $this->peopletag = Profile_list::staticGet('id', $id); if (empty($this->peopletag)) { - $this->clientError(_m('No such people tag.')); + $this->clientError(_m('No such list.')); } $oprofile = Ostatus_profile::staticGet('peopletag_id', $id); if (!empty($oprofile)) { - $this->clientError(_m('Cannot accept remote posts for a remote people tag.')); + $this->clientError(_m('Cannot accept remote posts for a remote list.')); } return true; @@ -89,7 +89,7 @@ class PeopletagsalmonAction extends SalmonAction $this->clientError(_m('Cannot read profile to set up profile tag subscription.')); } if ($oprofile->isGroup()) { - $this->clientError(_m('Groups cannot subscribe to people tags.')); + $this->clientError(_m('Groups cannot subscribe to lists.')); } common_log(LOG_INFO, "Remote profile {$oprofile->uri} subscribing to local peopletag ".$this->peopletag->getBestName()); @@ -107,7 +107,7 @@ class PeopletagsalmonAction extends SalmonAction try { Profile_tag_subscription::add($this->peopletag, $profile); } catch (Exception $e) { - $this->serverError(sprintf(_m('Could not subscribe remote user %1$s to people tag %2$s.'), + $this->serverError(sprintf(_m('Could not subscribe remote user %1$s to list %2$s.'), $oprofile->uri, $this->peopletag->getBestName())); } } @@ -120,10 +120,10 @@ class PeopletagsalmonAction extends SalmonAction { $oprofile = $this->ensureProfile(); if (!$oprofile) { - $this->clientError(_m('Cannot read profile to cancel people tag membership.')); + $this->clientError(_m('Cannot read profile to cancel list membership.')); } if ($oprofile->isGroup()) { - $this->clientError(_m('Groups cannot subscribe to people tags.')); + $this->clientError(_m('Groups cannot subscribe to lists.')); } common_log(LOG_INFO, "Remote profile {$oprofile->uri} unsubscribing from local peopletag ".$this->peopletag->getBestName()); @@ -133,7 +133,7 @@ class PeopletagsalmonAction extends SalmonAction Profile_tag_subscription::remove($this->peopletag->tagger, $this->peopletag->tag, $profile->id); } catch (Exception $e) { - $this->serverError(sprintf(_m('Could not remove remote user %1$s from people tag %2$s.'), + $this->serverError(sprintf(_m('Could not remove remote user %1$s from list %2$s.'), $oprofile->uri, $this->peopletag->getBestName())); return; } diff --git a/plugins/Realtime/RealtimePlugin.php b/plugins/Realtime/RealtimePlugin.php index 108a6c3b60..709d65ac5d 100644 --- a/plugins/Realtime/RealtimePlugin.php +++ b/plugins/Realtime/RealtimePlugin.php @@ -222,10 +222,6 @@ class RealtimePlugin extends Plugin ''); $action->elementEnd('address'); - if (common_logged_in()) { - $action->showNoticeForm(); - } - $action->showContentBlock(); $action->showScripts(); $action->elementEnd('body'); diff --git a/plugins/SearchSub/SearchSubPlugin.php b/plugins/SearchSub/SearchSubPlugin.php index 785c8fe006..de131c2b04 100644 --- a/plugins/SearchSub/SearchSubPlugin.php +++ b/plugins/SearchSub/SearchSubPlugin.php @@ -242,39 +242,6 @@ class SearchSubPlugin extends Plugin return true; } - /** - * Add a count of mirrored feeds into a user's profile sidebar stats. - * - * @param Profile $profile - * @param array $stats - * @return boolean hook return value - */ - function onProfileStats($profile, &$stats) - { - $cur = common_current_user(); - if (!empty($cur) && $cur->id == $profile->id) { - $searchsub = new SearchSub(); - $searchsub ->profile_id = $profile->id; - $entry = array( - 'id' => 'searchsubs', - 'label' => _m('Search subscriptions'), - 'link' => common_local_url('searchsubs', array('nickname' => $profile->nickname)), - 'value' => $searchsub->count(), - ); - - $insertAt = count($stats); - foreach ($stats as $i => $row) { - if ($row['id'] == 'groups') { - // Slip us in after them. - $insertAt = $i + 1; - break; - } - } - array_splice($stats, $insertAt, 0, array($entry)); - } - return true; - } - /** * Replace the built-in stub track commands with ones that control * search subscriptions. diff --git a/plugins/TagSub/TagSubPlugin.php b/plugins/TagSub/TagSubPlugin.php index ba1cff6673..59297a7fb3 100644 --- a/plugins/TagSub/TagSubPlugin.php +++ b/plugins/TagSub/TagSubPlugin.php @@ -208,39 +208,6 @@ class TagSubPlugin extends Plugin return true; } - /** - * Add a count of mirrored feeds into a user's profile sidebar stats. - * - * @param Profile $profile - * @param array $stats - * @return boolean hook return value - */ - function onProfileStats($profile, &$stats) - { - $cur = common_current_user(); - if (!empty($cur) && $cur->id == $profile->id) { - $tagsub = new TagSub(); - $tagsub->profile_id = $profile->id; - $entry = array( - 'id' => 'tagsubs', - 'label' => _m('Tag subscriptions'), - 'link' => common_local_url('tagsubs', array('nickname' => $profile->nickname)), - 'value' => $tagsub->count(), - ); - - $insertAt = count($stats); - foreach ($stats as $i => $row) { - if ($row['id'] == 'groups') { - // Slip us in after them. - $insertAt = $i + 1; - break; - } - } - array_splice($stats, $insertAt, 0, array($entry)); - } - return true; - } - function onEndDefaultLocalNav($menu, $user) { $user = common_current_user(); diff --git a/theme/base/css/display.css b/theme/base/css/display.css index 68081a8898..7b1a134cd1 100644 --- a/theme/base/css/display.css +++ b/theme/base/css/display.css @@ -1834,8 +1834,16 @@ width:14.5%; border-top: 1px solid #ccc; } +#realtime_actions { + position: relative !important; + right: -4px !important; + float: right; + padding-top: 15px; + margin-bottom: -8px !important; +} + #realtime_actions li { - margin-right: -4px; + margin-left: 2px !important; } #realtime_play, #realtime_pause, #realtime_popup { @@ -1855,54 +1863,67 @@ width:14.5%; } #realtime_play, #realtime_pause, #realtime_popup { - opacity: 0.6; + opacity: 0.6; } #realtime_play:hover, #realtime_pause:hover, #realtime_popup:hover { - opacity: 1; + opacity: 1; } body.realtime-popup { min-width: 100%; -} - -.realtime-popup #wrap { - padding: 0px !important; - margin: 0px !important; + overflow-x: hidden; } .realtime-popup #content { padding: 0px !important; margin: 0px !important; - width: 98% !important; + left: 0; + right: 0; + width: 100% !important; + overflow: visible; } -.realtime-popup .form_notice { - float: left !important; - position: static !important; +.realtime-popup #content_inner { + padding: 5px; +} + +.realtime-popup .input_forms { + top: 0px; + left: 0px; + padding: 10px 0px 0px 5px; +} + +.realtime-popup .form_notice_placeholder .placeholder { + width: 445px; +} + +.realtime-popup .input_form { + width: 470px; } .realtime-popup .form_notice fieldset { - width: 450px !important; + width: 430px !important; } .realtime-popup .form_notice textarea { - width: 340px !important; -} - -.realtime-popup .form_notice .submit { - top: 58px !important; - height: 2em; - font-size: 0.8em; - width: 86px; + width: 425px !important; } .realtime-popup .form_notice label.notice_data-attach { - right: 70px; + right: 0px !important; + top: 3px !important; } -.realtime-popup .form_notice .notice_data-geo_wrap label, .realtime-popup .form_notice .notice_data-geo_wrap input { - right: 2px; +.realtime-popup .form_notice #notice_data-geo_wrap label, .realtime-popup .form_notice #notice_data-geo_wrap input { + right: 8px !important; + top: 3px !important; +} + +.realtime-popup .form_notice .error, +.realtime-popup .form_notice .success, +.realtime-popup .form_notice .notice-status { + width: 430px; } /* icons */ diff --git a/theme/neo/css/display.css b/theme/neo/css/display.css index 528f8553de..13e03af710 100644 --- a/theme/neo/css/display.css +++ b/theme/neo/css/display.css @@ -542,8 +542,8 @@ address { } .section .entities li { - margin-right: 23px; - margin-bottom: 12px; + margin-right: 3.6px; + margin-bottom: 5px; width: 24px; } @@ -734,6 +734,27 @@ div.entry-content a.response:after { width: 390px; } +.threaded-replies .to-selector { + display: none; +} + +.user_in.realtime-popup .notice div.entry-content { + max-width: 320px; +} + +.realtime-popup .threaded-replies { + margin-left: 15px; +} + +.realtime-popup .threaded-replies .form_notice textarea { + width: 385px !important; +} + +.realtime-popup .threaded-replies .form_notice label.notice_data-attach { + top: 10px !important; + right: 10px !important; +} + #content .notice .notice { width: 100%; margin-left: 0; @@ -971,51 +992,6 @@ padding-right:0; } -#realtime_actions { - position: relative !important; - float: right; - padding-top: 15px; - margin-bottom: -8px !important; -} - -.realtime-popup #content { - padding-left: 4px !important; - padding-right: 4px !important; - margin-right: 0px; - left: 0; - right: 0; - width: 400px; - overflow: visible; -} - -.realtime-popup .threaded-replies { - margin-left: 10px; -} - -.realtime-popup .input_forms { - display: none; /* XXX fixme! */ -} - -.realtime-popup .form_notice textarea { - width: 325px !important; -} - -.realtime-popup .form_notice #notice_action-submit { - top: 59px !important; - right: 6px !important; -} - -.realtime-popup .form_notice label.notice_data-attach, .realtime-popup .form_notice input.notice_data-attach { - right: 74px; - top: 3px !important; -} - -.realtime-popup .form_notice #notice_data-geo_wrap label, .realtime-popup .form_notice #notice_data-geo_wrap input { - right: 8px; - top: 3px !important; -} - - /* Bookmark specific styles */ #content .bookmark .entry-title {