1
0
Fork 0

Merge pull request #13288 from MrPetovan/task/user-server-block

Add Ignore Author Server button to post actions
This commit is contained in:
Michael Vogel 2023-08-20 20:41:17 +02:00 committed by GitHub
commit 1edb7b6464
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
38 changed files with 1677 additions and 465 deletions

View file

@ -1,6 +1,6 @@
-- ------------------------------------------ -- ------------------------------------------
-- Friendica 2023.09-dev (Giant Rhubarb) -- Friendica 2023.09-dev (Giant Rhubarb)
-- DB_UPDATE_VERSION 1525 -- DB_UPDATE_VERSION 1527
-- ------------------------------------------ -- ------------------------------------------
@ -101,6 +101,18 @@ CREATE TABLE IF NOT EXISTS `user` (
FOREIGN KEY (`parent-uid`) REFERENCES `user` (`uid`) ON UPDATE RESTRICT ON DELETE CASCADE FOREIGN KEY (`parent-uid`) REFERENCES `user` (`uid`) ON UPDATE RESTRICT ON DELETE CASCADE
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='The local users'; ) DEFAULT COLLATE utf8mb4_general_ci COMMENT='The local users';
--
-- TABLE user-gserver
--
CREATE TABLE IF NOT EXISTS `user-gserver` (
`uid` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'Owner User id',
`gsid` int unsigned NOT NULL DEFAULT 0 COMMENT 'Gserver id',
`ignored` boolean NOT NULL DEFAULT '0' COMMENT 'server accounts are ignored for the user',
PRIMARY KEY(`uid`,`gsid`),
FOREIGN KEY (`uid`) REFERENCES `user` (`uid`) ON UPDATE RESTRICT ON DELETE CASCADE,
FOREIGN KEY (`gsid`) REFERENCES `gserver` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='User settings about remote servers';
-- --
-- TABLE item-uri -- TABLE item-uri
-- --
@ -2044,6 +2056,7 @@ CREATE VIEW `post-user-view` AS SELECT
`owner`.`blocked` AS `owner-blocked`, `owner`.`blocked` AS `owner-blocked`,
`owner`.`hidden` AS `owner-hidden`, `owner`.`hidden` AS `owner-hidden`,
`owner`.`updated` AS `owner-updated`, `owner`.`updated` AS `owner-updated`,
`owner`.`gsid` AS `owner-gsid`,
`owner`.`contact-type` AS `owner-contact-type`, `owner`.`contact-type` AS `owner-contact-type`,
`post-user`.`causer-id` AS `causer-id`, `post-user`.`causer-id` AS `causer-id`,
`causer`.`uri-id` AS `causer-uri-id`, `causer`.`uri-id` AS `causer-uri-id`,
@ -2056,6 +2069,7 @@ CREATE VIEW `post-user-view` AS SELECT
`causer`.`network` AS `causer-network`, `causer`.`network` AS `causer-network`,
`causer`.`blocked` AS `causer-blocked`, `causer`.`blocked` AS `causer-blocked`,
`causer`.`hidden` AS `causer-hidden`, `causer`.`hidden` AS `causer-hidden`,
`causer`.`gsid` AS `causer-gsid`,
`causer`.`contact-type` AS `causer-contact-type`, `causer`.`contact-type` AS `causer-contact-type`,
`post-delivery-data`.`postopts` AS `postopts`, `post-delivery-data`.`postopts` AS `postopts`,
`post-delivery-data`.`inform` AS `inform`, `post-delivery-data`.`inform` AS `inform`,
@ -2189,6 +2203,7 @@ CREATE VIEW `post-thread-user-view` AS SELECT
`contact`.`pending` AS `contact-pending`, `contact`.`pending` AS `contact-pending`,
`contact`.`rel` AS `contact-rel`, `contact`.`rel` AS `contact-rel`,
`contact`.`uid` AS `contact-uid`, `contact`.`uid` AS `contact-uid`,
`contact`.`gsid` AS `contact-gsid`,
`contact`.`contact-type` AS `contact-contact-type`, `contact`.`contact-type` AS `contact-contact-type`,
IF (`post-user`.`network` IN ('apub', 'dfrn', 'dspr', 'stat'), true, `contact`.`writable`) AS `writable`, IF (`post-user`.`network` IN ('apub', 'dfrn', 'dspr', 'stat'), true, `contact`.`writable`) AS `writable`,
`contact`.`self` AS `self`, `contact`.`self` AS `self`,
@ -2224,6 +2239,7 @@ CREATE VIEW `post-thread-user-view` AS SELECT
`owner`.`blocked` AS `owner-blocked`, `owner`.`blocked` AS `owner-blocked`,
`owner`.`hidden` AS `owner-hidden`, `owner`.`hidden` AS `owner-hidden`,
`owner`.`updated` AS `owner-updated`, `owner`.`updated` AS `owner-updated`,
`owner`.`gsid` AS `owner-gsid`,
`owner`.`contact-type` AS `owner-contact-type`, `owner`.`contact-type` AS `owner-contact-type`,
`post-thread-user`.`causer-id` AS `causer-id`, `post-thread-user`.`causer-id` AS `causer-id`,
`causer`.`uri-id` AS `causer-uri-id`, `causer`.`uri-id` AS `causer-uri-id`,
@ -2236,6 +2252,7 @@ CREATE VIEW `post-thread-user-view` AS SELECT
`causer`.`network` AS `causer-network`, `causer`.`network` AS `causer-network`,
`causer`.`blocked` AS `causer-blocked`, `causer`.`blocked` AS `causer-blocked`,
`causer`.`hidden` AS `causer-hidden`, `causer`.`hidden` AS `causer-hidden`,
`causer`.`gsid` AS `causer-gsid`,
`causer`.`contact-type` AS `causer-contact-type`, `causer`.`contact-type` AS `causer-contact-type`,
`post-delivery-data`.`postopts` AS `postopts`, `post-delivery-data`.`postopts` AS `postopts`,
`post-delivery-data`.`inform` AS `inform`, `post-delivery-data`.`inform` AS `inform`,
@ -2391,6 +2408,7 @@ CREATE VIEW `post-view` AS SELECT
`owner`.`hidden` AS `owner-hidden`, `owner`.`hidden` AS `owner-hidden`,
`owner`.`updated` AS `owner-updated`, `owner`.`updated` AS `owner-updated`,
`owner`.`contact-type` AS `owner-contact-type`, `owner`.`contact-type` AS `owner-contact-type`,
`owner`.`gsid` AS `owner-gsid`,
`post`.`causer-id` AS `causer-id`, `post`.`causer-id` AS `causer-id`,
`causer`.`uri-id` AS `causer-uri-id`, `causer`.`uri-id` AS `causer-uri-id`,
`causer`.`url` AS `causer-link`, `causer`.`url` AS `causer-link`,
@ -2403,6 +2421,7 @@ CREATE VIEW `post-view` AS SELECT
`causer`.`blocked` AS `causer-blocked`, `causer`.`blocked` AS `causer-blocked`,
`causer`.`hidden` AS `causer-hidden`, `causer`.`hidden` AS `causer-hidden`,
`causer`.`contact-type` AS `causer-contact-type`, `causer`.`contact-type` AS `causer-contact-type`,
`causer`.`gsid` AS `causer-gsid`,
`post-question`.`id` AS `question-id`, `post-question`.`id` AS `question-id`,
`post-question`.`multiple` AS `question-multiple`, `post-question`.`multiple` AS `question-multiple`,
`post-question`.`voters` AS `question-voters`, `post-question`.`voters` AS `question-voters`,
@ -2533,6 +2552,7 @@ CREATE VIEW `post-thread-view` AS SELECT
`owner`.`blocked` AS `owner-blocked`, `owner`.`blocked` AS `owner-blocked`,
`owner`.`hidden` AS `owner-hidden`, `owner`.`hidden` AS `owner-hidden`,
`owner`.`updated` AS `owner-updated`, `owner`.`updated` AS `owner-updated`,
`owner`.`gsid` AS `owner-gsid`,
`owner`.`contact-type` AS `owner-contact-type`, `owner`.`contact-type` AS `owner-contact-type`,
`post-thread`.`causer-id` AS `causer-id`, `post-thread`.`causer-id` AS `causer-id`,
`causer`.`uri-id` AS `causer-uri-id`, `causer`.`uri-id` AS `causer-uri-id`,
@ -2545,6 +2565,7 @@ CREATE VIEW `post-thread-view` AS SELECT
`causer`.`network` AS `causer-network`, `causer`.`network` AS `causer-network`,
`causer`.`blocked` AS `causer-blocked`, `causer`.`blocked` AS `causer-blocked`,
`causer`.`hidden` AS `causer-hidden`, `causer`.`hidden` AS `causer-hidden`,
`causer`.`gsid` AS `causer-gsid`,
`causer`.`contact-type` AS `causer-contact-type`, `causer`.`contact-type` AS `causer-contact-type`,
`post-question`.`id` AS `question-id`, `post-question`.`id` AS `question-id`,
`post-question`.`multiple` AS `question-multiple`, `post-question`.`multiple` AS `question-multiple`,
@ -2707,7 +2728,8 @@ CREATE VIEW `network-thread-view` AS SELECT
AND (`post-thread-user`.`hidden` IS NULL OR NOT `post-thread-user`.`hidden`) AND (`post-thread-user`.`hidden` IS NULL OR NOT `post-thread-user`.`hidden`)
AND NOT `authorcontact`.`blocked` AND NOT `ownercontact`.`blocked` AND NOT `authorcontact`.`blocked` AND NOT `ownercontact`.`blocked`
AND (`author`.`blocked` IS NULL OR NOT `author`.`blocked`) AND (`author`.`blocked` IS NULL OR NOT `author`.`blocked`)
AND (`owner`.`blocked` IS NULL OR NOT `owner`.`blocked`); AND (`owner`.`blocked` IS NULL OR NOT `owner`.`blocked`)
AND NOT EXISTS(SELECT `gsid` FROM `user-gserver` WHERE `uid` = `post-thread-user`.`uid` AND `gsid` IN (`authorcontact`.`gsid`, `ownercontact`.`gsid`) AND `ignored`);
-- --
-- VIEW owner-view -- VIEW owner-view

View file

@ -86,6 +86,7 @@ Database Tables
| [tag](help/database/db_tag) | tags and mentions | | [tag](help/database/db_tag) | tags and mentions |
| [user](help/database/db_user) | The local users | | [user](help/database/db_user) | The local users |
| [user-contact](help/database/db_user-contact) | User specific public contact data | | [user-contact](help/database/db_user-contact) | User specific public contact data |
| [user-gserver](help/database/db_user-gserver) | User settings about remote servers |
| [userd](help/database/db_userd) | Deleted usernames | | [userd](help/database/db_userd) | Deleted usernames |
| [verb](help/database/db_verb) | Activity Verbs | | [verb](help/database/db_verb) | Activity Verbs |
| [worker-ipc](help/database/db_worker-ipc) | Inter process communication between the frontend and the worker | | [worker-ipc](help/database/db_worker-ipc) | Inter process communication between the frontend and the worker |

View file

@ -0,0 +1,30 @@
Table user-gserver
===========
User settings about remote servers
Fields
------
| Field | Description | Type | Null | Key | Default | Extra |
| ------- | ---------------------------------------- | ------------------ | ---- | --- | ------- | ----- |
| uid | Owner User id | mediumint unsigned | NO | | 0 | |
| gsid | Gserver id | int unsigned | NO | | 0 | |
| ignored | server accounts are ignored for the user | boolean | NO | | 0 | |
Indexes
------------
| Name | Fields |
| ------- | --------- |
| PRIMARY | uid, gsid |
Foreign Keys
------------
| Field | Target Table | Target Field |
|-------|--------------|--------------|
| uid | [user](help/database/db_user) | uid |
| gsid | [gserver](help/database/db_gserver) | id |
Return to [database documentation](help/database)

View file

@ -245,10 +245,12 @@ class Page implements ArrayAccess
*/ */
$this->page['htmlhead'] = Renderer::replaceMacros($tpl, [ $this->page['htmlhead'] = Renderer::replaceMacros($tpl, [
'$l10n' => [ '$l10n' => [
'delitem' => $l10n->t('Delete this item?'), 'delitem' => $l10n->t('Delete this item?'),
'blockAuthor' => $l10n->t('Block this author? They won\'t be able to follow you nor see your public posts, and you won\'t be able to see their posts and their notifications.'), 'blockAuthor' => $l10n->t("Block this author? They won't be able to follow you nor see your public posts, and you won't be able to see their posts and their notifications."),
'ignoreAuthor' => $l10n->t('Ignore this author? You won\'t be able to see their posts and their notifications.'), 'ignoreAuthor' => $l10n->t("Ignore this author? You won't be able to see their posts and their notifications."),
'collapseAuthor' => $l10n->t('Collapse this author\'s posts?'), 'collapseAuthor' => $l10n->t("Collapse this author's posts?"),
'ignoreServer' => $l10n->t("Ignore this author's server?"),
'ignoreServerDesc' => $l10n->t("You won't see any content from this server including reshares in your Network page, the community pages and individual conversations."),
'likeError' => $l10n->t('Like not successful'), 'likeError' => $l10n->t('Like not successful'),
'dislikeError' => $l10n->t('Dislike not successful'), 'dislikeError' => $l10n->t('Dislike not successful'),

View file

@ -45,6 +45,8 @@ use Friendica\Network\HTTPException\InternalServerErrorException;
use Friendica\Object\Post as PostObject; use Friendica\Object\Post as PostObject;
use Friendica\Object\Thread; use Friendica\Object\Thread;
use Friendica\Protocol\Activity; use Friendica\Protocol\Activity;
use Friendica\User\Settings\Entity\UserGServer;
use Friendica\User\Settings\Repository;
use Friendica\Util\Crypto; use Friendica\Util\Crypto;
use Friendica\Util\DateTimeFormat; use Friendica\Util\DateTimeFormat;
use Friendica\Util\Profiler; use Friendica\Util\Profiler;
@ -90,22 +92,25 @@ class Conversation
private $mode; private $mode;
/** @var IHandleUserSessions */ /** @var IHandleUserSessions */
private $session; private $session;
/** @var Repository\UserGServer */
private $userGServer;
public function __construct(LoggerInterface $logger, Profiler $profiler, Activity $activity, L10n $l10n, Item $item, Arguments $args, BaseURL $baseURL, IManageConfigValues $config, IManagePersonalConfigValues $pConfig, App\Page $page, App\Mode $mode, App $app, IHandleUserSessions $session) public function __construct(Repository\UserGServer $userGServer, LoggerInterface $logger, Profiler $profiler, Activity $activity, L10n $l10n, Item $item, Arguments $args, BaseURL $baseURL, IManageConfigValues $config, IManagePersonalConfigValues $pConfig, App\Page $page, App\Mode $mode, App $app, IHandleUserSessions $session)
{ {
$this->activity = $activity; $this->activity = $activity;
$this->item = $item; $this->item = $item;
$this->config = $config; $this->config = $config;
$this->mode = $mode; $this->mode = $mode;
$this->baseURL = $baseURL; $this->baseURL = $baseURL;
$this->profiler = $profiler; $this->profiler = $profiler;
$this->logger = $logger; $this->logger = $logger;
$this->l10n = $l10n; $this->l10n = $l10n;
$this->args = $args; $this->args = $args;
$this->pConfig = $pConfig; $this->pConfig = $pConfig;
$this->page = $page; $this->page = $page;
$this->app = $app; $this->app = $app;
$this->session = $session; $this->session = $session;
$this->userGServer = $userGServer;
} }
/** /**
@ -459,8 +464,14 @@ class Conversation
$live_update_div = ''; $live_update_div = '';
$userGservers = $this->userGServer->listIgnoredByUser($this->session->getLocalUserId());
$ignoredGsids = array_map(function (UserGServer $userGServer) {
return $userGServer->gsid;
}, $userGservers->getArrayCopy());
if ($mode === self::MODE_NETWORK) { if ($mode === self::MODE_NETWORK) {
$items = $this->addChildren($items, false, $order, $uid, $mode); $items = $this->addChildren($items, false, $order, $uid, $mode, $ignoredGsids);
if (!$update) { if (!$update) {
/* /*
* The special div is needed for liveUpdate to kick in for this page. * The special div is needed for liveUpdate to kick in for this page.
@ -486,7 +497,7 @@ class Conversation
. "'; </script>\r\n"; . "'; </script>\r\n";
} }
} elseif ($mode === self::MODE_PROFILE) { } elseif ($mode === self::MODE_PROFILE) {
$items = $this->addChildren($items, false, $order, $uid, $mode); $items = $this->addChildren($items, false, $order, $uid, $mode, $ignoredGsids);
if (!$update) { if (!$update) {
$tab = !empty($_GET['tab']) ? trim($_GET['tab']) : 'posts'; $tab = !empty($_GET['tab']) ? trim($_GET['tab']) : 'posts';
@ -511,7 +522,7 @@ class Conversation
. "; var netargs = '?f='; </script>\r\n"; . "; var netargs = '?f='; </script>\r\n";
} }
} elseif ($mode === self::MODE_DISPLAY) { } elseif ($mode === self::MODE_DISPLAY) {
$items = $this->addChildren($items, false, $order, $uid, $mode); $items = $this->addChildren($items, false, $order, $uid, $mode, $ignoredGsids);
if (!$update) { if (!$update) {
$live_update_div = '<div id="live-display"></div>' . "\r\n" $live_update_div = '<div id="live-display"></div>' . "\r\n"
@ -519,7 +530,7 @@ class Conversation
. "</script>"; . "</script>";
} }
} elseif ($mode === self::MODE_COMMUNITY) { } elseif ($mode === self::MODE_COMMUNITY) {
$items = $this->addChildren($items, true, $order, $uid, $mode); $items = $this->addChildren($items, true, $order, $uid, $mode, $ignoredGsids);
if (!$update) { if (!$update) {
$live_update_div = '<div id="live-community"></div>' . "\r\n" $live_update_div = '<div id="live-community"></div>' . "\r\n"
@ -530,7 +541,7 @@ class Conversation
. "'; </script>\r\n"; . "'; </script>\r\n";
} }
} elseif ($mode === self::MODE_CONTACTS) { } elseif ($mode === self::MODE_CONTACTS) {
$items = $this->addChildren($items, false, $order, $uid, $mode); $items = $this->addChildren($items, false, $order, $uid, $mode, $ignoredGsids);
if (!$update) { if (!$update) {
$live_update_div = '<div id="live-contact"></div>' . "\r\n" $live_update_div = '<div id="live-contact"></div>' . "\r\n"
@ -812,13 +823,14 @@ class Conversation
* *
* @param array $parents Parent items * @param array $parents Parent items
* @param bool $block_authors * @param bool $block_authors
* @param bool $order * @param string $order Either "received" or "commented"
* @param int $uid * @param int $uid
* @param string $mode * @param string $mode One of self::MODE_*
* @param array $ignoredGsids List of ids of servers ignored by the user
* @return array items with parents and comments * @return array items with parents and comments
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws InternalServerErrorException
*/ */
private function addChildren(array $parents, bool $block_authors, string $order, int $uid, string $mode): array private function addChildren(array $parents, bool $block_authors, string $order, int $uid, string $mode, array $ignoredGsids = []): array
{ {
$this->profiler->startRecording('rendering'); $this->profiler->startRecording('rendering');
if (count($parents) > 1) { if (count($parents) > 1) {
@ -900,6 +912,13 @@ class Conversation
continue; continue;
} }
if (in_array($row['author-gsid'], $ignoredGsids)
|| in_array($row['owner-gsid'], $ignoredGsids)
|| in_array($row['causer-gsid'], $ignoredGsids)
) {
continue;
}
if (($mode != self::MODE_CONTACTS) && !$row['origin']) { if (($mode != self::MODE_CONTACTS) && !$row['origin']) {
$row['featured'] = false; $row['featured'] = false;
} }
@ -1462,6 +1481,7 @@ class Conversation
'received' => $item['received'], 'received' => $item['received'],
'created_date' => $item['created'], 'created_date' => $item['created'],
'uriid' => $item['uri-id'], 'uriid' => $item['uri-id'],
'author_gsid' => $item['author-gsid'],
'network' => $item['network'], 'network' => $item['network'],
'network_name' => ContactSelector::networkToName($item['author-network'], $item['author-link'], $item['network'], $item['author-gsid']), 'network_name' => ContactSelector::networkToName($item['author-network'], $item['author-link'], $item['network'], $item['author-gsid']),
'network_icon' => ContactSelector::networkToIcon($item['network'], $item['author-link'], $item['author-gsid']), 'network_icon' => ContactSelector::networkToIcon($item['network'], $item['author-link'], $item['author-gsid']),

View file

@ -50,6 +50,7 @@ use Friendica\Protocol\Activity;
use Friendica\Util\ACLFormatter; use Friendica\Util\ACLFormatter;
use Friendica\Util\DateTimeFormat; use Friendica\Util\DateTimeFormat;
use Friendica\Util\Emailer; use Friendica\Util\Emailer;
use Friendica\Util\Network;
use Friendica\Util\ParseUrl; use Friendica\Util\ParseUrl;
use Friendica\Util\Profiler; use Friendica\Util\Profiler;
use Friendica\Util\Proxy; use Friendica\Util\Proxy;
@ -367,7 +368,7 @@ class Item
{ {
$this->profiler->startRecording('rendering'); $this->profiler->startRecording('rendering');
$sub_link = $contact_url = $pm_url = $status_link = ''; $sub_link = $contact_url = $pm_url = $status_link = '';
$photos_link = $posts_link = $block_link = $ignore_link = ''; $photos_link = $posts_link = $block_link = $ignore_link = $collapse_link = $ignoreserver_link = '';
if ($this->userSession->getLocalUserId() && $this->userSession->getLocalUserId() == $item['uid'] && $item['gravity'] == ItemModel::GRAVITY_PARENT && !$item['self'] && !$item['mention']) { if ($this->userSession->getLocalUserId() && $this->userSession->getLocalUserId() == $item['uid'] && $item['gravity'] == ItemModel::GRAVITY_PARENT && !$item['self'] && !$item['mention']) {
$sub_link = 'javascript:doFollowThread(' . $item['id'] . '); return false;'; $sub_link = 'javascript:doFollowThread(' . $item['id'] . '); return false;';
@ -407,6 +408,10 @@ class Item
$collapse_link = $item['self'] ? '' : $contact_url . '/collapse?t=' . $formSecurityToken; $collapse_link = $item['self'] ? '' : $contact_url . '/collapse?t=' . $formSecurityToken;
} }
if (!empty($item['author-gsid'])) {
$ignoreserver_link = Network::isLocalLink($contact_url) ? '' : 'settings/server/' . $item['author-gsid'] . '/ignore';
}
if ($cid && !$item['self']) { if ($cid && !$item['self']) {
$contact_url = 'contact/' . $cid; $contact_url = 'contact/' . $cid;
$posts_link = $contact_url . '/posts'; $posts_link = $contact_url . '/posts';
@ -427,7 +432,8 @@ class Item
$this->l10n->t('Send PM') => $pm_url, $this->l10n->t('Send PM') => $pm_url,
$this->l10n->t('Block') => $block_link, $this->l10n->t('Block') => $block_link,
$this->l10n->t('Ignore') => $ignore_link, $this->l10n->t('Ignore') => $ignore_link,
$this->l10n->t('Collapse') => $collapse_link $this->l10n->t('Collapse') => $collapse_link,
$this->l10n->t("Ignore %s's server", $item['author-name']) => $ignoreserver_link,
]; ];
if (!empty($item['language'])) { if (!empty($item['language'])) {

View file

@ -671,6 +671,15 @@ abstract class DI
return self::$dice->create(Security\Authentication::class); return self::$dice->create(Security\Authentication::class);
} }
//
// "User" namespace instances
//
public static function userGServer(): User\Settings\Repository\UserGServer
{
return self::$dice->create(User\Settings\Repository\UserGServer::class);
}
// //
// "Util" namespace instances // "Util" namespace instances
// //

View file

@ -0,0 +1,151 @@
<?php
/**
* @copyright Copyright (C) 2010-2023, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* 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 <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\Federation\Entity;
use DateTimeImmutable;
use Psr\Http\Message\UriInterface;
/**
* @property-read int $id
* @property-read string $url
* @property-read string $nurl
* @property-read string $version
* @property-read string $siteName
* @property-read string $info
* @property-read int $registerPolicy
* @property-read int $registeredUsers
* @property-read string $poco
* @property-read string $noscrape
* @property-read string $network
* @property-read string $platform
* @property-read int $relaySubscribe
* @property-read string $relayScope
* @property-read DateTimeImmutable $created
* @property-read ?DateTimeImmutable $lastPocoQuery
* @property-read ?DateTimeImmutable $lastContact
* @property-read ?DateTimeImmutable $lastFailure
* @property-read int $directoryType
* @property-read int $detectionMethod
* @property-read bool $failed
* @property-read DateTimeImmutable $nextContact
* @property-read int $protocol
* @property-read int $activeWeekUsers
* @property-read int $activeMonthUsers
* @property-read int $activeHalfyearUsers
* @property-read int $localPosts
* @property-read int $localComments
* @property-read bool $blocked
*/
class GServer extends \Friendica\BaseEntity
{
/** @var ?int */
protected $id;
/** @var UriInterface */
protected $url;
/** @var UriInterface */
protected $nurl;
/** @var string */
protected $version;
/** @var string */
protected $siteName;
/** @var string */
protected $info;
/** @var int One of Module\Register::* constant values */
protected $registerPolicy;
/** @var int */
protected $registeredUsers;
/** @var ?UriInterface */
protected $poco;
/** @var ?UriInterface */
protected $noscrape;
/** @var string One of the Protocol::* constant values */
protected $network;
/** @var string */
protected $platform;
/** @var bool */
protected $relaySubscribe;
/** @var string */
protected $relayScope;
/** @var DateTimeImmutable */
protected $created;
/** @var DateTimeImmutable */
protected $lastPocoQuery;
/** @var DateTimeImmutable */
protected $lastContact;
/** @var DateTimeImmutable */
protected $lastFailure;
/** @var int One of Model\Gserver::DT_* constant values */
protected $directoryType;
/** @var ?int One of Model\Gserver::DETECT_* constant values */
protected $detectionMethod;
/** @var bool */
protected $failed;
/** @var DateTimeImmutable */
protected $nextContact;
/** @var ?int One of Model\Post\DeliveryData::* constant values */
protected $protocol;
/** @var ?int */
protected $activeWeekUsers;
/** @var ?int */
protected $activeMonthUsers;
/** @var ?int */
protected $activeHalfyearUsers;
/** @var ?int */
protected $localPosts;
/** @var ?int */
protected $localComments;
/** @var bool */
protected $blocked;
public function __construct(UriInterface $url, UriInterface $nurl, string $version, string $siteName, string $info, int $registerPolicy, int $registeredUsers, ?UriInterface $poco, ?UriInterface $noscrape, string $network, string $platform, bool $relaySubscribe, string $relayScope, DateTimeImmutable $created, ?DateTimeImmutable $lastPocoQuery, ?DateTimeImmutable $lastContact, ?DateTimeImmutable $lastFailure, int $directoryType, ?int $detectionMethod, bool $failed, ?DateTimeImmutable $nextContact, ?int $protocol, ?int $activeWeekUsers, ?int $activeMonthUsers, ?int $activeHalfyearUsers, ?int $localPosts, ?int $localComments, bool $blocked, ?int $id = null)
{
$this->url = $url;
$this->nurl = $nurl;
$this->version = $version;
$this->siteName = $siteName;
$this->info = $info;
$this->registerPolicy = $registerPolicy;
$this->registeredUsers = $registeredUsers;
$this->poco = $poco;
$this->noscrape = $noscrape;
$this->network = $network;
$this->platform = $platform;
$this->relaySubscribe = $relaySubscribe;
$this->relayScope = $relayScope;
$this->created = $created;
$this->lastPocoQuery = $lastPocoQuery;
$this->lastContact = $lastContact;
$this->lastFailure = $lastFailure;
$this->directoryType = $directoryType;
$this->detectionMethod = $detectionMethod;
$this->failed = $failed;
$this->nextContact = $nextContact;
$this->protocol = $protocol;
$this->activeWeekUsers = $activeWeekUsers;
$this->activeMonthUsers = $activeMonthUsers;
$this->activeHalfyearUsers = $activeHalfyearUsers;
$this->localPosts = $localPosts;
$this->localComments = $localComments;
$this->blocked = $blocked;
$this->id = $id;
}
}

View file

@ -0,0 +1,68 @@
<?php
/**
* @copyright Copyright (C) 2010-2023, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* 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 <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\Federation\Factory;
use Friendica\Capabilities\ICanCreateFromTableRow;
use Friendica\Database\DBA;
use Friendica\Federation\Entity;
use GuzzleHttp\Psr7\Uri;
class GServer extends \Friendica\BaseFactory implements ICanCreateFromTableRow
{
/**
* @inheritDoc
*/
public function createFromTableRow(array $row): Entity\GServer
{
return new Entity\GServer(
new Uri($row['url']),
new Uri($row['nurl']),
$row['version'],
$row['site_name'],
$row['info'] ?? '',
$row['register_policy'],
$row['registered-users'],
$row['poco'] ? new Uri($row['poco']) : null,
$row['noscrape'] ? new Uri($row['noscrape']) : null,
$row['network'],
$row['platform'],
$row['relay-subscribe'],
$row['relay-scope'],
new \DateTimeImmutable($row['created']),
$row['last_poco_query'] !== DBA::NULL_DATETIME ? new \DateTimeImmutable($row['last_poco_query']) : null,
$row['last_contact'] !== DBA::NULL_DATETIME ? new \DateTimeImmutable($row['last_contact']) : null,
$row['last_failure'] !== DBA::NULL_DATETIME ? new \DateTimeImmutable($row['last_failure']) : null,
$row['directory-type'],
$row['detection-method'],
$row['failed'],
$row['next_contact'] !== DBA::NULL_DATETIME ? new \DateTimeImmutable($row['next_contact']) : null,
$row['protocol'],
$row['active-week-users'],
$row['active-month-users'],
$row['active-halfyear-users'],
$row['local-posts'],
$row['local-comments'],
$row['blocked'],
$row['id'],
);
}
}

View file

@ -0,0 +1,47 @@
<?php
/**
* @copyright Copyright (C) 2010-2023, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* 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 <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\Federation\Repository;
use Friendica\Database\Database;
use Friendica\Federation\Factory;
use Friendica\Federation\Entity;
use Psr\Log\LoggerInterface;
class GServer extends \Friendica\BaseRepository
{
protected static $table_name = 'gserver';
public function __construct(Database $database, LoggerInterface $logger, Factory\GServer $factory)
{
parent::__construct($database, $logger, $factory);
}
/**
* @param int $gsid
* @return Entity\GServer
* @throws \Friendica\Network\HTTPException\NotFoundException
*/
public function selectOneById(int $gsid): Entity\GServer
{
return $this->_selectOne(['id' => $gsid]);
}
}

View file

@ -96,8 +96,8 @@ class Item
'content-warning', 'location', 'coord', 'app', 'rendered-hash', 'rendered-html', 'object', 'content-warning', 'location', 'coord', 'app', 'rendered-hash', 'rendered-html', 'object',
'quote-uri', 'quote-uri-id', 'allow_cid', 'allow_gid', 'deny_cid', 'deny_gid', 'mention', 'global', 'quote-uri', 'quote-uri-id', 'allow_cid', 'allow_gid', 'deny_cid', 'deny_gid', 'mention', 'global',
'author-id', 'author-link', 'author-alias', 'author-name', 'author-avatar', 'author-network', 'author-updated', 'author-gsid', 'author-addr', 'author-uri-id', 'author-id', 'author-link', 'author-alias', 'author-name', 'author-avatar', 'author-network', 'author-updated', 'author-gsid', 'author-addr', 'author-uri-id',
'owner-id', 'owner-link', 'owner-alias', 'owner-name', 'owner-avatar', 'owner-network', 'owner-contact-type', 'owner-updated', 'owner-id', 'owner-link', 'owner-alias', 'owner-name', 'owner-avatar', 'owner-network', 'owner-contact-type', 'owner-updated', 'owner-gsid',
'causer-id', 'causer-link', 'causer-alias', 'causer-name', 'causer-avatar', 'causer-contact-type', 'causer-network', 'causer-id', 'causer-link', 'causer-alias', 'causer-name', 'causer-avatar', 'causer-contact-type', 'causer-network', 'causer-gsid',
'contact-id', 'contact-uid', 'contact-link', 'contact-name', 'contact-avatar', 'contact-id', 'contact-uid', 'contact-link', 'contact-name', 'contact-avatar',
'writable', 'self', 'cid', 'alias', 'writable', 'self', 'cid', 'alias',
'event-created', 'event-edited', 'event-start', 'event-finish', 'event-created', 'event-edited', 'event-start', 'event-finish',

View file

@ -453,12 +453,10 @@ class Post
AND (NOT `causer-blocked` OR `causer-id` = ? OR `causer-id` IS NULL) AND NOT `contact-blocked` AND (NOT `causer-blocked` OR `causer-id` = ? OR `causer-id` IS NULL) AND NOT `contact-blocked`
AND ((NOT `contact-readonly` AND NOT `contact-pending` AND (`contact-rel` IN (?, ?))) AND ((NOT `contact-readonly` AND NOT `contact-pending` AND (`contact-rel` IN (?, ?)))
OR `self` OR `contact-uid` = ?) OR `self` OR `contact-uid` = ?)
AND NOT `" . $view . "`.`uri-id` IN (SELECT `uri-id` FROM `post-user` WHERE `uid` = ? AND `hidden`) AND NOT EXISTS(SELECT `uri-id` FROM `post-user` WHERE `uid` = ? AND `uri-id` = " . DBA::quoteIdentifier($view) . ".`uri-id` AND `hidden`)
AND NOT `author-id` IN (SELECT `cid` FROM `user-contact` WHERE `uid` = ? AND `blocked` AND `cid` = `author-id`) AND NOT EXISTS(SELECT `cid` FROM `user-contact` WHERE `uid` = ? AND `cid` IN (`author-id`, `owner-id`) AND (`blocked` OR `ignored`))
AND NOT `owner-id` IN (SELECT `cid` FROM `user-contact` WHERE `uid` = ? AND `blocked` AND `cid` = `owner-id`) AND NOT EXISTS(SELECT `gsid` FROM `user-gserver` WHERE `uid` = ? AND `gsid` IN (`author-gsid`, `owner-gsid`, `causer-gsid`) AND `ignored`)",
AND NOT `author-id` IN (SELECT `cid` FROM `user-contact` WHERE `uid` = ? AND `ignored` AND `cid` = `author-id`) 0, Contact::SHARING, Contact::FRIEND, 0, $uid, $uid, $uid]);
AND NOT `owner-id` IN (SELECT `cid` FROM `user-contact` WHERE `uid` = ? AND `ignored` AND `cid` = `owner-id`)",
0, Contact::SHARING, Contact::FRIEND, 0, $uid, $uid, $uid, $uid, $uid]);
$select_string = implode(', ', array_map([DBA::class, 'quoteIdentifier'], $selected)); $select_string = implode(', ', array_map([DBA::class, 'quoteIdentifier'], $selected));

View file

@ -133,14 +133,14 @@ class UserNotification
public static function setNotification(int $uri_id, int $uid) public static function setNotification(int $uri_id, int $uid)
{ {
$fields = ['id', 'uri-id', 'parent-uri-id', 'uid', 'body', 'parent', 'gravity', 'vid', 'gravity', $fields = ['id', 'uri-id', 'parent-uri-id', 'uid', 'body', 'parent', 'gravity', 'vid', 'gravity',
'contact-id', 'author-id', 'owner-id', 'causer-id', 'contact-id', 'author-id', 'author-gsid', 'owner-id', 'owner-gsid', 'causer-id', 'causer-gsid',
'private', 'thr-parent', 'thr-parent-id', 'parent-uri-id', 'parent-uri', 'verb']; 'private', 'thr-parent', 'thr-parent-id', 'parent-uri-id', 'parent-uri', 'verb'];
$item = Post::selectFirst($fields, ['uri-id' => $uri_id, 'uid' => $uid, 'origin' => false]); $item = Post::selectFirst($fields, ['uri-id' => $uri_id, 'uid' => $uid, 'origin' => false]);
if (!DBA::isResult($item)) { if (!DBA::isResult($item)) {
return; return;
} }
$parent = Post::selectFirstPost(['author-id', 'owner-id', 'causer-id'], ['uri-id' => $item['parent-uri-id']]); $parent = Post::selectFirstPost(['author-id', 'author-gsid', 'owner-id', 'owner-gsid', 'causer-id', 'causer-gsid',], ['uri-id' => $item['parent-uri-id']]);
if (!DBA::isResult($parent)) { if (!DBA::isResult($parent)) {
return; return;
} }
@ -195,6 +195,13 @@ class UserNotification
} }
} }
foreach (array_unique([$parent['author-gsid'], $parent['owner-gsid'], $parent['causer-gsid'], $item['author-gsid'], $item['owner-gsid'], $item['causer-gsid']]) as $gsid) {
if ($gsid && DI::userGServer()->isIgnoredByUser($uid, $gsid)) {
Logger::debug('Server is ignored by user', ['uid' => $uid, 'gsid' => $gsid, 'uri-id' => $item['uri-id']]);
return;
}
}
$user = User::getById($uid, ['account-type', 'account_removed', 'account_expired']); $user = User::getById($uid, ['account-type', 'account_removed', 'account_expired']);
if (in_array($user['account-type'], [User::ACCOUNT_TYPE_COMMUNITY, User::ACCOUNT_TYPE_RELAY])) { if (in_array($user['account-type'], [User::ACCOUNT_TYPE_COMMUNITY, User::ACCOUNT_TYPE_RELAY])) {
return; return;

View file

@ -151,6 +151,13 @@ class BaseSettings extends BaseModule
'accesskey' => 'b', 'accesskey' => 'b',
]; ];
$tabs[] = [
'label' => $this->t('Remote servers'),
'url' => 'settings/server',
'selected' => static::class == Settings\Server\Index::class ? 'active' : '',
'accesskey' => 's',
];
$tabs[] = [ $tabs[] = [
'label' => $this->t('Export personal data'), 'label' => $this->t('Export personal data'),
'url' => 'settings/userexport', 'url' => 'settings/userexport',

View file

@ -23,8 +23,7 @@ namespace Friendica\Module\Contact;
use Friendica\App; use Friendica\App;
use Friendica\BaseModule; use Friendica\BaseModule;
use Friendica\Contact\LocalRelationship\Entity; use Friendica\Contact\LocalRelationship;
use Friendica\Contact\LocalRelationship\Repository;
use Friendica\Content\ContactSelector; use Friendica\Content\ContactSelector;
use Friendica\Content\Nav; use Friendica\Content\Nav;
use Friendica\Content\Text\BBCode; use Friendica\Content\Text\BBCode;
@ -34,13 +33,16 @@ use Friendica\Core\Hook;
use Friendica\Core\L10n; use Friendica\Core\L10n;
use Friendica\Core\Protocol; use Friendica\Core\Protocol;
use Friendica\Core\Renderer; use Friendica\Core\Renderer;
use Friendica\Core\Session\Capability\IHandleUserSessions;
use Friendica\Database\Database;
use Friendica\Database\DBA; use Friendica\Database\DBA;
use Friendica\DI;
use Friendica\Model\Contact;
use Friendica\Model\Circle; use Friendica\Model\Circle;
use Friendica\Model\Contact;
use Friendica\Module; use Friendica\Module;
use Friendica\Module\Response; use Friendica\Module\Response;
use Friendica\Navigation\SystemMessages;
use Friendica\Network\HTTPException; use Friendica\Network\HTTPException;
use Friendica\User\Settings;
use Friendica\Util\DateTimeFormat; use Friendica\Util\DateTimeFormat;
use Friendica\Util\Profiler; use Friendica\Util\Profiler;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
@ -50,31 +52,37 @@ use Psr\Log\LoggerInterface;
*/ */
class Profile extends BaseModule class Profile extends BaseModule
{ {
/** /** @var LocalRelationship\Repository\LocalRelationship */
* @var Repository\LocalRelationship
*/
private $localRelationship; private $localRelationship;
/** /** @var App\Page */
* @var App\Page
*/
private $page; private $page;
/** /** @var IManageConfigValues */
* @var IManageConfigValues
*/
private $config; private $config;
/** @var IHandleUserSessions */
private $session;
/** @var SystemMessages */
private $systemMessages;
/** @var Database */
private $db;
/** @var Settings\Repository\UserGServer */
private $userGServer;
public function __construct(L10n $l10n, Repository\LocalRelationship $localRelationship, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, App\Page $page, IManageConfigValues $config, array $server, array $parameters = []) public function __construct(Settings\Repository\UserGServer $userGServer, Database $db, SystemMessages $systemMessages, IHandleUserSessions $session, L10n $l10n, LocalRelationship\Repository\LocalRelationship $localRelationship, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, App\Page $page, IManageConfigValues $config, array $server, array $parameters = [])
{ {
parent::__construct($l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters); parent::__construct($l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
$this->localRelationship = $localRelationship; $this->localRelationship = $localRelationship;
$this->page = $page; $this->page = $page;
$this->config = $config; $this->config = $config;
$this->session = $session;
$this->systemMessages = $systemMessages;
$this->db = $db;
$this->userGServer = $userGServer;
} }
protected function post(array $request = []) protected function post(array $request = [])
{ {
if (!DI::userSession()->getLocalUserId()) { if (!$this->session->getLocalUserId()) {
return; return;
} }
@ -82,8 +90,8 @@ class Profile extends BaseModule
// Backward compatibility: The update still needs a user-specific contact ID // Backward compatibility: The update still needs a user-specific contact ID
// Change to user-contact table check by version 2022.03 // Change to user-contact table check by version 2022.03
$cdata = Contact::getPublicAndUserContactID($contact_id, DI::userSession()->getLocalUserId()); $cdata = Contact::getPublicAndUserContactID($contact_id, $this->session->getLocalUserId());
if (empty($cdata['user']) || !DBA::exists('contact', ['id' => $cdata['user'], 'deleted' => false])) { if (empty($cdata['user']) || !$this->db->exists('contact', ['id' => $cdata['user'], 'deleted' => false])) {
return; return;
} }
@ -124,35 +132,35 @@ class Profile extends BaseModule
$fields['info'] = $_POST['info']; $fields['info'] = $_POST['info'];
} }
if (!Contact::update($fields, ['id' => $cdata['user'], 'uid' => DI::userSession()->getLocalUserId()])) { if (!Contact::update($fields, ['id' => $cdata['user'], 'uid' => $this->session->getLocalUserId()])) {
DI::sysmsg()->addNotice($this->t('Failed to update contact record.')); $this->systemMessages->addNotice($this->t('Failed to update contact record.'));
} }
} }
protected function content(array $request = []): string protected function content(array $request = []): string
{ {
if (!DI::userSession()->getLocalUserId()) { if (!$this->session->getLocalUserId()) {
return Module\Security\Login::form($_SERVER['REQUEST_URI']); return Module\Security\Login::form($_SERVER['REQUEST_URI']);
} }
// Backward compatibility: Ensure to use the public contact when the user contact is provided // Backward compatibility: Ensure to use the public contact when the user contact is provided
// Remove by version 2022.03 // Remove by version 2022.03
$data = Contact::getPublicAndUserContactID(intval($this->parameters['id']), DI::userSession()->getLocalUserId()); $data = Contact::getPublicAndUserContactID(intval($this->parameters['id']), $this->session->getLocalUserId());
if (empty($data)) { if (empty($data)) {
throw new HTTPException\NotFoundException($this->t('Contact not found.')); throw new HTTPException\NotFoundException($this->t('Contact not found.'));
} }
$contact = Contact::getById($data['public']); $contact = Contact::getById($data['public']);
if (!DBA::isResult($contact)) { if (!$this->db->isResult($contact)) {
throw new HTTPException\NotFoundException($this->t('Contact not found.')); throw new HTTPException\NotFoundException($this->t('Contact not found.'));
} }
// Don't display contacts that are about to be deleted // Don't display contacts that are about to be deleted
if (DBA::isResult($contact) && (!empty($contact['deleted']) || !empty($contact['network']) && $contact['network'] == Protocol::PHANTOM)) { if ($this->db->isResult($contact) && (!empty($contact['deleted']) || !empty($contact['network']) && $contact['network'] == Protocol::PHANTOM)) {
throw new HTTPException\NotFoundException($this->t('Contact not found.')); throw new HTTPException\NotFoundException($this->t('Contact not found.'));
} }
$localRelationship = $this->localRelationship->getForUserContact(DI::userSession()->getLocalUserId(), $contact['id']); $localRelationship = $this->localRelationship->getForUserContact($this->session->getLocalUserId(), $contact['id']);
if ($localRelationship->rel === Contact::SELF) { if ($localRelationship->rel === Contact::SELF) {
$this->baseUrl->redirect('profile/' . $contact['nick'] . '/profile'); $this->baseUrl->redirect('profile/' . $contact['nick'] . '/profile');
@ -167,55 +175,55 @@ class Profile extends BaseModule
} }
if ($cmd === 'updateprofile') { if ($cmd === 'updateprofile') {
self::updateContactFromProbe($contact['id']); $this->updateContactFromProbe($contact['id']);
} }
if ($cmd === 'block') { if ($cmd === 'block') {
if ($localRelationship->blocked) { if ($localRelationship->blocked) {
// @TODO Backward compatibility, replace with $localRelationship->unblock() // @TODO Backward compatibility, replace with $localRelationship->unblock()
Contact\User::setBlocked($contact['id'], DI::userSession()->getLocalUserId(), false); Contact\User::setBlocked($contact['id'], $this->session->getLocalUserId(), false);
$message = $this->t('Contact has been unblocked'); $message = $this->t('Contact has been unblocked');
} else { } else {
// @TODO Backward compatibility, replace with $localRelationship->block() // @TODO Backward compatibility, replace with $localRelationship->block()
Contact\User::setBlocked($contact['id'], DI::userSession()->getLocalUserId(), true); Contact\User::setBlocked($contact['id'], $this->session->getLocalUserId(), true);
$message = $this->t('Contact has been blocked'); $message = $this->t('Contact has been blocked');
} }
// @TODO: add $this->localRelationship->save($localRelationship); // @TODO: add $this->localRelationship->save($localRelationship);
DI::sysmsg()->addInfo($message); $this->systemMessages->addInfo($message);
} }
if ($cmd === 'ignore') { if ($cmd === 'ignore') {
if ($localRelationship->ignored) { if ($localRelationship->ignored) {
// @TODO Backward compatibility, replace with $localRelationship->unblock() // @TODO Backward compatibility, replace with $localRelationship->unblock()
Contact\User::setIgnored($contact['id'], DI::userSession()->getLocalUserId(), false); Contact\User::setIgnored($contact['id'], $this->session->getLocalUserId(), false);
$message = $this->t('Contact has been unignored'); $message = $this->t('Contact has been unignored');
} else { } else {
// @TODO Backward compatibility, replace with $localRelationship->block() // @TODO Backward compatibility, replace with $localRelationship->block()
Contact\User::setIgnored($contact['id'], DI::userSession()->getLocalUserId(), true); Contact\User::setIgnored($contact['id'], $this->session->getLocalUserId(), true);
$message = $this->t('Contact has been ignored'); $message = $this->t('Contact has been ignored');
} }
// @TODO: add $this->localRelationship->save($localRelationship); // @TODO: add $this->localRelationship->save($localRelationship);
DI::sysmsg()->addInfo($message); $this->systemMessages->addInfo($message);
} }
if ($cmd === 'collapse') { if ($cmd === 'collapse') {
if ($localRelationship->collapsed) { if ($localRelationship->collapsed) {
// @TODO Backward compatibility, replace with $localRelationship->unblock() // @TODO Backward compatibility, replace with $localRelationship->unblock()
Contact\User::setCollapsed($contact['id'], DI::userSession()->getLocalUserId(), false); Contact\User::setCollapsed($contact['id'], $this->session->getLocalUserId(), false);
$message = $this->t('Contact has been uncollapsed'); $message = $this->t('Contact has been uncollapsed');
} else { } else {
// @TODO Backward compatibility, replace with $localRelationship->block() // @TODO Backward compatibility, replace with $localRelationship->block()
Contact\User::setCollapsed($contact['id'], DI::userSession()->getLocalUserId(), true); Contact\User::setCollapsed($contact['id'], $this->session->getLocalUserId(), true);
$message = $this->t('Contact has been collapsed'); $message = $this->t('Contact has been collapsed');
} }
// @TODO: add $this->localRelationship->save($localRelationship); // @TODO: add $this->localRelationship->save($localRelationship);
DI::sysmsg()->addInfo($message); $this->systemMessages->addInfo($message);
} }
$this->baseUrl->redirect('contact/' . $contact['id']); $this->baseUrl->redirect('contact/' . $contact['id']);
@ -259,6 +267,11 @@ class Profile extends BaseModule
$insecure = $this->t('Private communications are not available for this contact.'); $insecure = $this->t('Private communications are not available for this contact.');
$serverIgnored =
$this->userGServer->isIgnoredByUser($this->session->getLocalUserId(), $contact['gsid']) ?
$this->t('This contact is on a server you ignored.')
: '';
$last_update = (($contact['last-update'] <= DBA::NULL_DATETIME) ? $this->t('Never') : DateTimeFormat::local($contact['last-update'], 'D, j M Y, g:i A')); $last_update = (($contact['last-update'] <= DBA::NULL_DATETIME) ? $this->t('Never') : DateTimeFormat::local($contact['last-update'], 'D, j M Y, g:i A'));
if ($contact['last-update'] > DBA::NULL_DATETIME) { if ($contact['last-update'] > DBA::NULL_DATETIME) {
@ -363,6 +376,8 @@ class Profile extends BaseModule
'$collapsed' => $localRelationship->collapsed ? $this->t('Currently collapsed') : '', '$collapsed' => $localRelationship->collapsed ? $this->t('Currently collapsed') : '',
'$archived' => ($contact['archive'] ? $this->t('Currently archived') : ''), '$archived' => ($contact['archive'] ? $this->t('Currently archived') : ''),
'$insecure' => (in_array($contact['network'], [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::MAIL, Protocol::DIASPORA]) ? '' : $insecure), '$insecure' => (in_array($contact['network'], [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::MAIL, Protocol::DIASPORA]) ? '' : $insecure),
'$serverIgnored' => $serverIgnored,
'$manageServers' => $this->t('Manage remote servers'),
'$cinfo' => ['info', '', $localRelationship->info, ''], '$cinfo' => ['info', '', $localRelationship->info, ''],
'$hidden' => ['hidden', $this->t('Hide this contact from others'), $localRelationship->hidden, $this->t('Replies/likes to your public posts <strong>may</strong> still be visible')], '$hidden' => ['hidden', $this->t('Hide this contact from others'), $localRelationship->hidden, $this->t('Replies/likes to your public posts <strong>may</strong> still be visible')],
'$notify_new_posts' => ['notify_new_posts', $this->t('Notification for new posts'), ($localRelationship->notifyNewPosts), $this->t('Send a notification of every new post of this contact')], '$notify_new_posts' => ['notify_new_posts', $this->t('Notification for new posts'), ($localRelationship->notifyNewPosts), $this->t('Send a notification of every new post of this contact')],
@ -413,11 +428,11 @@ class Profile extends BaseModule
* This includes actions like e.g. 'block', 'hide', 'delete' and others * This includes actions like e.g. 'block', 'hide', 'delete' and others
* *
* @param array $contact Public contact row * @param array $contact Public contact row
* @param Entity\LocalRelationship $localRelationship * @param LocalRelationship\Entity\LocalRelationship $localRelationship
* @return array with contact related actions * @return array with contact related actions
* @throws HTTPException\InternalServerErrorException * @throws HTTPException\InternalServerErrorException
*/ */
private function getContactActions(array $contact, Entity\LocalRelationship $localRelationship): array private function getContactActions(array $contact, LocalRelationship\Entity\LocalRelationship $localRelationship): array
{ {
$poll_enabled = in_array($contact['network'], [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::OSTATUS, Protocol::FEED, Protocol::MAIL]); $poll_enabled = in_array($contact['network'], [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::OSTATUS, Protocol::FEED, Protocol::MAIL]);
$contact_actions = []; $contact_actions = [];
@ -518,10 +533,9 @@ class Profile extends BaseModule
* @throws HTTPException\InternalServerErrorException * @throws HTTPException\InternalServerErrorException
* @throws \ImagickException * @throws \ImagickException
*/ */
private static function updateContactFromProbe(int $contact_id) private function updateContactFromProbe(int $contact_id)
{ {
$contact = DBA::selectFirst('contact', ['url'], ['id' => $contact_id, 'uid' => [0, DI::userSession()->getLocalUserId()], 'deleted' => false]); if (!$this->db->exists('contact', ['id' => $contact_id, 'uid' => [0, $this->session->getLocalUserId()], 'deleted' => false])) {
if (!DBA::isResult($contact)) {
return; return;
} }

View file

@ -356,7 +356,7 @@ class Community extends BaseModule
} }
} }
$r = Post::selectThreadForUser(0, ['uri-id', 'commented', 'author-link'], $condition, $params); $r = Post::selectThreadForUser(DI::userSession()->getLocalUserId() ?: 0, ['uri-id', 'commented', 'author-link'], $condition, $params);
$items = Post::toArray($r); $items = Post::toArray($r);
if (empty($items)) { if (empty($items)) {

View file

@ -133,7 +133,9 @@ class Display extends BaseModule
} }
if (empty($item)) { if (empty($item)) {
throw new HTTPException\NotFoundException($this->t('The requested item doesn\'t exist or has been deleted.')); $this->page['aside'] = '';
$displayNotFound = new DisplayNotFound($this->l10n, $this->baseUrl, $this->args, $this->logger, $this->profiler, $this->response, $this->server, $this->parameters);
return $displayNotFound->content();
} }
if ($item['gravity'] != Item::GRAVITY_PARENT) { if ($item['gravity'] != Item::GRAVITY_PARENT) {

View file

@ -0,0 +1,117 @@
<?php
/**
* @copyright Copyright (C) 2010-2023, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* 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 <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\Module\Settings\Server;
use Friendica\App;
use Friendica\Core\L10n;
use Friendica\Core\Renderer;
use Friendica\Core\Session\Capability\IHandleUserSessions;
use Friendica\Core\System;
use Friendica\Federation\Repository\GServer;
use Friendica\Module\Response;
use Friendica\Network\HTTPException\BadRequestException;
use Friendica\User\Settings\Repository\UserGServer;
use Friendica\Util\Profiler;
use Psr\Log\LoggerInterface;
class Action extends \Friendica\BaseModule
{
/** @var IHandleUserSessions */
private $session;
/** @var UserGServer */
private $repository;
/** @var GServer */
private $gserverRepo;
public function __construct(GServer $gserverRepo, UserGServer $repository, IHandleUserSessions $session, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, array $server, array $parameters = [])
{
parent::__construct($l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
$this->session = $session;
$this->repository = $repository;
$this->gserverRepo = $gserverRepo;
}
public function content(array $request = []): string
{
$GServer = $this->gserverRepo->selectOneById($this->parameters['gsid']);
switch ($this->parameters['action']) {
case 'ignore':
$action = $this->t('Do you want to ignore this server?');
$desc = $this->t("You won't see any content from this server including reshares in your Network page, the community pages and individual conversations.");
break;
case 'unignore':
$action = $this->t('Do you want to unignore this server?');
$desc = '';
break;
default:
throw new BadRequestException('Unknown user server action ' . $this->parameters['action']);
}
$tpl = Renderer::getMarkupTemplate('settings/server/action.tpl');
return Renderer::replaceMacros($tpl, [
'$l10n' => [
'title' => $this->t('Remote server settings'),
'action' => $action,
'siteName' => $this->t('Server Name'),
'siteUrl' => $this->t('Server URL'),
'desc' => $desc,
'submit' => $this->t('Submit'),
],
'$action' => $this->args->getQueryString(),
'$GServer' => $GServer,
'$form_security_token' => self::getFormSecurityToken('settings-server'),
]);
}
public function post(array $request = [])
{
if (!empty($request['redirect_url'])) {
self::checkFormSecurityTokenRedirectOnError($this->args->getQueryString(), 'settings-server');
}
$userGServer = $this->repository->getOneByUserAndServer($this->session->getLocalUserId(), $this->parameters['gsid']);
switch ($this->parameters['action']) {
case 'ignore':
$userGServer->ignore();
break;
case 'unignore':
$userGServer->unignore();
break;
default:
throw new BadRequestException('Unknown user server action ' . $this->parameters['action']);
}
$this->repository->save($userGServer);
if (!empty($request['redirect_url'])) {
$this->baseUrl->redirect($request['redirect_url']);
}
System::exit();
}
}

View file

@ -0,0 +1,126 @@
<?php
/**
* @copyright Copyright (C) 2010-2023, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* 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 <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\Module\Settings\Server;
use Friendica\App;
use Friendica\Content\Pager;
use Friendica\Core\L10n;
use Friendica\Core\Renderer;
use Friendica\Core\Session\Capability\IHandleUserSessions;
use Friendica\Module\BaseSettings;
use Friendica\Module\Response;
use Friendica\Navigation\SystemMessages;
use Friendica\Network\HTTPException\NotFoundException;
use Friendica\User\Settings\Entity\UserGServer;
use Friendica\User\Settings\Repository;
use Friendica\Util\Profiler;
use Psr\Log\LoggerInterface;
class Index extends BaseSettings
{
/** @var Repository\UserGServer */
private $repository;
/** @var SystemMessages */
private $systemMessages;
public function __construct(SystemMessages $systemMessages, Repository\UserGServer $repository, IHandleUserSessions $session, App\Page $page, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, array $server, array $parameters = [])
{
parent::__construct($session, $page, $l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
$this->repository = $repository;
$this->systemMessages = $systemMessages;
}
protected function post(array $request = [])
{
self::checkFormSecurityTokenRedirectOnError($this->args->getQueryString(), 'settings-server');
foreach ($request['delete'] ?? [] as $gsid => $delete) {
if ($delete) {
unset($request['ignored'][$gsid]);
try {
$userGServer = $this->repository->selectOneByUserAndServer($this->session->getLocalUserId(), $gsid, false);
$this->repository->delete($userGServer);
} catch (NotFoundException $e) {
// Nothing to delete
}
}
}
foreach ($request['ignored'] ?? [] as $gsid => $ignored) {
$userGServer = $this->repository->getOneByUserAndServer($this->session->getLocalUserId(), $gsid, false);
if ($userGServer->ignored != $ignored) {
$userGServer->toggleIgnored();
$this->repository->save($userGServer);
}
}
$this->systemMessages->addInfo($this->t('Settings saved'));
$this->baseUrl->redirect($this->args->getQueryString());
}
protected function content(array $request = []): string
{
parent::content();
$pager = new Pager($this->l10n, $this->args->getQueryString(), 30);
$total = $this->repository->countByUser($this->session->getLocalUserId());
$servers = $this->repository->selectByUserWithPagination($this->session->getLocalUserId(), $pager);
$ignoredCheckboxes = array_map(function (UserGServer $server) {
return ['ignored[' . $server->gsid . ']', '', $server->ignored];
}, $servers->getArrayCopy());
$deleteCheckboxes = array_map(function (UserGServer $server) {
return ['delete[' . $server->gsid . ']'];
}, $servers->getArrayCopy());
$tpl = Renderer::getMarkupTemplate('settings/server/index.tpl');
return Renderer::replaceMacros($tpl, [
'$l10n' => [
'title' => $this->t('Remote server settings'),
'desc' => $this->t('Here you can find all the remote servers you have taken individual moderation actions against. For a list of servers your node has blocked, please check out the <a href="friendica">Information</a> page.'),
'siteName' => $this->t('Server Name'),
'ignored' => $this->t('Ignored'),
'ignored_title' => $this->t("You won't see any content from this server including reshares in your Network page, the community pages and individual conversations."),
'delete' => $this->t('Delete'),
'delete_title' => $this->t('Delete all your settings for the remote server'),
'submit' => $this->t('Save changes'),
],
'$count' => $total,
'$servers' => $servers,
'$form_security_token' => self::getFormSecurityToken('settings-server'),
'$ignoredCheckboxes' => $ignoredCheckboxes,
'$deleteCheckboxes' => $deleteCheckboxes,
'$paginate' => $pager->renderFull($total),
]);
}
}

View file

@ -31,18 +31,21 @@ class DisplayNotFound extends \Friendica\BaseModule
{ {
protected function content(array $request = []): string protected function content(array $request = []): string
{ {
$reasons = [
$this->t("The top-level post isn't visible."),
$this->t('The top-level post was deleted.'),
$this->t('This node has blocked the top-level author or the author of the shared post.'),
$this->t('You have ignored or blocked the top-level author or the author of the shared post.'),
$this->t("You have ignored the top-level author's server or the shared post author's server."),
];
$tpl = Renderer::getMarkupTemplate('special/displaynotfound.tpl'); $tpl = Renderer::getMarkupTemplate('special/displaynotfound.tpl');
return Renderer::replaceMacros($tpl, [ return Renderer::replaceMacros($tpl, [
'$l10n' => [ '$l10n' => [
'title' => $this->t('Not Found'), 'title' => $this->t('Conversation Not Found'),
'message' => $this->t("<p>Unfortunately, the requested conversation isn't available to you.</p> 'desc1' => $this->t("Unfortunately, the requested conversation isn't available to you."),
<p>Possible reasons include:</p> 'desc2' => $this->t('Possible reasons include:'),
<ul> 'reasons' => $reasons,
<li>The top-level post isn't visible.</li>
<li>The top-level post was deleted.</li>
<li>The node has blocked the top-level author or the author of the shared post.</li>
<li>You have ignored or blocked the top-level author or the author of the shared post.</li>
</ul>"),
] ]
]); ]);
} }

View file

@ -38,6 +38,7 @@ use Friendica\Model\User;
use Friendica\Protocol\Activity; use Friendica\Protocol\Activity;
use Friendica\Util\Crypto; use Friendica\Util\Crypto;
use Friendica\Util\DateTimeFormat; use Friendica\Util\DateTimeFormat;
use Friendica\Util\Network;
use Friendica\Util\Proxy; use Friendica\Util\Proxy;
use Friendica\Util\Strings; use Friendica\Util\Strings;
use Friendica\Util\Temporal; use Friendica\Util\Temporal;
@ -248,11 +249,12 @@ class Post
$pinned = DI::l10n()->t('Pinned item'); $pinned = DI::l10n()->t('Pinned item');
} }
$drop = false; $drop = false;
$block = false; $block = false;
$ignore = false; $ignore = false;
$collapse = false; $collapse = false;
$report = false; $report = false;
$ignoreServer = false;
if (DI::userSession()->getLocalUserId()) { if (DI::userSession()->getLocalUserId()) {
$drop = [ $drop = [
'dropping' => $dropping, 'dropping' => $dropping,
@ -282,6 +284,11 @@ class Post
'label' => DI::l10n()->t('Report post'), 'label' => DI::l10n()->t('Report post'),
'href' => 'moderation/report/create?' . http_build_query(['cid' => $item['author-id'], 'uri-ids' => [$item['uri-id']]]), 'href' => 'moderation/report/create?' . http_build_query(['cid' => $item['author-id'], 'uri-ids' => [$item['uri-id']]]),
]; ];
if (!Network::isLocalLink($item['plink'])) {
$ignoreServer = [
'label' => DI::l10n()->t("Ignore %s's server", $item['author-name']),
];
}
} }
$filer = DI::userSession()->getLocalUserId() ? DI::l10n()->t('Save to folder') : false; $filer = DI::userSession()->getLocalUserId() ? DI::l10n()->t('Save to folder') : false;
@ -557,6 +564,7 @@ class Post
'ignore_author' => $ignore, 'ignore_author' => $ignore,
'collapse' => $collapse, 'collapse' => $collapse,
'report' => $report, 'report' => $report,
'ignore_server' => $ignoreServer,
'vote' => $buttons, 'vote' => $buttons,
'like_html' => $responses['like']['output'], 'like_html' => $responses['like']['output'],
'dislike_html' => $responses['dislike']['output'], 'dislike_html' => $responses['dislike']['output'],
@ -571,6 +579,7 @@ class Post
'wait' => DI::l10n()->t('Please wait'), 'wait' => DI::l10n()->t('Please wait'),
'thread_level' => $thread_level, 'thread_level' => $thread_level,
'edited' => $edited, 'edited' => $edited,
'author_gsid' => $item['author-gsid'],
'network' => $item['network'], 'network' => $item['network'],
'network_name' => ContactSelector::networkToName($item['author-network'], $item['author-link'], $item['network'], $item['author-gsid']), 'network_name' => ContactSelector::networkToName($item['author-network'], $item['author-link'], $item['network'], $item['author-gsid']),
'network_icon' => ContactSelector::networkToIcon($item['network'], $item['author-link'], $item['author-gsid']), 'network_icon' => ContactSelector::networkToIcon($item['network'], $item['author-link'], $item['author-gsid']),

View file

@ -0,0 +1,30 @@
<?php
/**
* @copyright Copyright (C) 2010-2023, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* 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 <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\User\Settings\Collection;
class UserGServers extends \Friendica\BaseCollection
{
public function current(): \Friendica\User\Settings\Entity\UserGServer
{
return parent::current();
}
}

View file

@ -0,0 +1,92 @@
<?php
/**
* @copyright Copyright (C) 2010-2023, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* 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 <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\User\Settings\Entity;
use Friendica\Federation\Entity\GServer;
/**
* @property-read int $uid
* @property-read int $gsid
* @property-read bool $ignored
* @property-read ?GServer $gserver
*/
class UserGServer extends \Friendica\BaseEntity
{
/** @var int User id */
protected $uid;
/** @var int GServer id */
protected $gsid;
/** @var bool Whether the user ignored this server */
protected $ignored;
/** @var ?GServer */
protected $gserver;
public function __construct(int $uid, int $gsid, bool $ignored = false, ?GServer $gserver = null)
{
$this->uid = $uid;
$this->gsid = $gsid;
$this->ignored = $ignored;
$this->gserver = $gserver;
}
/**
* Toggle the ignored property.
*
* Chainable.
*
* @return $this
*/
public function toggleIgnored(): UserGServer
{
$this->ignored = !$this->ignored;
return $this;
}
/**
* Set the ignored property.
*
* Chainable.
*
* @return $this
*/
public function ignore(): UserGServer
{
$this->ignored = true;
return $this;
}
/**
* Unset the ignored property.
*
* Chainable.
*
* @return $this
*/
public function unignore(): UserGServer
{
$this->ignored = false;
return $this;
}
}

View file

@ -0,0 +1,60 @@
<?php
/**
* @copyright Copyright (C) 2010-2023, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* 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 <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\User\Settings\Factory;
use Friendica\Capabilities\ICanCreateFromTableRow;
use Friendica\Federation\Entity\GServer;
use Friendica\User\Settings\Entity;
class UserGServer extends \Friendica\BaseFactory implements ICanCreateFromTableRow
{
/**
* @param array $row `user-gserver` table row
* @param GServer|null $server Corresponding GServer entity
* @return Entity\UserGServer
*/
public function createFromTableRow(array $row, GServer $server = null): Entity\UserGServer
{
return new Entity\UserGServer(
$row['uid'],
$row['gsid'],
$row['ignored'],
$server,
);
}
/**
* @param int $uid
* @param int $gsid
* @param GServer|null $gserver Corresponding GServer entity
* @return Entity\UserGServer
*/
public function createFromUserAndServer(int $uid, int $gsid, GServer $gserver = null): Entity\UserGServer
{
return new Entity\UserGServer(
$uid,
$gsid,
false,
$gserver,
);
}
}

View file

@ -0,0 +1,156 @@
<?php
/**
* @copyright Copyright (C) 2010-2023, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* 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 <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\User\Settings\Repository;
use Exception;
use Friendica\BaseCollection;
use Friendica\BaseEntity;
use Friendica\Content\Pager;
use Friendica\Database\Database;
use Friendica\Federation\Repository\GServer;
use Friendica\Network\HTTPException\InternalServerErrorException;
use Friendica\Network\HTTPException\NotFoundException;
use Friendica\User\Settings\Collection;
use Friendica\User\Settings\Entity;
use Friendica\User\Settings\Factory;
use Psr\Log\LoggerInterface;
class UserGServer extends \Friendica\BaseRepository
{
protected static $table_name = 'user-gserver';
/** @var Factory\UserGServer */
protected $factory;
/** @var GServer */
protected $gserverRepository;
public function __construct(GServer $gserverRepository, Database $database, LoggerInterface $logger, Factory\UserGServer $factory)
{
parent::__construct($database, $logger, $factory);
$this->gserverRepository = $gserverRepository;
}
/**
* Returns an existing UserGServer entity or create one on the fly
*
* @param int $uid
* @param int $gsid
* @param bool $hydrate Populate the related GServer entity
* @return Entity\UserGServer
*/
public function getOneByUserAndServer(int $uid, int $gsid, bool $hydrate = true): Entity\UserGServer
{
try {
return $this->selectOneByUserAndServer($uid, $gsid, $hydrate);
} catch (NotFoundException $e) {
return $this->factory->createFromUserAndServer($uid, $gsid, $hydrate ? $this->gserverRepository->selectOneById($gsid) : null);
}
}
/**
* @param int $uid
* @param int $gsid
* @param bool $hydrate Populate the related GServer entity
* @return Entity\UserGServer
* @throws NotFoundException
*/
public function selectOneByUserAndServer(int $uid, int $gsid, bool $hydrate = true): Entity\UserGServer
{
return $this->_selectOne(['uid' => $uid, 'gsid' => $gsid], [], $hydrate);
}
public function save(Entity\UserGServer $userGServer): Entity\UserGServer
{
$fields = [
'uid' => $userGServer->uid,
'gsid' => $userGServer->gsid,
'ignored' => $userGServer->ignored,
];
$this->db->insert(static::$table_name, $fields, Database::INSERT_UPDATE);
return $userGServer;
}
public function selectByUserWithPagination(int $uid, Pager $pager): Collection\UserGServers
{
return $this->_select(['uid' => $uid], ['limit' => [$pager->getStart(), $pager->getItemsPerPage()]]);
}
public function countByUser(int $uid): int
{
return $this->count(['uid' => $uid]);
}
public function isIgnoredByUser(int $uid, int $gsid): bool
{
return $this->exists(['uid' => $uid, 'gsid' => $gsid, 'ignored' => 1]);
}
/**
* @param Entity\UserGServer $userGServer
* @return bool
* @throws InternalServerErrorException in case the underlying storage cannot delete the record
*/
public function delete(Entity\UserGServer $userGServer): bool
{
try {
return $this->db->delete(self::$table_name, ['uid' => $userGServer->uid, 'gsid' => $userGServer->gsid]);
} catch (\Exception $exception) {
throw new InternalServerErrorException('Cannot delete the UserGServer', $exception);
}
}
protected function _selectOne(array $condition, array $params = [], bool $hydrate = true): BaseEntity
{
$fields = $this->db->selectFirst(static::$table_name, [], $condition, $params);
if (!$this->db->isResult($fields)) {
throw new NotFoundException();
}
return $this->factory->createFromTableRow($fields, $hydrate ? $this->gserverRepository->selectOneById($fields['gsid']) : null);
}
/**
* @param array $condition
* @param array $params
* @return Collection\UserGServers
* @throws Exception
*/
protected function _select(array $condition, array $params = [], bool $hydrate = true): BaseCollection
{
$rows = $this->db->selectToArray(static::$table_name, [], $condition, $params);
$Entities = new Collection\UserGServers();
foreach ($rows as $fields) {
$Entities[] = $this->factory->createFromTableRow($fields, $hydrate ? $this->gserverRepository->selectOneById($fields['gsid']) : null);
}
return $Entities;
}
public function listIgnoredByUser(int $uid): Collection\UserGServers
{
return $this->_select(['uid' => $uid, 'ignored' => 1], [], false);
}
}

View file

@ -56,7 +56,7 @@ use Friendica\Database\DBA;
// This file is required several times during the test in DbaDefinition which justifies this condition // This file is required several times during the test in DbaDefinition which justifies this condition
if (!defined('DB_UPDATE_VERSION')) { if (!defined('DB_UPDATE_VERSION')) {
define('DB_UPDATE_VERSION', 1525); define('DB_UPDATE_VERSION', 1527);
} }
return [ return [
@ -159,6 +159,17 @@ return [
"email" => ["email(64)"], "email" => ["email(64)"],
] ]
], ],
"user-gserver" => [
"comment" => "User settings about remote servers",
"fields" => [
"uid" => ["type" => "mediumint unsigned", "not null" => "1", "default" => "0", "foreign" => ["user" => "uid"], "comment" => "Owner User id"],
"gsid" => ["type" => "int unsigned", "not null" => "1", "default" => "0", "foreign" => ["gserver" => "id"], "comment" => "Gserver id"],
"ignored" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "server accounts are ignored for the user"],
],
"indexes" => [
"PRIMARY" => ["uid", "gsid"],
],
],
"item-uri" => [ "item-uri" => [
"comment" => "URI and GUID for items", "comment" => "URI and GUID for items",
"fields" => [ "fields" => [

View file

@ -197,6 +197,7 @@
"owner-blocked" => ["owner", "blocked"], "owner-blocked" => ["owner", "blocked"],
"owner-hidden" => ["owner", "hidden"], "owner-hidden" => ["owner", "hidden"],
"owner-updated" => ["owner", "updated"], "owner-updated" => ["owner", "updated"],
"owner-gsid" => ["owner", "gsid"],
"owner-contact-type" => ["owner", "contact-type"], "owner-contact-type" => ["owner", "contact-type"],
"causer-id" => ["post-user", "causer-id"], "causer-id" => ["post-user", "causer-id"],
"causer-uri-id" => ["causer", "uri-id"], "causer-uri-id" => ["causer", "uri-id"],
@ -209,6 +210,7 @@
"causer-network" => ["causer", "network"], "causer-network" => ["causer", "network"],
"causer-blocked" => ["causer", "blocked"], "causer-blocked" => ["causer", "blocked"],
"causer-hidden" => ["causer", "hidden"], "causer-hidden" => ["causer", "hidden"],
"causer-gsid" => ["causer", "gsid"],
"causer-contact-type" => ["causer", "contact-type"], "causer-contact-type" => ["causer", "contact-type"],
"postopts" => ["post-delivery-data", "postopts"], "postopts" => ["post-delivery-data", "postopts"],
"inform" => ["post-delivery-data", "inform"], "inform" => ["post-delivery-data", "inform"],
@ -340,6 +342,7 @@
"contact-pending" => ["contact", "pending"], "contact-pending" => ["contact", "pending"],
"contact-rel" => ["contact", "rel"], "contact-rel" => ["contact", "rel"],
"contact-uid" => ["contact", "uid"], "contact-uid" => ["contact", "uid"],
"contact-gsid" => ["contact", "gsid"],
"contact-contact-type" => ["contact", "contact-type"], "contact-contact-type" => ["contact", "contact-type"],
"writable" => "IF (`post-user`.`network` IN ('apub', 'dfrn', 'dspr', 'stat'), true, `contact`.`writable`)", "writable" => "IF (`post-user`.`network` IN ('apub', 'dfrn', 'dspr', 'stat'), true, `contact`.`writable`)",
"self" => ["contact", "self"], "self" => ["contact", "self"],
@ -375,6 +378,7 @@
"owner-blocked" => ["owner", "blocked"], "owner-blocked" => ["owner", "blocked"],
"owner-hidden" => ["owner", "hidden"], "owner-hidden" => ["owner", "hidden"],
"owner-updated" => ["owner", "updated"], "owner-updated" => ["owner", "updated"],
"owner-gsid" => ["owner", "gsid"],
"owner-contact-type" => ["owner", "contact-type"], "owner-contact-type" => ["owner", "contact-type"],
"causer-id" => ["post-thread-user", "causer-id"], "causer-id" => ["post-thread-user", "causer-id"],
"causer-uri-id" => ["causer", "uri-id"], "causer-uri-id" => ["causer", "uri-id"],
@ -387,6 +391,7 @@
"causer-network" => ["causer", "network"], "causer-network" => ["causer", "network"],
"causer-blocked" => ["causer", "blocked"], "causer-blocked" => ["causer", "blocked"],
"causer-hidden" => ["causer", "hidden"], "causer-hidden" => ["causer", "hidden"],
"causer-gsid" => ["causer", "gsid"],
"causer-contact-type" => ["causer", "contact-type"], "causer-contact-type" => ["causer", "contact-type"],
"postopts" => ["post-delivery-data", "postopts"], "postopts" => ["post-delivery-data", "postopts"],
"inform" => ["post-delivery-data", "inform"], "inform" => ["post-delivery-data", "inform"],
@ -540,6 +545,7 @@
"owner-hidden" => ["owner", "hidden"], "owner-hidden" => ["owner", "hidden"],
"owner-updated" => ["owner", "updated"], "owner-updated" => ["owner", "updated"],
"owner-contact-type" => ["owner", "contact-type"], "owner-contact-type" => ["owner", "contact-type"],
"owner-gsid" => ["owner", "gsid"],
"causer-id" => ["post", "causer-id"], "causer-id" => ["post", "causer-id"],
"causer-uri-id" => ["causer", "uri-id"], "causer-uri-id" => ["causer", "uri-id"],
"causer-link" => ["causer", "url"], "causer-link" => ["causer", "url"],
@ -552,6 +558,7 @@
"causer-blocked" => ["causer", "blocked"], "causer-blocked" => ["causer", "blocked"],
"causer-hidden" => ["causer", "hidden"], "causer-hidden" => ["causer", "hidden"],
"causer-contact-type" => ["causer", "contact-type"], "causer-contact-type" => ["causer", "contact-type"],
"causer-gsid" => ["causer", "gsid"],
"question-id" => ["post-question", "id"], "question-id" => ["post-question", "id"],
"question-multiple" => ["post-question", "multiple"], "question-multiple" => ["post-question", "multiple"],
"question-voters" => ["post-question", "voters"], "question-voters" => ["post-question", "voters"],
@ -680,6 +687,7 @@
"owner-blocked" => ["owner", "blocked"], "owner-blocked" => ["owner", "blocked"],
"owner-hidden" => ["owner", "hidden"], "owner-hidden" => ["owner", "hidden"],
"owner-updated" => ["owner", "updated"], "owner-updated" => ["owner", "updated"],
"owner-gsid" => ["owner", "gsid"],
"owner-contact-type" => ["owner", "contact-type"], "owner-contact-type" => ["owner", "contact-type"],
"causer-id" => ["post-thread", "causer-id"], "causer-id" => ["post-thread", "causer-id"],
"causer-uri-id" => ["causer", "uri-id"], "causer-uri-id" => ["causer", "uri-id"],
@ -692,6 +700,7 @@
"causer-network" => ["causer", "network"], "causer-network" => ["causer", "network"],
"causer-blocked" => ["causer", "blocked"], "causer-blocked" => ["causer", "blocked"],
"causer-hidden" => ["causer", "hidden"], "causer-hidden" => ["causer", "hidden"],
"causer-gsid" => ["causer", "gsid"],
"causer-contact-type" => ["causer", "contact-type"], "causer-contact-type" => ["causer", "contact-type"],
"question-id" => ["post-question", "id"], "question-id" => ["post-question", "id"],
"question-multiple" => ["post-question", "multiple"], "question-multiple" => ["post-question", "multiple"],
@ -843,7 +852,8 @@
AND (`post-thread-user`.`hidden` IS NULL OR NOT `post-thread-user`.`hidden`) AND (`post-thread-user`.`hidden` IS NULL OR NOT `post-thread-user`.`hidden`)
AND NOT `authorcontact`.`blocked` AND NOT `ownercontact`.`blocked` AND NOT `authorcontact`.`blocked` AND NOT `ownercontact`.`blocked`
AND (`author`.`blocked` IS NULL OR NOT `author`.`blocked`) AND (`author`.`blocked` IS NULL OR NOT `author`.`blocked`)
AND (`owner`.`blocked` IS NULL OR NOT `owner`.`blocked`)" AND (`owner`.`blocked` IS NULL OR NOT `owner`.`blocked`)
AND NOT EXISTS(SELECT `gsid` FROM `user-gserver` WHERE `uid` = `post-thread-user`.`uid` AND `gsid` IN (`authorcontact`.`gsid`, `ownercontact`.`gsid`) AND `ignored`)"
], ],
"owner-view" => [ "owner-view" => [
"fields" => [ "fields" => [

View file

@ -639,6 +639,10 @@ return [
], ],
'/settings' => [ '/settings' => [
'/server' => [
'[/]' => [Module\Settings\Server\Index::class, [R::GET, R::POST]],
'/{gsid:\d+}/{action}' => [Module\Settings\Server\Action::class, [R::GET, R::POST]],
],
'[/]' => [Module\Settings\Account::class, [R::GET, R::POST]], '[/]' => [Module\Settings\Account::class, [R::GET, R::POST]],
'/account' => [ '/account' => [
'[/]' => [Module\Settings\Account::class, [R::GET, R::POST]], '[/]' => [Module\Settings\Account::class, [R::GET, R::POST]],

View file

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: 2023.09-dev\n" "Project-Id-Version: 2023.09-dev\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-08-11 01:11+0200\n" "POT-Creation-Date: 2023-08-20 14:31-0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -281,7 +281,7 @@ msgstr ""
msgid "Your message:" msgid "Your message:"
msgstr "" msgstr ""
#: mod/message.php:199 mod/message.php:354 src/Content/Conversation.php:361 #: mod/message.php:199 mod/message.php:354 src/Content/Conversation.php:366
#: src/Module/Post/Edit.php:131 #: src/Module/Post/Edit.php:131
msgid "Upload photo" msgid "Upload photo"
msgstr "" msgstr ""
@ -292,9 +292,9 @@ msgid "Insert web link"
msgstr "" msgstr ""
#: mod/message.php:201 mod/message.php:357 mod/photos.php:1301 #: mod/message.php:201 mod/message.php:357 mod/photos.php:1301
#: src/Content/Conversation.php:392 src/Content/Conversation.php:1508 #: src/Content/Conversation.php:397 src/Content/Conversation.php:1528
#: src/Module/Item/Compose.php:206 src/Module/Post/Edit.php:145 #: src/Module/Item/Compose.php:206 src/Module/Post/Edit.php:145
#: src/Module/Profile/UnkMail.php:154 src/Object/Post.php:571 #: src/Module/Profile/UnkMail.php:154 src/Object/Post.php:579
msgid "Please wait" msgid "Please wait"
msgstr "" msgstr ""
@ -302,7 +302,7 @@ msgstr ""
#: mod/photos.php:824 mod/photos.php:1101 mod/photos.php:1142 #: mod/photos.php:824 mod/photos.php:1101 mod/photos.php:1142
#: mod/photos.php:1198 mod/photos.php:1278 #: mod/photos.php:1198 mod/photos.php:1278
#: src/Module/Calendar/Event/Form.php:250 src/Module/Contact/Advanced.php:132 #: src/Module/Calendar/Event/Form.php:250 src/Module/Contact/Advanced.php:132
#: src/Module/Contact/Profile.php:339 #: src/Module/Contact/Profile.php:352
#: src/Module/Debug/ActivityPubConversion.php:140 #: src/Module/Debug/ActivityPubConversion.php:140
#: src/Module/Debug/Babel.php:313 src/Module/Debug/Localtime.php:64 #: src/Module/Debug/Babel.php:313 src/Module/Debug/Localtime.php:64
#: src/Module/Debug/Probe.php:54 src/Module/Debug/WebFinger.php:51 #: src/Module/Debug/Probe.php:54 src/Module/Debug/WebFinger.php:51
@ -315,7 +315,8 @@ msgstr ""
#: src/Module/Moderation/Report/Create.php:211 #: src/Module/Moderation/Report/Create.php:211
#: src/Module/Moderation/Report/Create.php:263 #: src/Module/Moderation/Report/Create.php:263
#: src/Module/Profile/Profile.php:274 src/Module/Profile/UnkMail.php:155 #: src/Module/Profile/Profile.php:274 src/Module/Profile/UnkMail.php:155
#: src/Module/Settings/Profile/Index.php:257 src/Object/Post.php:1087 #: src/Module/Settings/Profile/Index.php:257
#: src/Module/Settings/Server/Action.php:79 src/Object/Post.php:1096
#: view/theme/duepuntozero/config.php:85 view/theme/frio/config.php:171 #: view/theme/duepuntozero/config.php:85 view/theme/frio/config.php:171
#: view/theme/quattro/config.php:87 view/theme/vier/config.php:135 #: view/theme/quattro/config.php:87 view/theme/vier/config.php:135
msgid "Submit" msgid "Submit"
@ -479,7 +480,7 @@ msgstr ""
msgid "Do not show a status post for this upload" msgid "Do not show a status post for this upload"
msgstr "" msgstr ""
#: mod/photos.php:736 mod/photos.php:1097 src/Content/Conversation.php:394 #: mod/photos.php:736 mod/photos.php:1097 src/Content/Conversation.php:399
#: src/Module/Calendar/Event/Form.php:253 src/Module/Post/Edit.php:183 #: src/Module/Calendar/Event/Form.php:253 src/Module/Post/Edit.php:183
msgid "Permissions" msgid "Permissions"
msgstr "" msgstr ""
@ -492,7 +493,7 @@ msgstr ""
msgid "Delete Album" msgid "Delete Album"
msgstr "" msgstr ""
#: mod/photos.php:803 mod/photos.php:903 src/Content/Conversation.php:410 #: mod/photos.php:803 mod/photos.php:903 src/Content/Conversation.php:415
#: src/Module/Contact/Follow.php:173 src/Module/Contact/Revoke.php:109 #: src/Module/Contact/Follow.php:173 src/Module/Contact/Revoke.php:109
#: src/Module/Contact/Unfollow.php:126 #: src/Module/Contact/Unfollow.php:126
#: src/Module/Media/Attachment/Browser.php:77 #: src/Module/Media/Attachment/Browser.php:77
@ -600,53 +601,54 @@ msgstr ""
#: mod/photos.php:1139 mod/photos.php:1195 mod/photos.php:1275 #: mod/photos.php:1139 mod/photos.php:1195 mod/photos.php:1275
#: src/Module/Contact.php:619 src/Module/Item/Compose.php:188 #: src/Module/Contact.php:619 src/Module/Item/Compose.php:188
#: src/Object/Post.php:1084 #: src/Object/Post.php:1093
msgid "This is you" msgid "This is you"
msgstr "" msgstr ""
#: mod/photos.php:1141 mod/photos.php:1197 mod/photos.php:1277 #: mod/photos.php:1141 mod/photos.php:1197 mod/photos.php:1277
#: src/Object/Post.php:565 src/Object/Post.php:1086 #: src/Object/Post.php:573 src/Object/Post.php:1095
msgid "Comment" msgid "Comment"
msgstr "" msgstr ""
#: mod/photos.php:1143 mod/photos.php:1199 mod/photos.php:1279 #: mod/photos.php:1143 mod/photos.php:1199 mod/photos.php:1279
#: src/Content/Conversation.php:407 src/Module/Calendar/Event/Form.php:248 #: src/Content/Conversation.php:412 src/Module/Calendar/Event/Form.php:248
#: src/Module/Item/Compose.php:201 src/Module/Post/Edit.php:165 #: src/Module/Item/Compose.php:201 src/Module/Post/Edit.php:165
#: src/Object/Post.php:1100 #: src/Object/Post.php:1109
msgid "Preview" msgid "Preview"
msgstr "" msgstr ""
#: mod/photos.php:1144 src/Content/Conversation.php:360 #: mod/photos.php:1144 src/Content/Conversation.php:365
#: src/Module/Post/Edit.php:130 src/Object/Post.php:1088 #: src/Module/Post/Edit.php:130 src/Object/Post.php:1097
msgid "Loading..." msgid "Loading..."
msgstr "" msgstr ""
#: mod/photos.php:1236 src/Content/Conversation.php:1424 #: mod/photos.php:1236 src/Content/Conversation.php:1443
#: src/Object/Post.php:260 #: src/Object/Post.php:262
msgid "Select" msgid "Select"
msgstr "" msgstr ""
#: mod/photos.php:1237 src/Content/Conversation.php:1425 #: mod/photos.php:1237 src/Content/Conversation.php:1444
#: src/Module/Moderation/Users/Active.php:136 #: src/Module/Moderation/Users/Active.php:136
#: src/Module/Moderation/Users/Blocked.php:136 #: src/Module/Moderation/Users/Blocked.php:136
#: src/Module/Moderation/Users/Index.php:151 #: src/Module/Moderation/Users/Index.php:151
#: src/Module/Settings/Connectors.php:244 #: src/Module/Settings/Connectors.php:244
#: src/Module/Settings/Server/Index.php:109
msgid "Delete" msgid "Delete"
msgstr "" msgstr ""
#: mod/photos.php:1298 src/Object/Post.php:402 #: mod/photos.php:1298 src/Object/Post.php:409
msgid "Like" msgid "Like"
msgstr "" msgstr ""
#: mod/photos.php:1299 src/Object/Post.php:402 #: mod/photos.php:1299 src/Object/Post.php:409
msgid "I like this (toggle)" msgid "I like this (toggle)"
msgstr "" msgstr ""
#: mod/photos.php:1300 src/Object/Post.php:403 #: mod/photos.php:1300 src/Object/Post.php:410
msgid "Dislike" msgid "Dislike"
msgstr "" msgstr ""
#: mod/photos.php:1302 src/Object/Post.php:403 #: mod/photos.php:1302 src/Object/Post.php:410
msgid "I don't like this (toggle)" msgid "I don't like this (toggle)"
msgstr "" msgstr ""
@ -682,77 +684,88 @@ msgstr ""
msgid "Collapse this author's posts?" msgid "Collapse this author's posts?"
msgstr "" msgstr ""
#: src/App/Page.php:253 #: src/App/Page.php:252
msgid "Like not successful" msgid "Ignore this author's server?"
msgstr "" msgstr ""
#: src/App/Page.php:254 #: src/App/Page.php:253 src/Module/Settings/Server/Action.php:61
msgid "Dislike not successful" #: src/Module/Settings/Server/Index.php:108
msgid ""
"You won't see any content from this server including reshares in your "
"Network page, the community pages and individual conversations."
msgstr "" msgstr ""
#: src/App/Page.php:255 #: src/App/Page.php:255
msgid "Sharing not successful" msgid "Like not successful"
msgstr "" msgstr ""
#: src/App/Page.php:256 #: src/App/Page.php:256
msgid "Attendance unsuccessful" msgid "Dislike not successful"
msgstr "" msgstr ""
#: src/App/Page.php:257 #: src/App/Page.php:257
msgid "Backend error" msgid "Sharing not successful"
msgstr "" msgstr ""
#: src/App/Page.php:258 #: src/App/Page.php:258
msgid "Attendance unsuccessful"
msgstr ""
#: src/App/Page.php:259
msgid "Backend error"
msgstr ""
#: src/App/Page.php:260
msgid "Network error" msgid "Network error"
msgstr "" msgstr ""
#: src/App/Page.php:261 #: src/App/Page.php:263
msgid "Drop files here to upload" msgid "Drop files here to upload"
msgstr "" msgstr ""
#: src/App/Page.php:262 #: src/App/Page.php:264
msgid "Your browser does not support drag and drop file uploads." msgid "Your browser does not support drag and drop file uploads."
msgstr "" msgstr ""
#: src/App/Page.php:263 #: src/App/Page.php:265
msgid "" msgid ""
"Please use the fallback form below to upload your files like in the olden " "Please use the fallback form below to upload your files like in the olden "
"days." "days."
msgstr "" msgstr ""
#: src/App/Page.php:264 #: src/App/Page.php:266
msgid "File is too big ({{filesize}}MiB). Max filesize: {{maxFilesize}}MiB." msgid "File is too big ({{filesize}}MiB). Max filesize: {{maxFilesize}}MiB."
msgstr "" msgstr ""
#: src/App/Page.php:265 #: src/App/Page.php:267
msgid "You can't upload files of this type." msgid "You can't upload files of this type."
msgstr "" msgstr ""
#: src/App/Page.php:266 #: src/App/Page.php:268
msgid "Server responded with {{statusCode}} code." msgid "Server responded with {{statusCode}} code."
msgstr "" msgstr ""
#: src/App/Page.php:267 #: src/App/Page.php:269
msgid "Cancel upload" msgid "Cancel upload"
msgstr "" msgstr ""
#: src/App/Page.php:268 #: src/App/Page.php:270
msgid "Upload canceled." msgid "Upload canceled."
msgstr "" msgstr ""
#: src/App/Page.php:269 #: src/App/Page.php:271
msgid "Are you sure you want to cancel this upload?" msgid "Are you sure you want to cancel this upload?"
msgstr "" msgstr ""
#: src/App/Page.php:270 #: src/App/Page.php:272
msgid "Remove file" msgid "Remove file"
msgstr "" msgstr ""
#: src/App/Page.php:271 #: src/App/Page.php:273
msgid "You can't upload any more files." msgid "You can't upload any more files."
msgstr "" msgstr ""
#: src/App/Page.php:349 #: src/App/Page.php:351
msgid "toggle mobile" msgid "toggle mobile"
msgstr "" msgstr ""
@ -1127,65 +1140,65 @@ msgstr ""
msgid "%s (via %s)" msgid "%s (via %s)"
msgstr "" msgstr ""
#: src/Content/Conversation.php:219 #: src/Content/Conversation.php:224
msgid "and" msgid "and"
msgstr "" msgstr ""
#: src/Content/Conversation.php:222 #: src/Content/Conversation.php:227
#, php-format #, php-format
msgid "and %d other people" msgid "and %d other people"
msgstr "" msgstr ""
#: src/Content/Conversation.php:228 #: src/Content/Conversation.php:233
#, php-format #, php-format
msgid "%2$s likes this." msgid "%2$s likes this."
msgid_plural "%2$s like this." msgid_plural "%2$s like this."
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#: src/Content/Conversation.php:230 #: src/Content/Conversation.php:235
#, php-format #, php-format
msgid "%2$s doesn't like this." msgid "%2$s doesn't like this."
msgid_plural "%2$s don't like this." msgid_plural "%2$s don't like this."
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#: src/Content/Conversation.php:232 #: src/Content/Conversation.php:237
#, php-format #, php-format
msgid "%2$s attends." msgid "%2$s attends."
msgid_plural "%2$s attend." msgid_plural "%2$s attend."
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#: src/Content/Conversation.php:234 #: src/Content/Conversation.php:239
#, php-format #, php-format
msgid "%2$s doesn't attend." msgid "%2$s doesn't attend."
msgid_plural "%2$s don't attend." msgid_plural "%2$s don't attend."
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#: src/Content/Conversation.php:236 #: src/Content/Conversation.php:241
#, php-format #, php-format
msgid "%2$s attends maybe." msgid "%2$s attends maybe."
msgid_plural "%2$s attend maybe." msgid_plural "%2$s attend maybe."
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#: src/Content/Conversation.php:238 #: src/Content/Conversation.php:243
#, php-format #, php-format
msgid "%2$s reshared this." msgid "%2$s reshared this."
msgid_plural "%2$s reshared this." msgid_plural "%2$s reshared this."
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#: src/Content/Conversation.php:267 #: src/Content/Conversation.php:272
#, php-format #, php-format
msgid "<button type=\"button\" %2$s>%1$d person</button> likes this" msgid "<button type=\"button\" %2$s>%1$d person</button> likes this"
msgid_plural "<button type=\"button\" %2$s>%1$d people</button> like this" msgid_plural "<button type=\"button\" %2$s>%1$d people</button> like this"
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#: src/Content/Conversation.php:270 #: src/Content/Conversation.php:275
#, php-format #, php-format
msgid "<button type=\"button\" %2$s>%1$d person</button> doesn't like this" msgid "<button type=\"button\" %2$s>%1$d person</button> doesn't like this"
msgid_plural "" msgid_plural ""
@ -1193,304 +1206,304 @@ msgid_plural ""
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#: src/Content/Conversation.php:273 #: src/Content/Conversation.php:278
#, php-format #, php-format
msgid "<button type=\"button\" %2$s>%1$d person</button> attends" msgid "<button type=\"button\" %2$s>%1$d person</button> attends"
msgid_plural "<button type=\"button\" %2$s>%1$d people</button> attend" msgid_plural "<button type=\"button\" %2$s>%1$d people</button> attend"
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#: src/Content/Conversation.php:276 #: src/Content/Conversation.php:281
#, php-format #, php-format
msgid "<button type=\"button\" %2$s>%1$d person</button> doesn't attend" msgid "<button type=\"button\" %2$s>%1$d person</button> doesn't attend"
msgid_plural "<button type=\"button\" %2$s>%1$d people</button> don't attend" msgid_plural "<button type=\"button\" %2$s>%1$d people</button> don't attend"
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#: src/Content/Conversation.php:279 #: src/Content/Conversation.php:284
#, php-format #, php-format
msgid "<button type=\"button\" %2$s>%1$d person</button> attends maybe" msgid "<button type=\"button\" %2$s>%1$d person</button> attends maybe"
msgid_plural "<button type=\"button\" %2$s>%1$d people</button> attend maybe" msgid_plural "<button type=\"button\" %2$s>%1$d people</button> attend maybe"
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#: src/Content/Conversation.php:282 #: src/Content/Conversation.php:287
#, php-format #, php-format
msgid "<button type=\"button\" %2$s>%1$d person</button> reshared this" msgid "<button type=\"button\" %2$s>%1$d person</button> reshared this"
msgid_plural "<button type=\"button\" %2$s>%1$d people</button> reshared this" msgid_plural "<button type=\"button\" %2$s>%1$d people</button> reshared this"
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#: src/Content/Conversation.php:329 #: src/Content/Conversation.php:334
msgid "Visible to <strong>everybody</strong>" msgid "Visible to <strong>everybody</strong>"
msgstr "" msgstr ""
#: src/Content/Conversation.php:330 src/Module/Item/Compose.php:200 #: src/Content/Conversation.php:335 src/Module/Item/Compose.php:200
#: src/Object/Post.php:1099 #: src/Object/Post.php:1108
msgid "Please enter a image/video/audio/webpage URL:" msgid "Please enter a image/video/audio/webpage URL:"
msgstr "" msgstr ""
#: src/Content/Conversation.php:331 #: src/Content/Conversation.php:336
msgid "Tag term:" msgid "Tag term:"
msgstr "" msgstr ""
#: src/Content/Conversation.php:332 src/Module/Filer/SaveTag.php:73 #: src/Content/Conversation.php:337 src/Module/Filer/SaveTag.php:73
msgid "Save to Folder:" msgid "Save to Folder:"
msgstr "" msgstr ""
#: src/Content/Conversation.php:333 #: src/Content/Conversation.php:338
msgid "Where are you right now?" msgid "Where are you right now?"
msgstr "" msgstr ""
#: src/Content/Conversation.php:334 #: src/Content/Conversation.php:339
msgid "Delete item(s)?" msgid "Delete item(s)?"
msgstr "" msgstr ""
#: src/Content/Conversation.php:346 src/Module/Item/Compose.php:175 #: src/Content/Conversation.php:351 src/Module/Item/Compose.php:175
msgid "Created at" msgid "Created at"
msgstr "" msgstr ""
#: src/Content/Conversation.php:356 #: src/Content/Conversation.php:361
msgid "New Post" msgid "New Post"
msgstr "" msgstr ""
#: src/Content/Conversation.php:359 #: src/Content/Conversation.php:364
msgid "Share" msgid "Share"
msgstr "" msgstr ""
#: src/Content/Conversation.php:362 src/Module/Post/Edit.php:132 #: src/Content/Conversation.php:367 src/Module/Post/Edit.php:132
msgid "upload photo" msgid "upload photo"
msgstr "" msgstr ""
#: src/Content/Conversation.php:363 src/Module/Post/Edit.php:133 #: src/Content/Conversation.php:368 src/Module/Post/Edit.php:133
msgid "Attach file" msgid "Attach file"
msgstr "" msgstr ""
#: src/Content/Conversation.php:364 src/Module/Post/Edit.php:134 #: src/Content/Conversation.php:369 src/Module/Post/Edit.php:134
msgid "attach file" msgid "attach file"
msgstr "" msgstr ""
#: src/Content/Conversation.php:365 src/Module/Item/Compose.php:190 #: src/Content/Conversation.php:370 src/Module/Item/Compose.php:190
#: src/Module/Post/Edit.php:171 src/Object/Post.php:1089 #: src/Module/Post/Edit.php:171 src/Object/Post.php:1098
msgid "Bold" msgid "Bold"
msgstr "" msgstr ""
#: src/Content/Conversation.php:366 src/Module/Item/Compose.php:191 #: src/Content/Conversation.php:371 src/Module/Item/Compose.php:191
#: src/Module/Post/Edit.php:172 src/Object/Post.php:1090 #: src/Module/Post/Edit.php:172 src/Object/Post.php:1099
msgid "Italic" msgid "Italic"
msgstr "" msgstr ""
#: src/Content/Conversation.php:367 src/Module/Item/Compose.php:192 #: src/Content/Conversation.php:372 src/Module/Item/Compose.php:192
#: src/Module/Post/Edit.php:173 src/Object/Post.php:1091 #: src/Module/Post/Edit.php:173 src/Object/Post.php:1100
msgid "Underline" msgid "Underline"
msgstr "" msgstr ""
#: src/Content/Conversation.php:368 src/Module/Item/Compose.php:193 #: src/Content/Conversation.php:373 src/Module/Item/Compose.php:193
#: src/Module/Post/Edit.php:174 src/Object/Post.php:1093 #: src/Module/Post/Edit.php:174 src/Object/Post.php:1102
msgid "Quote" msgid "Quote"
msgstr "" msgstr ""
#: src/Content/Conversation.php:369 src/Module/Item/Compose.php:194 #: src/Content/Conversation.php:374 src/Module/Item/Compose.php:194
#: src/Module/Post/Edit.php:175 src/Object/Post.php:1094 #: src/Module/Post/Edit.php:175 src/Object/Post.php:1103
msgid "Add emojis" msgid "Add emojis"
msgstr "" msgstr ""
#: src/Content/Conversation.php:370 src/Module/Item/Compose.php:195 #: src/Content/Conversation.php:375 src/Module/Item/Compose.php:195
#: src/Object/Post.php:1092 #: src/Object/Post.php:1101
msgid "Content Warning" msgid "Content Warning"
msgstr "" msgstr ""
#: src/Content/Conversation.php:371 src/Module/Item/Compose.php:196 #: src/Content/Conversation.php:376 src/Module/Item/Compose.php:196
#: src/Module/Post/Edit.php:176 src/Object/Post.php:1095 #: src/Module/Post/Edit.php:176 src/Object/Post.php:1104
msgid "Code" msgid "Code"
msgstr "" msgstr ""
#: src/Content/Conversation.php:372 src/Module/Item/Compose.php:197 #: src/Content/Conversation.php:377 src/Module/Item/Compose.php:197
#: src/Object/Post.php:1096 #: src/Object/Post.php:1105
msgid "Image" msgid "Image"
msgstr "" msgstr ""
#: src/Content/Conversation.php:373 src/Module/Item/Compose.php:198 #: src/Content/Conversation.php:378 src/Module/Item/Compose.php:198
#: src/Module/Post/Edit.php:177 src/Object/Post.php:1097 #: src/Module/Post/Edit.php:177 src/Object/Post.php:1106
msgid "Link" msgid "Link"
msgstr "" msgstr ""
#: src/Content/Conversation.php:374 src/Module/Item/Compose.php:199 #: src/Content/Conversation.php:379 src/Module/Item/Compose.php:199
#: src/Module/Post/Edit.php:178 src/Object/Post.php:1098 #: src/Module/Post/Edit.php:178 src/Object/Post.php:1107
msgid "Link or Media" msgid "Link or Media"
msgstr "" msgstr ""
#: src/Content/Conversation.php:375 #: src/Content/Conversation.php:380
msgid "Video" msgid "Video"
msgstr "" msgstr ""
#: src/Content/Conversation.php:376 src/Module/Item/Compose.php:202 #: src/Content/Conversation.php:381 src/Module/Item/Compose.php:202
#: src/Module/Post/Edit.php:141 #: src/Module/Post/Edit.php:141
msgid "Set your location" msgid "Set your location"
msgstr "" msgstr ""
#: src/Content/Conversation.php:377 src/Module/Post/Edit.php:142 #: src/Content/Conversation.php:382 src/Module/Post/Edit.php:142
msgid "set location" msgid "set location"
msgstr "" msgstr ""
#: src/Content/Conversation.php:378 src/Module/Post/Edit.php:143 #: src/Content/Conversation.php:383 src/Module/Post/Edit.php:143
msgid "Clear browser location" msgid "Clear browser location"
msgstr "" msgstr ""
#: src/Content/Conversation.php:379 src/Module/Post/Edit.php:144 #: src/Content/Conversation.php:384 src/Module/Post/Edit.php:144
msgid "clear location" msgid "clear location"
msgstr "" msgstr ""
#: src/Content/Conversation.php:381 src/Module/Item/Compose.php:207 #: src/Content/Conversation.php:386 src/Module/Item/Compose.php:207
#: src/Module/Post/Edit.php:157 #: src/Module/Post/Edit.php:157
msgid "Set title" msgid "Set title"
msgstr "" msgstr ""
#: src/Content/Conversation.php:383 src/Module/Item/Compose.php:208 #: src/Content/Conversation.php:388 src/Module/Item/Compose.php:208
#: src/Module/Post/Edit.php:159 #: src/Module/Post/Edit.php:159
msgid "Categories (comma-separated list)" msgid "Categories (comma-separated list)"
msgstr "" msgstr ""
#: src/Content/Conversation.php:388 src/Module/Item/Compose.php:224 #: src/Content/Conversation.php:393 src/Module/Item/Compose.php:224
msgid "Scheduled at" msgid "Scheduled at"
msgstr "" msgstr ""
#: src/Content/Conversation.php:393 src/Module/Post/Edit.php:146 #: src/Content/Conversation.php:398 src/Module/Post/Edit.php:146
msgid "Permission settings" msgid "Permission settings"
msgstr "" msgstr ""
#: src/Content/Conversation.php:403 src/Module/Post/Edit.php:155 #: src/Content/Conversation.php:408 src/Module/Post/Edit.php:155
msgid "Public post" msgid "Public post"
msgstr "" msgstr ""
#: src/Content/Conversation.php:417 src/Content/Widget/VCard.php:120 #: src/Content/Conversation.php:422 src/Content/Widget/VCard.php:120
#: src/Model/Profile.php:467 src/Module/Admin/Logs/View.php:92 #: src/Model/Profile.php:467 src/Module/Admin/Logs/View.php:92
#: src/Module/Post/Edit.php:181 #: src/Module/Post/Edit.php:181
msgid "Message" msgid "Message"
msgstr "" msgstr ""
#: src/Content/Conversation.php:418 src/Module/Post/Edit.php:182 #: src/Content/Conversation.php:423 src/Module/Post/Edit.php:182
#: src/Module/Settings/TwoFactor/Trusted.php:140 #: src/Module/Settings/TwoFactor/Trusted.php:140
msgid "Browser" msgid "Browser"
msgstr "" msgstr ""
#: src/Content/Conversation.php:420 src/Module/Post/Edit.php:185 #: src/Content/Conversation.php:425 src/Module/Post/Edit.php:185
msgid "Open Compose page" msgid "Open Compose page"
msgstr "" msgstr ""
#: src/Content/Conversation.php:569 #: src/Content/Conversation.php:580
msgid "remove" msgid "remove"
msgstr "" msgstr ""
#: src/Content/Conversation.php:573 #: src/Content/Conversation.php:584
msgid "Delete Selected Items" msgid "Delete Selected Items"
msgstr "" msgstr ""
#: src/Content/Conversation.php:728 src/Content/Conversation.php:731 #: src/Content/Conversation.php:739 src/Content/Conversation.php:742
#: src/Content/Conversation.php:734 src/Content/Conversation.php:737 #: src/Content/Conversation.php:745 src/Content/Conversation.php:748
#: src/Content/Conversation.php:740 #: src/Content/Conversation.php:751
#, php-format #, php-format
msgid "You had been addressed (%s)." msgid "You had been addressed (%s)."
msgstr "" msgstr ""
#: src/Content/Conversation.php:743 #: src/Content/Conversation.php:754
#, php-format #, php-format
msgid "You are following %s." msgid "You are following %s."
msgstr "" msgstr ""
#: src/Content/Conversation.php:746 #: src/Content/Conversation.php:757
msgid "You subscribed to one or more tags in this post." msgid "You subscribed to one or more tags in this post."
msgstr "" msgstr ""
#: src/Content/Conversation.php:765 #: src/Content/Conversation.php:776
#, php-format #, php-format
msgid "%s reshared this." msgid "%s reshared this."
msgstr "" msgstr ""
#: src/Content/Conversation.php:767 #: src/Content/Conversation.php:778
msgid "Reshared" msgid "Reshared"
msgstr "" msgstr ""
#: src/Content/Conversation.php:767 #: src/Content/Conversation.php:778
#, php-format #, php-format
msgid "Reshared by %s <%s>" msgid "Reshared by %s <%s>"
msgstr "" msgstr ""
#: src/Content/Conversation.php:770 #: src/Content/Conversation.php:781
#, php-format #, php-format
msgid "%s is participating in this thread." msgid "%s is participating in this thread."
msgstr "" msgstr ""
#: src/Content/Conversation.php:773 #: src/Content/Conversation.php:784
msgid "Stored for general reasons" msgid "Stored for general reasons"
msgstr "" msgstr ""
#: src/Content/Conversation.php:776 #: src/Content/Conversation.php:787
msgid "Global post" msgid "Global post"
msgstr "" msgstr ""
#: src/Content/Conversation.php:779 #: src/Content/Conversation.php:790
msgid "Sent via an relay server" msgid "Sent via an relay server"
msgstr "" msgstr ""
#: src/Content/Conversation.php:779 #: src/Content/Conversation.php:790
#, php-format #, php-format
msgid "Sent via the relay server %s <%s>" msgid "Sent via the relay server %s <%s>"
msgstr "" msgstr ""
#: src/Content/Conversation.php:782 #: src/Content/Conversation.php:793
msgid "Fetched" msgid "Fetched"
msgstr "" msgstr ""
#: src/Content/Conversation.php:782 #: src/Content/Conversation.php:793
#, php-format #, php-format
msgid "Fetched because of %s <%s>" msgid "Fetched because of %s <%s>"
msgstr "" msgstr ""
#: src/Content/Conversation.php:785 #: src/Content/Conversation.php:796
msgid "Stored because of a child post to complete this thread." msgid "Stored because of a child post to complete this thread."
msgstr "" msgstr ""
#: src/Content/Conversation.php:788 #: src/Content/Conversation.php:799
msgid "Local delivery" msgid "Local delivery"
msgstr "" msgstr ""
#: src/Content/Conversation.php:791 #: src/Content/Conversation.php:802
msgid "Stored because of your activity (like, comment, star, ...)" msgid "Stored because of your activity (like, comment, star, ...)"
msgstr "" msgstr ""
#: src/Content/Conversation.php:794 #: src/Content/Conversation.php:805
msgid "Distributed" msgid "Distributed"
msgstr "" msgstr ""
#: src/Content/Conversation.php:797 #: src/Content/Conversation.php:808
msgid "Pushed to us" msgid "Pushed to us"
msgstr "" msgstr ""
#: src/Content/Conversation.php:1452 src/Object/Post.php:248 #: src/Content/Conversation.php:1471 src/Object/Post.php:249
msgid "Pinned item" msgid "Pinned item"
msgstr "" msgstr ""
#: src/Content/Conversation.php:1468 src/Object/Post.php:515 #: src/Content/Conversation.php:1488 src/Object/Post.php:522
#: src/Object/Post.php:516 #: src/Object/Post.php:523
#, php-format #, php-format
msgid "View %s's profile @ %s" msgid "View %s's profile @ %s"
msgstr "" msgstr ""
#: src/Content/Conversation.php:1481 src/Object/Post.php:503 #: src/Content/Conversation.php:1501 src/Object/Post.php:510
msgid "Categories:" msgid "Categories:"
msgstr "" msgstr ""
#: src/Content/Conversation.php:1482 src/Object/Post.php:504 #: src/Content/Conversation.php:1502 src/Object/Post.php:511
msgid "Filed under:" msgid "Filed under:"
msgstr "" msgstr ""
#: src/Content/Conversation.php:1490 src/Object/Post.php:529 #: src/Content/Conversation.php:1510 src/Object/Post.php:536
#, php-format #, php-format
msgid "%s from %s" msgid "%s from %s"
msgstr "" msgstr ""
#: src/Content/Conversation.php:1506 #: src/Content/Conversation.php:1526
msgid "View in context" msgid "View in context"
msgstr "" msgstr ""
@ -1629,88 +1642,93 @@ msgstr ""
msgid "Create new group" msgid "Create new group"
msgstr "" msgstr ""
#: src/Content/Item.php:329 src/Model/Item.php:2998 #: src/Content/Item.php:330 src/Model/Item.php:2998
msgid "event" msgid "event"
msgstr "" msgstr ""
#: src/Content/Item.php:332 src/Content/Item.php:342 #: src/Content/Item.php:333 src/Content/Item.php:343
msgid "status" msgid "status"
msgstr "" msgstr ""
#: src/Content/Item.php:338 src/Model/Item.php:3000 #: src/Content/Item.php:339 src/Model/Item.php:3000
#: src/Module/Post/Tag/Add.php:123 #: src/Module/Post/Tag/Add.php:123
msgid "photo" msgid "photo"
msgstr "" msgstr ""
#: src/Content/Item.php:352 src/Module/Post/Tag/Add.php:141 #: src/Content/Item.php:353 src/Module/Post/Tag/Add.php:141
#, php-format #, php-format
msgid "%1$s tagged %2$s's %3$s with %4$s" msgid "%1$s tagged %2$s's %3$s with %4$s"
msgstr "" msgstr ""
#: src/Content/Item.php:421 view/theme/frio/theme.php:262 #: src/Content/Item.php:426 view/theme/frio/theme.php:262
msgid "Follow Thread" msgid "Follow Thread"
msgstr "" msgstr ""
#: src/Content/Item.php:422 src/Model/Contact.php:1210 #: src/Content/Item.php:427 src/Model/Contact.php:1211
msgid "View Status" msgid "View Status"
msgstr "" msgstr ""
#: src/Content/Item.php:423 src/Content/Item.php:443 src/Model/Contact.php:1159 #: src/Content/Item.php:428 src/Content/Item.php:449 src/Model/Contact.php:1160
#: src/Model/Contact.php:1202 src/Model/Contact.php:1211 #: src/Model/Contact.php:1203 src/Model/Contact.php:1212
#: src/Module/Directory.php:157 src/Module/Settings/Profile/Index.php:259 #: src/Module/Directory.php:157 src/Module/Settings/Profile/Index.php:259
msgid "View Profile" msgid "View Profile"
msgstr "" msgstr ""
#: src/Content/Item.php:424 src/Model/Contact.php:1212 #: src/Content/Item.php:429 src/Model/Contact.php:1213
msgid "View Photos" msgid "View Photos"
msgstr "" msgstr ""
#: src/Content/Item.php:425 src/Model/Contact.php:1203 #: src/Content/Item.php:430 src/Model/Contact.php:1204
#: src/Model/Contact.php:1213 #: src/Model/Contact.php:1214
msgid "Network Posts" msgid "Network Posts"
msgstr "" msgstr ""
#: src/Content/Item.php:426 src/Model/Contact.php:1204 #: src/Content/Item.php:431 src/Model/Contact.php:1205
#: src/Model/Contact.php:1214 #: src/Model/Contact.php:1215
msgid "View Contact" msgid "View Contact"
msgstr "" msgstr ""
#: src/Content/Item.php:427 src/Model/Contact.php:1215 #: src/Content/Item.php:432 src/Model/Contact.php:1216
msgid "Send PM" msgid "Send PM"
msgstr "" msgstr ""
#: src/Content/Item.php:428 src/Module/Contact.php:468 #: src/Content/Item.php:433 src/Module/Contact.php:468
#: src/Module/Contact/Profile.php:477 #: src/Module/Contact/Profile.php:492
#: src/Module/Moderation/Blocklist/Contact.php:116 #: src/Module/Moderation/Blocklist/Contact.php:116
#: src/Module/Moderation/Users/Active.php:137 #: src/Module/Moderation/Users/Active.php:137
#: src/Module/Moderation/Users/Index.php:152 #: src/Module/Moderation/Users/Index.php:152
msgid "Block" msgid "Block"
msgstr "" msgstr ""
#: src/Content/Item.php:429 src/Module/Contact.php:469 #: src/Content/Item.php:434 src/Module/Contact.php:469
#: src/Module/Contact/Profile.php:485 #: src/Module/Contact/Profile.php:500
#: src/Module/Notifications/Introductions.php:134 #: src/Module/Notifications/Introductions.php:134
#: src/Module/Notifications/Introductions.php:206 #: src/Module/Notifications/Introductions.php:206
#: src/Module/Notifications/Notification.php:89 #: src/Module/Notifications/Notification.php:89
msgid "Ignore" msgid "Ignore"
msgstr "" msgstr ""
#: src/Content/Item.php:430 src/Module/Contact.php:470 #: src/Content/Item.php:435 src/Module/Contact.php:470
#: src/Module/Contact/Profile.php:493 #: src/Module/Contact/Profile.php:508
msgid "Collapse" msgid "Collapse"
msgstr "" msgstr ""
#: src/Content/Item.php:434 src/Object/Post.php:484 #: src/Content/Item.php:436 src/Object/Post.php:289
#, php-format
msgid "Ignore %s's server"
msgstr ""
#: src/Content/Item.php:440 src/Object/Post.php:491
msgid "Languages" msgid "Languages"
msgstr "" msgstr ""
#: src/Content/Item.php:440 src/Content/Widget.php:80 #: src/Content/Item.php:446 src/Content/Widget.php:80
#: src/Model/Contact.php:1205 src/Model/Contact.php:1216 #: src/Model/Contact.php:1206 src/Model/Contact.php:1217
#: src/Module/Contact/Follow.php:167 view/theme/vier/theme.php:195 #: src/Module/Contact/Follow.php:167 view/theme/vier/theme.php:195
msgid "Connect/Follow" msgid "Connect/Follow"
msgstr "" msgstr ""
#: src/Content/Item.php:874 #: src/Content/Item.php:880
msgid "Unable to fetch user." msgid "Unable to fetch user."
msgstr "" msgstr ""
@ -1758,7 +1776,7 @@ msgstr ""
#: src/Content/Nav.php:228 src/Module/BaseProfile.php:49 #: src/Content/Nav.php:228 src/Module/BaseProfile.php:49
#: src/Module/BaseSettings.php:100 src/Module/Contact.php:504 #: src/Module/BaseSettings.php:100 src/Module/Contact.php:504
#: src/Module/Contact/Profile.php:392 src/Module/Profile/Profile.php:268 #: src/Module/Contact/Profile.php:407 src/Module/Profile/Profile.php:268
#: src/Module/Welcome.php:57 view/theme/frio/theme.php:230 #: src/Module/Welcome.php:57 view/theme/frio/theme.php:230
msgid "Profile" msgid "Profile"
msgstr "" msgstr ""
@ -1961,7 +1979,7 @@ msgid "Manage other pages"
msgstr "" msgstr ""
#: src/Content/Nav.php:325 src/Module/Admin/Addons/Details.php:114 #: src/Content/Nav.php:325 src/Module/Admin/Addons/Details.php:114
#: src/Module/Admin/Themes/Details.php:93 src/Module/BaseSettings.php:170 #: src/Module/Admin/Themes/Details.php:93 src/Module/BaseSettings.php:177
#: src/Module/Welcome.php:52 view/theme/frio/theme.php:242 #: src/Module/Welcome.php:52 view/theme/frio/theme.php:242
msgid "Settings" msgid "Settings"
msgstr "" msgstr ""
@ -2077,7 +2095,7 @@ msgid "The end"
msgstr "" msgstr ""
#: src/Content/Text/HTML.php:859 src/Content/Widget/VCard.php:116 #: src/Content/Text/HTML.php:859 src/Content/Widget/VCard.php:116
#: src/Model/Profile.php:461 src/Module/Contact/Profile.php:437 #: src/Model/Profile.php:461 src/Module/Contact/Profile.php:452
msgid "Follow" msgid "Follow"
msgstr "" msgstr ""
@ -2212,7 +2230,7 @@ msgstr ""
msgid "Organisations" msgid "Organisations"
msgstr "" msgstr ""
#: src/Content/Widget.php:536 src/Model/Contact.php:1680 #: src/Content/Widget.php:536 src/Model/Contact.php:1681
msgid "News" msgid "News"
msgstr "" msgstr ""
@ -2271,18 +2289,18 @@ msgid "More Trending Tags"
msgstr "" msgstr ""
#: src/Content/Widget/VCard.php:109 src/Model/Profile.php:376 #: src/Content/Widget/VCard.php:109 src/Model/Profile.php:376
#: src/Module/Contact/Profile.php:381 src/Module/Profile/Profile.php:199 #: src/Module/Contact/Profile.php:396 src/Module/Profile/Profile.php:199
msgid "XMPP:" msgid "XMPP:"
msgstr "" msgstr ""
#: src/Content/Widget/VCard.php:110 src/Model/Profile.php:377 #: src/Content/Widget/VCard.php:110 src/Model/Profile.php:377
#: src/Module/Contact/Profile.php:383 src/Module/Profile/Profile.php:203 #: src/Module/Contact/Profile.php:398 src/Module/Profile/Profile.php:203
msgid "Matrix:" msgid "Matrix:"
msgstr "" msgstr ""
#: src/Content/Widget/VCard.php:111 src/Model/Event.php:82 #: src/Content/Widget/VCard.php:111 src/Model/Event.php:82
#: src/Model/Event.php:109 src/Model/Event.php:471 src/Model/Event.php:963 #: src/Model/Event.php:109 src/Model/Event.php:471 src/Model/Event.php:963
#: src/Model/Profile.php:371 src/Module/Contact/Profile.php:379 #: src/Model/Profile.php:371 src/Module/Contact/Profile.php:394
#: src/Module/Directory.php:147 src/Module/Notifications/Introductions.php:187 #: src/Module/Directory.php:147 src/Module/Notifications/Introductions.php:187
#: src/Module/Profile/Profile.php:221 #: src/Module/Profile/Profile.php:221
msgid "Location:" msgid "Location:"
@ -2293,9 +2311,9 @@ msgstr ""
msgid "Network:" msgid "Network:"
msgstr "" msgstr ""
#: src/Content/Widget/VCard.php:118 src/Model/Contact.php:1206 #: src/Content/Widget/VCard.php:118 src/Model/Contact.php:1207
#: src/Model/Contact.php:1217 src/Model/Profile.php:463 #: src/Model/Contact.php:1218 src/Model/Profile.php:463
#: src/Module/Contact/Profile.php:429 #: src/Module/Contact/Profile.php:444
msgid "Unfollow" msgid "Unfollow"
msgstr "" msgstr ""
@ -2559,8 +2577,8 @@ msgstr ""
#: src/Core/Installer.php:511 #: src/Core/Installer.php:511
msgid "" msgid ""
"The web installer needs to be able to create a file called \"local.config.php" "The web installer needs to be able to create a file called \"local.config."
"\" in the \"config\" folder of your web server and it is unable to do so." "php\" in the \"config\" folder of your web server and it is unable to do so."
msgstr "" msgstr ""
#: src/Core/Installer.php:512 #: src/Core/Installer.php:512
@ -3047,82 +3065,82 @@ msgstr ""
msgid "Edit circles" msgid "Edit circles"
msgstr "" msgstr ""
#: src/Model/Contact.php:1223 src/Module/Moderation/Users/Pending.php:102 #: src/Model/Contact.php:1224 src/Module/Moderation/Users/Pending.php:102
#: src/Module/Notifications/Introductions.php:132 #: src/Module/Notifications/Introductions.php:132
#: src/Module/Notifications/Introductions.php:204 #: src/Module/Notifications/Introductions.php:204
msgid "Approve" msgid "Approve"
msgstr "" msgstr ""
#: src/Model/Contact.php:1676 #: src/Model/Contact.php:1677
msgid "Organisation" msgid "Organisation"
msgstr "" msgstr ""
#: src/Model/Contact.php:1684 #: src/Model/Contact.php:1685
msgid "Group" msgid "Group"
msgstr "" msgstr ""
#: src/Model/Contact.php:2993 #: src/Model/Contact.php:2988
msgid "Disallowed profile URL." msgid "Disallowed profile URL."
msgstr "" msgstr ""
#: src/Model/Contact.php:2998 src/Module/Friendica.php:102 #: src/Model/Contact.php:2993 src/Module/Friendica.php:101
msgid "Blocked domain" msgid "Blocked domain"
msgstr "" msgstr ""
#: src/Model/Contact.php:3003 #: src/Model/Contact.php:2998
msgid "Connect URL missing." msgid "Connect URL missing."
msgstr "" msgstr ""
#: src/Model/Contact.php:3012 #: src/Model/Contact.php:3007
msgid "" msgid ""
"The contact could not be added. Please check the relevant network " "The contact could not be added. Please check the relevant network "
"credentials in your Settings -> Social Networks page." "credentials in your Settings -> Social Networks page."
msgstr "" msgstr ""
#: src/Model/Contact.php:3030 #: src/Model/Contact.php:3025
#, php-format #, php-format
msgid "Expected network %s does not match actual network %s" msgid "Expected network %s does not match actual network %s"
msgstr "" msgstr ""
#: src/Model/Contact.php:3047 #: src/Model/Contact.php:3042
msgid "The profile address specified does not provide adequate information." msgid "The profile address specified does not provide adequate information."
msgstr "" msgstr ""
#: src/Model/Contact.php:3049 #: src/Model/Contact.php:3044
msgid "No compatible communication protocols or feeds were discovered." msgid "No compatible communication protocols or feeds were discovered."
msgstr "" msgstr ""
#: src/Model/Contact.php:3052 #: src/Model/Contact.php:3047
msgid "An author or name was not found." msgid "An author or name was not found."
msgstr "" msgstr ""
#: src/Model/Contact.php:3055 #: src/Model/Contact.php:3050
msgid "No browser URL could be matched to this address." msgid "No browser URL could be matched to this address."
msgstr "" msgstr ""
#: src/Model/Contact.php:3058 #: src/Model/Contact.php:3053
msgid "" msgid ""
"Unable to match @-style Identity Address with a known protocol or email " "Unable to match @-style Identity Address with a known protocol or email "
"contact." "contact."
msgstr "" msgstr ""
#: src/Model/Contact.php:3059 #: src/Model/Contact.php:3054
msgid "Use mailto: in front of address to force email check." msgid "Use mailto: in front of address to force email check."
msgstr "" msgstr ""
#: src/Model/Contact.php:3065 #: src/Model/Contact.php:3060
msgid "" msgid ""
"The profile address specified belongs to a network which has been disabled " "The profile address specified belongs to a network which has been disabled "
"on this site." "on this site."
msgstr "" msgstr ""
#: src/Model/Contact.php:3070 #: src/Model/Contact.php:3065
msgid "" msgid ""
"Limited profile. This person will be unable to receive direct/personal " "Limited profile. This person will be unable to receive direct/personal "
"notifications from you." "notifications from you."
msgstr "" msgstr ""
#: src/Model/Contact.php:3136 #: src/Model/Contact.php:3131
msgid "Unable to retrieve contact information." msgid "Unable to retrieve contact information."
msgstr "" msgstr ""
@ -3327,7 +3345,7 @@ msgstr ""
msgid "Homepage:" msgid "Homepage:"
msgstr "" msgstr ""
#: src/Model/Profile.php:375 src/Module/Contact/Profile.php:385 #: src/Model/Profile.php:375 src/Module/Contact/Profile.php:400
#: src/Module/Notifications/Introductions.php:189 #: src/Module/Notifications/Introductions.php:189
msgid "About:" msgid "About:"
msgstr "" msgstr ""
@ -5039,7 +5057,7 @@ msgid ""
"received." "received."
msgstr "" msgstr ""
#: src/Module/Admin/Site.php:513 src/Module/Contact/Profile.php:286 #: src/Module/Admin/Site.php:513 src/Module/Contact/Profile.php:299
#: src/Module/Settings/TwoFactor/Index.php:125 #: src/Module/Settings/TwoFactor/Index.php:125
msgid "Disabled" msgid "Disabled"
msgstr "" msgstr ""
@ -5185,9 +5203,9 @@ msgstr ""
#: src/Module/Admin/Summary.php:98 #: src/Module/Admin/Summary.php:98
msgid "" msgid ""
"The last update failed. Please run \"php bin/console.php dbstructure update" "The last update failed. Please run \"php bin/console.php dbstructure "
"\" from the command line and have a look at the errors that might appear. " "update\" from the command line and have a look at the errors that might "
"(Some of the errors are possibly inside the logfile.)" "appear. (Some of the errors are possibly inside the logfile.)"
msgstr "" msgstr ""
#: src/Module/Admin/Summary.php:102 #: src/Module/Admin/Summary.php:102
@ -5338,8 +5356,8 @@ msgstr ""
#, php-format #, php-format
msgid "" msgid ""
"Show some informations regarding the needed information to operate the node " "Show some informations regarding the needed information to operate the node "
"according e.g. to <a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer" "according e.g. to <a href=\"%s\" target=\"_blank\" rel=\"noopener "
"\">EU-GDPR</a>." "noreferrer\">EU-GDPR</a>."
msgstr "" msgstr ""
#: src/Module/Admin/Tos.php:81 #: src/Module/Admin/Tos.php:81
@ -5628,11 +5646,15 @@ msgstr ""
msgid "Connected apps" msgid "Connected apps"
msgstr "" msgstr ""
#: src/Module/BaseSettings.php:155 src/Module/Settings/UserExport.php:98 #: src/Module/BaseSettings.php:155
msgid "Remote servers"
msgstr ""
#: src/Module/BaseSettings.php:162 src/Module/Settings/UserExport.php:98
msgid "Export personal data" msgid "Export personal data"
msgstr "" msgstr ""
#: src/Module/BaseSettings.php:162 #: src/Module/BaseSettings.php:169
msgid "Remove account" msgid "Remove account"
msgstr "" msgstr ""
@ -5778,8 +5800,8 @@ msgstr ""
#: src/Module/Contact/Conversations.php:89 #: src/Module/Contact/Conversations.php:89
#: src/Module/Contact/Conversations.php:94 src/Module/Contact/Media.php:43 #: src/Module/Contact/Conversations.php:94 src/Module/Contact/Media.php:43
#: src/Module/Contact/Posts.php:78 src/Module/Contact/Posts.php:83 #: src/Module/Contact/Posts.php:78 src/Module/Contact/Posts.php:83
#: src/Module/Contact/Posts.php:88 src/Module/Contact/Profile.php:142 #: src/Module/Contact/Posts.php:88 src/Module/Contact/Profile.php:150
#: src/Module/Contact/Profile.php:147 src/Module/Contact/Profile.php:152 #: src/Module/Contact/Profile.php:155 src/Module/Contact/Profile.php:160
#: src/Module/Contact/Redir.php:94 src/Module/Contact/Redir.php:140 #: src/Module/Contact/Redir.php:94 src/Module/Contact/Redir.php:140
#: src/Module/FriendSuggest.php:71 src/Module/FriendSuggest.php:109 #: src/Module/FriendSuggest.php:71 src/Module/FriendSuggest.php:109
msgid "Contact not found." msgid "Contact not found."
@ -5888,7 +5910,7 @@ msgid "Only show blocked contacts"
msgstr "" msgstr ""
#: src/Module/Contact.php:369 src/Module/Contact.php:441 #: src/Module/Contact.php:369 src/Module/Contact.php:441
#: src/Object/Post.php:362 #: src/Module/Settings/Server/Index.php:107 src/Object/Post.php:369
msgid "Ignored" msgid "Ignored"
msgstr "" msgstr ""
@ -5937,18 +5959,18 @@ msgstr ""
msgid "Update" msgid "Update"
msgstr "" msgstr ""
#: src/Module/Contact.php:468 src/Module/Contact/Profile.php:477 #: src/Module/Contact.php:468 src/Module/Contact/Profile.php:492
#: src/Module/Moderation/Blocklist/Contact.php:117 #: src/Module/Moderation/Blocklist/Contact.php:117
#: src/Module/Moderation/Users/Blocked.php:138 #: src/Module/Moderation/Users/Blocked.php:138
#: src/Module/Moderation/Users/Index.php:154 #: src/Module/Moderation/Users/Index.php:154
msgid "Unblock" msgid "Unblock"
msgstr "" msgstr ""
#: src/Module/Contact.php:469 src/Module/Contact/Profile.php:485 #: src/Module/Contact.php:469 src/Module/Contact/Profile.php:500
msgid "Unignore" msgid "Unignore"
msgstr "" msgstr ""
#: src/Module/Contact.php:470 src/Module/Contact/Profile.php:493 #: src/Module/Contact.php:470 src/Module/Contact/Profile.php:508
msgid "Uncollapse" msgid "Uncollapse"
msgstr "" msgstr ""
@ -6000,7 +6022,7 @@ msgstr ""
msgid "Pending incoming contact request" msgid "Pending incoming contact request"
msgstr "" msgstr ""
#: src/Module/Contact.php:627 src/Module/Contact/Profile.php:346 #: src/Module/Contact.php:627 src/Module/Contact/Profile.php:359
#, php-format #, php-format
msgid "Visit %s's profile [%s]" msgid "Visit %s's profile [%s]"
msgstr "" msgstr ""
@ -6135,7 +6157,7 @@ msgstr ""
msgid "Your Identity Address:" msgid "Your Identity Address:"
msgstr "" msgstr ""
#: src/Module/Contact/Follow.php:170 src/Module/Contact/Profile.php:375 #: src/Module/Contact/Follow.php:170 src/Module/Contact/Profile.php:390
#: src/Module/Contact/Unfollow.php:129 #: src/Module/Contact/Unfollow.php:129
#: src/Module/Moderation/Blocklist/Contact.php:133 #: src/Module/Moderation/Blocklist/Contact.php:133
#: src/Module/Notifications/Introductions.php:129 #: src/Module/Notifications/Introductions.php:129
@ -6143,7 +6165,7 @@ msgstr ""
msgid "Profile URL" msgid "Profile URL"
msgstr "" msgstr ""
#: src/Module/Contact/Follow.php:171 src/Module/Contact/Profile.php:387 #: src/Module/Contact/Follow.php:171 src/Module/Contact/Profile.php:402
#: src/Module/Notifications/Introductions.php:191 #: src/Module/Notifications/Introductions.php:191
#: src/Module/Profile/Profile.php:234 #: src/Module/Profile/Profile.php:234
msgid "Tags:" msgid "Tags:"
@ -6182,249 +6204,257 @@ msgstr ""
msgid "Profile Match" msgid "Profile Match"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:128 #: src/Module/Contact/Profile.php:136
msgid "Failed to update contact record." msgid "Failed to update contact record."
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:178 #: src/Module/Contact/Profile.php:186
msgid "Contact has been unblocked" msgid "Contact has been unblocked"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:182 #: src/Module/Contact/Profile.php:190
msgid "Contact has been blocked" msgid "Contact has been blocked"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:194 #: src/Module/Contact/Profile.php:202
msgid "Contact has been unignored" msgid "Contact has been unignored"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:198 #: src/Module/Contact/Profile.php:206
msgid "Contact has been ignored" msgid "Contact has been ignored"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:210 #: src/Module/Contact/Profile.php:218
msgid "Contact has been uncollapsed" msgid "Contact has been uncollapsed"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:214 #: src/Module/Contact/Profile.php:222
msgid "Contact has been collapsed" msgid "Contact has been collapsed"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:242 #: src/Module/Contact/Profile.php:250
#, php-format #, php-format
msgid "You are mutual friends with %s" msgid "You are mutual friends with %s"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:243 #: src/Module/Contact/Profile.php:251
#, php-format #, php-format
msgid "You are sharing with %s" msgid "You are sharing with %s"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:244 #: src/Module/Contact/Profile.php:252
#, php-format #, php-format
msgid "%s is sharing with you" msgid "%s is sharing with you"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:260 #: src/Module/Contact/Profile.php:268
msgid "Private communications are not available for this contact." msgid "Private communications are not available for this contact."
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:262 #: src/Module/Contact/Profile.php:272
msgid "This contact is on a server you ignored."
msgstr ""
#: src/Module/Contact/Profile.php:275
msgid "Never" msgid "Never"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:265 #: src/Module/Contact/Profile.php:278
msgid "(Update was not successful)" msgid "(Update was not successful)"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:265 #: src/Module/Contact/Profile.php:278
msgid "(Update was successful)" msgid "(Update was successful)"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:267 src/Module/Contact/Profile.php:448 #: src/Module/Contact/Profile.php:280 src/Module/Contact/Profile.php:463
msgid "Suggest friends" msgid "Suggest friends"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:271 #: src/Module/Contact/Profile.php:284
#, php-format #, php-format
msgid "Network type: %s" msgid "Network type: %s"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:276 #: src/Module/Contact/Profile.php:289
msgid "Communications lost with this contact!" msgid "Communications lost with this contact!"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:282 #: src/Module/Contact/Profile.php:295
msgid "Fetch further information for feeds" msgid "Fetch further information for feeds"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:284 #: src/Module/Contact/Profile.php:297
msgid "" msgid ""
"Fetch information like preview pictures, title and teaser from the feed " "Fetch information like preview pictures, title and teaser from the feed "
"item. You can activate this if the feed doesn't contain much text. Keywords " "item. You can activate this if the feed doesn't contain much text. Keywords "
"are taken from the meta header in the feed item and are posted as hash tags." "are taken from the meta header in the feed item and are posted as hash tags."
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:287 #: src/Module/Contact/Profile.php:300
msgid "Fetch information" msgid "Fetch information"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:288 #: src/Module/Contact/Profile.php:301
msgid "Fetch keywords" msgid "Fetch keywords"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:289 #: src/Module/Contact/Profile.php:302
msgid "Fetch information and keywords" msgid "Fetch information and keywords"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:299 src/Module/Contact/Profile.php:304 #: src/Module/Contact/Profile.php:312 src/Module/Contact/Profile.php:317
#: src/Module/Contact/Profile.php:309 src/Module/Contact/Profile.php:315 #: src/Module/Contact/Profile.php:322 src/Module/Contact/Profile.php:328
msgid "No mirroring" msgid "No mirroring"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:300 src/Module/Contact/Profile.php:310 #: src/Module/Contact/Profile.php:313 src/Module/Contact/Profile.php:323
#: src/Module/Contact/Profile.php:316 #: src/Module/Contact/Profile.php:329
msgid "Mirror as my own posting" msgid "Mirror as my own posting"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:305 src/Module/Contact/Profile.php:311 #: src/Module/Contact/Profile.php:318 src/Module/Contact/Profile.php:324
msgid "Native reshare" msgid "Native reshare"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:328 #: src/Module/Contact/Profile.php:341
msgid "Contact Information / Notes" msgid "Contact Information / Notes"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:329 #: src/Module/Contact/Profile.php:342
msgid "Contact Settings" msgid "Contact Settings"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:337 #: src/Module/Contact/Profile.php:350
msgid "Contact" msgid "Contact"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:341 #: src/Module/Contact/Profile.php:354
msgid "Their personal note" msgid "Their personal note"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:343 #: src/Module/Contact/Profile.php:356
msgid "Edit contact notes" msgid "Edit contact notes"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:347 #: src/Module/Contact/Profile.php:360
msgid "Block/Unblock contact" msgid "Block/Unblock contact"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:348 #: src/Module/Contact/Profile.php:361
#: src/Module/Moderation/Report/Create.php:293 #: src/Module/Moderation/Report/Create.php:293
msgid "Ignore contact" msgid "Ignore contact"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:349 #: src/Module/Contact/Profile.php:362
msgid "View conversations" msgid "View conversations"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:354 #: src/Module/Contact/Profile.php:367
msgid "Last update:" msgid "Last update:"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:356 #: src/Module/Contact/Profile.php:369
msgid "Update public posts" msgid "Update public posts"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:358 src/Module/Contact/Profile.php:458 #: src/Module/Contact/Profile.php:371 src/Module/Contact/Profile.php:473
msgid "Update now" msgid "Update now"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:360 #: src/Module/Contact/Profile.php:373
msgid "Awaiting connection acknowledge" msgid "Awaiting connection acknowledge"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:361 #: src/Module/Contact/Profile.php:374
msgid "Currently blocked" msgid "Currently blocked"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:362 #: src/Module/Contact/Profile.php:375
msgid "Currently ignored" msgid "Currently ignored"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:363 #: src/Module/Contact/Profile.php:376
msgid "Currently collapsed" msgid "Currently collapsed"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:364 #: src/Module/Contact/Profile.php:377
msgid "Currently archived" msgid "Currently archived"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:367 #: src/Module/Contact/Profile.php:380
msgid "Manage remote servers"
msgstr ""
#: src/Module/Contact/Profile.php:382
#: src/Module/Notifications/Introductions.php:192 #: src/Module/Notifications/Introductions.php:192
msgid "Hide this contact from others" msgid "Hide this contact from others"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:367 #: src/Module/Contact/Profile.php:382
msgid "" msgid ""
"Replies/likes to your public posts <strong>may</strong> still be visible" "Replies/likes to your public posts <strong>may</strong> still be visible"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:368 #: src/Module/Contact/Profile.php:383
msgid "Notification for new posts" msgid "Notification for new posts"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:368 #: src/Module/Contact/Profile.php:383
msgid "Send a notification of every new post of this contact" msgid "Send a notification of every new post of this contact"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:370 #: src/Module/Contact/Profile.php:385
msgid "Keyword Deny List" msgid "Keyword Deny List"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:370 #: src/Module/Contact/Profile.php:385
msgid "" msgid ""
"Comma separated list of keywords that should not be converted to hashtags, " "Comma separated list of keywords that should not be converted to hashtags, "
"when \"Fetch information and keywords\" is selected" "when \"Fetch information and keywords\" is selected"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:388 #: src/Module/Contact/Profile.php:403
#: src/Module/Settings/TwoFactor/Index.php:139 #: src/Module/Settings/TwoFactor/Index.php:139
msgid "Actions" msgid "Actions"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:390 #: src/Module/Contact/Profile.php:405
#: src/Module/Settings/TwoFactor/Index.php:119 view/theme/frio/theme.php:229 #: src/Module/Settings/TwoFactor/Index.php:119 view/theme/frio/theme.php:229
msgid "Status" msgid "Status"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:396 #: src/Module/Contact/Profile.php:411
msgid "Mirror postings from this contact" msgid "Mirror postings from this contact"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:398 #: src/Module/Contact/Profile.php:413
msgid "" msgid ""
"Mark this contact as remote_self, this will cause friendica to repost new " "Mark this contact as remote_self, this will cause friendica to repost new "
"entries from this contact." "entries from this contact."
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:468 #: src/Module/Contact/Profile.php:483
msgid "Refetch contact data" msgid "Refetch contact data"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:479 #: src/Module/Contact/Profile.php:494
msgid "Toggle Blocked status" msgid "Toggle Blocked status"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:487 #: src/Module/Contact/Profile.php:502
msgid "Toggle Ignored status" msgid "Toggle Ignored status"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:495 #: src/Module/Contact/Profile.php:510
msgid "Toggle Collapsed status" msgid "Toggle Collapsed status"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:502 src/Module/Contact/Revoke.php:106 #: src/Module/Contact/Profile.php:517 src/Module/Contact/Revoke.php:106
msgid "Revoke Follow" msgid "Revoke Follow"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:504 #: src/Module/Contact/Profile.php:519
msgid "Revoke the follow from this contact" msgid "Revoke the follow from this contact"
msgstr "" msgstr ""
@ -6572,7 +6602,7 @@ msgstr ""
msgid "Posts that mention or involve you" msgid "Posts that mention or involve you"
msgstr "" msgstr ""
#: src/Module/Conversation/Network.php:289 src/Object/Post.php:374 #: src/Module/Conversation/Network.php:289 src/Object/Post.php:381
msgid "Starred" msgid "Starred"
msgstr "" msgstr ""
@ -6938,42 +6968,42 @@ msgstr ""
msgid "Read about the <a href=\"%1$s/tos\">Terms of Service</a> of this node." msgid "Read about the <a href=\"%1$s/tos\">Terms of Service</a> of this node."
msgstr "" msgstr ""
#: src/Module/Friendica.php:100 #: src/Module/Friendica.php:99
msgid "On this server the following remote servers are blocked." msgid "On this server the following remote servers are blocked."
msgstr "" msgstr ""
#: src/Module/Friendica.php:103 #: src/Module/Friendica.php:102
#: src/Module/Moderation/Blocklist/Server/Index.php:87 #: src/Module/Moderation/Blocklist/Server/Index.php:87
#: src/Module/Moderation/Blocklist/Server/Index.php:111 #: src/Module/Moderation/Blocklist/Server/Index.php:111
msgid "Reason for the block" msgid "Reason for the block"
msgstr "" msgstr ""
#: src/Module/Friendica.php:105 #: src/Module/Friendica.php:104
msgid "Download this list in CSV format" msgid "Download this list in CSV format"
msgstr "" msgstr ""
#: src/Module/Friendica.php:119 #: src/Module/Friendica.php:118
#, php-format #, php-format
msgid "" msgid ""
"This is Friendica, version %s that is running at the web location %s. The " "This is Friendica, version %s that is running at the web location %s. The "
"database version is %s, the post update version is %s." "database version is %s, the post update version is %s."
msgstr "" msgstr ""
#: src/Module/Friendica.php:124 #: src/Module/Friendica.php:123
msgid "" msgid ""
"Please visit <a href=\"https://friendi.ca\">Friendi.ca</a> to learn more " "Please visit <a href=\"https://friendi.ca\">Friendi.ca</a> to learn more "
"about the Friendica project." "about the Friendica project."
msgstr "" msgstr ""
#: src/Module/Friendica.php:125 #: src/Module/Friendica.php:124
msgid "Bug reports and issues: please visit" msgid "Bug reports and issues: please visit"
msgstr "" msgstr ""
#: src/Module/Friendica.php:125 #: src/Module/Friendica.php:124
msgid "the bugtracker at github" msgid "the bugtracker at github"
msgstr "" msgstr ""
#: src/Module/Friendica.php:126 #: src/Module/Friendica.php:125
msgid "" msgid ""
"Suggestions, praise, etc. - please email \"info\" at \"friendi - dot - ca" "Suggestions, praise, etc. - please email \"info\" at \"friendi - dot - ca"
msgstr "" msgstr ""
@ -7288,10 +7318,6 @@ msgid ""
"<a href=\"/settings/display\">Theme Customization settings</a>." "<a href=\"/settings/display\">Theme Customization settings</a>."
msgstr "" msgstr ""
#: src/Module/Item/Display.php:136 src/Module/Update/Display.php:55
msgid "The requested item doesn't exist or has been deleted."
msgstr ""
#: src/Module/Item/Feed.php:86 #: src/Module/Item/Feed.php:86
msgid "The feed for this item is unavailable." msgid "The feed for this item is unavailable."
msgstr "" msgstr ""
@ -7550,6 +7576,8 @@ msgid "Matching known servers"
msgstr "" msgstr ""
#: src/Module/Moderation/Blocklist/Server/Add.php:130 #: src/Module/Moderation/Blocklist/Server/Add.php:130
#: src/Module/Settings/Server/Action.php:76
#: src/Module/Settings/Server/Index.php:106
msgid "Server Name" msgid "Server Name"
msgstr "" msgstr ""
@ -8520,21 +8548,21 @@ msgstr ""
msgid "<b>Attributed To:</b> %s<br>" msgid "<b>Attributed To:</b> %s<br>"
msgstr "" msgstr ""
#: src/Module/Photo.php:129 #: src/Module/Photo.php:130
msgid "The Photo is not available." msgid "The Photo is not available."
msgstr "" msgstr ""
#: src/Module/Photo.php:154 #: src/Module/Photo.php:155
#, php-format #, php-format
msgid "The Photo with id %s is not available." msgid "The Photo with id %s is not available."
msgstr "" msgstr ""
#: src/Module/Photo.php:191 #: src/Module/Photo.php:192
#, php-format #, php-format
msgid "Invalid external resource with url %s." msgid "Invalid external resource with url %s."
msgstr "" msgstr ""
#: src/Module/Photo.php:193 #: src/Module/Photo.php:194
#, php-format #, php-format
msgid "Invalid photo with id %s." msgid "Invalid photo with id %s."
msgstr "" msgstr ""
@ -8640,8 +8668,8 @@ msgstr ""
#: src/Module/Profile/Profile.php:158 #: src/Module/Profile/Profile.php:158
#, php-format #, php-format
msgid "" msgid ""
"You're currently viewing your profile as <b>%s</b> <a href=\"%s\" class=" "You're currently viewing your profile as <b>%s</b> <a href=\"%s\" "
"\"btn btn-sm pull-right\">Cancel</a>" "class=\"btn btn-sm pull-right\">Cancel</a>"
msgstr "" msgstr ""
#: src/Module/Profile/Profile.php:167 #: src/Module/Profile/Profile.php:167
@ -9189,8 +9217,8 @@ msgstr ""
#: src/Module/Security/TwoFactor/Verify.php:100 #: src/Module/Security/TwoFactor/Verify.php:100
#, php-format #, php-format
msgid "" msgid ""
"If you do not have access to your authentication code you can use a <a href=" "If you do not have access to your authentication code you can use a <a "
"\"%s\">two-factor recovery code</a>." "href=\"%s\">two-factor recovery code</a>."
msgstr "" msgstr ""
#: src/Module/Security/TwoFactor/Verify.php:101 #: src/Module/Security/TwoFactor/Verify.php:101
@ -10387,6 +10415,42 @@ msgstr ""
msgid "Please enter your password for verification:" msgid "Please enter your password for verification:"
msgstr "" msgstr ""
#: src/Module/Settings/Server/Action.php:60
msgid "Do you want to ignore this server?"
msgstr ""
#: src/Module/Settings/Server/Action.php:64
msgid "Do you want to unignore this server?"
msgstr ""
#: src/Module/Settings/Server/Action.php:74
#: src/Module/Settings/Server/Index.php:104
msgid "Remote server settings"
msgstr ""
#: src/Module/Settings/Server/Action.php:77
msgid "Server URL"
msgstr ""
#: src/Module/Settings/Server/Index.php:78
msgid "Settings saved"
msgstr ""
#: src/Module/Settings/Server/Index.php:105
msgid ""
"Here you can find all the remote servers you have taken individual "
"moderation actions against. For a list of servers your node has blocked, "
"please check out the <a href=\"friendica\">Information</a> page."
msgstr ""
#: src/Module/Settings/Server/Index.php:110
msgid "Delete all your settings for the remote server"
msgstr ""
#: src/Module/Settings/Server/Index.php:111
msgid "Save changes"
msgstr ""
#: src/Module/Settings/TwoFactor/AppSpecific.php:66 #: src/Module/Settings/TwoFactor/AppSpecific.php:66
#: src/Module/Settings/TwoFactor/Recovery.php:64 #: src/Module/Settings/TwoFactor/Recovery.php:64
#: src/Module/Settings/TwoFactor/Trusted.php:67 #: src/Module/Settings/TwoFactor/Trusted.php:67
@ -10668,8 +10732,8 @@ msgstr ""
#: src/Module/Settings/TwoFactor/Verify.php:149 #: src/Module/Settings/TwoFactor/Verify.php:149
#, php-format #, php-format
msgid "" msgid ""
"<p>Or you can open the following URL in your mobile device:</p><p><a href=" "<p>Or you can open the following URL in your mobile device:</p><p><a "
"\"%s\">%s</a></p>" "href=\"%s\">%s</a></p>"
msgstr "" msgstr ""
#: src/Module/Settings/TwoFactor/Verify.php:156 #: src/Module/Settings/TwoFactor/Verify.php:156
@ -10707,22 +10771,41 @@ msgid ""
"e.g. Mastodon." "e.g. Mastodon."
msgstr "" msgstr ""
#: src/Module/Special/DisplayNotFound.php:35
msgid "The top-level post isn't visible."
msgstr ""
#: src/Module/Special/DisplayNotFound.php:36
msgid "The top-level post was deleted."
msgstr ""
#: src/Module/Special/DisplayNotFound.php:37 #: src/Module/Special/DisplayNotFound.php:37
msgid "Not Found" msgid ""
"This node has blocked the top-level author or the author of the shared post."
msgstr "" msgstr ""
#: src/Module/Special/DisplayNotFound.php:38 #: src/Module/Special/DisplayNotFound.php:38
msgid "" msgid ""
"<p>Unfortunately, the requested conversation isn't available to you.</p>\n" "You have ignored or blocked the top-level author or the author of the shared "
"<p>Possible reasons include:</p>\n" "post."
"<ul>\n" msgstr ""
"\t<li>The top-level post isn't visible.</li>\n"
"\t<li>The top-level post was deleted.</li>\n" #: src/Module/Special/DisplayNotFound.php:39
"\t<li>The node has blocked the top-level author or the author of the shared " msgid ""
"post.</li>\n" "You have ignored the top-level author's server or the shared post author's "
"\t<li>You have ignored or blocked the top-level author or the author of the " "server."
"shared post.</li>\n" msgstr ""
"</ul>"
#: src/Module/Special/DisplayNotFound.php:45
msgid "Conversation Not Found"
msgstr ""
#: src/Module/Special/DisplayNotFound.php:46
msgid "Unfortunately, the requested conversation isn't available to you."
msgstr ""
#: src/Module/Special/DisplayNotFound.php:47
msgid "Possible reasons include:"
msgstr "" msgstr ""
#: src/Module/Special/HTTPException.php:78 #: src/Module/Special/HTTPException.php:78
@ -10759,9 +10842,9 @@ msgstr ""
msgid "" msgid ""
"At any point in time a logged in user can export their account data from the " "At any point in time a logged in user can export their account data from the "
"<a href=\"%1$s/settings/userexport\">account settings</a>. If the user wants " "<a href=\"%1$s/settings/userexport\">account settings</a>. If the user wants "
"to delete their account they can do so at <a href=\"%1$s/settings/removeme\">" "to delete their account they can do so at <a href=\"%1$s/settings/"
"%1$s/settings/removeme</a>. The deletion of the account will be permanent. " "removeme\">%1$s/settings/removeme</a>. The deletion of the account will be "
"Deletion of the data will also be requested from the nodes of the " "permanent. Deletion of the data will also be requested from the nodes of the "
"communication partners." "communication partners."
msgstr "" msgstr ""
@ -10777,6 +10860,10 @@ msgstr ""
msgid "Parameter uri_id is missing." msgid "Parameter uri_id is missing."
msgstr "" msgstr ""
#: src/Module/Update/Display.php:55
msgid "The requested item doesn't exist or has been deleted."
msgstr ""
#: src/Module/User/Import.php:103 #: src/Module/User/Import.php:103
msgid "User imports on closed servers can only be done by an administrator." msgid "User imports on closed servers can only be done by an administrator."
msgstr "" msgstr ""
@ -11487,258 +11574,258 @@ msgstr ""
msgid "%s posted an update." msgid "%s posted an update."
msgstr "" msgstr ""
#: src/Object/Post.php:139 #: src/Object/Post.php:140
msgid "Private Message" msgid "Private Message"
msgstr "" msgstr ""
#: src/Object/Post.php:143 #: src/Object/Post.php:144
msgid "Public Message" msgid "Public Message"
msgstr "" msgstr ""
#: src/Object/Post.php:147 #: src/Object/Post.php:148
msgid "Unlisted Message" msgid "Unlisted Message"
msgstr "" msgstr ""
#: src/Object/Post.php:182 #: src/Object/Post.php:183
msgid "This entry was edited" msgid "This entry was edited"
msgstr "" msgstr ""
#: src/Object/Post.php:210 #: src/Object/Post.php:211
msgid "Connector Message" msgid "Connector Message"
msgstr "" msgstr ""
#: src/Object/Post.php:226 src/Object/Post.php:228 #: src/Object/Post.php:227 src/Object/Post.php:229
msgid "Edit" msgid "Edit"
msgstr "" msgstr ""
#: src/Object/Post.php:261 #: src/Object/Post.php:263
msgid "Delete globally" msgid "Delete globally"
msgstr "" msgstr ""
#: src/Object/Post.php:261 #: src/Object/Post.php:263
msgid "Remove locally" msgid "Remove locally"
msgstr "" msgstr ""
#: src/Object/Post.php:268 #: src/Object/Post.php:270
#, php-format #, php-format
msgid "Block %s" msgid "Block %s"
msgstr "" msgstr ""
#: src/Object/Post.php:273 #: src/Object/Post.php:275
#, php-format #, php-format
msgid "Ignore %s" msgid "Ignore %s"
msgstr "" msgstr ""
#: src/Object/Post.php:278 #: src/Object/Post.php:280
#, php-format #, php-format
msgid "Collapse %s" msgid "Collapse %s"
msgstr "" msgstr ""
#: src/Object/Post.php:282 #: src/Object/Post.php:284
msgid "Report post" msgid "Report post"
msgstr "" msgstr ""
#: src/Object/Post.php:287 #: src/Object/Post.php:294
msgid "Save to folder" msgid "Save to folder"
msgstr "" msgstr ""
#: src/Object/Post.php:327 #: src/Object/Post.php:334
msgid "I will attend" msgid "I will attend"
msgstr "" msgstr ""
#: src/Object/Post.php:327 #: src/Object/Post.php:334
msgid "I will not attend" msgid "I will not attend"
msgstr "" msgstr ""
#: src/Object/Post.php:327 #: src/Object/Post.php:334
msgid "I might attend" msgid "I might attend"
msgstr "" msgstr ""
#: src/Object/Post.php:357 #: src/Object/Post.php:364
msgid "Ignore thread" msgid "Ignore thread"
msgstr "" msgstr ""
#: src/Object/Post.php:358 #: src/Object/Post.php:365
msgid "Unignore thread" msgid "Unignore thread"
msgstr "" msgstr ""
#: src/Object/Post.php:359 #: src/Object/Post.php:366
msgid "Toggle ignore status" msgid "Toggle ignore status"
msgstr "" msgstr ""
#: src/Object/Post.php:369 #: src/Object/Post.php:376
msgid "Add star" msgid "Add star"
msgstr "" msgstr ""
#: src/Object/Post.php:370 #: src/Object/Post.php:377
msgid "Remove star" msgid "Remove star"
msgstr "" msgstr ""
#: src/Object/Post.php:371 #: src/Object/Post.php:378
msgid "Toggle star status" msgid "Toggle star status"
msgstr "" msgstr ""
#: src/Object/Post.php:382 #: src/Object/Post.php:389
msgid "Pin" msgid "Pin"
msgstr "" msgstr ""
#: src/Object/Post.php:383 #: src/Object/Post.php:390
msgid "Unpin" msgid "Unpin"
msgstr "" msgstr ""
#: src/Object/Post.php:384 #: src/Object/Post.php:391
msgid "Toggle pin status" msgid "Toggle pin status"
msgstr "" msgstr ""
#: src/Object/Post.php:387 #: src/Object/Post.php:394
msgid "Pinned" msgid "Pinned"
msgstr "" msgstr ""
#: src/Object/Post.php:392 #: src/Object/Post.php:399
msgid "Add tag" msgid "Add tag"
msgstr "" msgstr ""
#: src/Object/Post.php:405 #: src/Object/Post.php:412
msgid "Quote share this" msgid "Quote share this"
msgstr "" msgstr ""
#: src/Object/Post.php:405 #: src/Object/Post.php:412
msgid "Quote Share" msgid "Quote Share"
msgstr "" msgstr ""
#: src/Object/Post.php:408 #: src/Object/Post.php:415
msgid "Reshare this" msgid "Reshare this"
msgstr "" msgstr ""
#: src/Object/Post.php:408 #: src/Object/Post.php:415
msgid "Reshare" msgid "Reshare"
msgstr "" msgstr ""
#: src/Object/Post.php:409 #: src/Object/Post.php:416
msgid "Cancel your Reshare" msgid "Cancel your Reshare"
msgstr "" msgstr ""
#: src/Object/Post.php:409 #: src/Object/Post.php:416
msgid "Unshare" msgid "Unshare"
msgstr "" msgstr ""
#: src/Object/Post.php:460 #: src/Object/Post.php:467
#, php-format #, php-format
msgid "%s (Received %s)" msgid "%s (Received %s)"
msgstr "" msgstr ""
#: src/Object/Post.php:466 #: src/Object/Post.php:473
msgid "Comment this item on your system" msgid "Comment this item on your system"
msgstr "" msgstr ""
#: src/Object/Post.php:466 #: src/Object/Post.php:473
msgid "Remote comment" msgid "Remote comment"
msgstr "" msgstr ""
#: src/Object/Post.php:488 #: src/Object/Post.php:495
msgid "Share via ..." msgid "Share via ..."
msgstr "" msgstr ""
#: src/Object/Post.php:488 #: src/Object/Post.php:495
msgid "Share via external services" msgid "Share via external services"
msgstr "" msgstr ""
#: src/Object/Post.php:517 #: src/Object/Post.php:524
msgid "to" msgid "to"
msgstr "" msgstr ""
#: src/Object/Post.php:518 #: src/Object/Post.php:525
msgid "via" msgid "via"
msgstr "" msgstr ""
#: src/Object/Post.php:519 #: src/Object/Post.php:526
msgid "Wall-to-Wall" msgid "Wall-to-Wall"
msgstr "" msgstr ""
#: src/Object/Post.php:520 #: src/Object/Post.php:527
msgid "via Wall-To-Wall:" msgid "via Wall-To-Wall:"
msgstr "" msgstr ""
#: src/Object/Post.php:566 #: src/Object/Post.php:574
#, php-format #, php-format
msgid "Reply to %s" msgid "Reply to %s"
msgstr "" msgstr ""
#: src/Object/Post.php:569 #: src/Object/Post.php:577
msgid "More" msgid "More"
msgstr "" msgstr ""
#: src/Object/Post.php:587 #: src/Object/Post.php:596
msgid "Notifier task is pending" msgid "Notifier task is pending"
msgstr "" msgstr ""
#: src/Object/Post.php:588 #: src/Object/Post.php:597
msgid "Delivery to remote servers is pending" msgid "Delivery to remote servers is pending"
msgstr "" msgstr ""
#: src/Object/Post.php:589 #: src/Object/Post.php:598
msgid "Delivery to remote servers is underway" msgid "Delivery to remote servers is underway"
msgstr "" msgstr ""
#: src/Object/Post.php:590 #: src/Object/Post.php:599
msgid "Delivery to remote servers is mostly done" msgid "Delivery to remote servers is mostly done"
msgstr "" msgstr ""
#: src/Object/Post.php:591 #: src/Object/Post.php:600
msgid "Delivery to remote servers is done" msgid "Delivery to remote servers is done"
msgstr "" msgstr ""
#: src/Object/Post.php:611 #: src/Object/Post.php:620
#, php-format #, php-format
msgid "%d comment" msgid "%d comment"
msgid_plural "%d comments" msgid_plural "%d comments"
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#: src/Object/Post.php:612 #: src/Object/Post.php:621
msgid "Show more" msgid "Show more"
msgstr "" msgstr ""
#: src/Object/Post.php:613 #: src/Object/Post.php:622
msgid "Show fewer" msgid "Show fewer"
msgstr "" msgstr ""
#: src/Object/Post.php:649 #: src/Object/Post.php:658
#, php-format #, php-format
msgid "Reshared by: %s" msgid "Reshared by: %s"
msgstr "" msgstr ""
#: src/Object/Post.php:654 #: src/Object/Post.php:663
#, php-format #, php-format
msgid "Viewed by: %s" msgid "Viewed by: %s"
msgstr "" msgstr ""
#: src/Object/Post.php:659 #: src/Object/Post.php:668
#, php-format #, php-format
msgid "Liked by: %s" msgid "Liked by: %s"
msgstr "" msgstr ""
#: src/Object/Post.php:664 #: src/Object/Post.php:673
#, php-format #, php-format
msgid "Disliked by: %s" msgid "Disliked by: %s"
msgstr "" msgstr ""
#: src/Object/Post.php:669 #: src/Object/Post.php:678
#, php-format #, php-format
msgid "Attended by: %s" msgid "Attended by: %s"
msgstr "" msgstr ""
#: src/Object/Post.php:674 #: src/Object/Post.php:683
#, php-format #, php-format
msgid "Maybe attended by: %s" msgid "Maybe attended by: %s"
msgstr "" msgstr ""
#: src/Object/Post.php:679 #: src/Object/Post.php:688
#, php-format #, php-format
msgid "Not attended by: %s" msgid "Not attended by: %s"
msgstr "" msgstr ""
#: src/Object/Post.php:684 #: src/Object/Post.php:693
#, php-format #, php-format
msgid "Reacted with %s by: %s" msgid "Reacted with %s by: %s"
msgstr "" msgstr ""

View file

@ -57,7 +57,7 @@
{{if $c[0]['total'] > 0}} {{if $c[0]['total'] > 0}}
<tr> <tr>
<th>{{$c[0]['platform']}}</th> <th>{{$c[0]['platform']}}</th>
<th><strong>{{$c[0]['total']}}</strong></td> <th><strong>{{$c[0]['total']}}</strong></th>
<td>{{$c[0]['network']}}</td> <td>{{$c[0]['network']}}</td>
</tr> </tr>
<tr> <tr>

View file

@ -0,0 +1,27 @@
<div id="settings-server" class="generic-page-wrapper">
<h1>{{$l10n.title}}</h1>
<form action="{{$action}}" method="POST">
<input type="hidden" name="form_security_token" value="{{$form_security_token}}">
<input type="hidden" name="redirect_url" value="settings/server">
<p>{{$l10n.action}}</p>
{{if $l10n.desc}}
<p>{{$l10n.desc}}</p>
{{/if}}
<table>
<tr>
<th>{{$l10n.siteName}}</th>
<td>{{$GServer->siteName}}</td>
</tr>
<tr>
<th>{{$l10n.siteUrl}}</th>
<td><a href="{{$GServer->url}}">{{$GServer->url}}</a></td>
</tr>
</table>
<p><button type="submit" class="btn btn-primary">{{$l10n.submit}}</button></p>
</form>
</div>

View file

@ -0,0 +1,45 @@
<div id="settings-server" class="generic-page-wrapper">
<h1>{{$l10n.title}} ({{$count}})</h1>
<p>{{$l10n.desc nofilter}}</p>
{{$paginate nofilter}}
<form action="" method="POST">
<input type="hidden" name="form_security_token" value="{{$form_security_token}}">
<p><button type="submit" class="btn btn-primary">{{$l10n.submit}}</button></p>
<table class="table table-striped table-condensed table-bordered">
<tr>
<th>{{$l10n.siteName}}</th>
<th><span title="{{$l10n.ignored_title}}">{{$l10n.ignored}} <i class="fa fa-question-circle icon-question-sign"></i></span></th>
<th>
<span title="{{$l10n.delete_title}}">
<i class="fa fa-trash icon-trash" aria-hidden="true" title="{{$l10n.delete}}"></i>
<span class="sr-only">{{$l10n.delete}}</span>
<i class="fa fa-question-circle icon-question-sign"></i>
</span>
</th>
</tr>
{{foreach $servers as $index => $server}}
<tr>
<td>
<a href="{{$server->gserver->url}}">{{($server->gserver->siteName) ? $server->gserver->siteName : $server->gserver->url}} <i class="fa fa-external-link"></i></a>
</td>
<td>
{{include file="field_checkbox.tpl" field=$ignoredCheckboxes[$index]}}
</td>
<td>
{{include file="field_checkbox.tpl" field=$deleteCheckboxes[$index]}}
</td>
</tr>
{{/foreach}}
</table>
<p><button type="submit" class="btn btn-primary">{{$l10n.submit}}</button></p>
</form>
{{$paginate nofilter}}
</div>

View file

@ -1,5 +1,11 @@
<div id="exception" class="generic-page-wrapper"> <div id="exception" class="generic-page-wrapper">
<img class="hare" src="images/friendica-404_svg_flexy-o-hare.png"/> <img class="hare" src="images/friendica-404_svg_flexy-o-hare.png"/>
<h1>{{$title}}</h1> <h1>{{$l10n.title}}</h1>
{{$message nofilter}} <p>{{$l10n.desc1}}</p>
<p>{{$l10n.desc2}}</p>
<ul>
{{foreach $l10n.reasons as $reason}}
<li>{{$reason}}</li>
{{/foreach}}
</ul>
</div> </div>

View file

@ -210,6 +210,10 @@ function confirmCollapse() {
return confirm(aStr.collapseAuthor); return confirm(aStr.collapseAuthor);
} }
function confirmIgnoreServer() {
return confirm(aStr.ignoreServer + "\n" + aStr.ignoreServerDesc);
}
/** /**
* Hide and removes an item element from the DOM after the deletion url is * Hide and removes an item element from the DOM after the deletion url is
* successful, restore it else. * successful, restore it else.
@ -325,4 +329,34 @@ function collapseAuthor(url, elementId) {
}); });
} }
} }
/**
* Ignore author server
*
* @param {string} url The server ignore URL
* @param {string} elementId The DOM id of the item element
* @returns {undefined}
*/
function ignoreServer(url, elementId) {
if (confirmIgnoreServer()) {
$("body").css("cursor", "wait");
var $el = $(document.getElementById(elementId));
$el.fadeTo("fast", 0.33, function () {
$.post(url)
.then(function () {
$el.remove();
})
.fail(function () {
// @todo Show related error message
$el.fadeTo("fast", 1);
})
.always(function () {
$("body").css("cursor", "auto");
});
});
}
}
// @license-end // @license-end

View file

@ -61,6 +61,7 @@
{{if $ignored}}<li><div id="ignore-message">{{$ignored}}</div></li>{{/if}} {{if $ignored}}<li><div id="ignore-message">{{$ignored}}</div></li>{{/if}}
{{if $collapsed}}<li><div id="collapse-message">{{$collapsed}}</div></li>{{/if}} {{if $collapsed}}<li><div id="collapse-message">{{$collapsed}}</div></li>{{/if}}
{{if $archived}}<li><div id="archive-message">{{$archived}}</div></li>{{/if}} {{if $archived}}<li><div id="archive-message">{{$archived}}</div></li>{{/if}}
{{if $serverIgnored}}<li><div id="serverIgnored-message">{{$serverIgnored}} <a href="settings/server">{{$manageServers}}</a></div></li>{{/if}}
</ul> </ul>
</div> {{* End of contact-edit-status-wrapper *}} </div> {{* End of contact-edit-status-wrapper *}}

View file

@ -3,10 +3,12 @@
They are loaded into the html <head> so that js functions can use them *}} They are loaded into the html <head> so that js functions can use them *}}
<script type="text/javascript"> <script type="text/javascript">
const aStr = { const aStr = {
delitem : "{{$l10n.delitem|escape:'javascript' nofilter}}", delitem : "{{$l10n.delitem|escape:'javascript' nofilter}}",
blockAuthor : "{{$l10n.blockAuthor|escape:'javascript' nofilter}}", blockAuthor : "{{$l10n.blockAuthor|escape:'javascript' nofilter}}",
ignoreAuthor : "{{$l10n.ignoreAuthor|escape:'javascript' nofilter}}", ignoreAuthor : "{{$l10n.ignoreAuthor|escape:'javascript' nofilter}}",
collapseAuthor : "{{$l10n.collapseAuthor|escape:'javascript' nofilter}}", collapseAuthor : "{{$l10n.collapseAuthor|escape:'javascript' nofilter}}",
ignoreServer : "{{$l10n.ignoreServer|escape:'javascript' nofilter}}",
ignoreServerDesc : "{{$l10n.ignoreServerDesc|escape:'javascript' nofilter}}",
}; };
const aActErr = { const aActErr = {
like : "{{$l10n.likeError|escape:'javascript' nofilter}}", like : "{{$l10n.likeError|escape:'javascript' nofilter}}",

View file

@ -401,13 +401,17 @@ as the value of $top_child_total (this is done at the end of this file)
{{/if}} {{/if}}
{{if $item.ignore_author}} {{if $item.ignore_author}}
<li role="menuitem"> <li role="menuitem">
<a class="btn-link navicon ignore" href="javascript:ignoreAuthor('item/ignore/{{$item.id}}', 'item-{{$item.guid}}');" title="{{$item.ignore_author.label}}"><i class="fa fa-ban" aria-hidden="true"></i> {{$item.ignore_author.label}}</a> <a class="btn-link navicon ignore" href="javascript:ignoreAuthor('item/ignore/{{$item.id}}', 'item-{{$item.guid}}');" title="{{$item.ignore_author.label}}"><i class="fa fa-eye-slash" aria-hidden="true"></i> {{$item.ignore_author.label}}</a>
</li> </li>
{{/if}} {{/if}}
{{if $item.collapse}} {{if $item.collapse}}
<li role="menuitem"> <li role="menuitem">
<a class="btn-link navicon collapse" href="javascript:collapseAuthor('item/collapse/{{$item.id}}', 'item-{{$item.guid}}');" title="{{$item.collapse.label}}"><i class="fa fa-ban" aria-hidden="true"></i> {{$item.collapse.label}}</a> <a class="btn-link navicon collapse" href="javascript:collapseAuthor('item/collapse/{{$item.id}}', 'item-{{$item.guid}}');" title="{{$item.collapse.label}}"><i class="fa fa-minus-square" aria-hidden="true"></i> {{$item.collapse.label}}</a>
</li> </li>
{{/if}}
{{if $item.ignore_server}}
<li role="menuitem">
<a class="btn-link navicon ignoreServer" href="javascript:ignoreServer('settings/server/{{$item.author_gsid}}/ignore', 'item-{{$item.guid}}');" title="{{$item.ignore_server.label}}"><i class="fa fa-eye-slash" aria-hidden="true"></i> {{$item.ignore_server.label}}</a>
</li> </li>
{{/if}} {{/if}}
{{if $item.report}} {{if $item.report}}

View file

@ -3281,3 +3281,7 @@ fbrowser.photo .photo-album-image-wrapper { margin-left: 10px; }
#colorbox img { #colorbox img {
max-width: 100%; max-width: 100%;
} }
#settings-server td + td {
text-align: center;
}