This commit is contained in:
Hannes Mannerheim 2015-11-29 20:19:23 +01:00
parent 73a77a02fb
commit 4b66bcfe04
27 changed files with 722 additions and 21 deletions

View File

@ -141,6 +141,19 @@ class QvitterPlugin extends Plugin {
public function onRouterInitialized($m)
{
$m->connect('api/qvitter/:nickname/lists/:id/subscribers.json',
array('action' => 'ApiQvitterListSubscribers',
'nickname' => '[a-zA-Z0-9]+',
'id' => '[a-zA-Z0-9]+'));
$m->connect('api/qvitter/:nickname/lists/:id/members.json',
array('action' => 'ApiQvitterListMembers',
'nickname' => '[a-zA-Z0-9]+',
'id' => '[a-zA-Z0-9]+'));
$m->connect('api/qvitter/:nickname/lists/:id/statuses.json',
array('action' => 'ApiQvitterTimelineList',
'nickname' => '[a-zA-Z0-9]+',
'id' => '[a-zA-Z0-9]+'));
$m->connect('api/qvitter/blocks.json',
array('action' => 'ApiQvitterBlocks'));
$m->connect('api/qvitter/hello.json',
@ -277,6 +290,23 @@ class QvitterPlugin extends Plugin {
array('action' => 'groupmembers'),
array('nickname' => Nickname::DISPLAY_FMT),
'qvitter');
URLMapperOverwrite::overwrite_variable($m, ':nickname/all/:tag',
array('action' => 'showprofiletag'),
array('nickname' => Nickname::DISPLAY_FMT,
'tag' => Router::REGEX_TAG),
'qvitter');
URLMapperOverwrite::overwrite_variable($m, ':tagger/all/:tag/tagged',
array('action' => 'peopletagged'),
array('tagger' => Nickname::DISPLAY_FMT,
'tag' => Router::REGEX_TAG),
'qvitter');
URLMapperOverwrite::overwrite_variable($m, ':tagger/all/:tag/subscribers',
array('action' => 'peopletagsubscribers'),
array('tagger' => Nickname::DISPLAY_FMT,
'tag' => Router::REGEX_TAG),
'qvitter');
$m->connect('group/:nickname/admins',
array('action' => 'qvitter'),

View File

@ -0,0 +1,172 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* List a list's members
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package GNUsocial
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author Zach Copley <zach@status.net>
* @author Hannes Mannerheim <h@nnesmannerhe.im>
* @copyright 2009 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://www.gnu.org/software/social/
*/
if (!defined('GNUSOCIAL')) {
exit(1);
}
/**
* List 20 newest admins of the group specified by name or ID.
*
* @category API
* @package GNUsocial
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author Zach Copley <zach@status.net>
* @author Hannes Mannerheim <h@nnesmannerhe.im>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://www.gnu.org/software/social/
*/
class ApiQvitterListMembersAction extends ApiPrivateAuthAction
{
var $list = null;
var $profiles = null;
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*/
protected function prepare(array $args=array())
{
parent::prepare($args);
$this->list = $this->getTargetList($this->arg('nickname'), $this->arg('id'));
if (!$this->list instanceof Profile_list) {
// TRANS: Client error displayed trying to show list membership on a non-existing list.
$this->clientError(_('List not found.'), 404);
}
$this->profiles = $this->getProfiles();
return true;
}
/**
* Handle the request
*
* Show the admin of the group
*
* @param array $args $_REQUEST data (unused)
*
* @return void
*/
protected function handle()
{
parent::handle();
$this->showJsonUsers($this->profiles);
}
/**
* Fetch the admins of a group
*
* @return array $profiles list of profiles
*/
function getProfiles()
{
$profiles = array();
$profile = $this->list->getTagged(
($this->page - 1) * $this->count,
$this->count,
$this->since_id,
$this->max_id
);
while ($profile->fetch()) {
$profiles[] = clone($profile);
}
return $profiles;
}
/**
* Is this action read only?
*
* @param array $args other arguments
*
* @return boolean true
*/
function isReadOnly($args)
{
return true;
}
/**
* When was this list of profiles last modified?
*
* @return string datestamp of the lastest profile in the group
*/
function lastModified()
{
if (!empty($this->profiles) && (count($this->profiles) > 0)) {
return strtotime($this->profiles[0]->created);
}
return null;
}
/**
* An entity tag for this list of groups
*
* Returns an Etag based on the action name, language
* the group id, and timestamps of the first and last
* user who has joined the group
*
* @return string etag
*/
function etag()
{
if (!empty($this->profiles) && (count($this->profiles) > 0)) {
$last = count($this->profiles) - 1;
return '"' . implode(
':',
array($this->arg('action'),
common_user_cache_hash($this->auth_user),
common_language(),
$this->group->id,
strtotime($this->profiles[0]->created),
strtotime($this->profiles[$last]->created))
)
. '"';
}
return null;
}
}

View File

@ -0,0 +1,172 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* List a list's members
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package GNUsocial
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author Zach Copley <zach@status.net>
* @author Hannes Mannerheim <h@nnesmannerhe.im>
* @copyright 2009 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://www.gnu.org/software/social/
*/
if (!defined('GNUSOCIAL')) {
exit(1);
}
/**
* List 20 newest admins of the group specified by name or ID.
*
* @category API
* @package GNUsocial
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author Zach Copley <zach@status.net>
* @author Hannes Mannerheim <h@nnesmannerhe.im>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://www.gnu.org/software/social/
*/
class ApiQvitterListSubscribersAction extends ApiPrivateAuthAction
{
var $list = null;
var $profiles = null;
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*/
protected function prepare(array $args=array())
{
parent::prepare($args);
$this->list = $this->getTargetList($this->arg('nickname'), $this->arg('id'));
if (!$this->list instanceof Profile_list) {
// TRANS: Client error displayed trying to show list membership on a non-existing list.
$this->clientError(_('List not found.'), 404);
}
$this->profiles = $this->getProfiles();
return true;
}
/**
* Handle the request
*
* Show the admin of the group
*
* @param array $args $_REQUEST data (unused)
*
* @return void
*/
protected function handle()
{
parent::handle();
$this->showJsonUsers($this->profiles);
}
/**
* Fetch the admins of a group
*
* @return array $profiles list of profiles
*/
function getProfiles()
{
$profiles = array();
$profile = $this->list->getSubscribers(
($this->page - 1) * $this->count,
$this->count,
$this->since_id,
$this->max_id
);
while ($profile->fetch()) {
$profiles[] = clone($profile);
}
return $profiles;
}
/**
* Is this action read only?
*
* @param array $args other arguments
*
* @return boolean true
*/
function isReadOnly($args)
{
return true;
}
/**
* When was this list of profiles last modified?
*
* @return string datestamp of the lastest profile in the group
*/
function lastModified()
{
if (!empty($this->profiles) && (count($this->profiles) > 0)) {
return strtotime($this->profiles[0]->created);
}
return null;
}
/**
* An entity tag for this list of groups
*
* Returns an Etag based on the action name, language
* the group id, and timestamps of the first and last
* user who has joined the group
*
* @return string etag
*/
function etag()
{
if (!empty($this->profiles) && (count($this->profiles) > 0)) {
$last = count($this->profiles) - 1;
return '"' . implode(
':',
array($this->arg('action'),
common_user_cache_hash($this->auth_user),
common_language(),
$this->group->id,
strtotime($this->profiles[0]->created),
strtotime($this->profiles[$last]->created))
)
. '"';
}
return null;
}
}

View File

@ -0,0 +1,161 @@
<?php
/* · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
· ·
· ·
· Q V I T T E R ·
· ·
· http://github.com/hannesmannerheim/qvitter ·
· ·
· ·
· <o) ·
· /_//// ·
· (____/ ·
· (o< ·
· o> \\\\_\ ·
· \\) \____) ·
· ·
· ·
· ·
· Qvitter is free software: you can redistribute it and / or modify it ·
· under the terms of the GNU Affero General Public License as published by ·
· the Free Software Foundation, either version three of the License or (at ·
· your option) any later version. ·
· ·
· Qvitter is distributed in hope that it will be useful but WITHOUT ANY ·
· WARRANTY; without even the implied warranty of MERCHANTABILTY or FITNESS ·
· FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for ·
· more details. ·
· ·
· You should have received a copy of the GNU Affero General Public License ·
· along with Qvitter. If not, see <http://www.gnu.org/licenses/>. ·
· ·
· Contact h@nnesmannerhe.im if you have any questions. ·
· ·
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · */
if (!defined('STATUSNET')) {
exit(1);
}
/**
* Returns the most recent notices (default 20) in the list
*/
class ApiQvitterTimelineListAction extends ApiBareAuthAction
{
var $notices = null;
var $list = null;
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*
*/
protected function prepare(array $args=array())
{
parent::prepare($args);
$this->list = $this->getTargetList($this->arg('nickname'), $this->arg('id'));
if (!($this->list instanceof Profile_list)) {
// TRANS: Client error displayed when requesting a non existing list
$this->clientError(_('List not found.'), 404);
}
$this->notices = $this->getNotices();
return true;
}
/**
* Handle the request
*
* Just show the notices
*
* @return void
*/
protected function handle()
{
parent::handle();
$this->showJsonTimeline($this->notices);
}
/**
* Get notices
*
* @return array notices
*/
function getNotices()
{
$notices = array();
$stream = new PeopletagNoticeStream($this->list);
$notice = $stream->getNotices(($this->page - 1) * $this->count,
$this->count,
$this->since_id,
$this->max_id);
$notices = $notice->fetchAll();
NoticeList::prefill($notices);
return $notices;
}
/**
* Is this action read only?
*
* @param array $args other arguments
*
* @return boolean true
*/
function isReadOnly($args)
{
return true;
}
/**
* When was this feed last modified?
*
* @return string datestamp of the latest notice in the stream
*/
function lastModified()
{
if (!empty($this->notices) && (count($this->notices) > 0)) {
return strtotime($this->notices[0]->created);
}
return null;
}
/**
* An entity tag for this stream
*
* Returns an Etag based on the action name, language, and
* timestamps of the first and last notice in the timeline
*
* @return string etag
*/
function etag()
{
if (!empty($this->notices) && (count($this->notices) > 0)) {
$last = count($this->notices) - 1;
return '"' . implode(
':',
array($this->arg('action'),
common_user_cache_hash($this->auth_user),
common_language(),
strtotime($this->notices[0]->created),
strtotime($this->notices[$last]->created))
)
. '"';
}
return null;
}
}

View File

@ -821,6 +821,11 @@ function setNewCurrentStream(streamObject,setLocation,fallbackId,actionOnSuccess
|| streamObject.name == 'group admin list') {
showErrorMessage(window.sL.ERRORcouldNotFindGroupWithNickname.replace('{nickname}',replaceHtmlSpecialChars(streamObject.nickname)));
}
else if(streamObject.name == 'list notice stream'
|| streamObject.name == 'list members'
|| streamObject.name == 'list subscribers') {
showErrorMessage(window.sL.ERRORcouldNotFindList);
}
else {
showErrorMessage(window.sL.ERRORcouldNotFindPage + '<br><br>url: ' + url);
}

View File

@ -426,6 +426,62 @@ function pathToStreamRouter(path) {
return streamObject;
}
// {screen_name}/all/{listname}
if(pathSplit.length == 3 && /^[a-zA-Z0-9]+$/.test(pathSplit[0]) && pathSplit[1] == 'all' && /^[a-zA-Z0-9]+$/.test(pathSplit[2])) {
streamObject.name = 'list notice stream';
streamObject.nickname = pathSplit[2];
streamObject.stream = 'qvitter/' + pathSplit[0] + '/lists/' + pathSplit[2] + '/statuses.json';
streamObject.type = 'notices';
if(window.loggedIn.screen_name == pathSplit[0]) {
streamObject.streamHeader = window.sL.myListWithListName.replace('{list-name}',streamObject.nickname);
streamObject.streamSubHeader = window.sL.myListWithListName.replace('{list-name}',streamObject.nickname) + '<div class="queet-streams">/ <a class="queet-stream list-members" href="' + window.siteInstanceURL + pathSplit[0] + '/all/' + streamObject.nickname + '/tagged">' + window.sL.listMembers + '</a> / <a class="queet-stream list-subscribers" href="' + window.siteInstanceURL + pathSplit[0] + '/all/' + streamObject.nickname + '/subscribers">' + window.sL.listSubscribers + '</a></div>';
}
else {
streamObject.streamHeader = window.sL.nicknamesListWithListName.replace('{list-name}',streamObject.nickname).replace('{nickname}',pathSplit[0]);
streamObject.streamSubHeader = window.sL.nicknamesListWithListName.replace('{list-name}',streamObject.nickname).replace('{nickname}',pathSplit[0]) + '<div class="queet-streams">/ <a class="queet-stream list-members" href="' + window.siteInstanceURL + pathSplit[0] + '/all/' + streamObject.nickname + '/tagged">' + window.sL.listMembers + '</a> / <a class="queet-stream list-subscribers" href="' + window.siteInstanceURL + pathSplit[0] + '/all/' + streamObject.nickname + '/subscribers">' + window.sL.listSubscribers + '</a></div>';
}
return streamObject;
}
// {screen_name}/all/{listname}/members
if(pathSplit.length == 4 && /^[a-zA-Z0-9]+$/.test(pathSplit[0]) && pathSplit[1] == 'all' && /^[a-zA-Z0-9]+$/.test(pathSplit[2]) && pathSplit[3] == 'tagged') {
streamObject.name = 'list members';
streamObject.nickname = pathSplit[2];
streamObject.parentPath = pathSplit[0] + '/all/' + pathSplit[2];
streamObject.stream = 'qvitter/' + pathSplit[0] + '/lists/' + pathSplit[2] + '/members.json';
streamObject.maxIdOrPage = 'page';
streamObject.type = 'users';
if(window.loggedIn.screen_name == pathSplit[0]) {
streamObject.streamHeader = window.sL.myListWithListName.replace('{list-name}',streamObject.nickname);
streamObject.streamSubHeader = '<div class="queet-streams"><a class="queet-stream list-notice-stream" href="' + window.siteInstanceURL + pathSplit[0] + '/all/' + streamObject.nickname + '">' + window.sL.myListWithListName.replace('{list-name}',streamObject.nickname) + '</a> /</div>' + window.sL.listMembers + '<div class="queet-streams">/ <a class="queet-stream list-subscribers" href="' + window.siteInstanceURL + pathSplit[0] + '/all/' + streamObject.nickname + '/subscribers">' + window.sL.listSubscribers + '</a></div>';
}
else {
streamObject.streamHeader = window.sL.nicknamesListWithListName.replace('{list-name}',streamObject.nickname).replace('{nickname}',pathSplit[0]);
streamObject.streamSubHeader = '<div class="queet-streams"><a class="queet-stream list-notice-stream" href="' + window.siteInstanceURL + pathSplit[0] + '/all/' + streamObject.nickname + '">' + window.sL.nicknamesListWithListName.replace('{list-name}',streamObject.nickname).replace('{nickname}',pathSplit[0]) + '</a> /</div>' + window.sL.listMembers + '<div class="queet-streams">/ <a class="queet-stream list-subscribers" href="' + window.siteInstanceURL + pathSplit[0] + '/all/' + streamObject.nickname + '/subscribers">' + window.sL.listSubscribers + '</a></div>';
}
return streamObject;
}
// {screen_name}/all/{listname}/subscribers
if(pathSplit.length == 4 && /^[a-zA-Z0-9]+$/.test(pathSplit[0]) && pathSplit[1] == 'all' && /^[a-zA-Z0-9]+$/.test(pathSplit[2]) && pathSplit[3] == 'subscribers') {
streamObject.name = 'list subscribers';
streamObject.nickname = pathSplit[2];
streamObject.parentPath = pathSplit[0] + '/all/' + pathSplit[2];
streamObject.stream = 'qvitter/' + pathSplit[0] + '/lists/' + pathSplit[2] + '/subscribers.json';
streamObject.maxIdOrPage = 'page';
streamObject.type = 'users';
if(window.loggedIn.screen_name == pathSplit[0]) {
streamObject.streamHeader = window.sL.myListWithListName.replace('{list-name}',streamObject.nickname);
streamObject.streamSubHeader = '<div class="queet-streams"><a class="queet-stream list-notice-stream" href="' + window.siteInstanceURL + pathSplit[0] + '/all/' + streamObject.nickname + '">' + window.sL.myListWithListName.replace('{list-name}',streamObject.nickname) + '</a> / <a class="queet-stream list-members" href="' + window.siteInstanceURL + pathSplit[0] + '/all/' + streamObject.nickname + '/tagged">' + window.sL.listMembers + '</a> /</div>' + window.sL.listSubscribers;
}
else {
streamObject.streamHeader = window.sL.nicknamesListWithListName.replace('{list-name}',streamObject.nickname).replace('{nickname}',pathSplit[0]);
streamObject.streamSubHeader = '<div class="queet-streams"><a class="queet-stream list-notice-stream" href="' + window.siteInstanceURL + pathSplit[0] + '/all/' + streamObject.nickname + '">' + window.sL.nicknamesListWithListName.replace('{list-name}',streamObject.nickname).replace('{nickname}',pathSplit[0]) + '</a> / <a class="queet-stream list-members" href="' + window.siteInstanceURL + pathSplit[0] + '/all/' + streamObject.nickname + '/tagged">' + window.sL.listMembers + '</a> /</div>' + window.sL.listSubscribers;
}
return streamObject;
}
// other plugins can add streams to Qvitter
if(window.pluginStreamObjects.length > 0) {
$.each(window.pluginStreamObjects,function(k,pluginStreamObject) {

View File

@ -151,5 +151,10 @@
"ERRORfailedMarkingAllNotificationsAsRead":"Failed marking all notifications as seen.",
"newNotification": "{new-notice-count} new notification",
"newNotifications": "{new-notice-count} new notifications",
"thisIsANoticeFromABlockedUser":"Warning: This is a notice from a user you have blocked. Click to show it."
"thisIsANoticeFromABlockedUser":"Warning: This is a notice from a user you have blocked. Click to show it.",
"nicknamesListWithListName":"{nickname}s list: {list-name}",
"myListWithListName":"My list: {list-name}",
"listMembers":"Members",
"listSubscribers":"Subscribers",
"ERRORcouldNotFindList":"There is no such list."
}

View File

@ -151,5 +151,10 @@
"ERRORfailedMarkingAllNotificationsAsRead":"Failed marking all notifications as seen.",
"newNotification": "{new-notice-count} new notification",
"newNotifications": "{new-notice-count} new notifications",
"thisIsANoticeFromABlockedUser":"Warning: This is a notice from a user you have blocked. Click to show it."
"thisIsANoticeFromABlockedUser":"Warning: This is a notice from a user you have blocked. Click to show it.",
"nicknamesListWithListName":"{nickname}s list: {list-name}",
"myListWithListName":"My list: {list-name}",
"listMembers":"Members",
"listSubscribers":"Subscribers",
"ERRORcouldNotFindList":"There is no such list."
}

View File

@ -151,5 +151,10 @@
"ERRORfailedMarkingAllNotificationsAsRead":"Failed marking all notifications as seen.",
"newNotification": "{new-notice-count} new notification",
"newNotifications": "{new-notice-count} new notifications",
"thisIsANoticeFromABlockedUser":"Warning: This is a notice from a user you have blocked. Click to show it."
"thisIsANoticeFromABlockedUser":"Warning: This is a notice from a user you have blocked. Click to show it.",
"nicknamesListWithListName":"{nickname}s list: {list-name}",
"myListWithListName":"My list: {list-name}",
"listMembers":"Members",
"listSubscribers":"Subscribers",
"ERRORcouldNotFindList":"There is no such list."
}

View File

@ -151,5 +151,10 @@
"ERRORfailedMarkingAllNotificationsAsRead":"Alle Benachrichtigungen als gelesen markieren fehlgeschlagen.",
"newNotification": "{new-notice-count} neue Benachrichtigung",
"newNotifications": "{new-notice-count} neue Benachrichtigungen",
"thisIsANoticeFromABlockedUser":"Achtung: Dies ist ein Queet von einem Nutzer, den du blockiert hast. Klicke um ihn anzuzeigen."
"thisIsANoticeFromABlockedUser":"Achtung: Dies ist ein Queet von einem Nutzer, den du blockiert hast. Klicke um ihn anzuzeigen.",
"nicknamesListWithListName":"{nickname}s list: {list-name}",
"myListWithListName":"My list: {list-name}",
"listMembers":"Members",
"listSubscribers":"Subscribers",
"ERRORcouldNotFindList":"There is no such list."
}

View File

@ -151,5 +151,10 @@
"ERRORfailedMarkingAllNotificationsAsRead":"Failed marking all notifications as seen.",
"newNotification": "{new-notice-count} new notification",
"newNotifications": "{new-notice-count} new notifications",
"thisIsANoticeFromABlockedUser":"Warning: This is a notice from a user you have blocked. Click to show it."
"thisIsANoticeFromABlockedUser":"Warning: This is a notice from a user you have blocked. Click to show it.",
"nicknamesListWithListName":"{nickname}s list: {list-name}",
"myListWithListName":"My list: {list-name}",
"listMembers":"Members",
"listSubscribers":"Subscribers",
"ERRORcouldNotFindList":"There is no such list."
}

View File

@ -151,5 +151,10 @@
"ERRORfailedMarkingAllNotificationsAsRead":"Failed marking all notifications as seen.",
"newNotification": "{new-notice-count} new notification",
"newNotifications": "{new-notice-count} new notifications",
"thisIsANoticeFromABlockedUser":"Warning: This is a notice from a user you have blocked. Click to show it."
"thisIsANoticeFromABlockedUser":"Warning: This is a notice from a user you have blocked. Click to show it.",
"nicknamesListWithListName":"{nickname}s list: {list-name}",
"myListWithListName":"My list: {list-name}",
"listMembers":"Members",
"listSubscribers":"Subscribers",
"ERRORcouldNotFindList":"There is no such list."
}

View File

@ -151,5 +151,10 @@
"ERRORfailedMarkingAllNotificationsAsRead":"Error al marcar todas las notificaciones como vistas.",
"newNotification": "{new-notice-count} nueva notificación",
"newNotifications": "{new-notice-count} nuevas notificaciones",
"thisIsANoticeFromABlockedUser":"Atención: Ésta es una nota de un usuario que bloqueaste. Pulsa para mostrarla."
"thisIsANoticeFromABlockedUser":"Atención: Ésta es una nota de un usuario que bloqueaste. Pulsa para mostrarla.",
"nicknamesListWithListName":"{nickname}s list: {list-name}",
"myListWithListName":"My list: {list-name}",
"listMembers":"Members",
"listSubscribers":"Subscribers",
"ERRORcouldNotFindList":"There is no such list."
}

View File

@ -151,5 +151,10 @@
"ERRORfailedMarkingAllNotificationsAsRead":"Failed marking all notifications as seen.",
"newNotification": "{new-notice-count} new notification",
"newNotifications": "{new-notice-count} new notifications",
"thisIsANoticeFromABlockedUser":"Warning: This is a notice from a user you have blocked. Click to show it."
"thisIsANoticeFromABlockedUser":"Warning: This is a notice from a user you have blocked. Click to show it.",
"nicknamesListWithListName":"{nickname}s list: {list-name}",
"myListWithListName":"My list: {list-name}",
"listMembers":"Members",
"listSubscribers":"Subscribers",
"ERRORcouldNotFindList":"There is no such list."
}

View File

@ -151,5 +151,10 @@
"ERRORfailedMarkingAllNotificationsAsRead":"Failed marking all notifications as seen.",
"newNotification": "{new-notice-count} new notification",
"newNotifications": "{new-notice-count} new notifications",
"thisIsANoticeFromABlockedUser":"Warning: This is a notice from a user you have blocked. Click to show it."
"thisIsANoticeFromABlockedUser":"Warning: This is a notice from a user you have blocked. Click to show it.",
"nicknamesListWithListName":"{nickname}s list: {list-name}",
"myListWithListName":"My list: {list-name}",
"listMembers":"Members",
"listSubscribers":"Subscribers",
"ERRORcouldNotFindList":"There is no such list."
}

View File

@ -151,5 +151,10 @@
"ERRORfailedMarkingAllNotificationsAsRead":"Failed marking all notifications as seen.",
"newNotification": "{new-notice-count} new notification",
"newNotifications": "{new-notice-count} new notifications",
"thisIsANoticeFromABlockedUser":"Warning: This is a notice from a user you have blocked. Click to show it."
"thisIsANoticeFromABlockedUser":"Warning: This is a notice from a user you have blocked. Click to show it.",
"nicknamesListWithListName":"{nickname}s list: {list-name}",
"myListWithListName":"My list: {list-name}",
"listMembers":"Members",
"listSubscribers":"Subscribers",
"ERRORcouldNotFindList":"There is no such list."
}

View File

@ -151,5 +151,10 @@
"ERRORfailedMarkingAllNotificationsAsRead":"Failed marking all notifications as seen.",
"newNotification": "{new-notice-count} new notification",
"newNotifications": "{new-notice-count} new notifications",
"thisIsANoticeFromABlockedUser":"Warning: This is a notice from a user you have blocked. Click to show it."
"thisIsANoticeFromABlockedUser":"Warning: This is a notice from a user you have blocked. Click to show it.",
"nicknamesListWithListName":"{nickname}s list: {list-name}",
"myListWithListName":"My list: {list-name}",
"listMembers":"Members",
"listSubscribers":"Subscribers",
"ERRORcouldNotFindList":"There is no such list."
}

View File

@ -151,5 +151,10 @@
"ERRORfailedMarkingAllNotificationsAsRead":"Échec du marquage de toutes les notifications comme vues",
"newNotification": "{new-notice-count} nouvelle notification",
"newNotifications": "{new-notice-count} nouvelles notifications",
"thisIsANoticeFromABlockedUser":"Warning: This is a notice from a user you have blocked. Click to show it."
"thisIsANoticeFromABlockedUser":"Warning: This is a notice from a user you have blocked. Click to show it.",
"nicknamesListWithListName":"{nickname}s list: {list-name}",
"myListWithListName":"My list: {list-name}",
"listMembers":"Members",
"listSubscribers":"Subscribers",
"ERRORcouldNotFindList":"There is no such list."
}

View File

@ -151,5 +151,10 @@
"ERRORfailedMarkingAllNotificationsAsRead":"Failed marking all notifications as seen.",
"newNotification": "{new-notice-count} new notification",
"newNotifications": "{new-notice-count} new notifications",
"thisIsANoticeFromABlockedUser":"Warning: This is a notice from a user you have blocked. Click to show it."
"thisIsANoticeFromABlockedUser":"Warning: This is a notice from a user you have blocked. Click to show it.",
"nicknamesListWithListName":"{nickname}s list: {list-name}",
"myListWithListName":"My list: {list-name}",
"listMembers":"Members",
"listSubscribers":"Subscribers",
"ERRORcouldNotFindList":"There is no such list."
}

View File

@ -151,5 +151,10 @@
"ERRORfailedMarkingAllNotificationsAsRead":"Failed marking all notifications as seen.",
"newNotification": "{new-notice-count} new notification",
"newNotifications": "{new-notice-count} new notifications",
"thisIsANoticeFromABlockedUser":"Warning: This is a notice from a user you have blocked. Click to show it."
"thisIsANoticeFromABlockedUser":"Warning: This is a notice from a user you have blocked. Click to show it.",
"nicknamesListWithListName":"{nickname}s list: {list-name}",
"myListWithListName":"My list: {list-name}",
"listMembers":"Members",
"listSubscribers":"Subscribers",
"ERRORcouldNotFindList":"There is no such list."
}

View File

@ -151,5 +151,10 @@
"ERRORfailedMarkingAllNotificationsAsRead":"On faliis, ke on markizez omna notifiki kom vidita.",
"newNotification": "{new-notice-count} nova notifiko",
"newNotifications": "{new-notice-count} nova notifiki",
"thisIsANoticeFromABlockedUser":"Averto: Ita mesajo esas da uzero quan vu blokusis. Kliktigez por ke on montrez olu."
"thisIsANoticeFromABlockedUser":"Averto: Ita mesajo esas da uzero quan vu blokusis. Kliktigez por ke on montrez olu.",
"nicknamesListWithListName":"{nickname}s list: {list-name}",
"myListWithListName":"My list: {list-name}",
"listMembers":"Members",
"listSubscribers":"Subscribers",
"ERRORcouldNotFindList":"There is no such list."
}

View File

@ -151,5 +151,10 @@
"ERRORfailedMarkingAllNotificationsAsRead":"Failed marking all notifications as seen.",
"newNotification": "{new-notice-count} new notification",
"newNotifications": "{new-notice-count} new notifications",
"thisIsANoticeFromABlockedUser":"Warning: This is a notice from a user you have blocked. Click to show it."
"thisIsANoticeFromABlockedUser":"Warning: This is a notice from a user you have blocked. Click to show it.",
"nicknamesListWithListName":"{nickname}s list: {list-name}",
"myListWithListName":"My list: {list-name}",
"listMembers":"Members",
"listSubscribers":"Subscribers",
"ERRORcouldNotFindList":"There is no such list."
}

View File

@ -151,5 +151,10 @@
"ERRORfailedMarkingAllNotificationsAsRead":"Feilet ved forsøk å markere alle varsler som lest.",
"newNotification": "{new-notice-count} nytt varsel",
"newNotifications": "{new-notice-count} nye varsler",
"thisIsANoticeFromABlockedUser":"Advarsel: Dette er en notis fra en bruker du har blokkert. Klikk for å se den."
"thisIsANoticeFromABlockedUser":"Advarsel: Dette er en notis fra en bruker du har blokkert. Klikk for å se den.",
"nicknamesListWithListName":"{nickname}s list: {list-name}",
"myListWithListName":"My list: {list-name}",
"listMembers":"Members",
"listSubscribers":"Subscribers",
"ERRORcouldNotFindList":"There is no such list."
}

View File

@ -151,5 +151,10 @@
"ERRORfailedMarkingAllNotificationsAsRead":"Failed marking all notifications as seen.",
"newNotification": "{new-notice-count} new notification",
"newNotifications": "{new-notice-count} new notifications",
"thisIsANoticeFromABlockedUser":"Warning: This is a notice from a user you have blocked. Click to show it."
"thisIsANoticeFromABlockedUser":"Warning: This is a notice from a user you have blocked. Click to show it.",
"nicknamesListWithListName":"{nickname}s list: {list-name}",
"myListWithListName":"My list: {list-name}",
"listMembers":"Members",
"listSubscribers":"Subscribers",
"ERRORcouldNotFindList":"There is no such list."
}

View File

@ -151,5 +151,10 @@
"ERRORfailedMarkingAllNotificationsAsRead":"Misslyckades med att markera alla notiser som lästa.",
"newNotification": "{new-notice-count} ny notis",
"newNotifications": "{new-notice-count} nya notiser",
"thisIsANoticeFromABlockedUser":"Varning! Det här är en qvittring från en användare som du har blockerat. Klicka för att visa den."
"thisIsANoticeFromABlockedUser":"Varning! Det här är en qvittring från en användare som du har blockerat. Klicka för att visa den.",
"nicknamesListWithListName":"Lista: {list-name} (av @{nickname})",
"myListWithListName":"Min lista: {list-name}",
"listMembers":"Listmedlemmar",
"listSubscribers":"Prenumeranter",
"ERRORcouldNotFindList":"Det finns ingen sådan lista."
}

View File

@ -150,5 +150,10 @@
"ERRORfailedMarkingAllNotificationsAsRead":"Failed marking all notifications as seen.",
"newNotification": "{new-notice-count} new notification",
"newNotifications": "{new-notice-count} new notifications",
"thisIsANoticeFromABlockedUser":"Warning: This is a notice from a user you have blocked. Click to show it."
"thisIsANoticeFromABlockedUser":"Warning: This is a notice from a user you have blocked. Click to show it.",
"nicknamesListWithListName":"{nickname}s list: {list-name}",
"myListWithListName":"My list: {list-name}",
"listMembers":"Members",
"listSubscribers":"Subscribers",
"ERRORcouldNotFindList":"There is no such list."
}

View File

@ -150,5 +150,10 @@
"ERRORfailedMarkingAllNotificationsAsRead":"Failed marking all notifications as seen.",
"newNotification": "{new-notice-count} new notification",
"newNotifications": "{new-notice-count} new notifications",
"thisIsANoticeFromABlockedUser":"Warning: This is a notice from a user you have blocked. Click to show it."
"thisIsANoticeFromABlockedUser":"Warning: This is a notice from a user you have blocked. Click to show it.",
"nicknamesListWithListName":"{nickname}s list: {list-name}",
"myListWithListName":"My list: {list-name}",
"listMembers":"Members",
"listSubscribers":"Subscribers",
"ERRORcouldNotFindList":"There is no such list."
}