diff --git a/database.sql b/database.sql
index 7305e65d2..b0f3ca796 100644
--- a/database.sql
+++ b/database.sql
@@ -1,6 +1,6 @@
-- ------------------------------------------
-- 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
) 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
--
@@ -2044,6 +2056,7 @@ CREATE VIEW `post-user-view` AS SELECT
`owner`.`blocked` AS `owner-blocked`,
`owner`.`hidden` AS `owner-hidden`,
`owner`.`updated` AS `owner-updated`,
+ `owner`.`gsid` AS `owner-gsid`,
`owner`.`contact-type` AS `owner-contact-type`,
`post-user`.`causer-id` AS `causer-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`.`blocked` AS `causer-blocked`,
`causer`.`hidden` AS `causer-hidden`,
+ `causer`.`gsid` AS `causer-gsid`,
`causer`.`contact-type` AS `causer-contact-type`,
`post-delivery-data`.`postopts` AS `postopts`,
`post-delivery-data`.`inform` AS `inform`,
@@ -2189,6 +2203,7 @@ CREATE VIEW `post-thread-user-view` AS SELECT
`contact`.`pending` AS `contact-pending`,
`contact`.`rel` AS `contact-rel`,
`contact`.`uid` AS `contact-uid`,
+ `contact`.`gsid` AS `contact-gsid`,
`contact`.`contact-type` AS `contact-contact-type`,
IF (`post-user`.`network` IN ('apub', 'dfrn', 'dspr', 'stat'), true, `contact`.`writable`) AS `writable`,
`contact`.`self` AS `self`,
@@ -2224,6 +2239,7 @@ CREATE VIEW `post-thread-user-view` AS SELECT
`owner`.`blocked` AS `owner-blocked`,
`owner`.`hidden` AS `owner-hidden`,
`owner`.`updated` AS `owner-updated`,
+ `owner`.`gsid` AS `owner-gsid`,
`owner`.`contact-type` AS `owner-contact-type`,
`post-thread-user`.`causer-id` AS `causer-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`.`blocked` AS `causer-blocked`,
`causer`.`hidden` AS `causer-hidden`,
+ `causer`.`gsid` AS `causer-gsid`,
`causer`.`contact-type` AS `causer-contact-type`,
`post-delivery-data`.`postopts` AS `postopts`,
`post-delivery-data`.`inform` AS `inform`,
@@ -2391,6 +2408,7 @@ CREATE VIEW `post-view` AS SELECT
`owner`.`hidden` AS `owner-hidden`,
`owner`.`updated` AS `owner-updated`,
`owner`.`contact-type` AS `owner-contact-type`,
+ `owner`.`gsid` AS `owner-gsid`,
`post`.`causer-id` AS `causer-id`,
`causer`.`uri-id` AS `causer-uri-id`,
`causer`.`url` AS `causer-link`,
@@ -2403,6 +2421,7 @@ CREATE VIEW `post-view` AS SELECT
`causer`.`blocked` AS `causer-blocked`,
`causer`.`hidden` AS `causer-hidden`,
`causer`.`contact-type` AS `causer-contact-type`,
+ `causer`.`gsid` AS `causer-gsid`,
`post-question`.`id` AS `question-id`,
`post-question`.`multiple` AS `question-multiple`,
`post-question`.`voters` AS `question-voters`,
@@ -2533,6 +2552,7 @@ CREATE VIEW `post-thread-view` AS SELECT
`owner`.`blocked` AS `owner-blocked`,
`owner`.`hidden` AS `owner-hidden`,
`owner`.`updated` AS `owner-updated`,
+ `owner`.`gsid` AS `owner-gsid`,
`owner`.`contact-type` AS `owner-contact-type`,
`post-thread`.`causer-id` AS `causer-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`.`blocked` AS `causer-blocked`,
`causer`.`hidden` AS `causer-hidden`,
+ `causer`.`gsid` AS `causer-gsid`,
`causer`.`contact-type` AS `causer-contact-type`,
`post-question`.`id` AS `question-id`,
`post-question`.`multiple` AS `question-multiple`,
@@ -2666,7 +2687,7 @@ CREATE VIEW `network-item-view` AS SELECT
`post-user`.`contact-id` AS `contact-id`,
`ownercontact`.`contact-type` AS `contact-type`
FROM `post-user`
- INNER JOIN `post-thread-user` ON `post-thread-user`.`uri-id` = `post-user`.`parent-uri-id` AND `post-thread-user`.`uid` = `post-user`.`uid`
+ INNER JOIN `post-thread-user` ON `post-thread-user`.`uri-id` = `post-user`.`parent-uri-id` AND `post-thread-user`.`uid` = `post-user`.`uid`
STRAIGHT_JOIN `contact` ON `contact`.`id` = `post-thread-user`.`contact-id`
STRAIGHT_JOIN `contact` AS `authorcontact` ON `authorcontact`.`id` = `post-thread-user`.`author-id`
STRAIGHT_JOIN `contact` AS `ownercontact` ON `ownercontact`.`id` = `post-thread-user`.`owner-id`
@@ -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 NOT `authorcontact`.`blocked` AND NOT `ownercontact`.`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
diff --git a/doc/database.md b/doc/database.md
index b92859157..284870657 100644
--- a/doc/database.md
+++ b/doc/database.md
@@ -86,6 +86,7 @@ Database Tables
| [tag](help/database/db_tag) | tags and mentions |
| [user](help/database/db_user) | The local users |
| [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 |
| [verb](help/database/db_verb) | Activity Verbs |
| [worker-ipc](help/database/db_worker-ipc) | Inter process communication between the frontend and the worker |
diff --git a/doc/database/db_user-gserver.md b/doc/database/db_user-gserver.md
new file mode 100644
index 000000000..b49a288f4
--- /dev/null
+++ b/doc/database/db_user-gserver.md
@@ -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)
diff --git a/src/App/Page.php b/src/App/Page.php
index 96bb59425..e369d482e 100644
--- a/src/App/Page.php
+++ b/src/App/Page.php
@@ -245,10 +245,12 @@ class Page implements ArrayAccess
*/
$this->page['htmlhead'] = Renderer::replaceMacros($tpl, [
'$l10n' => [
- '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.'),
- '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?'),
+ '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."),
+ '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?"),
+ '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'),
'dislikeError' => $l10n->t('Dislike not successful'),
diff --git a/src/Content/Conversation.php b/src/Content/Conversation.php
index 710422ee7..151a2bfc7 100644
--- a/src/Content/Conversation.php
+++ b/src/Content/Conversation.php
@@ -45,6 +45,8 @@ use Friendica\Network\HTTPException\InternalServerErrorException;
use Friendica\Object\Post as PostObject;
use Friendica\Object\Thread;
use Friendica\Protocol\Activity;
+use Friendica\User\Settings\Entity\UserGServer;
+use Friendica\User\Settings\Repository;
use Friendica\Util\Crypto;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Profiler;
@@ -90,22 +92,25 @@ class Conversation
private $mode;
/** @var IHandleUserSessions */
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->item = $item;
- $this->config = $config;
- $this->mode = $mode;
- $this->baseURL = $baseURL;
- $this->profiler = $profiler;
- $this->logger = $logger;
- $this->l10n = $l10n;
- $this->args = $args;
- $this->pConfig = $pConfig;
- $this->page = $page;
- $this->app = $app;
- $this->session = $session;
+ $this->activity = $activity;
+ $this->item = $item;
+ $this->config = $config;
+ $this->mode = $mode;
+ $this->baseURL = $baseURL;
+ $this->profiler = $profiler;
+ $this->logger = $logger;
+ $this->l10n = $l10n;
+ $this->args = $args;
+ $this->pConfig = $pConfig;
+ $this->page = $page;
+ $this->app = $app;
+ $this->session = $session;
+ $this->userGServer = $userGServer;
}
/**
@@ -459,8 +464,14 @@ class Conversation
$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) {
- $items = $this->addChildren($items, false, $order, $uid, $mode);
+ $items = $this->addChildren($items, false, $order, $uid, $mode, $ignoredGsids);
if (!$update) {
/*
* The special div is needed for liveUpdate to kick in for this page.
@@ -486,7 +497,7 @@ class Conversation
. "'; \r\n";
}
} elseif ($mode === self::MODE_PROFILE) {
- $items = $this->addChildren($items, false, $order, $uid, $mode);
+ $items = $this->addChildren($items, false, $order, $uid, $mode, $ignoredGsids);
if (!$update) {
$tab = !empty($_GET['tab']) ? trim($_GET['tab']) : 'posts';
@@ -511,7 +522,7 @@ class Conversation
. "; var netargs = '?f='; \r\n";
}
} elseif ($mode === self::MODE_DISPLAY) {
- $items = $this->addChildren($items, false, $order, $uid, $mode);
+ $items = $this->addChildren($items, false, $order, $uid, $mode, $ignoredGsids);
if (!$update) {
$live_update_div = '
' . "\r\n"
@@ -519,7 +530,7 @@ class Conversation
. "";
}
} elseif ($mode === self::MODE_COMMUNITY) {
- $items = $this->addChildren($items, true, $order, $uid, $mode);
+ $items = $this->addChildren($items, true, $order, $uid, $mode, $ignoredGsids);
if (!$update) {
$live_update_div = '' . "\r\n"
@@ -530,7 +541,7 @@ class Conversation
. "'; \r\n";
}
} elseif ($mode === self::MODE_CONTACTS) {
- $items = $this->addChildren($items, false, $order, $uid, $mode);
+ $items = $this->addChildren($items, false, $order, $uid, $mode, $ignoredGsids);
if (!$update) {
$live_update_div = '' . "\r\n"
@@ -812,13 +823,14 @@ class Conversation
*
* @param array $parents Parent items
* @param bool $block_authors
- * @param bool $order
+ * @param string $order Either "received" or "commented"
* @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
- * @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');
if (count($parents) > 1) {
@@ -900,6 +912,13 @@ class Conversation
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']) {
$row['featured'] = false;
}
@@ -1462,6 +1481,7 @@ class Conversation
'received' => $item['received'],
'created_date' => $item['created'],
'uriid' => $item['uri-id'],
+ 'author_gsid' => $item['author-gsid'],
'network' => $item['network'],
'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']),
diff --git a/src/Content/Item.php b/src/Content/Item.php
index c25e5296f..86493385f 100644
--- a/src/Content/Item.php
+++ b/src/Content/Item.php
@@ -50,6 +50,7 @@ use Friendica\Protocol\Activity;
use Friendica\Util\ACLFormatter;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Emailer;
+use Friendica\Util\Network;
use Friendica\Util\ParseUrl;
use Friendica\Util\Profiler;
use Friendica\Util\Proxy;
@@ -367,7 +368,7 @@ class Item
{
$this->profiler->startRecording('rendering');
$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']) {
$sub_link = 'javascript:doFollowThread(' . $item['id'] . '); return false;';
@@ -407,6 +408,10 @@ class Item
$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']) {
$contact_url = 'contact/' . $cid;
$posts_link = $contact_url . '/posts';
@@ -427,7 +432,8 @@ class Item
$this->l10n->t('Send PM') => $pm_url,
$this->l10n->t('Block') => $block_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'])) {
diff --git a/src/DI.php b/src/DI.php
index 34cf1c68d..2d6eb6ede 100644
--- a/src/DI.php
+++ b/src/DI.php
@@ -671,6 +671,15 @@ abstract class DI
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
//
diff --git a/src/Federation/Entity/GServer.php b/src/Federation/Entity/GServer.php
new file mode 100644
index 000000000..0e331f480
--- /dev/null
+++ b/src/Federation/Entity/GServer.php
@@ -0,0 +1,151 @@
+.
+ *
+ */
+
+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;
+ }
+}
diff --git a/src/Federation/Factory/GServer.php b/src/Federation/Factory/GServer.php
new file mode 100644
index 000000000..681cad7af
--- /dev/null
+++ b/src/Federation/Factory/GServer.php
@@ -0,0 +1,68 @@
+.
+ *
+ */
+
+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'],
+ );
+ }
+}
diff --git a/src/Federation/Repository/GServer.php b/src/Federation/Repository/GServer.php
new file mode 100644
index 000000000..47a9244f6
--- /dev/null
+++ b/src/Federation/Repository/GServer.php
@@ -0,0 +1,47 @@
+.
+ *
+ */
+
+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]);
+ }
+}
diff --git a/src/Model/Item.php b/src/Model/Item.php
index a2304056d..cf039da3a 100644
--- a/src/Model/Item.php
+++ b/src/Model/Item.php
@@ -96,8 +96,8 @@ class Item
'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',
'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',
- 'causer-id', 'causer-link', 'causer-alias', 'causer-name', 'causer-avatar', 'causer-contact-type', 'causer-network',
+ '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-gsid',
'contact-id', 'contact-uid', 'contact-link', 'contact-name', 'contact-avatar',
'writable', 'self', 'cid', 'alias',
'event-created', 'event-edited', 'event-start', 'event-finish',
diff --git a/src/Model/Post.php b/src/Model/Post.php
index 770ab0831..6f855867f 100644
--- a/src/Model/Post.php
+++ b/src/Model/Post.php
@@ -453,12 +453,10 @@ class Post
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 (?, ?)))
OR `self` OR `contact-uid` = ?)
- AND NOT `" . $view . "`.`uri-id` IN (SELECT `uri-id` FROM `post-user` WHERE `uid` = ? AND `hidden`)
- AND NOT `author-id` IN (SELECT `cid` FROM `user-contact` WHERE `uid` = ? AND `blocked` AND `cid` = `author-id`)
- AND NOT `owner-id` IN (SELECT `cid` FROM `user-contact` WHERE `uid` = ? AND `blocked` AND `cid` = `owner-id`)
- AND NOT `author-id` IN (SELECT `cid` FROM `user-contact` WHERE `uid` = ? AND `ignored` AND `cid` = `author-id`)
- 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]);
+ AND NOT EXISTS(SELECT `uri-id` FROM `post-user` WHERE `uid` = ? AND `uri-id` = " . DBA::quoteIdentifier($view) . ".`uri-id` AND `hidden`)
+ AND NOT EXISTS(SELECT `cid` FROM `user-contact` WHERE `uid` = ? AND `cid` IN (`author-id`, `owner-id`) AND (`blocked` OR `ignored`))
+ AND NOT EXISTS(SELECT `gsid` FROM `user-gserver` WHERE `uid` = ? AND `gsid` IN (`author-gsid`, `owner-gsid`, `causer-gsid`) AND `ignored`)",
+ 0, Contact::SHARING, Contact::FRIEND, 0, $uid, $uid, $uid]);
$select_string = implode(', ', array_map([DBA::class, 'quoteIdentifier'], $selected));
diff --git a/src/Model/Post/UserNotification.php b/src/Model/Post/UserNotification.php
index 012a49dbf..726e82d7e 100644
--- a/src/Model/Post/UserNotification.php
+++ b/src/Model/Post/UserNotification.php
@@ -133,14 +133,14 @@ class UserNotification
public static function setNotification(int $uri_id, int $uid)
{
$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'];
$item = Post::selectFirst($fields, ['uri-id' => $uri_id, 'uid' => $uid, 'origin' => false]);
if (!DBA::isResult($item)) {
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)) {
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']);
if (in_array($user['account-type'], [User::ACCOUNT_TYPE_COMMUNITY, User::ACCOUNT_TYPE_RELAY])) {
return;
diff --git a/src/Module/BaseSettings.php b/src/Module/BaseSettings.php
index a1e88e9a1..4b26a0f26 100644
--- a/src/Module/BaseSettings.php
+++ b/src/Module/BaseSettings.php
@@ -151,6 +151,13 @@ class BaseSettings extends BaseModule
'accesskey' => 'b',
];
+ $tabs[] = [
+ 'label' => $this->t('Remote servers'),
+ 'url' => 'settings/server',
+ 'selected' => static::class == Settings\Server\Index::class ? 'active' : '',
+ 'accesskey' => 's',
+ ];
+
$tabs[] = [
'label' => $this->t('Export personal data'),
'url' => 'settings/userexport',
diff --git a/src/Module/Contact/Profile.php b/src/Module/Contact/Profile.php
index 090f7cd86..399198062 100644
--- a/src/Module/Contact/Profile.php
+++ b/src/Module/Contact/Profile.php
@@ -23,8 +23,7 @@ namespace Friendica\Module\Contact;
use Friendica\App;
use Friendica\BaseModule;
-use Friendica\Contact\LocalRelationship\Entity;
-use Friendica\Contact\LocalRelationship\Repository;
+use Friendica\Contact\LocalRelationship;
use Friendica\Content\ContactSelector;
use Friendica\Content\Nav;
use Friendica\Content\Text\BBCode;
@@ -34,13 +33,16 @@ use Friendica\Core\Hook;
use Friendica\Core\L10n;
use Friendica\Core\Protocol;
use Friendica\Core\Renderer;
+use Friendica\Core\Session\Capability\IHandleUserSessions;
+use Friendica\Database\Database;
use Friendica\Database\DBA;
-use Friendica\DI;
-use Friendica\Model\Contact;
use Friendica\Model\Circle;
+use Friendica\Model\Contact;
use Friendica\Module;
use Friendica\Module\Response;
+use Friendica\Navigation\SystemMessages;
use Friendica\Network\HTTPException;
+use Friendica\User\Settings;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Profiler;
use Psr\Log\LoggerInterface;
@@ -50,31 +52,37 @@ use Psr\Log\LoggerInterface;
*/
class Profile extends BaseModule
{
- /**
- * @var Repository\LocalRelationship
- */
+ /** @var LocalRelationship\Repository\LocalRelationship */
private $localRelationship;
- /**
- * @var App\Page
- */
+ /** @var App\Page */
private $page;
- /**
- * @var IManageConfigValues
- */
+ /** @var IManageConfigValues */
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);
$this->localRelationship = $localRelationship;
$this->page = $page;
$this->config = $config;
+ $this->session = $session;
+ $this->systemMessages = $systemMessages;
+ $this->db = $db;
+ $this->userGServer = $userGServer;
}
protected function post(array $request = [])
{
- if (!DI::userSession()->getLocalUserId()) {
+ if (!$this->session->getLocalUserId()) {
return;
}
@@ -82,8 +90,8 @@ class Profile extends BaseModule
// Backward compatibility: The update still needs a user-specific contact ID
// Change to user-contact table check by version 2022.03
- $cdata = Contact::getPublicAndUserContactID($contact_id, DI::userSession()->getLocalUserId());
- if (empty($cdata['user']) || !DBA::exists('contact', ['id' => $cdata['user'], 'deleted' => false])) {
+ $cdata = Contact::getPublicAndUserContactID($contact_id, $this->session->getLocalUserId());
+ if (empty($cdata['user']) || !$this->db->exists('contact', ['id' => $cdata['user'], 'deleted' => false])) {
return;
}
@@ -124,35 +132,35 @@ class Profile extends BaseModule
$fields['info'] = $_POST['info'];
}
- if (!Contact::update($fields, ['id' => $cdata['user'], 'uid' => DI::userSession()->getLocalUserId()])) {
- DI::sysmsg()->addNotice($this->t('Failed to update contact record.'));
+ if (!Contact::update($fields, ['id' => $cdata['user'], 'uid' => $this->session->getLocalUserId()])) {
+ $this->systemMessages->addNotice($this->t('Failed to update contact record.'));
}
}
protected function content(array $request = []): string
{
- if (!DI::userSession()->getLocalUserId()) {
+ if (!$this->session->getLocalUserId()) {
return Module\Security\Login::form($_SERVER['REQUEST_URI']);
}
// Backward compatibility: Ensure to use the public contact when the user contact is provided
// 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)) {
throw new HTTPException\NotFoundException($this->t('Contact not found.'));
}
$contact = Contact::getById($data['public']);
- if (!DBA::isResult($contact)) {
+ if (!$this->db->isResult($contact)) {
throw new HTTPException\NotFoundException($this->t('Contact not found.'));
}
// 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.'));
}
- $localRelationship = $this->localRelationship->getForUserContact(DI::userSession()->getLocalUserId(), $contact['id']);
+ $localRelationship = $this->localRelationship->getForUserContact($this->session->getLocalUserId(), $contact['id']);
if ($localRelationship->rel === Contact::SELF) {
$this->baseUrl->redirect('profile/' . $contact['nick'] . '/profile');
@@ -167,55 +175,55 @@ class Profile extends BaseModule
}
if ($cmd === 'updateprofile') {
- self::updateContactFromProbe($contact['id']);
+ $this->updateContactFromProbe($contact['id']);
}
if ($cmd === 'block') {
if ($localRelationship->blocked) {
// @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');
} else {
// @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');
}
// @TODO: add $this->localRelationship->save($localRelationship);
- DI::sysmsg()->addInfo($message);
+ $this->systemMessages->addInfo($message);
}
if ($cmd === 'ignore') {
if ($localRelationship->ignored) {
// @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');
} else {
// @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');
}
// @TODO: add $this->localRelationship->save($localRelationship);
- DI::sysmsg()->addInfo($message);
+ $this->systemMessages->addInfo($message);
}
if ($cmd === 'collapse') {
if ($localRelationship->collapsed) {
// @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');
} else {
// @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');
}
// @TODO: add $this->localRelationship->save($localRelationship);
- DI::sysmsg()->addInfo($message);
+ $this->systemMessages->addInfo($message);
}
$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.');
+ $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'));
if ($contact['last-update'] > DBA::NULL_DATETIME) {
@@ -363,6 +376,8 @@ class Profile extends BaseModule
'$collapsed' => $localRelationship->collapsed ? $this->t('Currently collapsed') : '',
'$archived' => ($contact['archive'] ? $this->t('Currently archived') : ''),
'$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, ''],
'$hidden' => ['hidden', $this->t('Hide this contact from others'), $localRelationship->hidden, $this->t('Replies/likes to your public posts may 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')],
@@ -413,11 +428,11 @@ class Profile extends BaseModule
* This includes actions like e.g. 'block', 'hide', 'delete' and others
*
* @param array $contact Public contact row
- * @param Entity\LocalRelationship $localRelationship
+ * @param LocalRelationship\Entity\LocalRelationship $localRelationship
* @return array with contact related actions
* @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]);
$contact_actions = [];
@@ -518,10 +533,9 @@ class Profile extends BaseModule
* @throws HTTPException\InternalServerErrorException
* @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 (!DBA::isResult($contact)) {
+ if (!$this->db->exists('contact', ['id' => $contact_id, 'uid' => [0, $this->session->getLocalUserId()], 'deleted' => false])) {
return;
}
diff --git a/src/Module/Conversation/Community.php b/src/Module/Conversation/Community.php
index 7525ba1c1..3c3bbb8a8 100644
--- a/src/Module/Conversation/Community.php
+++ b/src/Module/Conversation/Community.php
@@ -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);
if (empty($items)) {
diff --git a/src/Module/Item/Display.php b/src/Module/Item/Display.php
index 21046628f..714598a8e 100644
--- a/src/Module/Item/Display.php
+++ b/src/Module/Item/Display.php
@@ -133,7 +133,9 @@ class Display extends BaseModule
}
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) {
diff --git a/src/Module/Settings/Server/Action.php b/src/Module/Settings/Server/Action.php
new file mode 100644
index 000000000..e06cbf26b
--- /dev/null
+++ b/src/Module/Settings/Server/Action.php
@@ -0,0 +1,117 @@
+.
+ *
+ */
+
+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();
+ }
+}
diff --git a/src/Module/Settings/Server/Index.php b/src/Module/Settings/Server/Index.php
new file mode 100644
index 000000000..f59e23a87
--- /dev/null
+++ b/src/Module/Settings/Server/Index.php
@@ -0,0 +1,126 @@
+.
+ *
+ */
+
+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 Information 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),
+ ]);
+ }
+}
diff --git a/src/Module/Special/DisplayNotFound.php b/src/Module/Special/DisplayNotFound.php
index d66ececdd..293f40aa0 100644
--- a/src/Module/Special/DisplayNotFound.php
+++ b/src/Module/Special/DisplayNotFound.php
@@ -31,18 +31,21 @@ class DisplayNotFound extends \Friendica\BaseModule
{
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');
return Renderer::replaceMacros($tpl, [
'$l10n' => [
- 'title' => $this->t('Not Found'),
- 'message' => $this->t("
Unfortunately, the requested conversation isn't available to you.
-
Possible reasons include:
-
-
The top-level post isn't visible.
-
The top-level post was deleted.
-
The node has blocked the top-level author or the author of the shared post.
-
You have ignored or blocked the top-level author or the author of the shared post.
-
"),
+ 'title' => $this->t('Conversation Not Found'),
+ 'desc1' => $this->t("Unfortunately, the requested conversation isn't available to you."),
+ 'desc2' => $this->t('Possible reasons include:'),
+ 'reasons' => $reasons,
]
]);
}
diff --git a/src/Object/Post.php b/src/Object/Post.php
index e7a178ef1..15a135079 100644
--- a/src/Object/Post.php
+++ b/src/Object/Post.php
@@ -38,6 +38,7 @@ use Friendica\Model\User;
use Friendica\Protocol\Activity;
use Friendica\Util\Crypto;
use Friendica\Util\DateTimeFormat;
+use Friendica\Util\Network;
use Friendica\Util\Proxy;
use Friendica\Util\Strings;
use Friendica\Util\Temporal;
@@ -248,11 +249,12 @@ class Post
$pinned = DI::l10n()->t('Pinned item');
}
- $drop = false;
- $block = false;
- $ignore = false;
- $collapse = false;
- $report = false;
+ $drop = false;
+ $block = false;
+ $ignore = false;
+ $collapse = false;
+ $report = false;
+ $ignoreServer = false;
if (DI::userSession()->getLocalUserId()) {
$drop = [
'dropping' => $dropping,
@@ -282,6 +284,11 @@ class Post
'label' => DI::l10n()->t('Report post'),
'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;
@@ -557,6 +564,7 @@ class Post
'ignore_author' => $ignore,
'collapse' => $collapse,
'report' => $report,
+ 'ignore_server' => $ignoreServer,
'vote' => $buttons,
'like_html' => $responses['like']['output'],
'dislike_html' => $responses['dislike']['output'],
@@ -571,6 +579,7 @@ class Post
'wait' => DI::l10n()->t('Please wait'),
'thread_level' => $thread_level,
'edited' => $edited,
+ 'author_gsid' => $item['author-gsid'],
'network' => $item['network'],
'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']),
diff --git a/src/User/Settings/Collection/UserGServers.php b/src/User/Settings/Collection/UserGServers.php
new file mode 100644
index 000000000..689b801cf
--- /dev/null
+++ b/src/User/Settings/Collection/UserGServers.php
@@ -0,0 +1,30 @@
+.
+ *
+ */
+
+namespace Friendica\User\Settings\Collection;
+
+class UserGServers extends \Friendica\BaseCollection
+{
+ public function current(): \Friendica\User\Settings\Entity\UserGServer
+ {
+ return parent::current();
+ }
+}
diff --git a/src/User/Settings/Entity/UserGServer.php b/src/User/Settings/Entity/UserGServer.php
new file mode 100644
index 000000000..e5afdc51e
--- /dev/null
+++ b/src/User/Settings/Entity/UserGServer.php
@@ -0,0 +1,92 @@
+.
+ *
+ */
+
+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;
+ }
+}
diff --git a/src/User/Settings/Factory/UserGServer.php b/src/User/Settings/Factory/UserGServer.php
new file mode 100644
index 000000000..61abe28cc
--- /dev/null
+++ b/src/User/Settings/Factory/UserGServer.php
@@ -0,0 +1,60 @@
+.
+ *
+ */
+
+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,
+ );
+ }
+}
diff --git a/src/User/Settings/Repository/UserGServer.php b/src/User/Settings/Repository/UserGServer.php
new file mode 100644
index 000000000..baf70095c
--- /dev/null
+++ b/src/User/Settings/Repository/UserGServer.php
@@ -0,0 +1,156 @@
+.
+ *
+ */
+
+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);
+ }
+}
diff --git a/static/dbstructure.config.php b/static/dbstructure.config.php
index c7575528e..dcda833aa 100644
--- a/static/dbstructure.config.php
+++ b/static/dbstructure.config.php
@@ -56,7 +56,7 @@ use Friendica\Database\DBA;
// This file is required several times during the test in DbaDefinition which justifies this condition
if (!defined('DB_UPDATE_VERSION')) {
- define('DB_UPDATE_VERSION', 1525);
+ define('DB_UPDATE_VERSION', 1527);
}
return [
@@ -159,6 +159,17 @@ return [
"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" => [
"comment" => "URI and GUID for items",
"fields" => [
diff --git a/static/dbview.config.php b/static/dbview.config.php
index e8641240c..5da17a42e 100644
--- a/static/dbview.config.php
+++ b/static/dbview.config.php
@@ -197,6 +197,7 @@
"owner-blocked" => ["owner", "blocked"],
"owner-hidden" => ["owner", "hidden"],
"owner-updated" => ["owner", "updated"],
+ "owner-gsid" => ["owner", "gsid"],
"owner-contact-type" => ["owner", "contact-type"],
"causer-id" => ["post-user", "causer-id"],
"causer-uri-id" => ["causer", "uri-id"],
@@ -209,6 +210,7 @@
"causer-network" => ["causer", "network"],
"causer-blocked" => ["causer", "blocked"],
"causer-hidden" => ["causer", "hidden"],
+ "causer-gsid" => ["causer", "gsid"],
"causer-contact-type" => ["causer", "contact-type"],
"postopts" => ["post-delivery-data", "postopts"],
"inform" => ["post-delivery-data", "inform"],
@@ -340,6 +342,7 @@
"contact-pending" => ["contact", "pending"],
"contact-rel" => ["contact", "rel"],
"contact-uid" => ["contact", "uid"],
+ "contact-gsid" => ["contact", "gsid"],
"contact-contact-type" => ["contact", "contact-type"],
"writable" => "IF (`post-user`.`network` IN ('apub', 'dfrn', 'dspr', 'stat'), true, `contact`.`writable`)",
"self" => ["contact", "self"],
@@ -375,6 +378,7 @@
"owner-blocked" => ["owner", "blocked"],
"owner-hidden" => ["owner", "hidden"],
"owner-updated" => ["owner", "updated"],
+ "owner-gsid" => ["owner", "gsid"],
"owner-contact-type" => ["owner", "contact-type"],
"causer-id" => ["post-thread-user", "causer-id"],
"causer-uri-id" => ["causer", "uri-id"],
@@ -387,6 +391,7 @@
"causer-network" => ["causer", "network"],
"causer-blocked" => ["causer", "blocked"],
"causer-hidden" => ["causer", "hidden"],
+ "causer-gsid" => ["causer", "gsid"],
"causer-contact-type" => ["causer", "contact-type"],
"postopts" => ["post-delivery-data", "postopts"],
"inform" => ["post-delivery-data", "inform"],
@@ -540,6 +545,7 @@
"owner-hidden" => ["owner", "hidden"],
"owner-updated" => ["owner", "updated"],
"owner-contact-type" => ["owner", "contact-type"],
+ "owner-gsid" => ["owner", "gsid"],
"causer-id" => ["post", "causer-id"],
"causer-uri-id" => ["causer", "uri-id"],
"causer-link" => ["causer", "url"],
@@ -552,6 +558,7 @@
"causer-blocked" => ["causer", "blocked"],
"causer-hidden" => ["causer", "hidden"],
"causer-contact-type" => ["causer", "contact-type"],
+ "causer-gsid" => ["causer", "gsid"],
"question-id" => ["post-question", "id"],
"question-multiple" => ["post-question", "multiple"],
"question-voters" => ["post-question", "voters"],
@@ -680,6 +687,7 @@
"owner-blocked" => ["owner", "blocked"],
"owner-hidden" => ["owner", "hidden"],
"owner-updated" => ["owner", "updated"],
+ "owner-gsid" => ["owner", "gsid"],
"owner-contact-type" => ["owner", "contact-type"],
"causer-id" => ["post-thread", "causer-id"],
"causer-uri-id" => ["causer", "uri-id"],
@@ -692,6 +700,7 @@
"causer-network" => ["causer", "network"],
"causer-blocked" => ["causer", "blocked"],
"causer-hidden" => ["causer", "hidden"],
+ "causer-gsid" => ["causer", "gsid"],
"causer-contact-type" => ["causer", "contact-type"],
"question-id" => ["post-question", "id"],
"question-multiple" => ["post-question", "multiple"],
@@ -804,7 +813,7 @@
"contact-type" => ["ownercontact", "contact-type"],
],
"query" => "FROM `post-user`
- INNER JOIN `post-thread-user` ON `post-thread-user`.`uri-id` = `post-user`.`parent-uri-id` AND `post-thread-user`.`uid` = `post-user`.`uid`
+ INNER JOIN `post-thread-user` ON `post-thread-user`.`uri-id` = `post-user`.`parent-uri-id` AND `post-thread-user`.`uid` = `post-user`.`uid`
STRAIGHT_JOIN `contact` ON `contact`.`id` = `post-thread-user`.`contact-id`
STRAIGHT_JOIN `contact` AS `authorcontact` ON `authorcontact`.`id` = `post-thread-user`.`author-id`
STRAIGHT_JOIN `contact` AS `ownercontact` ON `ownercontact`.`id` = `post-thread-user`.`owner-id`
@@ -843,7 +852,8 @@
AND (`post-thread-user`.`hidden` IS NULL OR NOT `post-thread-user`.`hidden`)
AND NOT `authorcontact`.`blocked` AND NOT `ownercontact`.`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" => [
"fields" => [
diff --git a/static/routes.config.php b/static/routes.config.php
index 71595e5a8..36ba2f249 100644
--- a/static/routes.config.php
+++ b/static/routes.config.php
@@ -639,6 +639,10 @@ return [
],
'/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]],
'/account' => [
'[/]' => [Module\Settings\Account::class, [R::GET, R::POST]],
diff --git a/view/lang/C/messages.po b/view/lang/C/messages.po
index 2d5faec2d..b9c94b038 100644
--- a/view/lang/C/messages.po
+++ b/view/lang/C/messages.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 2023.09-dev\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"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -281,7 +281,7 @@ msgstr ""
msgid "Your message:"
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
msgid "Upload photo"
msgstr ""
@@ -292,9 +292,9 @@ msgid "Insert web link"
msgstr ""
#: 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/Profile/UnkMail.php:154 src/Object/Post.php:571
+#: src/Module/Profile/UnkMail.php:154 src/Object/Post.php:579
msgid "Please wait"
msgstr ""
@@ -302,7 +302,7 @@ msgstr ""
#: mod/photos.php:824 mod/photos.php:1101 mod/photos.php:1142
#: mod/photos.php:1198 mod/photos.php:1278
#: 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/Babel.php:313 src/Module/Debug/Localtime.php:64
#: 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:263
#: 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/quattro/config.php:87 view/theme/vier/config.php:135
msgid "Submit"
@@ -479,7 +480,7 @@ msgstr ""
msgid "Do not show a status post for this upload"
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
msgid "Permissions"
msgstr ""
@@ -492,7 +493,7 @@ msgstr ""
msgid "Delete Album"
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/Unfollow.php:126
#: src/Module/Media/Attachment/Browser.php:77
@@ -600,53 +601,54 @@ msgstr ""
#: mod/photos.php:1139 mod/photos.php:1195 mod/photos.php:1275
#: 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"
msgstr ""
#: 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"
msgstr ""
#: 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/Object/Post.php:1100
+#: src/Object/Post.php:1109
msgid "Preview"
msgstr ""
-#: mod/photos.php:1144 src/Content/Conversation.php:360
-#: src/Module/Post/Edit.php:130 src/Object/Post.php:1088
+#: mod/photos.php:1144 src/Content/Conversation.php:365
+#: src/Module/Post/Edit.php:130 src/Object/Post.php:1097
msgid "Loading..."
msgstr ""
-#: mod/photos.php:1236 src/Content/Conversation.php:1424
-#: src/Object/Post.php:260
+#: mod/photos.php:1236 src/Content/Conversation.php:1443
+#: src/Object/Post.php:262
msgid "Select"
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/Blocked.php:136
#: src/Module/Moderation/Users/Index.php:151
#: src/Module/Settings/Connectors.php:244
+#: src/Module/Settings/Server/Index.php:109
msgid "Delete"
msgstr ""
-#: mod/photos.php:1298 src/Object/Post.php:402
+#: mod/photos.php:1298 src/Object/Post.php:409
msgid "Like"
msgstr ""
-#: mod/photos.php:1299 src/Object/Post.php:402
+#: mod/photos.php:1299 src/Object/Post.php:409
msgid "I like this (toggle)"
msgstr ""
-#: mod/photos.php:1300 src/Object/Post.php:403
+#: mod/photos.php:1300 src/Object/Post.php:410
msgid "Dislike"
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)"
msgstr ""
@@ -682,77 +684,88 @@ msgstr ""
msgid "Collapse this author's posts?"
msgstr ""
-#: src/App/Page.php:253
-msgid "Like not successful"
+#: src/App/Page.php:252
+msgid "Ignore this author's server?"
msgstr ""
-#: src/App/Page.php:254
-msgid "Dislike not successful"
+#: src/App/Page.php:253 src/Module/Settings/Server/Action.php:61
+#: 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 ""
#: src/App/Page.php:255
-msgid "Sharing not successful"
+msgid "Like not successful"
msgstr ""
#: src/App/Page.php:256
-msgid "Attendance unsuccessful"
+msgid "Dislike not successful"
msgstr ""
#: src/App/Page.php:257
-msgid "Backend error"
+msgid "Sharing not successful"
msgstr ""
#: 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"
msgstr ""
-#: src/App/Page.php:261
+#: src/App/Page.php:263
msgid "Drop files here to upload"
msgstr ""
-#: src/App/Page.php:262
+#: src/App/Page.php:264
msgid "Your browser does not support drag and drop file uploads."
msgstr ""
-#: src/App/Page.php:263
+#: src/App/Page.php:265
msgid ""
"Please use the fallback form below to upload your files like in the olden "
"days."
msgstr ""
-#: src/App/Page.php:264
+#: src/App/Page.php:266
msgid "File is too big ({{filesize}}MiB). Max filesize: {{maxFilesize}}MiB."
msgstr ""
-#: src/App/Page.php:265
+#: src/App/Page.php:267
msgid "You can't upload files of this type."
msgstr ""
-#: src/App/Page.php:266
+#: src/App/Page.php:268
msgid "Server responded with {{statusCode}} code."
msgstr ""
-#: src/App/Page.php:267
+#: src/App/Page.php:269
msgid "Cancel upload"
msgstr ""
-#: src/App/Page.php:268
+#: src/App/Page.php:270
msgid "Upload canceled."
msgstr ""
-#: src/App/Page.php:269
+#: src/App/Page.php:271
msgid "Are you sure you want to cancel this upload?"
msgstr ""
-#: src/App/Page.php:270
+#: src/App/Page.php:272
msgid "Remove file"
msgstr ""
-#: src/App/Page.php:271
+#: src/App/Page.php:273
msgid "You can't upload any more files."
msgstr ""
-#: src/App/Page.php:349
+#: src/App/Page.php:351
msgid "toggle mobile"
msgstr ""
@@ -1127,65 +1140,65 @@ msgstr ""
msgid "%s (via %s)"
msgstr ""
-#: src/Content/Conversation.php:219
+#: src/Content/Conversation.php:224
msgid "and"
msgstr ""
-#: src/Content/Conversation.php:222
+#: src/Content/Conversation.php:227
#, php-format
msgid "and %d other people"
msgstr ""
-#: src/Content/Conversation.php:228
+#: src/Content/Conversation.php:233
#, php-format
msgid "%2$s likes this."
msgid_plural "%2$s like this."
msgstr[0] ""
msgstr[1] ""
-#: src/Content/Conversation.php:230
+#: src/Content/Conversation.php:235
#, php-format
msgid "%2$s doesn't like this."
msgid_plural "%2$s don't like this."
msgstr[0] ""
msgstr[1] ""
-#: src/Content/Conversation.php:232
+#: src/Content/Conversation.php:237
#, php-format
msgid "%2$s attends."
msgid_plural "%2$s attend."
msgstr[0] ""
msgstr[1] ""
-#: src/Content/Conversation.php:234
+#: src/Content/Conversation.php:239
#, php-format
msgid "%2$s doesn't attend."
msgid_plural "%2$s don't attend."
msgstr[0] ""
msgstr[1] ""
-#: src/Content/Conversation.php:236
+#: src/Content/Conversation.php:241
#, php-format
msgid "%2$s attends maybe."
msgid_plural "%2$s attend maybe."
msgstr[0] ""
msgstr[1] ""
-#: src/Content/Conversation.php:238
+#: src/Content/Conversation.php:243
#, php-format
msgid "%2$s reshared this."
msgid_plural "%2$s reshared this."
msgstr[0] ""
msgstr[1] ""
-#: src/Content/Conversation.php:267
+#: src/Content/Conversation.php:272
#, php-format
msgid " likes this"
msgid_plural " like this"
msgstr[0] ""
msgstr[1] ""
-#: src/Content/Conversation.php:270
+#: src/Content/Conversation.php:275
#, php-format
msgid " doesn't like this"
msgid_plural ""
@@ -1193,304 +1206,304 @@ msgid_plural ""
msgstr[0] ""
msgstr[1] ""
-#: src/Content/Conversation.php:273
+#: src/Content/Conversation.php:278
#, php-format
msgid " attends"
msgid_plural " attend"
msgstr[0] ""
msgstr[1] ""
-#: src/Content/Conversation.php:276
+#: src/Content/Conversation.php:281
#, php-format
msgid " doesn't attend"
msgid_plural " don't attend"
msgstr[0] ""
msgstr[1] ""
-#: src/Content/Conversation.php:279
+#: src/Content/Conversation.php:284
#, php-format
msgid " attends maybe"
msgid_plural " attend maybe"
msgstr[0] ""
msgstr[1] ""
-#: src/Content/Conversation.php:282
+#: src/Content/Conversation.php:287
#, php-format
msgid " reshared this"
msgid_plural " reshared this"
msgstr[0] ""
msgstr[1] ""
-#: src/Content/Conversation.php:329
+#: src/Content/Conversation.php:334
msgid "Visible to everybody"
msgstr ""
-#: src/Content/Conversation.php:330 src/Module/Item/Compose.php:200
-#: src/Object/Post.php:1099
+#: src/Content/Conversation.php:335 src/Module/Item/Compose.php:200
+#: src/Object/Post.php:1108
msgid "Please enter a image/video/audio/webpage URL:"
msgstr ""
-#: src/Content/Conversation.php:331
+#: src/Content/Conversation.php:336
msgid "Tag term:"
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:"
msgstr ""
-#: src/Content/Conversation.php:333
+#: src/Content/Conversation.php:338
msgid "Where are you right now?"
msgstr ""
-#: src/Content/Conversation.php:334
+#: src/Content/Conversation.php:339
msgid "Delete item(s)?"
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"
msgstr ""
-#: src/Content/Conversation.php:356
+#: src/Content/Conversation.php:361
msgid "New Post"
msgstr ""
-#: src/Content/Conversation.php:359
+#: src/Content/Conversation.php:364
msgid "Share"
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"
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"
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"
msgstr ""
-#: src/Content/Conversation.php:365 src/Module/Item/Compose.php:190
-#: src/Module/Post/Edit.php:171 src/Object/Post.php:1089
+#: src/Content/Conversation.php:370 src/Module/Item/Compose.php:190
+#: src/Module/Post/Edit.php:171 src/Object/Post.php:1098
msgid "Bold"
msgstr ""
-#: src/Content/Conversation.php:366 src/Module/Item/Compose.php:191
-#: src/Module/Post/Edit.php:172 src/Object/Post.php:1090
+#: src/Content/Conversation.php:371 src/Module/Item/Compose.php:191
+#: src/Module/Post/Edit.php:172 src/Object/Post.php:1099
msgid "Italic"
msgstr ""
-#: src/Content/Conversation.php:367 src/Module/Item/Compose.php:192
-#: src/Module/Post/Edit.php:173 src/Object/Post.php:1091
+#: src/Content/Conversation.php:372 src/Module/Item/Compose.php:192
+#: src/Module/Post/Edit.php:173 src/Object/Post.php:1100
msgid "Underline"
msgstr ""
-#: src/Content/Conversation.php:368 src/Module/Item/Compose.php:193
-#: src/Module/Post/Edit.php:174 src/Object/Post.php:1093
+#: src/Content/Conversation.php:373 src/Module/Item/Compose.php:193
+#: src/Module/Post/Edit.php:174 src/Object/Post.php:1102
msgid "Quote"
msgstr ""
-#: src/Content/Conversation.php:369 src/Module/Item/Compose.php:194
-#: src/Module/Post/Edit.php:175 src/Object/Post.php:1094
+#: src/Content/Conversation.php:374 src/Module/Item/Compose.php:194
+#: src/Module/Post/Edit.php:175 src/Object/Post.php:1103
msgid "Add emojis"
msgstr ""
-#: src/Content/Conversation.php:370 src/Module/Item/Compose.php:195
-#: src/Object/Post.php:1092
+#: src/Content/Conversation.php:375 src/Module/Item/Compose.php:195
+#: src/Object/Post.php:1101
msgid "Content Warning"
msgstr ""
-#: src/Content/Conversation.php:371 src/Module/Item/Compose.php:196
-#: src/Module/Post/Edit.php:176 src/Object/Post.php:1095
+#: src/Content/Conversation.php:376 src/Module/Item/Compose.php:196
+#: src/Module/Post/Edit.php:176 src/Object/Post.php:1104
msgid "Code"
msgstr ""
-#: src/Content/Conversation.php:372 src/Module/Item/Compose.php:197
-#: src/Object/Post.php:1096
+#: src/Content/Conversation.php:377 src/Module/Item/Compose.php:197
+#: src/Object/Post.php:1105
msgid "Image"
msgstr ""
-#: src/Content/Conversation.php:373 src/Module/Item/Compose.php:198
-#: src/Module/Post/Edit.php:177 src/Object/Post.php:1097
+#: src/Content/Conversation.php:378 src/Module/Item/Compose.php:198
+#: src/Module/Post/Edit.php:177 src/Object/Post.php:1106
msgid "Link"
msgstr ""
-#: src/Content/Conversation.php:374 src/Module/Item/Compose.php:199
-#: src/Module/Post/Edit.php:178 src/Object/Post.php:1098
+#: src/Content/Conversation.php:379 src/Module/Item/Compose.php:199
+#: src/Module/Post/Edit.php:178 src/Object/Post.php:1107
msgid "Link or Media"
msgstr ""
-#: src/Content/Conversation.php:375
+#: src/Content/Conversation.php:380
msgid "Video"
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
msgid "Set your location"
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"
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"
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"
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
msgid "Set title"
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
msgid "Categories (comma-separated list)"
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"
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"
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"
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/Module/Post/Edit.php:181
msgid "Message"
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
msgid "Browser"
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"
msgstr ""
-#: src/Content/Conversation.php:569
+#: src/Content/Conversation.php:580
msgid "remove"
msgstr ""
-#: src/Content/Conversation.php:573
+#: src/Content/Conversation.php:584
msgid "Delete Selected Items"
msgstr ""
-#: src/Content/Conversation.php:728 src/Content/Conversation.php:731
-#: src/Content/Conversation.php:734 src/Content/Conversation.php:737
-#: src/Content/Conversation.php:740
+#: src/Content/Conversation.php:739 src/Content/Conversation.php:742
+#: src/Content/Conversation.php:745 src/Content/Conversation.php:748
+#: src/Content/Conversation.php:751
#, php-format
msgid "You had been addressed (%s)."
msgstr ""
-#: src/Content/Conversation.php:743
+#: src/Content/Conversation.php:754
#, php-format
msgid "You are following %s."
msgstr ""
-#: src/Content/Conversation.php:746
+#: src/Content/Conversation.php:757
msgid "You subscribed to one or more tags in this post."
msgstr ""
-#: src/Content/Conversation.php:765
+#: src/Content/Conversation.php:776
#, php-format
msgid "%s reshared this."
msgstr ""
-#: src/Content/Conversation.php:767
+#: src/Content/Conversation.php:778
msgid "Reshared"
msgstr ""
-#: src/Content/Conversation.php:767
+#: src/Content/Conversation.php:778
#, php-format
msgid "Reshared by %s <%s>"
msgstr ""
-#: src/Content/Conversation.php:770
+#: src/Content/Conversation.php:781
#, php-format
msgid "%s is participating in this thread."
msgstr ""
-#: src/Content/Conversation.php:773
+#: src/Content/Conversation.php:784
msgid "Stored for general reasons"
msgstr ""
-#: src/Content/Conversation.php:776
+#: src/Content/Conversation.php:787
msgid "Global post"
msgstr ""
-#: src/Content/Conversation.php:779
+#: src/Content/Conversation.php:790
msgid "Sent via an relay server"
msgstr ""
-#: src/Content/Conversation.php:779
+#: src/Content/Conversation.php:790
#, php-format
msgid "Sent via the relay server %s <%s>"
msgstr ""
-#: src/Content/Conversation.php:782
+#: src/Content/Conversation.php:793
msgid "Fetched"
msgstr ""
-#: src/Content/Conversation.php:782
+#: src/Content/Conversation.php:793
#, php-format
msgid "Fetched because of %s <%s>"
msgstr ""
-#: src/Content/Conversation.php:785
+#: src/Content/Conversation.php:796
msgid "Stored because of a child post to complete this thread."
msgstr ""
-#: src/Content/Conversation.php:788
+#: src/Content/Conversation.php:799
msgid "Local delivery"
msgstr ""
-#: src/Content/Conversation.php:791
+#: src/Content/Conversation.php:802
msgid "Stored because of your activity (like, comment, star, ...)"
msgstr ""
-#: src/Content/Conversation.php:794
+#: src/Content/Conversation.php:805
msgid "Distributed"
msgstr ""
-#: src/Content/Conversation.php:797
+#: src/Content/Conversation.php:808
msgid "Pushed to us"
msgstr ""
-#: src/Content/Conversation.php:1452 src/Object/Post.php:248
+#: src/Content/Conversation.php:1471 src/Object/Post.php:249
msgid "Pinned item"
msgstr ""
-#: src/Content/Conversation.php:1468 src/Object/Post.php:515
-#: src/Object/Post.php:516
+#: src/Content/Conversation.php:1488 src/Object/Post.php:522
+#: src/Object/Post.php:523
#, php-format
msgid "View %s's profile @ %s"
msgstr ""
-#: src/Content/Conversation.php:1481 src/Object/Post.php:503
+#: src/Content/Conversation.php:1501 src/Object/Post.php:510
msgid "Categories:"
msgstr ""
-#: src/Content/Conversation.php:1482 src/Object/Post.php:504
+#: src/Content/Conversation.php:1502 src/Object/Post.php:511
msgid "Filed under:"
msgstr ""
-#: src/Content/Conversation.php:1490 src/Object/Post.php:529
+#: src/Content/Conversation.php:1510 src/Object/Post.php:536
#, php-format
msgid "%s from %s"
msgstr ""
-#: src/Content/Conversation.php:1506
+#: src/Content/Conversation.php:1526
msgid "View in context"
msgstr ""
@@ -1629,88 +1642,93 @@ msgstr ""
msgid "Create new group"
msgstr ""
-#: src/Content/Item.php:329 src/Model/Item.php:2998
+#: src/Content/Item.php:330 src/Model/Item.php:2998
msgid "event"
msgstr ""
-#: src/Content/Item.php:332 src/Content/Item.php:342
+#: src/Content/Item.php:333 src/Content/Item.php:343
msgid "status"
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
msgid "photo"
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
msgid "%1$s tagged %2$s's %3$s with %4$s"
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"
msgstr ""
-#: src/Content/Item.php:422 src/Model/Contact.php:1210
+#: src/Content/Item.php:427 src/Model/Contact.php:1211
msgid "View Status"
msgstr ""
-#: src/Content/Item.php:423 src/Content/Item.php:443 src/Model/Contact.php:1159
-#: src/Model/Contact.php:1202 src/Model/Contact.php:1211
+#: src/Content/Item.php:428 src/Content/Item.php:449 src/Model/Contact.php:1160
+#: src/Model/Contact.php:1203 src/Model/Contact.php:1212
#: src/Module/Directory.php:157 src/Module/Settings/Profile/Index.php:259
msgid "View Profile"
msgstr ""
-#: src/Content/Item.php:424 src/Model/Contact.php:1212
+#: src/Content/Item.php:429 src/Model/Contact.php:1213
msgid "View Photos"
msgstr ""
-#: src/Content/Item.php:425 src/Model/Contact.php:1203
-#: src/Model/Contact.php:1213
+#: src/Content/Item.php:430 src/Model/Contact.php:1204
+#: src/Model/Contact.php:1214
msgid "Network Posts"
msgstr ""
-#: src/Content/Item.php:426 src/Model/Contact.php:1204
-#: src/Model/Contact.php:1214
+#: src/Content/Item.php:431 src/Model/Contact.php:1205
+#: src/Model/Contact.php:1215
msgid "View Contact"
msgstr ""
-#: src/Content/Item.php:427 src/Model/Contact.php:1215
+#: src/Content/Item.php:432 src/Model/Contact.php:1216
msgid "Send PM"
msgstr ""
-#: src/Content/Item.php:428 src/Module/Contact.php:468
-#: src/Module/Contact/Profile.php:477
+#: src/Content/Item.php:433 src/Module/Contact.php:468
+#: src/Module/Contact/Profile.php:492
#: src/Module/Moderation/Blocklist/Contact.php:116
#: src/Module/Moderation/Users/Active.php:137
#: src/Module/Moderation/Users/Index.php:152
msgid "Block"
msgstr ""
-#: src/Content/Item.php:429 src/Module/Contact.php:469
-#: src/Module/Contact/Profile.php:485
+#: src/Content/Item.php:434 src/Module/Contact.php:469
+#: src/Module/Contact/Profile.php:500
#: src/Module/Notifications/Introductions.php:134
#: src/Module/Notifications/Introductions.php:206
#: src/Module/Notifications/Notification.php:89
msgid "Ignore"
msgstr ""
-#: src/Content/Item.php:430 src/Module/Contact.php:470
-#: src/Module/Contact/Profile.php:493
+#: src/Content/Item.php:435 src/Module/Contact.php:470
+#: src/Module/Contact/Profile.php:508
msgid "Collapse"
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"
msgstr ""
-#: src/Content/Item.php:440 src/Content/Widget.php:80
-#: src/Model/Contact.php:1205 src/Model/Contact.php:1216
+#: src/Content/Item.php:446 src/Content/Widget.php:80
+#: src/Model/Contact.php:1206 src/Model/Contact.php:1217
#: src/Module/Contact/Follow.php:167 view/theme/vier/theme.php:195
msgid "Connect/Follow"
msgstr ""
-#: src/Content/Item.php:874
+#: src/Content/Item.php:880
msgid "Unable to fetch user."
msgstr ""
@@ -1758,7 +1776,7 @@ msgstr ""
#: src/Content/Nav.php:228 src/Module/BaseProfile.php:49
#: 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
msgid "Profile"
msgstr ""
@@ -1961,7 +1979,7 @@ msgid "Manage other pages"
msgstr ""
#: 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
msgid "Settings"
msgstr ""
@@ -2077,7 +2095,7 @@ msgid "The end"
msgstr ""
#: 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"
msgstr ""
@@ -2212,7 +2230,7 @@ msgstr ""
msgid "Organisations"
msgstr ""
-#: src/Content/Widget.php:536 src/Model/Contact.php:1680
+#: src/Content/Widget.php:536 src/Model/Contact.php:1681
msgid "News"
msgstr ""
@@ -2271,18 +2289,18 @@ msgid "More Trending Tags"
msgstr ""
#: 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:"
msgstr ""
#: 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:"
msgstr ""
#: 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/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/Profile/Profile.php:221
msgid "Location:"
@@ -2293,9 +2311,9 @@ msgstr ""
msgid "Network:"
msgstr ""
-#: src/Content/Widget/VCard.php:118 src/Model/Contact.php:1206
-#: src/Model/Contact.php:1217 src/Model/Profile.php:463
-#: src/Module/Contact/Profile.php:429
+#: src/Content/Widget/VCard.php:118 src/Model/Contact.php:1207
+#: src/Model/Contact.php:1218 src/Model/Profile.php:463
+#: src/Module/Contact/Profile.php:444
msgid "Unfollow"
msgstr ""
@@ -2559,8 +2577,8 @@ msgstr ""
#: src/Core/Installer.php:511
msgid ""
-"The web installer needs to be able to create a file called \"local.config.php"
-"\" in the \"config\" folder of your web server and it is unable to do so."
+"The web installer needs to be able to create a file called \"local.config."
+"php\" in the \"config\" folder of your web server and it is unable to do so."
msgstr ""
#: src/Core/Installer.php:512
@@ -3047,82 +3065,82 @@ msgstr ""
msgid "Edit circles"
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:204
msgid "Approve"
msgstr ""
-#: src/Model/Contact.php:1676
+#: src/Model/Contact.php:1677
msgid "Organisation"
msgstr ""
-#: src/Model/Contact.php:1684
+#: src/Model/Contact.php:1685
msgid "Group"
msgstr ""
-#: src/Model/Contact.php:2993
+#: src/Model/Contact.php:2988
msgid "Disallowed profile URL."
msgstr ""
-#: src/Model/Contact.php:2998 src/Module/Friendica.php:102
+#: src/Model/Contact.php:2993 src/Module/Friendica.php:101
msgid "Blocked domain"
msgstr ""
-#: src/Model/Contact.php:3003
+#: src/Model/Contact.php:2998
msgid "Connect URL missing."
msgstr ""
-#: src/Model/Contact.php:3012
+#: src/Model/Contact.php:3007
msgid ""
"The contact could not be added. Please check the relevant network "
"credentials in your Settings -> Social Networks page."
msgstr ""
-#: src/Model/Contact.php:3030
+#: src/Model/Contact.php:3025
#, php-format
msgid "Expected network %s does not match actual network %s"
msgstr ""
-#: src/Model/Contact.php:3047
+#: src/Model/Contact.php:3042
msgid "The profile address specified does not provide adequate information."
msgstr ""
-#: src/Model/Contact.php:3049
+#: src/Model/Contact.php:3044
msgid "No compatible communication protocols or feeds were discovered."
msgstr ""
-#: src/Model/Contact.php:3052
+#: src/Model/Contact.php:3047
msgid "An author or name was not found."
msgstr ""
-#: src/Model/Contact.php:3055
+#: src/Model/Contact.php:3050
msgid "No browser URL could be matched to this address."
msgstr ""
-#: src/Model/Contact.php:3058
+#: src/Model/Contact.php:3053
msgid ""
"Unable to match @-style Identity Address with a known protocol or email "
"contact."
msgstr ""
-#: src/Model/Contact.php:3059
+#: src/Model/Contact.php:3054
msgid "Use mailto: in front of address to force email check."
msgstr ""
-#: src/Model/Contact.php:3065
+#: src/Model/Contact.php:3060
msgid ""
"The profile address specified belongs to a network which has been disabled "
"on this site."
msgstr ""
-#: src/Model/Contact.php:3070
+#: src/Model/Contact.php:3065
msgid ""
"Limited profile. This person will be unable to receive direct/personal "
"notifications from you."
msgstr ""
-#: src/Model/Contact.php:3136
+#: src/Model/Contact.php:3131
msgid "Unable to retrieve contact information."
msgstr ""
@@ -3327,7 +3345,7 @@ msgstr ""
msgid "Homepage:"
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
msgid "About:"
msgstr ""
@@ -5039,7 +5057,7 @@ msgid ""
"received."
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
msgid "Disabled"
msgstr ""
@@ -5185,9 +5203,9 @@ msgstr ""
#: src/Module/Admin/Summary.php:98
msgid ""
-"The last update failed. Please run \"php bin/console.php dbstructure update"
-"\" from the command line and have a look at the errors that might appear. "
-"(Some of the errors are possibly inside the logfile.)"
+"The last update failed. Please run \"php bin/console.php dbstructure "
+"update\" from the command line and have a look at the errors that might "
+"appear. (Some of the errors are possibly inside the logfile.)"
msgstr ""
#: src/Module/Admin/Summary.php:102
@@ -5338,8 +5356,8 @@ msgstr ""
#, php-format
msgid ""
"Show some informations regarding the needed information to operate the node "
-"according e.g. to EU-GDPR."
+"according e.g. to EU-GDPR."
msgstr ""
#: src/Module/Admin/Tos.php:81
@@ -5628,11 +5646,15 @@ msgstr ""
msgid "Connected apps"
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"
msgstr ""
-#: src/Module/BaseSettings.php:162
+#: src/Module/BaseSettings.php:169
msgid "Remove account"
msgstr ""
@@ -5778,8 +5800,8 @@ msgstr ""
#: src/Module/Contact/Conversations.php:89
#: 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:88 src/Module/Contact/Profile.php:142
-#: src/Module/Contact/Profile.php:147 src/Module/Contact/Profile.php:152
+#: src/Module/Contact/Posts.php:88 src/Module/Contact/Profile.php:150
+#: 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/FriendSuggest.php:71 src/Module/FriendSuggest.php:109
msgid "Contact not found."
@@ -5888,7 +5910,7 @@ msgid "Only show blocked contacts"
msgstr ""
#: 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"
msgstr ""
@@ -5937,18 +5959,18 @@ msgstr ""
msgid "Update"
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/Users/Blocked.php:138
#: src/Module/Moderation/Users/Index.php:154
msgid "Unblock"
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"
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"
msgstr ""
@@ -6000,7 +6022,7 @@ msgstr ""
msgid "Pending incoming contact request"
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
msgid "Visit %s's profile [%s]"
msgstr ""
@@ -6135,7 +6157,7 @@ msgstr ""
msgid "Your Identity Address:"
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/Moderation/Blocklist/Contact.php:133
#: src/Module/Notifications/Introductions.php:129
@@ -6143,7 +6165,7 @@ msgstr ""
msgid "Profile URL"
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/Profile/Profile.php:234
msgid "Tags:"
@@ -6182,249 +6204,257 @@ msgstr ""
msgid "Profile Match"
msgstr ""
-#: src/Module/Contact/Profile.php:128
+#: src/Module/Contact/Profile.php:136
msgid "Failed to update contact record."
msgstr ""
-#: src/Module/Contact/Profile.php:178
+#: src/Module/Contact/Profile.php:186
msgid "Contact has been unblocked"
msgstr ""
-#: src/Module/Contact/Profile.php:182
+#: src/Module/Contact/Profile.php:190
msgid "Contact has been blocked"
msgstr ""
-#: src/Module/Contact/Profile.php:194
+#: src/Module/Contact/Profile.php:202
msgid "Contact has been unignored"
msgstr ""
-#: src/Module/Contact/Profile.php:198
+#: src/Module/Contact/Profile.php:206
msgid "Contact has been ignored"
msgstr ""
-#: src/Module/Contact/Profile.php:210
+#: src/Module/Contact/Profile.php:218
msgid "Contact has been uncollapsed"
msgstr ""
-#: src/Module/Contact/Profile.php:214
+#: src/Module/Contact/Profile.php:222
msgid "Contact has been collapsed"
msgstr ""
-#: src/Module/Contact/Profile.php:242
+#: src/Module/Contact/Profile.php:250
#, php-format
msgid "You are mutual friends with %s"
msgstr ""
-#: src/Module/Contact/Profile.php:243
+#: src/Module/Contact/Profile.php:251
#, php-format
msgid "You are sharing with %s"
msgstr ""
-#: src/Module/Contact/Profile.php:244
+#: src/Module/Contact/Profile.php:252
#, php-format
msgid "%s is sharing with you"
msgstr ""
-#: src/Module/Contact/Profile.php:260
+#: src/Module/Contact/Profile.php:268
msgid "Private communications are not available for this contact."
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"
msgstr ""
-#: src/Module/Contact/Profile.php:265
+#: src/Module/Contact/Profile.php:278
msgid "(Update was not successful)"
msgstr ""
-#: src/Module/Contact/Profile.php:265
+#: src/Module/Contact/Profile.php:278
msgid "(Update was successful)"
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"
msgstr ""
-#: src/Module/Contact/Profile.php:271
+#: src/Module/Contact/Profile.php:284
#, php-format
msgid "Network type: %s"
msgstr ""
-#: src/Module/Contact/Profile.php:276
+#: src/Module/Contact/Profile.php:289
msgid "Communications lost with this contact!"
msgstr ""
-#: src/Module/Contact/Profile.php:282
+#: src/Module/Contact/Profile.php:295
msgid "Fetch further information for feeds"
msgstr ""
-#: src/Module/Contact/Profile.php:284
+#: src/Module/Contact/Profile.php:297
msgid ""
"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 "
"are taken from the meta header in the feed item and are posted as hash tags."
msgstr ""
-#: src/Module/Contact/Profile.php:287
+#: src/Module/Contact/Profile.php:300
msgid "Fetch information"
msgstr ""
-#: src/Module/Contact/Profile.php:288
+#: src/Module/Contact/Profile.php:301
msgid "Fetch keywords"
msgstr ""
-#: src/Module/Contact/Profile.php:289
+#: src/Module/Contact/Profile.php:302
msgid "Fetch information and keywords"
msgstr ""
-#: src/Module/Contact/Profile.php:299 src/Module/Contact/Profile.php:304
-#: src/Module/Contact/Profile.php:309 src/Module/Contact/Profile.php:315
+#: src/Module/Contact/Profile.php:312 src/Module/Contact/Profile.php:317
+#: src/Module/Contact/Profile.php:322 src/Module/Contact/Profile.php:328
msgid "No mirroring"
msgstr ""
-#: src/Module/Contact/Profile.php:300 src/Module/Contact/Profile.php:310
-#: src/Module/Contact/Profile.php:316
+#: src/Module/Contact/Profile.php:313 src/Module/Contact/Profile.php:323
+#: src/Module/Contact/Profile.php:329
msgid "Mirror as my own posting"
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"
msgstr ""
-#: src/Module/Contact/Profile.php:328
+#: src/Module/Contact/Profile.php:341
msgid "Contact Information / Notes"
msgstr ""
-#: src/Module/Contact/Profile.php:329
+#: src/Module/Contact/Profile.php:342
msgid "Contact Settings"
msgstr ""
-#: src/Module/Contact/Profile.php:337
+#: src/Module/Contact/Profile.php:350
msgid "Contact"
msgstr ""
-#: src/Module/Contact/Profile.php:341
+#: src/Module/Contact/Profile.php:354
msgid "Their personal note"
msgstr ""
-#: src/Module/Contact/Profile.php:343
+#: src/Module/Contact/Profile.php:356
msgid "Edit contact notes"
msgstr ""
-#: src/Module/Contact/Profile.php:347
+#: src/Module/Contact/Profile.php:360
msgid "Block/Unblock contact"
msgstr ""
-#: src/Module/Contact/Profile.php:348
+#: src/Module/Contact/Profile.php:361
#: src/Module/Moderation/Report/Create.php:293
msgid "Ignore contact"
msgstr ""
-#: src/Module/Contact/Profile.php:349
+#: src/Module/Contact/Profile.php:362
msgid "View conversations"
msgstr ""
-#: src/Module/Contact/Profile.php:354
+#: src/Module/Contact/Profile.php:367
msgid "Last update:"
msgstr ""
-#: src/Module/Contact/Profile.php:356
+#: src/Module/Contact/Profile.php:369
msgid "Update public posts"
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"
msgstr ""
-#: src/Module/Contact/Profile.php:360
+#: src/Module/Contact/Profile.php:373
msgid "Awaiting connection acknowledge"
msgstr ""
-#: src/Module/Contact/Profile.php:361
+#: src/Module/Contact/Profile.php:374
msgid "Currently blocked"
msgstr ""
-#: src/Module/Contact/Profile.php:362
+#: src/Module/Contact/Profile.php:375
msgid "Currently ignored"
msgstr ""
-#: src/Module/Contact/Profile.php:363
+#: src/Module/Contact/Profile.php:376
msgid "Currently collapsed"
msgstr ""
-#: src/Module/Contact/Profile.php:364
+#: src/Module/Contact/Profile.php:377
msgid "Currently archived"
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
msgid "Hide this contact from others"
msgstr ""
-#: src/Module/Contact/Profile.php:367
+#: src/Module/Contact/Profile.php:382
msgid ""
"Replies/likes to your public posts may still be visible"
msgstr ""
-#: src/Module/Contact/Profile.php:368
+#: src/Module/Contact/Profile.php:383
msgid "Notification for new posts"
msgstr ""
-#: src/Module/Contact/Profile.php:368
+#: src/Module/Contact/Profile.php:383
msgid "Send a notification of every new post of this contact"
msgstr ""
-#: src/Module/Contact/Profile.php:370
+#: src/Module/Contact/Profile.php:385
msgid "Keyword Deny List"
msgstr ""
-#: src/Module/Contact/Profile.php:370
+#: src/Module/Contact/Profile.php:385
msgid ""
"Comma separated list of keywords that should not be converted to hashtags, "
"when \"Fetch information and keywords\" is selected"
msgstr ""
-#: src/Module/Contact/Profile.php:388
+#: src/Module/Contact/Profile.php:403
#: src/Module/Settings/TwoFactor/Index.php:139
msgid "Actions"
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
msgid "Status"
msgstr ""
-#: src/Module/Contact/Profile.php:396
+#: src/Module/Contact/Profile.php:411
msgid "Mirror postings from this contact"
msgstr ""
-#: src/Module/Contact/Profile.php:398
+#: src/Module/Contact/Profile.php:413
msgid ""
"Mark this contact as remote_self, this will cause friendica to repost new "
"entries from this contact."
msgstr ""
-#: src/Module/Contact/Profile.php:468
+#: src/Module/Contact/Profile.php:483
msgid "Refetch contact data"
msgstr ""
-#: src/Module/Contact/Profile.php:479
+#: src/Module/Contact/Profile.php:494
msgid "Toggle Blocked status"
msgstr ""
-#: src/Module/Contact/Profile.php:487
+#: src/Module/Contact/Profile.php:502
msgid "Toggle Ignored status"
msgstr ""
-#: src/Module/Contact/Profile.php:495
+#: src/Module/Contact/Profile.php:510
msgid "Toggle Collapsed status"
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"
msgstr ""
-#: src/Module/Contact/Profile.php:504
+#: src/Module/Contact/Profile.php:519
msgid "Revoke the follow from this contact"
msgstr ""
@@ -6572,7 +6602,7 @@ msgstr ""
msgid "Posts that mention or involve you"
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"
msgstr ""
@@ -6938,42 +6968,42 @@ msgstr ""
msgid "Read about the Terms of Service of this node."
msgstr ""
-#: src/Module/Friendica.php:100
+#: src/Module/Friendica.php:99
msgid "On this server the following remote servers are blocked."
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:111
msgid "Reason for the block"
msgstr ""
-#: src/Module/Friendica.php:105
+#: src/Module/Friendica.php:104
msgid "Download this list in CSV format"
msgstr ""
-#: src/Module/Friendica.php:119
+#: src/Module/Friendica.php:118
#, php-format
msgid ""
"This is Friendica, version %s that is running at the web location %s. The "
"database version is %s, the post update version is %s."
msgstr ""
-#: src/Module/Friendica.php:124
+#: src/Module/Friendica.php:123
msgid ""
"Please visit Friendi.ca to learn more "
"about the Friendica project."
msgstr ""
-#: src/Module/Friendica.php:125
+#: src/Module/Friendica.php:124
msgid "Bug reports and issues: please visit"
msgstr ""
-#: src/Module/Friendica.php:125
+#: src/Module/Friendica.php:124
msgid "the bugtracker at github"
msgstr ""
-#: src/Module/Friendica.php:126
+#: src/Module/Friendica.php:125
msgid ""
"Suggestions, praise, etc. - please email \"info\" at \"friendi - dot - ca"
msgstr ""
@@ -7288,10 +7318,6 @@ msgid ""
"Theme Customization settings."
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
msgid "The feed for this item is unavailable."
msgstr ""
@@ -7550,6 +7576,8 @@ msgid "Matching known servers"
msgstr ""
#: 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"
msgstr ""
@@ -8520,21 +8548,21 @@ msgstr ""
msgid "Attributed To: %s "
msgstr ""
-#: src/Module/Photo.php:129
+#: src/Module/Photo.php:130
msgid "The Photo is not available."
msgstr ""
-#: src/Module/Photo.php:154
+#: src/Module/Photo.php:155
#, php-format
msgid "The Photo with id %s is not available."
msgstr ""
-#: src/Module/Photo.php:191
+#: src/Module/Photo.php:192
#, php-format
msgid "Invalid external resource with url %s."
msgstr ""
-#: src/Module/Photo.php:193
+#: src/Module/Photo.php:194
#, php-format
msgid "Invalid photo with id %s."
msgstr ""
@@ -8640,8 +8668,8 @@ msgstr ""
#: src/Module/Profile/Profile.php:158
#, php-format
msgid ""
-"You're currently viewing your profile as %sCancel"
+"You're currently viewing your profile as %sCancel"
msgstr ""
#: src/Module/Profile/Profile.php:167
@@ -9189,8 +9217,8 @@ msgstr ""
#: src/Module/Security/TwoFactor/Verify.php:100
#, php-format
msgid ""
-"If you do not have access to your authentication code you can use a two-factor recovery code."
+"If you do not have access to your authentication code you can use a two-factor recovery code."
msgstr ""
#: src/Module/Security/TwoFactor/Verify.php:101
@@ -10387,6 +10415,42 @@ msgstr ""
msgid "Please enter your password for verification:"
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 Information 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/Recovery.php:64
#: src/Module/Settings/TwoFactor/Trusted.php:67
@@ -10668,8 +10732,8 @@ msgstr ""
#: src/Module/Settings/TwoFactor/Verify.php:149
#, php-format
msgid ""
-"
Or you can open the following URL in your mobile device:
{{/if}}
{{* End of contact-edit-status-wrapper *}}
diff --git a/view/theme/frio/templates/js_strings.tpl b/view/theme/frio/templates/js_strings.tpl
index f979355d7..8077ceb9e 100644
--- a/view/theme/frio/templates/js_strings.tpl
+++ b/view/theme/frio/templates/js_strings.tpl
@@ -3,10 +3,12 @@
They are loaded into the html so that js functions can use them *}}