Merge remote-tracking branch 'upstream/develop' into subscription

This commit is contained in:
Michael 2023-08-28 04:15:37 +00:00
commit ff6d14a022
53 changed files with 2238 additions and 1133 deletions

View file

@ -1,6 +1,6 @@
-- ------------------------------------------
-- Friendica 2023.09-dev (Giant Rhubarb)
-- DB_UPDATE_VERSION 1524
-- DB_UPDATE_VERSION 1529
-- ------------------------------------------
@ -101,6 +101,19 @@ 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`),
INDEX `gsid` (`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
--
@ -160,8 +173,8 @@ CREATE TABLE IF NOT EXISTS `contact` (
`archive` boolean NOT NULL DEFAULT '0' COMMENT '',
`unsearchable` boolean NOT NULL DEFAULT '0' COMMENT 'Contact prefers to not be searchable',
`sensitive` boolean NOT NULL DEFAULT '0' COMMENT 'Contact posts sensitive content',
`baseurl` varbinary(383) DEFAULT '' COMMENT 'baseurl of the contact',
`gsid` int unsigned COMMENT 'Global Server ID',
`baseurl` varbinary(383) DEFAULT '' COMMENT 'baseurl of the contact from the gserver record, can be missing',
`gsid` int unsigned COMMENT 'Global Server ID, can be missing',
`bd` date NOT NULL DEFAULT '0001-01-01' COMMENT '',
`reason` text COMMENT '',
`self` boolean NOT NULL DEFAULT '0' COMMENT '1 if the contact is the user him/her self',
@ -1586,7 +1599,7 @@ CREATE TABLE IF NOT EXISTS `profile` (
`profile-name` varchar(255) COMMENT 'Deprecated',
`is-default` boolean COMMENT 'Deprecated',
`hide-friends` boolean NOT NULL DEFAULT '0' COMMENT 'Hide friend list from viewers of this profile',
`name` varchar(255) NOT NULL DEFAULT '' COMMENT '',
`name` varchar(255) NOT NULL DEFAULT '' COMMENT 'Unused in favor of user.username',
`pdesc` varchar(255) COMMENT 'Deprecated',
`dob` varchar(32) NOT NULL DEFAULT '0000-00-00' COMMENT 'Day of birth',
`address` varchar(255) NOT NULL DEFAULT '' COMMENT '',
@ -2032,6 +2045,7 @@ CREATE VIEW `post-user-view` AS SELECT
`author`.`hidden` AS `author-hidden`,
`author`.`updated` AS `author-updated`,
`author`.`gsid` AS `author-gsid`,
`author`.`baseurl` AS `author-baseurl`,
`post-user`.`owner-id` AS `owner-id`,
`owner`.`uri-id` AS `owner-uri-id`,
`owner`.`url` AS `owner-link`,
@ -2044,6 +2058,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 +2071,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 +2205,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 +2241,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 +2254,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 +2410,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 +2423,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 +2554,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 +2567,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`,
@ -2707,7 +2730,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

View file

@ -11,6 +11,8 @@ If you installed Friendica in the ``path/to/friendica`` folder:
2. Copy the following items from ``path/to/friendica`` to ``path/to/friendica_new``:
* ``config/local.config.php``
* ``proxy/``
* ``.htaccess`` if using Apache web server
The following items only need to be copied if they are located inside your friendica path:
* your storage folder as set in **Admin -> Site -> File Upload -> Storage base path**
* your item cache as set in **Admin -> Site -> Performance -> Path to item cache**

View file

@ -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 |

View file

@ -51,8 +51,8 @@ Fields
| archive | | boolean | NO | | 0 | |
| unsearchable | Contact prefers to not be searchable | boolean | NO | | 0 | |
| sensitive | Contact posts sensitive content | boolean | NO | | 0 | |
| baseurl | baseurl of the contact | varbinary(383) | YES | | | |
| gsid | Global Server ID | int unsigned | YES | | NULL | |
| baseurl | baseurl of the contact from the gserver record, can be missing | varbinary(383) | YES | | | |
| gsid | Global Server ID, can be missing | int unsigned | YES | | NULL | |
| bd | | date | NO | | 0001-01-01 | |
| reason | | text | YES | | NULL | |
| self | 1 if the contact is the user him/her self | boolean | NO | | 0 | |

View file

@ -13,7 +13,7 @@ Fields
| profile-name | Deprecated | varchar(255) | YES | | NULL | |
| is-default | Deprecated | boolean | YES | | NULL | |
| hide-friends | Hide friend list from viewers of this profile | boolean | NO | | 0 | |
| name | | varchar(255) | NO | | | |
| name | Unused in favor of user.username | varchar(255) | NO | | | |
| pdesc | Deprecated | varchar(255) | YES | | NULL | |
| dob | Day of birth | varchar(32) | NO | | 0000-00-00 | |
| address | | varchar(255) | NO | | | |

View file

@ -0,0 +1,31 @@
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 |
| gsid | gsid |
Foreign Keys
------------
| Field | Target Table | Target Field |
|-------|--------------|--------------|
| uid | [user](help/database/db_user) | uid |
| gsid | [gserver](help/database/db_gserver) | id |
Return to [database documentation](help/database)

View file

@ -246,9 +246,11 @@ 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?'),
'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'),

View file

@ -46,6 +46,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;
@ -91,8 +93,10 @@ 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;
@ -107,6 +111,7 @@ class Conversation
$this->page = $page;
$this->app = $app;
$this->session = $session;
$this->userGServer = $userGServer;
}
/**
@ -460,8 +465,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.
@ -487,7 +498,7 @@ class Conversation
. "'; </script>\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';
@ -512,7 +523,7 @@ class Conversation
. "; var netargs = '?f='; </script>\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 = '<div id="live-display"></div>' . "\r\n"
@ -520,7 +531,7 @@ class Conversation
. "</script>";
}
} 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 = '<div id="live-community"></div>' . "\r\n"
@ -531,7 +542,7 @@ class Conversation
. "'; </script>\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 = '<div id="live-contact"></div>' . "\r\n"
@ -818,13 +829,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) {
@ -906,6 +918,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;
}
@ -1468,6 +1487,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']),

View file

@ -34,15 +34,16 @@ use Friendica\Core\Protocol;
use Friendica\Core\Session\Capability\IHandleUserSessions;
use Friendica\Core\System;
use Friendica\Database\DBA;
use Friendica\DI;
use Friendica\Model\Attach;
use Friendica\Model\Circle;
use Friendica\Model\Contact;
use Friendica\Model\Conversation;
use Friendica\Model\FileTag;
use Friendica\Model\Circle;
use Friendica\Model\Item as ItemModel;
use Friendica\Model\Photo;
use Friendica\Model\Tag;
use Friendica\Model\Post;
use Friendica\Model\Tag;
use Friendica\Model\User;
use Friendica\Network\HTTPException;
use Friendica\Object\EMail\ItemCCEMail;
@ -54,6 +55,7 @@ use Friendica\Util\ParseUrl;
use Friendica\Util\Profiler;
use Friendica\Util\Proxy;
use Friendica\Util\XML;
use GuzzleHttp\Psr7\Uri;
/**
* A content helper class for displaying items
@ -367,7 +369,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 +409,11 @@ class Item
$collapse_link = $item['self'] ? '' : $contact_url . '/collapse?t=' . $formSecurityToken;
}
$authorBaseUri = new Uri($item['author-baseurl'] ?? '');
if (!empty($item['author-gsid']) && $authorBaseUri->getHost() && !DI::baseUrl()->isLocalUrl($authorBaseUri)) {
$ignoreserver_link = 'settings/server/' . $item['author-gsid'] . '/ignore';
}
if ($cid && !$item['self']) {
$contact_url = 'contact/' . $cid;
$posts_link = $contact_url . '/posts';
@ -427,7 +434,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 server", $authorBaseUri->getHost()) => $ignoreserver_link,
];
if (!empty($item['language'])) {

View file

@ -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
//

View file

@ -0,0 +1,151 @@
<?php
/**
* @copyright Copyright (C) 2010-2023, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\Federation\Entity;
use DateTimeImmutable;
use Psr\Http\Message\UriInterface;
/**
* @property-read int $id
* @property-read string $url
* @property-read string $nurl
* @property-read string $version
* @property-read string $siteName
* @property-read string $info
* @property-read int $registerPolicy
* @property-read int $registeredUsers
* @property-read string $poco
* @property-read string $noscrape
* @property-read string $network
* @property-read string $platform
* @property-read int $relaySubscribe
* @property-read string $relayScope
* @property-read DateTimeImmutable $created
* @property-read ?DateTimeImmutable $lastPocoQuery
* @property-read ?DateTimeImmutable $lastContact
* @property-read ?DateTimeImmutable $lastFailure
* @property-read int $directoryType
* @property-read int $detectionMethod
* @property-read bool $failed
* @property-read DateTimeImmutable $nextContact
* @property-read int $protocol
* @property-read int $activeWeekUsers
* @property-read int $activeMonthUsers
* @property-read int $activeHalfyearUsers
* @property-read int $localPosts
* @property-read int $localComments
* @property-read bool $blocked
*/
class GServer extends \Friendica\BaseEntity
{
/** @var ?int */
protected $id;
/** @var UriInterface */
protected $url;
/** @var UriInterface */
protected $nurl;
/** @var string */
protected $version;
/** @var string */
protected $siteName;
/** @var string */
protected $info;
/** @var int One of Module\Register::* constant values */
protected $registerPolicy;
/** @var int */
protected $registeredUsers;
/** @var ?UriInterface */
protected $poco;
/** @var ?UriInterface */
protected $noscrape;
/** @var string One of the Protocol::* constant values */
protected $network;
/** @var string */
protected $platform;
/** @var bool */
protected $relaySubscribe;
/** @var string */
protected $relayScope;
/** @var DateTimeImmutable */
protected $created;
/** @var DateTimeImmutable */
protected $lastPocoQuery;
/** @var DateTimeImmutable */
protected $lastContact;
/** @var DateTimeImmutable */
protected $lastFailure;
/** @var int One of Model\Gserver::DT_* constant values */
protected $directoryType;
/** @var ?int One of Model\Gserver::DETECT_* constant values */
protected $detectionMethod;
/** @var bool */
protected $failed;
/** @var DateTimeImmutable */
protected $nextContact;
/** @var ?int One of Model\Post\DeliveryData::* constant values */
protected $protocol;
/** @var ?int */
protected $activeWeekUsers;
/** @var ?int */
protected $activeMonthUsers;
/** @var ?int */
protected $activeHalfyearUsers;
/** @var ?int */
protected $localPosts;
/** @var ?int */
protected $localComments;
/** @var bool */
protected $blocked;
public function __construct(UriInterface $url, UriInterface $nurl, string $version, string $siteName, string $info, int $registerPolicy, int $registeredUsers, ?UriInterface $poco, ?UriInterface $noscrape, string $network, string $platform, bool $relaySubscribe, string $relayScope, DateTimeImmutable $created, ?DateTimeImmutable $lastPocoQuery, ?DateTimeImmutable $lastContact, ?DateTimeImmutable $lastFailure, int $directoryType, ?int $detectionMethod, bool $failed, ?DateTimeImmutable $nextContact, ?int $protocol, ?int $activeWeekUsers, ?int $activeMonthUsers, ?int $activeHalfyearUsers, ?int $localPosts, ?int $localComments, bool $blocked, ?int $id = null)
{
$this->url = $url;
$this->nurl = $nurl;
$this->version = $version;
$this->siteName = $siteName;
$this->info = $info;
$this->registerPolicy = $registerPolicy;
$this->registeredUsers = $registeredUsers;
$this->poco = $poco;
$this->noscrape = $noscrape;
$this->network = $network;
$this->platform = $platform;
$this->relaySubscribe = $relaySubscribe;
$this->relayScope = $relayScope;
$this->created = $created;
$this->lastPocoQuery = $lastPocoQuery;
$this->lastContact = $lastContact;
$this->lastFailure = $lastFailure;
$this->directoryType = $directoryType;
$this->detectionMethod = $detectionMethod;
$this->failed = $failed;
$this->nextContact = $nextContact;
$this->protocol = $protocol;
$this->activeWeekUsers = $activeWeekUsers;
$this->activeMonthUsers = $activeMonthUsers;
$this->activeHalfyearUsers = $activeHalfyearUsers;
$this->localPosts = $localPosts;
$this->localComments = $localComments;
$this->blocked = $blocked;
$this->id = $id;
}
}

View file

@ -0,0 +1,68 @@
<?php
/**
* @copyright Copyright (C) 2010-2023, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\Federation\Factory;
use Friendica\Capabilities\ICanCreateFromTableRow;
use Friendica\Database\DBA;
use Friendica\Federation\Entity;
use GuzzleHttp\Psr7\Uri;
class GServer extends \Friendica\BaseFactory implements ICanCreateFromTableRow
{
/**
* @inheritDoc
*/
public function createFromTableRow(array $row): Entity\GServer
{
return new Entity\GServer(
new Uri($row['url']),
new Uri($row['nurl']),
$row['version'],
$row['site_name'],
$row['info'] ?? '',
$row['register_policy'],
$row['registered-users'],
$row['poco'] ? new Uri($row['poco']) : null,
$row['noscrape'] ? new Uri($row['noscrape']) : null,
$row['network'],
$row['platform'],
$row['relay-subscribe'],
$row['relay-scope'],
new \DateTimeImmutable($row['created']),
$row['last_poco_query'] !== DBA::NULL_DATETIME ? new \DateTimeImmutable($row['last_poco_query']) : null,
$row['last_contact'] !== DBA::NULL_DATETIME ? new \DateTimeImmutable($row['last_contact']) : null,
$row['last_failure'] !== DBA::NULL_DATETIME ? new \DateTimeImmutable($row['last_failure']) : null,
$row['directory-type'],
$row['detection-method'],
$row['failed'],
$row['next_contact'] !== DBA::NULL_DATETIME ? new \DateTimeImmutable($row['next_contact']) : null,
$row['protocol'],
$row['active-week-users'],
$row['active-month-users'],
$row['active-halfyear-users'],
$row['local-posts'],
$row['local-comments'],
$row['blocked'],
$row['id'],
);
}
}

View file

@ -0,0 +1,47 @@
<?php
/**
* @copyright Copyright (C) 2010-2023, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\Federation\Repository;
use Friendica\Database\Database;
use Friendica\Federation\Factory;
use Friendica\Federation\Entity;
use Psr\Log\LoggerInterface;
class GServer extends \Friendica\BaseRepository
{
protected static $table_name = 'gserver';
public function __construct(Database $database, LoggerInterface $logger, Factory\GServer $factory)
{
parent::__construct($database, $logger, $factory);
}
/**
* @param int $gsid
* @return Entity\GServer
* @throws \Friendica\Network\HTTPException\NotFoundException
*/
public function selectOneById(int $gsid): Entity\GServer
{
return $this->_selectOne(['id' => $gsid]);
}
}

View file

@ -791,7 +791,7 @@ class Contact
* @param int $uid
* @param bool $update_avatar Force the avatar update
* @return bool "true" if updated
* @throws HTTPException\InternalServerErrorException
* @throws \Exception
*/
public static function updateSelfFromUserID(int $uid, bool $update_avatar = false): bool
{

View file

@ -96,9 +96,9 @@ class Item
'wall', 'private', 'starred', 'origin', 'parent-origin', 'title', 'body', 'language',
'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',
'author-id', 'author-link', 'author-alias', 'author-name', 'author-avatar', 'author-network', 'author-updated', 'author-gsid', 'author-baseurl', 'author-addr', 'author-uri-id',
'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',

View file

@ -453,12 +453,10 @@ class Post
AND (NOT `causer-blocked` OR `causer-id` = ? OR `causer-id` IS NULL) AND NOT `contact-blocked`
AND ((NOT `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));

View file

@ -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;

View file

@ -37,6 +37,7 @@ use Friendica\DI;
use Friendica\Network\HTTPClient\Client\HttpClientAccept;
use Friendica\Network\HTTPClient\Client\HttpClientOptions;
use Friendica\Network\HTTPException;
use Friendica\Network\HTTPException\InternalServerErrorException;
use Friendica\Protocol\Activity;
use Friendica\Protocol\Diaspora;
use Friendica\Security\PermissionSet\Entity\PermissionSet;
@ -97,6 +98,7 @@ class Profile
* @param integer $uid User id
*
* @return boolean Whether update was successful
* @throws \Exception
*/
public static function update(array $fields, int $uid): bool
{
@ -116,10 +118,6 @@ class Profile
return false;
}
if ($old_owner['name'] != $owner['name']) {
User::update(['username' => $owner['name']], $uid);
}
$profile_fields = ['postal-code', 'dob', 'prv_keywords', 'homepage'];
foreach ($profile_fields as $field) {
if ($old_owner[$field] != $owner[$field]) {

View file

@ -37,6 +37,7 @@ use Friendica\Database\DBA;
use Friendica\DI;
use Friendica\Module;
use Friendica\Network\HTTPClient\Client\HttpClientAccept;
use Friendica\Network\HTTPException\InternalServerErrorException;
use Friendica\Security\TwoFactor\Model\AppSpecificPassword;
use Friendica\Network\HTTPException;
use Friendica\Object\Image;
@ -1331,30 +1332,15 @@ class User
* @param array $fields
* @param integer $uid
* @return boolean
* @throws Exception
*/
public static function update(array $fields, int $uid): bool
{
$old_owner = self::getOwnerDataById($uid);
if (empty($old_owner)) {
return false;
}
if (!DBA::update('user', $fields, ['uid' => $uid])) {
return false;
}
$update = Contact::updateSelfFromUserID($uid);
$owner = self::getOwnerDataById($uid);
if (empty($owner)) {
return false;
}
if ($old_owner['name'] != $owner['name']) {
Profile::update(['name' => $owner['name']], $uid);
}
if ($update) {
if (Contact::updateSelfFromUserID($uid)) {
Profile::publishUpdate($uid);
}

View file

@ -48,7 +48,7 @@ final class Report extends \Friendica\BaseRepository
$this->factory = $factory;
$this->postFactory = $postFactory;
$this->ruleFactory = $postFactory;
$this->ruleFactory = $ruleFactory;
}
public function selectOneById(int $lastInsertId): \Friendica\Moderation\Entity\Report

View file

@ -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',

View file

@ -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,17 @@ class Profile extends BaseModule
$insecure = $this->t('Private communications are not available for this contact.');
// @TODO: Figure out why gsid can be empty
if (empty($contact['gsid'])) {
$this->logger->notice('Empty gsid for contact', ['contact' => $contact]);
}
$serverIgnored =
$contact['gsid'] &&
$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 +382,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 <strong>may</strong> still be visible')],
'$notify_new_posts' => ['notify_new_posts', $this->t('Notification for new posts'), ($localRelationship->notifyNewPosts), $this->t('Send a notification of every new post of this contact')],
@ -413,11 +434,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 +539,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;
}

View file

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

View file

@ -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) {

View file

@ -38,6 +38,8 @@ class RobotsTxt extends BaseModule
'/search',
'/help',
'/proxy',
'/photo',
'/avatar',
];
header('Content-Type: text/plain');
@ -50,6 +52,10 @@ class RobotsTxt extends BaseModule
echo 'User-agent: ChatGPT-User' . PHP_EOL;
echo 'Disallow: /' . PHP_EOL;
echo PHP_EOL;
echo 'User-agent: GPTBot' . PHP_EOL;
echo 'Disallow: /' . PHP_EOL;
System::exit();
}
}

View file

@ -573,7 +573,7 @@ class Account extends BaseSettings
'$delete_openid' => ['delete_openid', DI::l10n()->t('Delete OpenID URL'), false, ''],
'$h_basic' => DI::l10n()->t('Basic Settings'),
'$username' => ['username', DI::l10n()->t('Full Name:'), $username, '', false, 'autocomplete="off"'],
'$username' => ['username', DI::l10n()->t('Display name:'), $username, '', false, 'autocomplete="off"'],
'$email' => ['email', DI::l10n()->t('Email Address:'), $email, '', '', 'autocomplete="off"', 'email'],
'$timezone' => ['timezone_select', DI::l10n()->t('Your Timezone:'), Temporal::getTimezoneSelect($timezone), ''],
'$language' => ['language', DI::l10n()->t('Your Language:'), $language, DI::l10n()->t('Set the language we use to show you friendica interface and to send you emails'), $lang_choices],

View file

@ -21,43 +21,75 @@
namespace Friendica\Module\Settings\Profile;
use Friendica\App;
use Friendica\Core\ACL;
use Friendica\Core\Hook;
use Friendica\Core\L10n;
use Friendica\Core\Protocol;
use Friendica\Core\Renderer;
use Friendica\Core\Session\Capability\IHandleUserSessions;
use Friendica\Core\Theme;
use Friendica\Database\DBA;
use Friendica\DI;
use Friendica\Model\Contact;
use Friendica\Model\Profile;
use Friendica\Profile\ProfileField\Collection\ProfileFields;
use Friendica\Profile\ProfileField\Entity\ProfileField;
use Friendica\Module\Response;
use Friendica\Navigation\SystemMessages;
use Friendica\Profile\ProfileField;
use Friendica\Model\User;
use Friendica\Module\BaseSettings;
use Friendica\Module\Security\Login;
use Friendica\Network\HTTPException;
use Friendica\Security\PermissionSet;
use Friendica\Util\ACLFormatter;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Profiler;
use Friendica\Util\Temporal;
use Friendica\Core\Worker;
use Psr\Log\LoggerInterface;
class Index extends BaseSettings
{
/** @var ProfileField\Repository\ProfileField */
private $profileFieldRepo;
/** @var ProfileField\Factory\ProfileField */
private $profileFieldFactory;
/** @var SystemMessages */
private $systemMessages;
/** @var PermissionSet\Repository\PermissionSet */
private $permissionSetRepo;
/** @var PermissionSet\Factory\PermissionSet */
private $permissionSetFactory;
/** @var ACLFormatter */
private $aclFormatter;
public function __construct(ACLFormatter $aclFormatter, PermissionSet\Factory\PermissionSet $permissionSetFactory, PermissionSet\Repository\PermissionSet $permissionSetRepo, SystemMessages $systemMessages, ProfileField\Factory\ProfileField $profileFieldFactory, ProfileField\Repository\ProfileField $profileFieldRepo, 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->profileFieldRepo = $profileFieldRepo;
$this->profileFieldFactory = $profileFieldFactory;
$this->systemMessages = $systemMessages;
$this->permissionSetRepo = $permissionSetRepo;
$this->permissionSetFactory = $permissionSetFactory;
$this->aclFormatter = $aclFormatter;
}
protected function post(array $request = [])
{
if (!DI::userSession()->getLocalUserId()) {
if (!$this->session->getLocalUserId()) {
return;
}
$profile = Profile::getByUID(DI::userSession()->getLocalUserId());
if (!DBA::isResult($profile)) {
$profile = Profile::getByUID($this->session->getLocalUserId());
if (!$profile) {
return;
}
self::checkFormSecurityTokenRedirectOnError('/settings/profile', 'settings_profile');
Hook::callAll('profile_post', $_POST);
Hook::callAll('profile_post', $request);
$dob = trim($_POST['dob'] ?? '');
$dob = trim($request['dob'] ?? '');
if ($dob && !in_array($dob, ['0000-00-00', DBA::NULL_DATE])) {
$y = substr($dob, 0, 4);
@ -79,39 +111,40 @@ class Index extends BaseSettings
}
}
$name = trim($_POST['name'] ?? '');
if (!strlen($name)) {
DI::sysmsg()->addNotice(DI::l10n()->t('Profile Name is required.'));
$username = trim($request['username'] ?? '');
if (!$username) {
$this->systemMessages->addNotice($this->t('Display Name is required.'));
return;
}
$about = trim($_POST['about']);
$address = trim($_POST['address']);
$locality = trim($_POST['locality']);
$region = trim($_POST['region']);
$postal_code = trim($_POST['postal_code']);
$country_name = trim($_POST['country_name']);
$pub_keywords = self::cleanKeywords(trim($_POST['pub_keywords']));
$prv_keywords = self::cleanKeywords(trim($_POST['prv_keywords']));
$xmpp = trim($_POST['xmpp']);
$matrix = trim($_POST['matrix']);
$homepage = trim($_POST['homepage']);
$about = trim($request['about']);
$address = trim($request['address']);
$locality = trim($request['locality']);
$region = trim($request['region']);
$postal_code = trim($request['postal_code']);
$country_name = trim($request['country_name']);
$pub_keywords = self::cleanKeywords(trim($request['pub_keywords']));
$prv_keywords = self::cleanKeywords(trim($request['prv_keywords']));
$xmpp = trim($request['xmpp']);
$matrix = trim($request['matrix']);
$homepage = trim($request['homepage']);
if ((strpos($homepage, 'http') !== 0) && (strlen($homepage))) {
// neither http nor https in URL, add them
$homepage = 'http://' . $homepage;
}
$profileFieldsNew = self::getProfileFieldsFromInput(
DI::userSession()->getLocalUserId(),
$_REQUEST['profile_field'],
$_REQUEST['profile_field_order']
$profileFieldsNew = $this->getProfileFieldsFromInput(
$this->session->getLocalUserId(),
$request['profile_field'],
$request['profile_field_order']
);
DI::profileField()->saveCollectionForUser(DI::userSession()->getLocalUserId(), $profileFieldsNew);
$this->profileFieldRepo->saveCollectionForUser($this->session->getLocalUserId(), $profileFieldsNew);
User::update(['username' => $username], $this->session->getLocalUserId());
$result = Profile::update(
[
'name' => $name,
'about' => $about,
'dob' => $dob,
'address' => $address,
@ -125,23 +158,23 @@ class Index extends BaseSettings
'pub_keywords' => $pub_keywords,
'prv_keywords' => $prv_keywords,
],
DI::userSession()->getLocalUserId()
$this->session->getLocalUserId()
);
Worker::add(Worker::PRIORITY_MEDIUM, 'CheckRelMeProfileLink', DI::userSession()->getLocalUserId());
Worker::add(Worker::PRIORITY_MEDIUM, 'CheckRelMeProfileLink', $this->session->getLocalUserId());
if (!$result) {
DI::sysmsg()->addNotice(DI::l10n()->t('Profile couldn\'t be updated.'));
$this->systemMessages->addNotice($this->t("Profile couldn't be updated."));
return;
}
DI::baseUrl()->redirect('settings/profile');
$this->baseUrl->redirect('settings/profile');
}
protected function content(array $request = []): string
{
if (!DI::userSession()->getLocalUserId()) {
DI::sysmsg()->addNotice(DI::l10n()->t('You must be logged in to use this module'));
if (!$this->session->getLocalUserId()) {
$this->systemMessages->addNotice($this->t('You must be logged in to use this module'));
return Login::form();
}
@ -149,21 +182,18 @@ class Index extends BaseSettings
$o = '';
$profile = User::getOwnerDataById(DI::userSession()->getLocalUserId());
if (!DBA::isResult($profile)) {
$owner = User::getOwnerDataById($this->session->getLocalUserId());
if (!$owner) {
throw new HTTPException\NotFoundException();
}
$a = DI::app();
DI::page()->registerFooterScript('view/asset/es-jquery-sortable/source/js/jquery-sortable-min.js');
DI::page()->registerFooterScript(Theme::getPathForFile('js/module/settings/profile/index.js'));
$this->page->registerFooterScript('view/asset/es-jquery-sortable/source/js/jquery-sortable-min.js');
$this->page->registerFooterScript(Theme::getPathForFile('js/module/settings/profile/index.js'));
$custom_fields = [];
$profileFields = DI::profileField()->selectByUserId(DI::userSession()->getLocalUserId());
$profileFields = $this->profileFieldRepo->selectByUserId($this->session->getLocalUserId());
foreach ($profileFields as $profileField) {
/** @var ProfileField $profileField */
$defaultPermissions = $profileField->permissionSet->withAllowedContacts(
Contact::pruneUnavailable($profileField->permissionSet->allow_cid)
);
@ -172,124 +202,125 @@ class Index extends BaseSettings
'id' => $profileField->id,
'legend' => $profileField->label,
'fields' => [
'label' => ['profile_field[' . $profileField->id . '][label]', DI::l10n()->t('Label:'), $profileField->label],
'value' => ['profile_field[' . $profileField->id . '][value]', DI::l10n()->t('Value:'), $profileField->value],
'label' => ['profile_field[' . $profileField->id . '][label]', $this->t('Label:'), $profileField->label],
'value' => ['profile_field[' . $profileField->id . '][value]', $this->t('Value:'), $profileField->value],
'acl' => ACL::getFullSelectorHTML(
DI::page(),
$a->getLoggedInUserId(),
$this->page,
$this->session->getLocalUserId(),
false,
$defaultPermissions->toArray(),
['network' => Protocol::DFRN],
'profile_field[' . $profileField->id . ']'
),
],
'permissions' => DI::l10n()->t('Field Permissions'),
'permdesc' => DI::l10n()->t("(click to open/close)"),
'permissions' => $this->t('Field Permissions'),
'permdesc' => $this->t("(click to open/close)"),
];
};
}
$custom_fields[] = [
'id' => 'new',
'legend' => DI::l10n()->t('Add a new profile field'),
'legend' => $this->t('Add a new profile field'),
'fields' => [
'label' => ['profile_field[new][label]', DI::l10n()->t('Label:')],
'value' => ['profile_field[new][value]', DI::l10n()->t('Value:')],
'label' => ['profile_field[new][label]', $this->t('Label:')],
'value' => ['profile_field[new][value]', $this->t('Value:')],
'acl' => ACL::getFullSelectorHTML(
DI::page(),
$a->getLoggedInUserId(),
$this->page,
$this->session->getLocalUserId(),
false,
['allow_cid' => []],
['network' => Protocol::DFRN],
'profile_field[new]'
),
],
'permissions' => DI::l10n()->t('Field Permissions'),
'permdesc' => DI::l10n()->t("(click to open/close)"),
'permissions' => $this->t('Field Permissions'),
'permdesc' => $this->t("(click to open/close)"),
];
DI::page()['htmlhead'] .= Renderer::replaceMacros(Renderer::getMarkupTemplate('settings/profile/index_head.tpl'), [
]);
$this->page['htmlhead'] .= Renderer::replaceMacros(Renderer::getMarkupTemplate('settings/profile/index_head.tpl'));
$personal_account = ($profile['account-type'] != User::ACCOUNT_TYPE_COMMUNITY);
$personal_account = ($owner['account-type'] != User::ACCOUNT_TYPE_COMMUNITY);
if ($profile['homepage_verified']) {
$homepage_help_text = DI::l10n()->t('The homepage is verified. A rel="me" link back to your Friendica profile page was found on the homepage.');
if ($owner['homepage_verified']) {
$homepage_help_text = $this->t('The homepage is verified. A rel="me" link back to your Friendica profile page was found on the homepage.');
} else {
$homepage_help_text = DI::l10n()->t('To verify your homepage, add a rel="me" link to it, pointing to your profile URL (%s).', $profile['url']);
$homepage_help_text = $this->t('To verify your homepage, add a rel="me" link to it, pointing to your profile URL (%s).', $owner['url']);
}
$tpl = Renderer::getMarkupTemplate('settings/profile/index.tpl');
$o .= Renderer::replaceMacros($tpl, [
'$l10n' => [
'profile_action' => $this->t('Profile Actions'),
'banner' => $this->t('Edit Profile Details'),
'submit' => $this->t('Submit'),
'profpic' => $this->t('Change Profile Photo'),
'viewprof' => $this->t('View Profile'),
'personal_section' => $this->t('Personal'),
'picture_section' => $this->t('Profile picture'),
'location_section' => $this->t('Location'),
'miscellaneous_section' => $this->t('Miscellaneous'),
'custom_fields_section' => $this->t('Custom Profile Fields'),
'profile_photo' => $this->t('Upload Profile Photo'),
'custom_fields_description' => $this->t('<p>Custom fields appear on <a href="%s">your profile page</a>.</p>
<p>You can use BBCodes in the field values.</p>
<p>Reorder by dragging the field title.</p>
<p>Empty the label field to remove a custom field.</p>
<p>Non-public fields can only be seen by the selected Friendica contacts or the Friendica contacts in the selected circles.</p>',
'profile/' . $owner['nickname'] . '/profile'
),
],
'$personal_account' => $personal_account,
'$form_security_token' => self::getFormSecurityToken('settings_profile'),
'$form_security_token_photo' => self::getFormSecurityToken('settings_profile_photo'),
'$profile_action' => DI::l10n()->t('Profile Actions'),
'$banner' => DI::l10n()->t('Edit Profile Details'),
'$submit' => DI::l10n()->t('Submit'),
'$profpic' => DI::l10n()->t('Change Profile Photo'),
'$profpiclink' => '/profile/' . $profile['nickname'] . '/photos',
'$viewprof' => DI::l10n()->t('View Profile'),
'$profpiclink' => '/profile/' . $owner['nickname'] . '/photos',
'$lbl_personal_section' => DI::l10n()->t('Personal'),
'$lbl_picture_section' => DI::l10n()->t('Profile picture'),
'$lbl_location_section' => DI::l10n()->t('Location'),
'$lbl_miscellaneous_section' => DI::l10n()->t('Miscellaneous'),
'$lbl_custom_fields_section' => DI::l10n()->t('Custom Profile Fields'),
'$lbl_profile_photo' => DI::l10n()->t('Upload Profile Photo'),
'$baseurl' => DI::baseUrl(),
'$nickname' => $profile['nickname'],
'$name' => ['name', DI::l10n()->t('Display name:'), $profile['name']],
'$about' => ['about', DI::l10n()->t('Description:'), $profile['about']],
'$dob' => Temporal::getDateofBirthField($profile['dob'], $profile['timezone']),
'$address' => ['address', DI::l10n()->t('Street Address:'), $profile['address']],
'$locality' => ['locality', DI::l10n()->t('Locality/City:'), $profile['locality']],
'$region' => ['region', DI::l10n()->t('Region/State:'), $profile['region']],
'$postal_code' => ['postal_code', DI::l10n()->t('Postal/Zip Code:'), $profile['postal-code']],
'$country_name' => ['country_name', DI::l10n()->t('Country:'), $profile['country-name']],
'$age' => ((intval($profile['dob'])) ? '(' . DI::l10n()->t('Age: ') . DI::l10n()->tt('%d year old', '%d years old', Temporal::getAgeByTimezone($profile['dob'], $profile['timezone'])) . ')' : ''),
'$xmpp' => ['xmpp', DI::l10n()->t('XMPP (Jabber) address:'), $profile['xmpp'], DI::l10n()->t('The XMPP address will be published so that people can follow you there.')],
'$matrix' => ['matrix', DI::l10n()->t('Matrix (Element) address:'), $profile['matrix'], DI::l10n()->t('The Matrix address will be published so that people can follow you there.')],
'$homepage' => ['homepage', DI::l10n()->t('Homepage URL:'), $profile['homepage'], $homepage_help_text],
'$pub_keywords' => ['pub_keywords', DI::l10n()->t('Public Keywords:'), $profile['pub_keywords'], DI::l10n()->t('(Used for suggesting potential friends, can be seen by others)')],
'$prv_keywords' => ['prv_keywords', DI::l10n()->t('Private Keywords:'), $profile['prv_keywords'], DI::l10n()->t('(Used for searching profiles, never shown to others)')],
'$custom_fields_description' => DI::l10n()->t("<p>Custom fields appear on <a href=\"%s\">your profile page</a>.</p>
<p>You can use BBCodes in the field values.</p>
<p>Reorder by dragging the field title.</p>
<p>Empty the label field to remove a custom field.</p>
<p>Non-public fields can only be seen by the selected Friendica contacts or the Friendica contacts in the selected circles.</p>",
'profile/' . $profile['nickname'] . '/profile'
),
'$nickname' => $owner['nickname'],
'$username' => ['username', $this->t('Display name:'), $owner['name']],
'$about' => ['about', $this->t('Description:'), $owner['about']],
'$dob' => Temporal::getDateofBirthField($owner['dob'], $owner['timezone']),
'$address' => ['address', $this->t('Street Address:'), $owner['address']],
'$locality' => ['locality', $this->t('Locality/City:'), $owner['locality']],
'$region' => ['region', $this->t('Region/State:'), $owner['region']],
'$postal_code' => ['postal_code', $this->t('Postal/Zip Code:'), $owner['postal-code']],
'$country_name' => ['country_name', $this->t('Country:'), $owner['country-name']],
'$age' => ((intval($owner['dob'])) ? '(' . $this->t('Age: ') . $this->tt('%d year old', '%d years old', Temporal::getAgeByTimezone($owner['dob'], $owner['timezone'])) . ')' : ''),
'$xmpp' => ['xmpp', $this->t('XMPP (Jabber) address:'), $owner['xmpp'], $this->t('The XMPP address will be published so that people can follow you there.')],
'$matrix' => ['matrix', $this->t('Matrix (Element) address:'), $owner['matrix'], $this->t('The Matrix address will be published so that people can follow you there.')],
'$homepage' => ['homepage', $this->t('Homepage URL:'), $owner['homepage'], $homepage_help_text],
'$pub_keywords' => ['pub_keywords', $this->t('Public Keywords:'), $owner['pub_keywords'], $this->t('(Used for suggesting potential friends, can be seen by others)')],
'$prv_keywords' => ['prv_keywords', $this->t('Private Keywords:'), $owner['prv_keywords'], $this->t('(Used for searching profiles, never shown to others)')],
'$custom_fields' => $custom_fields,
]);
$arr = ['profile' => $profile, 'entry' => $o];
$arr = ['profile' => $owner, 'entry' => $o];
Hook::callAll('profile_edit', $arr);
return $o;
}
private static function getProfileFieldsFromInput(int $uid, array $profileFieldInputs, array $profileFieldOrder): ProfileFields
private function getProfileFieldsFromInput(int $uid, array $profileFieldInputs, array $profileFieldOrder): ProfileField\Collection\ProfileFields
{
$profileFields = new ProfileFields();
$profileFields = new ProfileField\Collection\ProfileFields();
// Returns an associative array of id => order values
$profileFieldOrder = array_flip($profileFieldOrder);
// Creation of the new field
if (!empty($profileFieldInputs['new']['label'])) {
$permissionSet = DI::permissionSet()->selectOrCreate(DI::permissionSetFactory()->createFromString(
$permissionSet = $this->permissionSetRepo->selectOrCreate($this->permissionSetFactory->createFromString(
$uid,
DI::aclFormatter()->toString($profileFieldInputs['new']['contact_allow'] ?? ''),
DI::aclFormatter()->toString($profileFieldInputs['new']['circle_allow'] ?? ''),
DI::aclFormatter()->toString($profileFieldInputs['new']['contact_deny'] ?? ''),
DI::aclFormatter()->toString($profileFieldInputs['new']['circle_deny'] ?? '')
$this->aclFormatter->toString($profileFieldInputs['new']['contact_allow'] ?? ''),
$this->aclFormatter->toString($profileFieldInputs['new']['circle_allow'] ?? ''),
$this->aclFormatter->toString($profileFieldInputs['new']['contact_deny'] ?? ''),
$this->aclFormatter->toString($profileFieldInputs['new']['circle_deny'] ?? '')
));
$profileFields->append(DI::profileFieldFactory()->createFromValues(
$profileFields->append($this->profileFieldFactory->createFromValues(
$uid,
$profileFieldOrder['new'],
$profileFieldInputs['new']['label'],
@ -302,15 +333,15 @@ class Index extends BaseSettings
unset($profileFieldOrder['new']);
foreach ($profileFieldInputs as $id => $profileFieldInput) {
$permissionSet = DI::permissionSet()->selectOrCreate(DI::permissionSetFactory()->createFromString(
$permissionSet = $this->permissionSetRepo->selectOrCreate($this->permissionSetFactory->createFromString(
$uid,
DI::aclFormatter()->toString($profileFieldInput['contact_allow'] ?? ''),
DI::aclFormatter()->toString($profileFieldInput['circle_allow'] ?? ''),
DI::aclFormatter()->toString($profileFieldInput['contact_deny'] ?? ''),
DI::aclFormatter()->toString($profileFieldInput['circle_deny'] ?? '')
$this->aclFormatter->toString($profileFieldInput['contact_allow'] ?? ''),
$this->aclFormatter->toString($profileFieldInput['circle_allow'] ?? ''),
$this->aclFormatter->toString($profileFieldInput['contact_deny'] ?? ''),
$this->aclFormatter->toString($profileFieldInput['circle_deny'] ?? '')
));
$profileFields->append(DI::profileFieldFactory()->createFromValues(
$profileFields->append($this->profileFieldFactory->createFromValues(
$uid,
$profileFieldOrder[$id],
$profileFieldInput['label'],
@ -322,22 +353,20 @@ class Index extends BaseSettings
return $profileFields;
}
private static function cleanKeywords($keywords)
private static function cleanKeywords($keywords): string
{
$keywords = str_replace(',', ' ', $keywords);
$keywords = explode(' ', $keywords);
$cleaned = [];
foreach ($keywords as $keyword) {
$keyword = trim(strtolower($keyword));
$keyword = trim($keyword);
$keyword = trim($keyword, '#');
if ($keyword != '') {
$cleaned[] = $keyword;
}
}
$keywords = implode(', ', $cleaned);
return $keywords;
return implode(', ', $cleaned);
}
}

View file

@ -0,0 +1,117 @@
<?php
/**
* @copyright Copyright (C) 2010-2023, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\Module\Settings\Server;
use Friendica\App;
use Friendica\Core\L10n;
use Friendica\Core\Renderer;
use Friendica\Core\Session\Capability\IHandleUserSessions;
use Friendica\Core\System;
use Friendica\Federation\Repository\GServer;
use Friendica\Module\Response;
use Friendica\Network\HTTPException\BadRequestException;
use Friendica\User\Settings\Repository\UserGServer;
use Friendica\Util\Profiler;
use Psr\Log\LoggerInterface;
class Action extends \Friendica\BaseModule
{
/** @var IHandleUserSessions */
private $session;
/** @var UserGServer */
private $repository;
/** @var GServer */
private $gserverRepo;
public function __construct(GServer $gserverRepo, UserGServer $repository, IHandleUserSessions $session, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, array $server, array $parameters = [])
{
parent::__construct($l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
$this->session = $session;
$this->repository = $repository;
$this->gserverRepo = $gserverRepo;
}
public function content(array $request = []): string
{
$GServer = $this->gserverRepo->selectOneById($this->parameters['gsid']);
switch ($this->parameters['action']) {
case 'ignore':
$action = $this->t('Do you want to ignore this server?');
$desc = $this->t("You won't see any content from this server including reshares in your Network page, the community pages and individual conversations.");
break;
case 'unignore':
$action = $this->t('Do you want to unignore this server?');
$desc = '';
break;
default:
throw new BadRequestException('Unknown user server action ' . $this->parameters['action']);
}
$tpl = Renderer::getMarkupTemplate('settings/server/action.tpl');
return Renderer::replaceMacros($tpl, [
'$l10n' => [
'title' => $this->t('Remote server settings'),
'action' => $action,
'siteName' => $this->t('Server Name'),
'siteUrl' => $this->t('Server URL'),
'desc' => $desc,
'submit' => $this->t('Submit'),
],
'$action' => $this->args->getQueryString(),
'$GServer' => $GServer,
'$form_security_token' => self::getFormSecurityToken('settings-server'),
]);
}
public function post(array $request = [])
{
if (!empty($request['redirect_url'])) {
self::checkFormSecurityTokenRedirectOnError($this->args->getQueryString(), 'settings-server');
}
$userGServer = $this->repository->getOneByUserAndServer($this->session->getLocalUserId(), $this->parameters['gsid']);
switch ($this->parameters['action']) {
case 'ignore':
$userGServer->ignore();
break;
case 'unignore':
$userGServer->unignore();
break;
default:
throw new BadRequestException('Unknown user server action ' . $this->parameters['action']);
}
$this->repository->save($userGServer);
if (!empty($request['redirect_url'])) {
$this->baseUrl->redirect($request['redirect_url']);
}
System::exit();
}
}

View file

@ -0,0 +1,126 @@
<?php
/**
* @copyright Copyright (C) 2010-2023, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\Module\Settings\Server;
use Friendica\App;
use Friendica\Content\Pager;
use Friendica\Core\L10n;
use Friendica\Core\Renderer;
use Friendica\Core\Session\Capability\IHandleUserSessions;
use Friendica\Module\BaseSettings;
use Friendica\Module\Response;
use Friendica\Navigation\SystemMessages;
use Friendica\Network\HTTPException\NotFoundException;
use Friendica\User\Settings\Entity\UserGServer;
use Friendica\User\Settings\Repository;
use Friendica\Util\Profiler;
use Psr\Log\LoggerInterface;
class Index extends BaseSettings
{
/** @var Repository\UserGServer */
private $repository;
/** @var SystemMessages */
private $systemMessages;
public function __construct(SystemMessages $systemMessages, Repository\UserGServer $repository, IHandleUserSessions $session, App\Page $page, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, array $server, array $parameters = [])
{
parent::__construct($session, $page, $l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
$this->repository = $repository;
$this->systemMessages = $systemMessages;
}
protected function post(array $request = [])
{
self::checkFormSecurityTokenRedirectOnError($this->args->getQueryString(), 'settings-server');
foreach ($request['delete'] ?? [] as $gsid => $delete) {
if ($delete) {
unset($request['ignored'][$gsid]);
try {
$userGServer = $this->repository->selectOneByUserAndServer($this->session->getLocalUserId(), $gsid, false);
$this->repository->delete($userGServer);
} catch (NotFoundException $e) {
// Nothing to delete
}
}
}
foreach ($request['ignored'] ?? [] as $gsid => $ignored) {
$userGServer = $this->repository->getOneByUserAndServer($this->session->getLocalUserId(), $gsid, false);
if ($userGServer->ignored != $ignored) {
$userGServer->toggleIgnored();
$this->repository->save($userGServer);
}
}
$this->systemMessages->addInfo($this->t('Settings saved'));
$this->baseUrl->redirect($this->args->getQueryString());
}
protected function content(array $request = []): string
{
parent::content();
$pager = new Pager($this->l10n, $this->args->getQueryString(), 30);
$total = $this->repository->countByUser($this->session->getLocalUserId());
$servers = $this->repository->selectByUserWithPagination($this->session->getLocalUserId(), $pager);
$ignoredCheckboxes = array_map(function (UserGServer $server) {
return ['ignored[' . $server->gsid . ']', '', $server->ignored];
}, $servers->getArrayCopy());
$deleteCheckboxes = array_map(function (UserGServer $server) {
return ['delete[' . $server->gsid . ']'];
}, $servers->getArrayCopy());
$tpl = Renderer::getMarkupTemplate('settings/server/index.tpl');
return Renderer::replaceMacros($tpl, [
'$l10n' => [
'title' => $this->t('Remote server settings'),
'desc' => $this->t('Here you can find all the remote servers you have taken individual moderation actions against. For a list of servers your node has blocked, please check out the <a href="friendica">Information</a> page.'),
'siteName' => $this->t('Server Name'),
'ignored' => $this->t('Ignored'),
'ignored_title' => $this->t("You won't see any content from this server including reshares in your Network page, the community pages and individual conversations."),
'delete' => $this->t('Delete'),
'delete_title' => $this->t('Delete all your settings for the remote server'),
'submit' => $this->t('Save changes'),
],
'$count' => $total,
'$servers' => $servers,
'$form_security_token' => self::getFormSecurityToken('settings-server'),
'$ignoredCheckboxes' => $ignoredCheckboxes,
'$deleteCheckboxes' => $deleteCheckboxes,
'$paginate' => $pager->renderFull($total),
]);
}
}

View file

@ -31,18 +31,21 @@ class DisplayNotFound extends \Friendica\BaseModule
{
protected function content(array $request = []): string
{
$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("<p>Unfortunately, the requested conversation isn't available to you.</p>
<p>Possible reasons include:</p>
<ul>
<li>The top-level post isn't visible.</li>
<li>The top-level post was deleted.</li>
<li>The node has blocked the top-level author or the author of the shared post.</li>
<li>You have ignored or blocked the top-level author or the author of the shared post.</li>
</ul>"),
'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,
]
]);
}

View file

@ -31,16 +31,15 @@ use Friendica\Core\Renderer;
use Friendica\DI;
use Friendica\Model\Contact;
use Friendica\Model\Item;
use Friendica\Model\Photo;
use Friendica\Model\Post as PostModel;
use Friendica\Model\Tag;
use Friendica\Model\User;
use Friendica\Protocol\Activity;
use Friendica\Util\Crypto;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Proxy;
use Friendica\Util\Strings;
use Friendica\Util\Temporal;
use GuzzleHttp\Psr7\Uri;
use InvalidArgumentException;
/**
@ -253,6 +252,7 @@ class Post
$ignore = false;
$collapse = false;
$report = false;
$ignoreServer = false;
if (DI::userSession()->getLocalUserId()) {
$drop = [
'dropping' => $dropping,
@ -282,6 +282,12 @@ class Post
'label' => DI::l10n()->t('Report post'),
'href' => 'moderation/report/create?' . http_build_query(['cid' => $item['author-id'], 'uri-ids' => [$item['uri-id']]]),
];
$authorBaseUri = new Uri($item['author-baseurl'] ?? '');
if ($authorBaseUri->getHost() && !DI::baseUrl()->isLocalUrl($authorBaseUri)) {
$ignoreServer = [
'label' => DI::l10n()->t("Ignore %s server", $authorBaseUri->getHost()),
];
}
}
$filer = DI::userSession()->getLocalUserId() ? DI::l10n()->t('Save to folder') : false;
@ -557,6 +563,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 +578,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']),

View file

@ -211,7 +211,7 @@ class PermissionSet extends BaseRepository
}
/**
* Selects or creates a PermissionSet based on it's fields
* Selects or creates a PermissionSet based on its fields
*
* @param Entity\PermissionSet $permissionSet
*

View file

@ -0,0 +1,30 @@
<?php
/**
* @copyright Copyright (C) 2010-2023, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\User\Settings\Collection;
class UserGServers extends \Friendica\BaseCollection
{
public function current(): \Friendica\User\Settings\Entity\UserGServer
{
return parent::current();
}
}

View file

@ -0,0 +1,92 @@
<?php
/**
* @copyright Copyright (C) 2010-2023, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\User\Settings\Entity;
use Friendica\Federation\Entity\GServer;
/**
* @property-read int $uid
* @property-read int $gsid
* @property-read bool $ignored
* @property-read ?GServer $gserver
*/
class UserGServer extends \Friendica\BaseEntity
{
/** @var int User id */
protected $uid;
/** @var int GServer id */
protected $gsid;
/** @var bool Whether the user ignored this server */
protected $ignored;
/** @var ?GServer */
protected $gserver;
public function __construct(int $uid, int $gsid, bool $ignored = false, ?GServer $gserver = null)
{
$this->uid = $uid;
$this->gsid = $gsid;
$this->ignored = $ignored;
$this->gserver = $gserver;
}
/**
* Toggle the ignored property.
*
* Chainable.
*
* @return $this
*/
public function toggleIgnored(): UserGServer
{
$this->ignored = !$this->ignored;
return $this;
}
/**
* Set the ignored property.
*
* Chainable.
*
* @return $this
*/
public function ignore(): UserGServer
{
$this->ignored = true;
return $this;
}
/**
* Unset the ignored property.
*
* Chainable.
*
* @return $this
*/
public function unignore(): UserGServer
{
$this->ignored = false;
return $this;
}
}

View file

@ -0,0 +1,60 @@
<?php
/**
* @copyright Copyright (C) 2010-2023, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\User\Settings\Factory;
use Friendica\Capabilities\ICanCreateFromTableRow;
use Friendica\Federation\Entity\GServer;
use Friendica\User\Settings\Entity;
class UserGServer extends \Friendica\BaseFactory implements ICanCreateFromTableRow
{
/**
* @param array $row `user-gserver` table row
* @param GServer|null $server Corresponding GServer entity
* @return Entity\UserGServer
*/
public function createFromTableRow(array $row, GServer $server = null): Entity\UserGServer
{
return new Entity\UserGServer(
$row['uid'],
$row['gsid'],
$row['ignored'],
$server,
);
}
/**
* @param int $uid
* @param int $gsid
* @param GServer|null $gserver Corresponding GServer entity
* @return Entity\UserGServer
*/
public function createFromUserAndServer(int $uid, int $gsid, GServer $gserver = null): Entity\UserGServer
{
return new Entity\UserGServer(
$uid,
$gsid,
false,
$gserver,
);
}
}

View file

@ -0,0 +1,156 @@
<?php
/**
* @copyright Copyright (C) 2010-2023, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\User\Settings\Repository;
use Exception;
use Friendica\BaseCollection;
use Friendica\BaseEntity;
use Friendica\Content\Pager;
use Friendica\Database\Database;
use Friendica\Federation\Repository\GServer;
use Friendica\Network\HTTPException\InternalServerErrorException;
use Friendica\Network\HTTPException\NotFoundException;
use Friendica\User\Settings\Collection;
use Friendica\User\Settings\Entity;
use Friendica\User\Settings\Factory;
use Psr\Log\LoggerInterface;
class UserGServer extends \Friendica\BaseRepository
{
protected static $table_name = 'user-gserver';
/** @var Factory\UserGServer */
protected $factory;
/** @var GServer */
protected $gserverRepository;
public function __construct(GServer $gserverRepository, Database $database, LoggerInterface $logger, Factory\UserGServer $factory)
{
parent::__construct($database, $logger, $factory);
$this->gserverRepository = $gserverRepository;
}
/**
* Returns an existing UserGServer entity or create one on the fly
*
* @param int $uid
* @param int $gsid
* @param bool $hydrate Populate the related GServer entity
* @return Entity\UserGServer
*/
public function getOneByUserAndServer(int $uid, int $gsid, bool $hydrate = true): Entity\UserGServer
{
try {
return $this->selectOneByUserAndServer($uid, $gsid, $hydrate);
} catch (NotFoundException $e) {
return $this->factory->createFromUserAndServer($uid, $gsid, $hydrate ? $this->gserverRepository->selectOneById($gsid) : null);
}
}
/**
* @param int $uid
* @param int $gsid
* @param bool $hydrate Populate the related GServer entity
* @return Entity\UserGServer
* @throws NotFoundException
*/
public function selectOneByUserAndServer(int $uid, int $gsid, bool $hydrate = true): Entity\UserGServer
{
return $this->_selectOne(['uid' => $uid, 'gsid' => $gsid], [], $hydrate);
}
public function save(Entity\UserGServer $userGServer): Entity\UserGServer
{
$fields = [
'uid' => $userGServer->uid,
'gsid' => $userGServer->gsid,
'ignored' => $userGServer->ignored,
];
$this->db->insert(static::$table_name, $fields, Database::INSERT_UPDATE);
return $userGServer;
}
public function selectByUserWithPagination(int $uid, Pager $pager): Collection\UserGServers
{
return $this->_select(['uid' => $uid], ['limit' => [$pager->getStart(), $pager->getItemsPerPage()]]);
}
public function countByUser(int $uid): int
{
return $this->count(['uid' => $uid]);
}
public function isIgnoredByUser(int $uid, int $gsid): bool
{
return $this->exists(['uid' => $uid, 'gsid' => $gsid, 'ignored' => 1]);
}
/**
* @param Entity\UserGServer $userGServer
* @return bool
* @throws InternalServerErrorException in case the underlying storage cannot delete the record
*/
public function delete(Entity\UserGServer $userGServer): bool
{
try {
return $this->db->delete(self::$table_name, ['uid' => $userGServer->uid, 'gsid' => $userGServer->gsid]);
} catch (\Exception $exception) {
throw new InternalServerErrorException('Cannot delete the UserGServer', $exception);
}
}
protected function _selectOne(array $condition, array $params = [], bool $hydrate = true): BaseEntity
{
$fields = $this->db->selectFirst(static::$table_name, [], $condition, $params);
if (!$this->db->isResult($fields)) {
throw new NotFoundException();
}
return $this->factory->createFromTableRow($fields, $hydrate ? $this->gserverRepository->selectOneById($fields['gsid']) : null);
}
/**
* @param array $condition
* @param array $params
* @return Collection\UserGServers
* @throws Exception
*/
protected function _select(array $condition, array $params = [], bool $hydrate = true): BaseCollection
{
$rows = $this->db->selectToArray(static::$table_name, [], $condition, $params);
$Entities = new Collection\UserGServers();
foreach ($rows as $fields) {
$Entities[] = $this->factory->createFromTableRow($fields, $hydrate ? $this->gserverRepository->selectOneById($fields['gsid']) : null);
}
return $Entities;
}
public function listIgnoredByUser(int $uid): Collection\UserGServers
{
return $this->_select(['uid' => $uid, 'ignored' => 1], [], false);
}
}

View file

@ -56,7 +56,7 @@ use Friendica\Database\DBA;
// This file is required several times during the test in DbaDefinition which justifies this condition
if (!defined('DB_UPDATE_VERSION')) {
define('DB_UPDATE_VERSION', 1524);
define('DB_UPDATE_VERSION', 1529);
}
return [
@ -159,6 +159,18 @@ 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"],
"gsid" => ["gsid"]
],
],
"item-uri" => [
"comment" => "URI and GUID for items",
"fields" => [
@ -218,8 +230,8 @@ return [
"archive" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => ""],
"unsearchable" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "Contact prefers to not be searchable"],
"sensitive" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "Contact posts sensitive content"],
"baseurl" => ["type" => "varbinary(383)", "default" => "", "comment" => "baseurl of the contact"],
"gsid" => ["type" => "int unsigned", "foreign" => ["gserver" => "id", "on delete" => "restrict"], "comment" => "Global Server ID"],
"baseurl" => ["type" => "varbinary(383)", "default" => "", "comment" => "baseurl of the contact from the gserver record, can be missing"],
"gsid" => ["type" => "int unsigned", "foreign" => ["gserver" => "id", "on delete" => "restrict"], "comment" => "Global Server ID, can be missing"],
"bd" => ["type" => "date", "not null" => "1", "default" => DBA::NULL_DATE, "comment" => ""],
// User depending fields
"reason" => ["type" => "text", "comment" => ""],
@ -1583,7 +1595,7 @@ return [
"profile-name" => ["type" => "varchar(255)", "comment" => "Deprecated"],
"is-default" => ["type" => "boolean", "comment" => "Deprecated"],
"hide-friends" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "Hide friend list from viewers of this profile"],
"name" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""],
"name" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => "Unused in favor of user.username"],
"pdesc" => ["type" => "varchar(255)", "comment" => "Deprecated"],
"dob" => ["type" => "varchar(32)", "not null" => "1", "default" => "0000-00-00", "comment" => "Day of birth"],
"address" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""],

View file

@ -185,6 +185,7 @@
"author-hidden" => ["author", "hidden"],
"author-updated" => ["author", "updated"],
"author-gsid" => ["author", "gsid"],
"author-baseurl" => ["author", "baseurl"],
"owner-id" => ["post-user", "owner-id"],
"owner-uri-id" => ["owner", "uri-id"],
"owner-link" => ["owner", "url"],
@ -197,6 +198,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 +211,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 +343,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 +379,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 +392,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 +546,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 +559,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 +688,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 +701,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"],
@ -843,7 +853,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" => [

View file

@ -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]],

View file

@ -1349,3 +1349,31 @@ function update_1524(): int
return Update::SUCCESS;
}
function update_1525(): int
{
// Use expected value for user.username
if (!DBA::e('UPDATE `user` u
JOIN `profile` p
ON p.`uid` = u.`uid`
SET u.`username` = p.`name`
WHERE p.`name` != ""')) {
return Update::FAILED;
}
// Blank out deprecated field profile.name to avoid future confusion
if (!DBA::e('UPDATE `profile` p
SET p.`name` = ""')) {
return Update::FAILED;
}
// Update users' self-contact name if needed
if (!DBA::e('UPDATE `contact` c
JOIN `user` u
ON u.`uid` = c.`uid` AND c.`self` = 1
SET c.`name` = u.`username`')) {
return Update::FAILED;
}
return Update::SUCCESS;
}

View file

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 2023.09-dev\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-08-10 21:16+0000\n"
"POT-Creation-Date: 2023-08-25 08:35-0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -38,13 +38,13 @@ msgstr ""
msgid "Empty post discarded."
msgstr ""
#: mod/item.php:427 src/Module/Admin/Themes/Details.php:39
#: mod/item.php:428 src/Module/Admin/Themes/Details.php:39
#: src/Module/Admin/Themes/Index.php:59 src/Module/Debug/ItemBody.php:42
#: src/Module/Debug/ItemBody.php:57 src/Module/Item/Feed.php:80
msgid "Item not found."
msgstr ""
#: mod/item.php:451 mod/message.php:67 mod/message.php:113 mod/notes.php:45
#: mod/item.php:452 mod/message.php:67 mod/message.php:113 mod/notes.php:45
#: mod/photos.php:152 mod/photos.php:670 src/Model/Event.php:520
#: src/Module/Attach.php:55 src/Module/BaseApi.php:99
#: src/Module/BaseNotifications.php:98 src/Module/BaseSettings.php:52
@ -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:578
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:358
#: 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:230 src/Object/Post.php:1087
#: src/Module/Settings/Profile/Index.php:257
#: src/Module/Settings/Server/Action.php:79 src/Object/Post.php:1095
#: 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"
@ -388,7 +389,7 @@ msgid "Save"
msgstr ""
#: mod/photos.php:67 mod/photos.php:132 mod/photos.php:578
#: src/Model/Event.php:512 src/Model/Profile.php:234
#: src/Model/Event.php:512 src/Model/Profile.php:232
#: src/Module/Calendar/Export.php:74 src/Module/Calendar/Show.php:74
#: src/Module/DFRN/Poll.php:43 src/Module/Feed.php:65 src/Module/HCard.php:51
#: src/Module/Profile/Common.php:62 src/Module/Profile/Common.php:71
@ -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:1092
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:572 src/Object/Post.php:1094
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:1108
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:1096
msgid "Loading..."
msgstr ""
#: mod/photos.php:1236 src/Content/Conversation.php:1424
#: mod/photos.php:1236 src/Content/Conversation.php:1443
#: src/Object/Post.php:260
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:408
msgid "Like"
msgstr ""
#: mod/photos.php:1299 src/Object/Post.php:402
#: mod/photos.php:1299 src/Object/Post.php:408
msgid "I like this (toggle)"
msgstr ""
#: mod/photos.php:1300 src/Object/Post.php:403
#: mod/photos.php:1300 src/Object/Post.php:409
msgid "Dislike"
msgstr ""
#: mod/photos.php:1302 src/Object/Post.php:403
#: mod/photos.php:1302 src/Object/Post.php:409
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 ""
@ -779,17 +792,17 @@ msgstr ""
msgid "All contacts"
msgstr ""
#: src/BaseModule.php:433 src/Content/Widget.php:243 src/Core/ACL.php:195
#: src/BaseModule.php:433 src/Content/Widget.php:239 src/Core/ACL.php:195
#: src/Module/Contact.php:415 src/Module/PermissionTooltip.php:127
#: src/Module/PermissionTooltip.php:149
msgid "Followers"
msgstr ""
#: src/BaseModule.php:438 src/Content/Widget.php:244 src/Module/Contact.php:418
#: src/BaseModule.php:438 src/Content/Widget.php:240 src/Module/Contact.php:418
msgid "Following"
msgstr ""
#: src/BaseModule.php:443 src/Content/Widget.php:245 src/Module/Contact.php:421
#: src/BaseModule.php:443 src/Content/Widget.php:241 src/Module/Contact.php:421
msgid "Mutual friends"
msgstr ""
@ -943,7 +956,7 @@ msgstr ""
msgid "Enter user nickname: "
msgstr ""
#: src/Console/User.php:182 src/Model/User.php:692
#: src/Console/User.php:182 src/Model/User.php:693
#: src/Module/Api/Twitter/ContactEndpoint.php:74
#: src/Module/Moderation/Users/Active.php:71
#: src/Module/Moderation/Users/Blocked.php:71
@ -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 "<button type=\"button\" %2$s>%1$d person</button> likes this"
msgid_plural "<button type=\"button\" %2$s>%1$d people</button> like this"
msgstr[0] ""
msgstr[1] ""
#: src/Content/Conversation.php:270
#: src/Content/Conversation.php:275
#, php-format
msgid "<button type=\"button\" %2$s>%1$d person</button> 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 "<button type=\"button\" %2$s>%1$d person</button> attends"
msgid_plural "<button type=\"button\" %2$s>%1$d people</button> attend"
msgstr[0] ""
msgstr[1] ""
#: src/Content/Conversation.php:276
#: src/Content/Conversation.php:281
#, php-format
msgid "<button type=\"button\" %2$s>%1$d person</button> doesn't attend"
msgid_plural "<button type=\"button\" %2$s>%1$d people</button> don't attend"
msgstr[0] ""
msgstr[1] ""
#: src/Content/Conversation.php:279
#: src/Content/Conversation.php:284
#, php-format
msgid "<button type=\"button\" %2$s>%1$d person</button> attends maybe"
msgid_plural "<button type=\"button\" %2$s>%1$d people</button> attend maybe"
msgstr[0] ""
msgstr[1] ""
#: src/Content/Conversation.php:282
#: src/Content/Conversation.php:287
#, php-format
msgid "<button type=\"button\" %2$s>%1$d person</button> reshared this"
msgid_plural "<button type=\"button\" %2$s>%1$d people</button> reshared this"
msgstr[0] ""
msgstr[1] ""
#: src/Content/Conversation.php:329
#: src/Content/Conversation.php:334
msgid "Visible to <strong>everybody</strong>"
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:1107
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:1097
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:1098
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:1099
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:1101
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:1102
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:1100
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:1103
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:1104
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:1105
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:1106
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/Model/Profile.php:469 src/Module/Admin/Logs/View.php:92
#: 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:247
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:521
#: src/Object/Post.php:522
#, 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:509
msgid "Categories:"
msgstr ""
#: src/Content/Conversation.php:1482 src/Object/Post.php:504
#: src/Content/Conversation.php:1502 src/Object/Post.php:510
msgid "Filed under:"
msgstr ""
#: src/Content/Conversation.php:1490 src/Object/Post.php:529
#: src/Content/Conversation.php:1510 src/Object/Post.php:535
#, php-format
msgid "%s from %s"
msgstr ""
#: src/Content/Conversation.php:1506
#: src/Content/Conversation.php:1526
msgid "View in context"
msgstr ""
@ -1607,8 +1620,8 @@ msgid ""
msgstr ""
#: src/Content/GroupManager.php:152 src/Content/Nav.php:276
#: src/Content/Text/HTML.php:880 src/Content/Widget.php:541
#: src/Model/User.php:1254
#: src/Content/Text/HTML.php:880 src/Content/Widget.php:537
#: src/Model/User.php:1255
msgid "Groups"
msgstr ""
@ -1616,12 +1629,12 @@ msgstr ""
msgid "External link to group"
msgstr ""
#: src/Content/GroupManager.php:158 src/Content/Widget.php:516
#: src/Content/GroupManager.php:158 src/Content/Widget.php:512
msgid "show less"
msgstr ""
#: src/Content/GroupManager.php:159 src/Content/Widget.php:414
#: src/Content/Widget.php:517
#: src/Content/GroupManager.php:159 src/Content/Widget.php:410
#: src/Content/Widget.php:513
msgid "show more"
msgstr ""
@ -1629,88 +1642,93 @@ msgstr ""
msgid "Create new group"
msgstr ""
#: src/Content/Item.php:329 src/Model/Item.php:2993
#: src/Content/Item.php:331 src/Model/Item.php:2998
msgid "event"
msgstr ""
#: src/Content/Item.php:332 src/Content/Item.php:342
#: src/Content/Item.php:334 src/Content/Item.php:344
msgid "status"
msgstr ""
#: src/Content/Item.php:338 src/Model/Item.php:2995
#: src/Content/Item.php:340 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:354 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:428 view/theme/frio/theme.php:262
msgid "Follow Thread"
msgstr ""
#: src/Content/Item.php:422 src/Model/Contact.php:1205
#: src/Content/Item.php:429 src/Model/Contact.php:1211
msgid "View Status"
msgstr ""
#: src/Content/Item.php:423 src/Content/Item.php:443 src/Model/Contact.php:1154
#: src/Model/Contact.php:1197 src/Model/Contact.php:1206
#: src/Module/Directory.php:157 src/Module/Settings/Profile/Index.php:233
#: src/Content/Item.php:430 src/Content/Item.php:451 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:1207
#: src/Content/Item.php:431 src/Model/Contact.php:1213
msgid "View Photos"
msgstr ""
#: src/Content/Item.php:425 src/Model/Contact.php:1198
#: src/Model/Contact.php:1208
#: src/Content/Item.php:432 src/Model/Contact.php:1204
#: src/Model/Contact.php:1214
msgid "Network Posts"
msgstr ""
#: src/Content/Item.php:426 src/Model/Contact.php:1199
#: src/Model/Contact.php:1209
#: src/Content/Item.php:433 src/Model/Contact.php:1205
#: src/Model/Contact.php:1215
msgid "View Contact"
msgstr ""
#: src/Content/Item.php:427 src/Model/Contact.php:1210
#: src/Content/Item.php:434 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:435 src/Module/Contact.php:468
#: src/Module/Contact/Profile.php:498
#: 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:436 src/Module/Contact.php:469
#: src/Module/Contact/Profile.php:506
#: 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:437 src/Module/Contact.php:470
#: src/Module/Contact/Profile.php:514
msgid "Collapse"
msgstr ""
#: src/Content/Item.php:434 src/Object/Post.php:484
#: src/Content/Item.php:438 src/Object/Post.php:288
#, php-format
msgid "Ignore %s server"
msgstr ""
#: src/Content/Item.php:442 src/Object/Post.php:490
msgid "Languages"
msgstr ""
#: src/Content/Item.php:440 src/Content/Widget.php:80
#: src/Model/Contact.php:1200 src/Model/Contact.php:1211
#: src/Content/Item.php:448 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:882
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:413 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 ""
@ -2043,8 +2061,8 @@ msgid ""
"<a href=\"%1$s\" target=\"_blank\" rel=\"noopener noreferrer\">%2$s</a> %3$s"
msgstr ""
#: src/Content/Text/BBCode.php:939 src/Model/Item.php:3735
#: src/Model/Item.php:3741 src/Model/Item.php:3742
#: src/Content/Text/BBCode.php:939 src/Model/Item.php:3740
#: src/Model/Item.php:3746 src/Model/Item.php:3747
msgid "Link to source"
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:463 src/Module/Contact/Profile.php:437
#: src/Model/Profile.php:461 src/Module/Contact/Profile.php:458
msgid "Follow"
msgstr ""
@ -2147,80 +2165,80 @@ msgstr ""
msgid "Local Directory"
msgstr ""
#: src/Content/Widget.php:219 src/Model/Circle.php:600
#: src/Content/Widget.php:215 src/Model/Circle.php:600
#: src/Module/Contact.php:401 src/Module/Welcome.php:76
msgid "Circles"
msgstr ""
#: src/Content/Widget.php:221
#: src/Content/Widget.php:217
msgid "Everyone"
msgstr ""
#: src/Content/Widget.php:246 src/Module/Contact.php:424
#: src/Content/Widget.php:242 src/Module/Contact.php:424
msgid "No relationship"
msgstr ""
#: src/Content/Widget.php:251
#: src/Content/Widget.php:247
msgid "Relationships"
msgstr ""
#: src/Content/Widget.php:253 src/Module/Circle.php:292
#: src/Content/Widget.php:249 src/Module/Circle.php:292
#: src/Module/Contact.php:345
msgid "All Contacts"
msgstr ""
#: src/Content/Widget.php:292
#: src/Content/Widget.php:288
msgid "Protocols"
msgstr ""
#: src/Content/Widget.php:294
#: src/Content/Widget.php:290
msgid "All Protocols"
msgstr ""
#: src/Content/Widget.php:322
#: src/Content/Widget.php:318
msgid "Saved Folders"
msgstr ""
#: src/Content/Widget.php:324 src/Content/Widget.php:355
#: src/Content/Widget.php:320 src/Content/Widget.php:351
msgid "Everything"
msgstr ""
#: src/Content/Widget.php:353
#: src/Content/Widget.php:349
msgid "Categories"
msgstr ""
#: src/Content/Widget.php:410
#: src/Content/Widget.php:406
#, php-format
msgid "%d contact in common"
msgid_plural "%d contacts in common"
msgstr[0] ""
msgstr[1] ""
#: src/Content/Widget.php:510
#: src/Content/Widget.php:506
msgid "Archives"
msgstr ""
#: src/Content/Widget.php:518
#: src/Content/Widget.php:514
msgid "On this date"
msgstr ""
#: src/Content/Widget.php:538
#: src/Content/Widget.php:534
msgid "Persons"
msgstr ""
#: src/Content/Widget.php:539
#: src/Content/Widget.php:535
msgid "Organisations"
msgstr ""
#: src/Content/Widget.php:540 src/Model/Contact.php:1675
#: src/Content/Widget.php:536 src/Model/Contact.php:1681
msgid "News"
msgstr ""
#: src/Content/Widget.php:546 src/Module/Settings/Account.php:454
#: src/Content/Widget.php:542 src/Module/Settings/Account.php:454
msgid "Account Types"
msgstr ""
#: src/Content/Widget.php:548 src/Module/Moderation/BaseUsers.php:69
#: src/Content/Widget.php:544 src/Module/Moderation/BaseUsers.php:69
msgid "All"
msgstr ""
@ -2270,32 +2288,32 @@ msgstr[1] ""
msgid "More Trending Tags"
msgstr ""
#: src/Content/Widget/VCard.php:109 src/Model/Profile.php:378
#: src/Module/Contact/Profile.php:381 src/Module/Profile/Profile.php:199
#: src/Content/Widget/VCard.php:109 src/Model/Profile.php:376
#: src/Module/Contact/Profile.php:402 src/Module/Profile/Profile.php:199
msgid "XMPP:"
msgstr ""
#: src/Content/Widget/VCard.php:110 src/Model/Profile.php:379
#: src/Module/Contact/Profile.php:383 src/Module/Profile/Profile.php:203
#: src/Content/Widget/VCard.php:110 src/Model/Profile.php:377
#: src/Module/Contact/Profile.php:404 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:373 src/Module/Contact/Profile.php:379
#: src/Model/Profile.php:371 src/Module/Contact/Profile.php:400
#: src/Module/Directory.php:147 src/Module/Notifications/Introductions.php:187
#: src/Module/Profile/Profile.php:221
msgid "Location:"
msgstr ""
#: src/Content/Widget/VCard.php:114 src/Model/Profile.php:476
#: src/Content/Widget/VCard.php:114 src/Model/Profile.php:474
#: src/Module/Notifications/Introductions.php:201
msgid "Network:"
msgstr ""
#: src/Content/Widget/VCard.php:118 src/Model/Contact.php:1201
#: src/Model/Contact.php:1212 src/Model/Profile.php:465
#: 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:450
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,17 +3065,17 @@ msgstr ""
msgid "Edit circles"
msgstr ""
#: src/Model/Contact.php:1218 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:1671
#: src/Model/Contact.php:1677
msgid "Organisation"
msgstr ""
#: src/Model/Contact.php:1679
#: src/Model/Contact.php:1685
msgid "Group"
msgstr ""
@ -3065,7 +3083,7 @@ msgstr ""
msgid "Disallowed profile URL."
msgstr ""
#: src/Model/Contact.php:2993 src/Module/Friendica.php:102
#: src/Model/Contact.php:2993 src/Module/Friendica.php:101
msgid "Blocked domain"
msgstr ""
@ -3227,81 +3245,81 @@ msgstr ""
msgid "Happy Birthday %s"
msgstr ""
#: src/Model/Item.php:2056
#: src/Model/Item.php:2057
#, php-format
msgid "Detected languages in this post:\\n%s"
msgstr ""
#: src/Model/Item.php:2997
#: src/Model/Item.php:3002
msgid "activity"
msgstr ""
#: src/Model/Item.php:2999
#: src/Model/Item.php:3004
msgid "comment"
msgstr ""
#: src/Model/Item.php:3002 src/Module/Post/Tag/Add.php:123
#: src/Model/Item.php:3007 src/Module/Post/Tag/Add.php:123
msgid "post"
msgstr ""
#: src/Model/Item.php:3172
#: src/Model/Item.php:3177
#, php-format
msgid "%s is blocked"
msgstr ""
#: src/Model/Item.php:3174
#: src/Model/Item.php:3179
#, php-format
msgid "%s is ignored"
msgstr ""
#: src/Model/Item.php:3176
#: src/Model/Item.php:3181
#, php-format
msgid "Content from %s is collapsed"
msgstr ""
#: src/Model/Item.php:3180
#: src/Model/Item.php:3185
#, php-format
msgid "Content warning: %s"
msgstr ""
#: src/Model/Item.php:3642
#: src/Model/Item.php:3647
msgid "bytes"
msgstr ""
#: src/Model/Item.php:3673
#: src/Model/Item.php:3678
#, php-format
msgid "%2$s (%3$d%%, %1$d vote)"
msgid_plural "%2$s (%3$d%%, %1$d votes)"
msgstr[0] ""
msgstr[1] ""
#: src/Model/Item.php:3675
#: src/Model/Item.php:3680
#, php-format
msgid "%2$s (%1$d vote)"
msgid_plural "%2$s (%1$d votes)"
msgstr[0] ""
msgstr[1] ""
#: src/Model/Item.php:3680
#: src/Model/Item.php:3685
#, php-format
msgid "%d voter. Poll end: %s"
msgid_plural "%d voters. Poll end: %s"
msgstr[0] ""
msgstr[1] ""
#: src/Model/Item.php:3682
#: src/Model/Item.php:3687
#, php-format
msgid "%d voter."
msgid_plural "%d voters."
msgstr[0] ""
msgstr[1] ""
#: src/Model/Item.php:3684
#: src/Model/Item.php:3689
#, php-format
msgid "Poll end: %s"
msgstr ""
#: src/Model/Item.php:3718 src/Model/Item.php:3719
#: src/Model/Item.php:3723 src/Model/Item.php:3724
msgid "View on separate page"
msgstr ""
@ -3309,295 +3327,295 @@ msgstr ""
msgid "[no subject]"
msgstr ""
#: src/Model/Photo.php:1184 src/Module/Media/Photo/Upload.php:170
#: src/Model/Photo.php:1190 src/Module/Media/Photo/Upload.php:170
msgid "Wall Photos"
msgstr ""
#: src/Model/Profile.php:361 src/Module/Profile/Profile.php:283
#: src/Model/Profile.php:359 src/Module/Profile/Profile.php:283
#: src/Module/Profile/Profile.php:285
msgid "Edit profile"
msgstr ""
#: src/Model/Profile.php:363
#: src/Model/Profile.php:361
msgid "Change profile photo"
msgstr ""
#: src/Model/Profile.php:376 src/Module/Directory.php:152
#: src/Model/Profile.php:374 src/Module/Directory.php:152
#: src/Module/Profile/Profile.php:209
msgid "Homepage:"
msgstr ""
#: src/Model/Profile.php:377 src/Module/Contact/Profile.php:385
#: src/Model/Profile.php:375 src/Module/Contact/Profile.php:406
#: src/Module/Notifications/Introductions.php:189
msgid "About:"
msgstr ""
#: src/Model/Profile.php:467
#: src/Model/Profile.php:465
msgid "Atom feed"
msgstr ""
#: src/Model/Profile.php:474
#: src/Model/Profile.php:472
msgid "This website has been verified to belong to the same person."
msgstr ""
#: src/Model/Profile.php:511
#: src/Model/Profile.php:509
msgid "F d"
msgstr ""
#: src/Model/Profile.php:575 src/Model/Profile.php:664
#: src/Model/Profile.php:573 src/Model/Profile.php:662
msgid "[today]"
msgstr ""
#: src/Model/Profile.php:584
#: src/Model/Profile.php:582
msgid "Birthday Reminders"
msgstr ""
#: src/Model/Profile.php:585
#: src/Model/Profile.php:583
msgid "Birthdays this week:"
msgstr ""
#: src/Model/Profile.php:613
#: src/Model/Profile.php:611
msgid "g A l F d"
msgstr ""
#: src/Model/Profile.php:651
#: src/Model/Profile.php:649
msgid "[No description]"
msgstr ""
#: src/Model/Profile.php:677
#: src/Model/Profile.php:675
msgid "Event Reminders"
msgstr ""
#: src/Model/Profile.php:678
#: src/Model/Profile.php:676
msgid "Upcoming events the next 7 days:"
msgstr ""
#: src/Model/Profile.php:875
#: src/Model/Profile.php:873
#, php-format
msgid "OpenWebAuth: %1$s welcomes %2$s"
msgstr ""
#: src/Model/Profile.php:1015
#: src/Model/Profile.php:1013
msgid "Hometown:"
msgstr ""
#: src/Model/Profile.php:1016
#: src/Model/Profile.php:1014
msgid "Marital Status:"
msgstr ""
#: src/Model/Profile.php:1017
#: src/Model/Profile.php:1015
msgid "With:"
msgstr ""
#: src/Model/Profile.php:1018
#: src/Model/Profile.php:1016
msgid "Since:"
msgstr ""
#: src/Model/Profile.php:1019
#: src/Model/Profile.php:1017
msgid "Sexual Preference:"
msgstr ""
#: src/Model/Profile.php:1020
#: src/Model/Profile.php:1018
msgid "Political Views:"
msgstr ""
#: src/Model/Profile.php:1021
#: src/Model/Profile.php:1019
msgid "Religious Views:"
msgstr ""
#: src/Model/Profile.php:1022
#: src/Model/Profile.php:1020
msgid "Likes:"
msgstr ""
#: src/Model/Profile.php:1023
#: src/Model/Profile.php:1021
msgid "Dislikes:"
msgstr ""
#: src/Model/Profile.php:1024
#: src/Model/Profile.php:1022
msgid "Title/Description:"
msgstr ""
#: src/Model/Profile.php:1025 src/Module/Admin/Summary.php:197
#: src/Model/Profile.php:1023 src/Module/Admin/Summary.php:197
#: src/Module/Moderation/Report/Create.php:280
#: src/Module/Moderation/Summary.php:77
msgid "Summary"
msgstr ""
#: src/Model/Profile.php:1026
#: src/Model/Profile.php:1024
msgid "Musical interests"
msgstr ""
#: src/Model/Profile.php:1027
#: src/Model/Profile.php:1025
msgid "Books, literature"
msgstr ""
#: src/Model/Profile.php:1028
#: src/Model/Profile.php:1026
msgid "Television"
msgstr ""
#: src/Model/Profile.php:1029
#: src/Model/Profile.php:1027
msgid "Film/dance/culture/entertainment"
msgstr ""
#: src/Model/Profile.php:1030
#: src/Model/Profile.php:1028
msgid "Hobbies/Interests"
msgstr ""
#: src/Model/Profile.php:1031
#: src/Model/Profile.php:1029
msgid "Love/romance"
msgstr ""
#: src/Model/Profile.php:1032
#: src/Model/Profile.php:1030
msgid "Work/employment"
msgstr ""
#: src/Model/Profile.php:1033
#: src/Model/Profile.php:1031
msgid "School/education"
msgstr ""
#: src/Model/Profile.php:1034
#: src/Model/Profile.php:1032
msgid "Contact information and Social Networks"
msgstr ""
#: src/Model/User.php:225 src/Model/User.php:1167
#: src/Model/User.php:226 src/Model/User.php:1168
msgid "SERIOUS ERROR: Generation of security keys failed."
msgstr ""
#: src/Model/User.php:601 src/Model/User.php:634
#: src/Model/User.php:602 src/Model/User.php:635
msgid "Login failed"
msgstr ""
#: src/Model/User.php:666
#: src/Model/User.php:667
msgid "Not enough information to authenticate"
msgstr ""
#: src/Model/User.php:787
#: src/Model/User.php:788
msgid "Password can't be empty"
msgstr ""
#: src/Model/User.php:829
#: src/Model/User.php:830
msgid "Empty passwords are not allowed."
msgstr ""
#: src/Model/User.php:833
#: src/Model/User.php:834
msgid ""
"The new password has been exposed in a public data dump, please choose "
"another."
msgstr ""
#: src/Model/User.php:837
#: src/Model/User.php:838
msgid "The password length is limited to 72 characters."
msgstr ""
#: src/Model/User.php:841
#: src/Model/User.php:842
msgid "The password can't contain white spaces nor accentuated letters"
msgstr ""
#: src/Model/User.php:1050
#: src/Model/User.php:1051
msgid "Passwords do not match. Password unchanged."
msgstr ""
#: src/Model/User.php:1057
#: src/Model/User.php:1058
msgid "An invitation is required."
msgstr ""
#: src/Model/User.php:1061
#: src/Model/User.php:1062
msgid "Invitation could not be verified."
msgstr ""
#: src/Model/User.php:1069
#: src/Model/User.php:1070
msgid "Invalid OpenID url"
msgstr ""
#: src/Model/User.php:1082 src/Security/Authentication.php:241
#: src/Model/User.php:1083 src/Security/Authentication.php:241
msgid ""
"We encountered a problem while logging in with the OpenID you provided. "
"Please check the correct spelling of the ID."
msgstr ""
#: src/Model/User.php:1082 src/Security/Authentication.php:241
#: src/Model/User.php:1083 src/Security/Authentication.php:241
msgid "The error message was:"
msgstr ""
#: src/Model/User.php:1088
#: src/Model/User.php:1089
msgid "Please enter the required information."
msgstr ""
#: src/Model/User.php:1102
#: src/Model/User.php:1103
#, php-format
msgid ""
"system.username_min_length (%s) and system.username_max_length (%s) are "
"excluding each other, swapping values."
msgstr ""
#: src/Model/User.php:1109
#: src/Model/User.php:1110
#, php-format
msgid "Username should be at least %s character."
msgid_plural "Username should be at least %s characters."
msgstr[0] ""
msgstr[1] ""
#: src/Model/User.php:1113
#: src/Model/User.php:1114
#, php-format
msgid "Username should be at most %s character."
msgid_plural "Username should be at most %s characters."
msgstr[0] ""
msgstr[1] ""
#: src/Model/User.php:1121
#: src/Model/User.php:1122
msgid "That doesn't appear to be your full (First Last) name."
msgstr ""
#: src/Model/User.php:1126
#: src/Model/User.php:1127
msgid "Your email domain is not among those allowed on this site."
msgstr ""
#: src/Model/User.php:1130
#: src/Model/User.php:1131
msgid "Not a valid email address."
msgstr ""
#: src/Model/User.php:1133
#: src/Model/User.php:1134
msgid "The nickname was blocked from registration by the nodes admin."
msgstr ""
#: src/Model/User.php:1137 src/Model/User.php:1143
#: src/Model/User.php:1138 src/Model/User.php:1144
msgid "Cannot use that email."
msgstr ""
#: src/Model/User.php:1149
#: src/Model/User.php:1150
msgid "Your nickname can only contain a-z, 0-9 and _."
msgstr ""
#: src/Model/User.php:1157 src/Model/User.php:1214
#: src/Model/User.php:1158 src/Model/User.php:1215
msgid "Nickname is already registered. Please choose another."
msgstr ""
#: src/Model/User.php:1201 src/Model/User.php:1205
#: src/Model/User.php:1202 src/Model/User.php:1206
msgid "An error occurred during registration. Please try again."
msgstr ""
#: src/Model/User.php:1228
#: src/Model/User.php:1229
msgid "An error occurred creating your default profile. Please try again."
msgstr ""
#: src/Model/User.php:1235
#: src/Model/User.php:1236
msgid "An error occurred creating your self contact. Please try again."
msgstr ""
#: src/Model/User.php:1240
#: src/Model/User.php:1241
msgid "Friends"
msgstr ""
#: src/Model/User.php:1244
#: src/Model/User.php:1245
msgid ""
"An error occurred creating your default contact circle. Please try again."
msgstr ""
#: src/Model/User.php:1288
#: src/Model/User.php:1289
msgid "Profile Photos"
msgstr ""
#: src/Model/User.php:1483
#: src/Model/User.php:1469
#, php-format
msgid ""
"\n"
@ -3605,7 +3623,7 @@ msgid ""
"\t\t\tthe administrator of %2$s has set up an account for you."
msgstr ""
#: src/Model/User.php:1486
#: src/Model/User.php:1472
#, php-format
msgid ""
"\n"
@ -3643,12 +3661,12 @@ msgid ""
"\t\tThank you and welcome to %4$s."
msgstr ""
#: src/Model/User.php:1519 src/Model/User.php:1626
#: src/Model/User.php:1505 src/Model/User.php:1612
#, php-format
msgid "Registration details for %s"
msgstr ""
#: src/Model/User.php:1539
#: src/Model/User.php:1525
#, php-format
msgid ""
"\n"
@ -3664,12 +3682,12 @@ msgid ""
"\t\t"
msgstr ""
#: src/Model/User.php:1558
#: src/Model/User.php:1544
#, php-format
msgid "Registration at %s"
msgstr ""
#: src/Model/User.php:1582
#: src/Model/User.php:1568
#, php-format
msgid ""
"\n"
@ -3678,7 +3696,7 @@ msgid ""
"\t\t\t"
msgstr ""
#: src/Model/User.php:1590
#: src/Model/User.php:1576
#, php-format
msgid ""
"\n"
@ -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:305
#: 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 <a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer"
"\">EU-GDPR</a>."
"according e.g. to <a href=\"%s\" target=\"_blank\" rel=\"noopener "
"noreferrer\">EU-GDPR</a>."
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:368
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:498
#: 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:506
msgid "Unignore"
msgstr ""
#: src/Module/Contact.php:470 src/Module/Contact/Profile.php:493
#: src/Module/Contact.php:470 src/Module/Contact/Profile.php:514
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:365
#, 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:396
#: 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:408
#: 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:278
msgid "This contact is on a server you ignored."
msgstr ""
#: src/Module/Contact/Profile.php:281
msgid "Never"
msgstr ""
#: src/Module/Contact/Profile.php:265
#: src/Module/Contact/Profile.php:284
msgid "(Update was not successful)"
msgstr ""
#: src/Module/Contact/Profile.php:265
#: src/Module/Contact/Profile.php:284
msgid "(Update was successful)"
msgstr ""
#: src/Module/Contact/Profile.php:267 src/Module/Contact/Profile.php:448
#: src/Module/Contact/Profile.php:286 src/Module/Contact/Profile.php:469
msgid "Suggest friends"
msgstr ""
#: src/Module/Contact/Profile.php:271
#: src/Module/Contact/Profile.php:290
#, php-format
msgid "Network type: %s"
msgstr ""
#: src/Module/Contact/Profile.php:276
#: src/Module/Contact/Profile.php:295
msgid "Communications lost with this contact!"
msgstr ""
#: src/Module/Contact/Profile.php:282
#: src/Module/Contact/Profile.php:301
msgid "Fetch further information for feeds"
msgstr ""
#: src/Module/Contact/Profile.php:284
#: src/Module/Contact/Profile.php:303
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:306
msgid "Fetch information"
msgstr ""
#: src/Module/Contact/Profile.php:288
#: src/Module/Contact/Profile.php:307
msgid "Fetch keywords"
msgstr ""
#: src/Module/Contact/Profile.php:289
#: src/Module/Contact/Profile.php:308
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:318 src/Module/Contact/Profile.php:323
#: src/Module/Contact/Profile.php:328 src/Module/Contact/Profile.php:334
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:319 src/Module/Contact/Profile.php:329
#: src/Module/Contact/Profile.php:335
msgid "Mirror as my own posting"
msgstr ""
#: src/Module/Contact/Profile.php:305 src/Module/Contact/Profile.php:311
#: src/Module/Contact/Profile.php:324 src/Module/Contact/Profile.php:330
msgid "Native reshare"
msgstr ""
#: src/Module/Contact/Profile.php:328
#: src/Module/Contact/Profile.php:347
msgid "Contact Information / Notes"
msgstr ""
#: src/Module/Contact/Profile.php:329
#: src/Module/Contact/Profile.php:348
msgid "Contact Settings"
msgstr ""
#: src/Module/Contact/Profile.php:337
#: src/Module/Contact/Profile.php:356
msgid "Contact"
msgstr ""
#: src/Module/Contact/Profile.php:341
#: src/Module/Contact/Profile.php:360
msgid "Their personal note"
msgstr ""
#: src/Module/Contact/Profile.php:343
#: src/Module/Contact/Profile.php:362
msgid "Edit contact notes"
msgstr ""
#: src/Module/Contact/Profile.php:347
#: src/Module/Contact/Profile.php:366
msgid "Block/Unblock contact"
msgstr ""
#: src/Module/Contact/Profile.php:348
#: src/Module/Contact/Profile.php:367
#: src/Module/Moderation/Report/Create.php:293
msgid "Ignore contact"
msgstr ""
#: src/Module/Contact/Profile.php:349
#: src/Module/Contact/Profile.php:368
msgid "View conversations"
msgstr ""
#: src/Module/Contact/Profile.php:354
#: src/Module/Contact/Profile.php:373
msgid "Last update:"
msgstr ""
#: src/Module/Contact/Profile.php:356
#: src/Module/Contact/Profile.php:375
msgid "Update public posts"
msgstr ""
#: src/Module/Contact/Profile.php:358 src/Module/Contact/Profile.php:458
#: src/Module/Contact/Profile.php:377 src/Module/Contact/Profile.php:479
msgid "Update now"
msgstr ""
#: src/Module/Contact/Profile.php:360
#: src/Module/Contact/Profile.php:379
msgid "Awaiting connection acknowledge"
msgstr ""
#: src/Module/Contact/Profile.php:361
#: src/Module/Contact/Profile.php:380
msgid "Currently blocked"
msgstr ""
#: src/Module/Contact/Profile.php:362
#: src/Module/Contact/Profile.php:381
msgid "Currently ignored"
msgstr ""
#: src/Module/Contact/Profile.php:363
#: src/Module/Contact/Profile.php:382
msgid "Currently collapsed"
msgstr ""
#: src/Module/Contact/Profile.php:364
#: src/Module/Contact/Profile.php:383
msgid "Currently archived"
msgstr ""
#: src/Module/Contact/Profile.php:367
#: src/Module/Contact/Profile.php:386
msgid "Manage remote servers"
msgstr ""
#: src/Module/Contact/Profile.php:388
#: src/Module/Notifications/Introductions.php:192
msgid "Hide this contact from others"
msgstr ""
#: src/Module/Contact/Profile.php:367
#: src/Module/Contact/Profile.php:388
msgid ""
"Replies/likes to your public posts <strong>may</strong> still be visible"
msgstr ""
#: src/Module/Contact/Profile.php:368
#: src/Module/Contact/Profile.php:389
msgid "Notification for new posts"
msgstr ""
#: src/Module/Contact/Profile.php:368
#: src/Module/Contact/Profile.php:389
msgid "Send a notification of every new post of this contact"
msgstr ""
#: src/Module/Contact/Profile.php:370
#: src/Module/Contact/Profile.php:391
msgid "Keyword Deny List"
msgstr ""
#: src/Module/Contact/Profile.php:370
#: src/Module/Contact/Profile.php:391
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:409
#: src/Module/Settings/TwoFactor/Index.php:139
msgid "Actions"
msgstr ""
#: src/Module/Contact/Profile.php:390
#: src/Module/Contact/Profile.php:411
#: 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:417
msgid "Mirror postings from this contact"
msgstr ""
#: src/Module/Contact/Profile.php:398
#: src/Module/Contact/Profile.php:419
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:489
msgid "Refetch contact data"
msgstr ""
#: src/Module/Contact/Profile.php:479
#: src/Module/Contact/Profile.php:500
msgid "Toggle Blocked status"
msgstr ""
#: src/Module/Contact/Profile.php:487
#: src/Module/Contact/Profile.php:508
msgid "Toggle Ignored status"
msgstr ""
#: src/Module/Contact/Profile.php:495
#: src/Module/Contact/Profile.php:516
msgid "Toggle Collapsed status"
msgstr ""
#: src/Module/Contact/Profile.php:502 src/Module/Contact/Revoke.php:106
#: src/Module/Contact/Profile.php:523 src/Module/Contact/Revoke.php:106
msgid "Revoke Follow"
msgstr ""
#: src/Module/Contact/Profile.php:504
#: src/Module/Contact/Profile.php:525
msgid "Revoke the follow from this contact"
msgstr ""
@ -6564,7 +6594,7 @@ msgid "Sort by post creation date"
msgstr ""
#: src/Module/Conversation/Network.php:281
#: src/Module/Settings/Profile/Index.php:235
#: src/Module/Settings/Profile/Index.php:260
msgid "Personal"
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:380
msgid "Starred"
msgstr ""
@ -6796,7 +6826,7 @@ msgid "Twitter Source / Tweet URL (requires API key)"
msgstr ""
#: src/Module/Debug/Feed.php:52 src/Module/Filer/SaveTag.php:47
#: src/Module/Settings/Profile/Index.php:144
#: src/Module/Settings/Profile/Index.php:177
msgid "You must be logged in to use this module"
msgstr ""
@ -6938,42 +6968,42 @@ msgstr ""
msgid "Read about the <a href=\"%1$s/tos\">Terms of Service</a> 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 <a href=\"https://friendi.ca\">Friendi.ca</a> 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 ""
"<a href=\"/settings/display\">Theme Customization settings</a>."
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 "<b>Attributed To:</b> %s<br>"
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 ""
@ -8586,20 +8614,20 @@ msgstr ""
#: src/Module/Profile/Conversations.php:106
#: src/Module/Profile/Conversations.php:109 src/Module/Profile/Profile.php:351
#: src/Module/Profile/Profile.php:354 src/Protocol/Feed.php:1090
#: src/Module/Profile/Profile.php:354 src/Protocol/Feed.php:1098
#: src/Protocol/OStatus.php:1009
#, php-format
msgid "%s's timeline"
msgstr ""
#: src/Module/Profile/Conversations.php:107 src/Module/Profile/Profile.php:352
#: src/Protocol/Feed.php:1094 src/Protocol/OStatus.php:1014
#: src/Protocol/Feed.php:1102 src/Protocol/OStatus.php:1014
#, php-format
msgid "%s's posts"
msgstr ""
#: src/Module/Profile/Conversations.php:108 src/Module/Profile/Profile.php:353
#: src/Protocol/Feed.php:1097 src/Protocol/OStatus.php:1018
#: src/Protocol/Feed.php:1105 src/Protocol/OStatus.php:1018
#, php-format
msgid "%s's comments"
msgstr ""
@ -8640,11 +8668,11 @@ msgstr ""
#: src/Module/Profile/Profile.php:158
#, php-format
msgid ""
"You're currently viewing your profile as <b>%s</b> <a href=\"%s\" class="
"\"btn btn-sm pull-right\">Cancel</a>"
"You're currently viewing your profile as <b>%s</b> <a href=\"%s\" "
"class=\"btn btn-sm pull-right\">Cancel</a>"
msgstr ""
#: src/Module/Profile/Profile.php:167 src/Module/Settings/Account.php:576
#: src/Module/Profile/Profile.php:167
msgid "Full Name:"
msgstr ""
@ -8664,12 +8692,12 @@ msgstr ""
msgid "Birthday:"
msgstr ""
#: src/Module/Profile/Profile.php:190 src/Module/Settings/Profile/Index.php:253
#: src/Module/Profile/Profile.php:190 src/Module/Settings/Profile/Index.php:291
#: src/Util/Temporal.php:170
msgid "Age: "
msgstr ""
#: src/Module/Profile/Profile.php:190 src/Module/Settings/Profile/Index.php:253
#: src/Module/Profile/Profile.php:190 src/Module/Settings/Profile/Index.php:291
#: src/Util/Temporal.php:170
#, php-format
msgid "%d year old"
@ -8677,7 +8705,7 @@ msgid_plural "%d years old"
msgstr[0] ""
msgstr[1] ""
#: src/Module/Profile/Profile.php:195 src/Module/Settings/Profile/Index.php:246
#: src/Module/Profile/Profile.php:195 src/Module/Settings/Profile/Index.php:284
msgid "Description:"
msgstr ""
@ -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 <a href="
"\"%s\">two-factor recovery code</a>."
"If you do not have access to your authentication code you can use a <a "
"href=\"%s\">two-factor recovery code</a>."
msgstr ""
#: src/Module/Security/TwoFactor/Verify.php:101
@ -9362,6 +9390,11 @@ msgstr ""
msgid "Basic Settings"
msgstr ""
#: src/Module/Settings/Account.php:576
#: src/Module/Settings/Profile/Index.php:283
msgid "Display name:"
msgstr ""
#: src/Module/Settings/Account.php:577
msgid "Email Address:"
msgstr ""
@ -10126,146 +10159,85 @@ msgstr ""
msgid "Remove authorization"
msgstr ""
#: src/Module/Settings/Profile/Index.php:84
msgid "Profile Name is required."
#: src/Module/Settings/Profile/Index.php:116
msgid "Display Name is required."
msgstr ""
#: src/Module/Settings/Profile/Index.php:134
#: src/Module/Settings/Profile/Index.php:167
msgid "Profile couldn't be updated."
msgstr ""
#: src/Module/Settings/Profile/Index.php:175
#: src/Module/Settings/Profile/Index.php:195
#: src/Module/Settings/Profile/Index.php:205
#: src/Module/Settings/Profile/Index.php:226
msgid "Label:"
msgstr ""
#: src/Module/Settings/Profile/Index.php:176
#: src/Module/Settings/Profile/Index.php:196
#: src/Module/Settings/Profile/Index.php:206
#: src/Module/Settings/Profile/Index.php:227
msgid "Value:"
msgstr ""
#: src/Module/Settings/Profile/Index.php:186
#: src/Module/Settings/Profile/Index.php:206
#: src/Module/Settings/Profile/Index.php:217
#: src/Module/Settings/Profile/Index.php:238
msgid "Field Permissions"
msgstr ""
#: src/Module/Settings/Profile/Index.php:187
#: src/Module/Settings/Profile/Index.php:207
#: src/Module/Settings/Profile/Index.php:218
#: src/Module/Settings/Profile/Index.php:239
msgid "(click to open/close)"
msgstr ""
#: src/Module/Settings/Profile/Index.php:193
#: src/Module/Settings/Profile/Index.php:224
msgid "Add a new profile field"
msgstr ""
#: src/Module/Settings/Profile/Index.php:216
#: src/Module/Settings/Profile/Index.php:247
msgid ""
"The homepage is verified. A rel=\"me\" link back to your Friendica profile "
"page was found on the homepage."
msgstr ""
#: src/Module/Settings/Profile/Index.php:218
#: src/Module/Settings/Profile/Index.php:249
#, php-format
msgid ""
"To verify your homepage, add a rel=\"me\" link to it, pointing to your "
"profile URL (%s)."
msgstr ""
#: src/Module/Settings/Profile/Index.php:228
#: src/Module/Settings/Profile/Index.php:255
msgid "Profile Actions"
msgstr ""
#: src/Module/Settings/Profile/Index.php:229
#: src/Module/Settings/Profile/Index.php:256
msgid "Edit Profile Details"
msgstr ""
#: src/Module/Settings/Profile/Index.php:231
#: src/Module/Settings/Profile/Index.php:258
msgid "Change Profile Photo"
msgstr ""
#: src/Module/Settings/Profile/Index.php:236
#: src/Module/Settings/Profile/Index.php:261
msgid "Profile picture"
msgstr ""
#: src/Module/Settings/Profile/Index.php:237
#: src/Module/Settings/Profile/Index.php:262
msgid "Location"
msgstr ""
#: src/Module/Settings/Profile/Index.php:238 src/Util/Temporal.php:97
#: src/Module/Settings/Profile/Index.php:263 src/Util/Temporal.php:97
#: src/Util/Temporal.php:99
msgid "Miscellaneous"
msgstr ""
#: src/Module/Settings/Profile/Index.php:239
#: src/Module/Settings/Profile/Index.php:264
msgid "Custom Profile Fields"
msgstr ""
#: src/Module/Settings/Profile/Index.php:241 src/Module/Welcome.php:58
#: src/Module/Settings/Profile/Index.php:265 src/Module/Welcome.php:58
msgid "Upload Profile Photo"
msgstr ""
#: src/Module/Settings/Profile/Index.php:245
msgid "Display name:"
msgstr ""
#: src/Module/Settings/Profile/Index.php:248
msgid "Street Address:"
msgstr ""
#: src/Module/Settings/Profile/Index.php:249
msgid "Locality/City:"
msgstr ""
#: src/Module/Settings/Profile/Index.php:250
msgid "Region/State:"
msgstr ""
#: src/Module/Settings/Profile/Index.php:251
msgid "Postal/Zip Code:"
msgstr ""
#: src/Module/Settings/Profile/Index.php:252
msgid "Country:"
msgstr ""
#: src/Module/Settings/Profile/Index.php:254
msgid "XMPP (Jabber) address:"
msgstr ""
#: src/Module/Settings/Profile/Index.php:254
msgid "The XMPP address will be published so that people can follow you there."
msgstr ""
#: src/Module/Settings/Profile/Index.php:255
msgid "Matrix (Element) address:"
msgstr ""
#: src/Module/Settings/Profile/Index.php:255
msgid ""
"The Matrix address will be published so that people can follow you there."
msgstr ""
#: src/Module/Settings/Profile/Index.php:256
msgid "Homepage URL:"
msgstr ""
#: src/Module/Settings/Profile/Index.php:257
msgid "Public Keywords:"
msgstr ""
#: src/Module/Settings/Profile/Index.php:257
msgid "(Used for suggesting potential friends, can be seen by others)"
msgstr ""
#: src/Module/Settings/Profile/Index.php:258
msgid "Private Keywords:"
msgstr ""
#: src/Module/Settings/Profile/Index.php:258
msgid "(Used for searching profiles, never shown to others)"
msgstr ""
#: src/Module/Settings/Profile/Index.php:259
#: src/Module/Settings/Profile/Index.php:266
#, php-format
msgid ""
"<p>Custom fields appear on <a href=\"%s\">your profile page</a>.</p>\n"
@ -10276,6 +10248,63 @@ msgid ""
"contacts or the Friendica contacts in the selected circles.</p>"
msgstr ""
#: src/Module/Settings/Profile/Index.php:286
msgid "Street Address:"
msgstr ""
#: src/Module/Settings/Profile/Index.php:287
msgid "Locality/City:"
msgstr ""
#: src/Module/Settings/Profile/Index.php:288
msgid "Region/State:"
msgstr ""
#: src/Module/Settings/Profile/Index.php:289
msgid "Postal/Zip Code:"
msgstr ""
#: src/Module/Settings/Profile/Index.php:290
msgid "Country:"
msgstr ""
#: src/Module/Settings/Profile/Index.php:292
msgid "XMPP (Jabber) address:"
msgstr ""
#: src/Module/Settings/Profile/Index.php:292
msgid "The XMPP address will be published so that people can follow you there."
msgstr ""
#: src/Module/Settings/Profile/Index.php:293
msgid "Matrix (Element) address:"
msgstr ""
#: src/Module/Settings/Profile/Index.php:293
msgid ""
"The Matrix address will be published so that people can follow you there."
msgstr ""
#: src/Module/Settings/Profile/Index.php:294
msgid "Homepage URL:"
msgstr ""
#: src/Module/Settings/Profile/Index.php:295
msgid "Public Keywords:"
msgstr ""
#: src/Module/Settings/Profile/Index.php:295
msgid "(Used for suggesting potential friends, can be seen by others)"
msgstr ""
#: src/Module/Settings/Profile/Index.php:296
msgid "Private Keywords:"
msgstr ""
#: src/Module/Settings/Profile/Index.php:296
msgid "(Used for searching profiles, never shown to others)"
msgstr ""
#: src/Module/Settings/Profile/Photo/Crop.php:107
#: src/Module/Settings/Profile/Photo/Crop.php:125
#: src/Module/Settings/Profile/Photo/Crop.php:143
@ -10386,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 <a href=\"friendica\">Information</a> page."
msgstr ""
#: src/Module/Settings/Server/Index.php:110
msgid "Delete all your settings for the remote server"
msgstr ""
#: src/Module/Settings/Server/Index.php:111
msgid "Save changes"
msgstr ""
#: src/Module/Settings/TwoFactor/AppSpecific.php:66
#: src/Module/Settings/TwoFactor/Recovery.php:64
#: src/Module/Settings/TwoFactor/Trusted.php:67
@ -10667,8 +10732,8 @@ msgstr ""
#: src/Module/Settings/TwoFactor/Verify.php:149
#, php-format
msgid ""
"<p>Or you can open the following URL in your mobile device:</p><p><a href="
"\"%s\">%s</a></p>"
"<p>Or you can open the following URL in your mobile device:</p><p><a "
"href=\"%s\">%s</a></p>"
msgstr ""
#: src/Module/Settings/TwoFactor/Verify.php:156
@ -10706,22 +10771,41 @@ msgid ""
"e.g. Mastodon."
msgstr ""
#: src/Module/Special/DisplayNotFound.php:35
msgid "The top-level post isn't visible."
msgstr ""
#: src/Module/Special/DisplayNotFound.php:36
msgid "The top-level post was deleted."
msgstr ""
#: src/Module/Special/DisplayNotFound.php:37
msgid "Not Found"
msgid ""
"This node has blocked the top-level author or the author of the shared post."
msgstr ""
#: src/Module/Special/DisplayNotFound.php:38
msgid ""
"<p>Unfortunately, the requested conversation isn't available to you.</p>\n"
"<p>Possible reasons include:</p>\n"
"<ul>\n"
"\t<li>The top-level post isn't visible.</li>\n"
"\t<li>The top-level post was deleted.</li>\n"
"\t<li>The node has blocked the top-level author or the author of the shared "
"post.</li>\n"
"\t<li>You have ignored or blocked the top-level author or the author of the "
"shared post.</li>\n"
"</ul>"
"You have ignored or blocked the top-level author or the author of the shared "
"post."
msgstr ""
#: src/Module/Special/DisplayNotFound.php:39
msgid ""
"You have ignored the top-level author's server or the shared post author's "
"server."
msgstr ""
#: src/Module/Special/DisplayNotFound.php:45
msgid "Conversation Not Found"
msgstr ""
#: src/Module/Special/DisplayNotFound.php:46
msgid "Unfortunately, the requested conversation isn't available to you."
msgstr ""
#: src/Module/Special/DisplayNotFound.php:47
msgid "Possible reasons include:"
msgstr ""
#: src/Module/Special/HTTPException.php:78
@ -10758,9 +10842,9 @@ msgstr ""
msgid ""
"At any point in time a logged in user can export their account data from the "
"<a href=\"%1$s/settings/userexport\">account settings</a>. If the user wants "
"to delete their account they can do so at <a href=\"%1$s/settings/removeme\">"
"%1$s/settings/removeme</a>. The deletion of the account will be permanent. "
"Deletion of the data will also be requested from the nodes of the "
"to delete their account they can do so at <a href=\"%1$s/settings/"
"removeme\">%1$s/settings/removeme</a>. The deletion of the account will be "
"permanent. Deletion of the data will also be requested from the nodes of the "
"communication partners."
msgstr ""
@ -10776,6 +10860,10 @@ msgstr ""
msgid "Parameter uri_id is missing."
msgstr ""
#: src/Module/Update/Display.php:55
msgid "The requested item doesn't exist or has been deleted."
msgstr ""
#: src/Module/User/Import.php:103
msgid "User imports on closed servers can only be done by an administrator."
msgstr ""
@ -11486,27 +11574,27 @@ msgstr ""
msgid "%s posted an update."
msgstr ""
#: src/Object/Post.php:139
#: src/Object/Post.php:138
msgid "Private Message"
msgstr ""
#: src/Object/Post.php:143
#: src/Object/Post.php:142
msgid "Public Message"
msgstr ""
#: src/Object/Post.php:147
#: src/Object/Post.php:146
msgid "Unlisted Message"
msgstr ""
#: src/Object/Post.php:182
#: src/Object/Post.php:181
msgid "This entry was edited"
msgstr ""
#: src/Object/Post.php:210
#: src/Object/Post.php:209
msgid "Connector Message"
msgstr ""
#: src/Object/Post.php:226 src/Object/Post.php:228
#: src/Object/Post.php:225 src/Object/Post.php:227
msgid "Edit"
msgstr ""
@ -11537,207 +11625,207 @@ msgstr ""
msgid "Report post"
msgstr ""
#: src/Object/Post.php:287
#: src/Object/Post.php:293
msgid "Save to folder"
msgstr ""
#: src/Object/Post.php:327
#: src/Object/Post.php:333
msgid "I will attend"
msgstr ""
#: src/Object/Post.php:327
#: src/Object/Post.php:333
msgid "I will not attend"
msgstr ""
#: src/Object/Post.php:327
#: src/Object/Post.php:333
msgid "I might attend"
msgstr ""
#: src/Object/Post.php:357
#: src/Object/Post.php:363
msgid "Ignore thread"
msgstr ""
#: src/Object/Post.php:358
#: src/Object/Post.php:364
msgid "Unignore thread"
msgstr ""
#: src/Object/Post.php:359
#: src/Object/Post.php:365
msgid "Toggle ignore status"
msgstr ""
#: src/Object/Post.php:369
#: src/Object/Post.php:375
msgid "Add star"
msgstr ""
#: src/Object/Post.php:370
#: src/Object/Post.php:376
msgid "Remove star"
msgstr ""
#: src/Object/Post.php:371
#: src/Object/Post.php:377
msgid "Toggle star status"
msgstr ""
#: src/Object/Post.php:382
#: src/Object/Post.php:388
msgid "Pin"
msgstr ""
#: src/Object/Post.php:383
#: src/Object/Post.php:389
msgid "Unpin"
msgstr ""
#: src/Object/Post.php:384
#: src/Object/Post.php:390
msgid "Toggle pin status"
msgstr ""
#: src/Object/Post.php:387
#: src/Object/Post.php:393
msgid "Pinned"
msgstr ""
#: src/Object/Post.php:392
#: src/Object/Post.php:398
msgid "Add tag"
msgstr ""
#: src/Object/Post.php:405
#: src/Object/Post.php:411
msgid "Quote share this"
msgstr ""
#: src/Object/Post.php:405
#: src/Object/Post.php:411
msgid "Quote Share"
msgstr ""
#: src/Object/Post.php:408
#: src/Object/Post.php:414
msgid "Reshare this"
msgstr ""
#: src/Object/Post.php:408
#: src/Object/Post.php:414
msgid "Reshare"
msgstr ""
#: src/Object/Post.php:409
#: src/Object/Post.php:415
msgid "Cancel your Reshare"
msgstr ""
#: src/Object/Post.php:409
#: src/Object/Post.php:415
msgid "Unshare"
msgstr ""
#: src/Object/Post.php:460
#: src/Object/Post.php:466
#, php-format
msgid "%s (Received %s)"
msgstr ""
#: src/Object/Post.php:466
#: src/Object/Post.php:472
msgid "Comment this item on your system"
msgstr ""
#: src/Object/Post.php:466
#: src/Object/Post.php:472
msgid "Remote comment"
msgstr ""
#: src/Object/Post.php:488
#: src/Object/Post.php:494
msgid "Share via ..."
msgstr ""
#: src/Object/Post.php:488
#: src/Object/Post.php:494
msgid "Share via external services"
msgstr ""
#: src/Object/Post.php:517
#: src/Object/Post.php:523
msgid "to"
msgstr ""
#: src/Object/Post.php:518
#: src/Object/Post.php:524
msgid "via"
msgstr ""
#: src/Object/Post.php:519
#: src/Object/Post.php:525
msgid "Wall-to-Wall"
msgstr ""
#: src/Object/Post.php:520
#: src/Object/Post.php:526
msgid "via Wall-To-Wall:"
msgstr ""
#: src/Object/Post.php:566
#: src/Object/Post.php:573
#, php-format
msgid "Reply to %s"
msgstr ""
#: src/Object/Post.php:569
#: src/Object/Post.php:576
msgid "More"
msgstr ""
#: src/Object/Post.php:587
#: src/Object/Post.php:595
msgid "Notifier task is pending"
msgstr ""
#: src/Object/Post.php:588
#: src/Object/Post.php:596
msgid "Delivery to remote servers is pending"
msgstr ""
#: src/Object/Post.php:589
#: src/Object/Post.php:597
msgid "Delivery to remote servers is underway"
msgstr ""
#: src/Object/Post.php:590
#: src/Object/Post.php:598
msgid "Delivery to remote servers is mostly done"
msgstr ""
#: src/Object/Post.php:591
#: src/Object/Post.php:599
msgid "Delivery to remote servers is done"
msgstr ""
#: src/Object/Post.php:611
#: src/Object/Post.php:619
#, php-format
msgid "%d comment"
msgid_plural "%d comments"
msgstr[0] ""
msgstr[1] ""
#: src/Object/Post.php:612
#: src/Object/Post.php:620
msgid "Show more"
msgstr ""
#: src/Object/Post.php:613
#: src/Object/Post.php:621
msgid "Show fewer"
msgstr ""
#: src/Object/Post.php:649
#: src/Object/Post.php:657
#, php-format
msgid "Reshared by: %s"
msgstr ""
#: src/Object/Post.php:654
#: src/Object/Post.php:662
#, php-format
msgid "Viewed by: %s"
msgstr ""
#: src/Object/Post.php:659
#: src/Object/Post.php:667
#, php-format
msgid "Liked by: %s"
msgstr ""
#: src/Object/Post.php:664
#: src/Object/Post.php:672
#, php-format
msgid "Disliked by: %s"
msgstr ""
#: src/Object/Post.php:669
#: src/Object/Post.php:677
#, php-format
msgid "Attended by: %s"
msgstr ""
#: src/Object/Post.php:674
#: src/Object/Post.php:682
#, php-format
msgid "Maybe attended by: %s"
msgstr ""
#: src/Object/Post.php:679
#: src/Object/Post.php:687
#, php-format
msgid "Not attended by: %s"
msgstr ""
#: src/Object/Post.php:684
#: src/Object/Post.php:692
#, php-format
msgid "Reacted with %s by: %s"
msgstr ""

View file

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

View file

@ -1,110 +1,118 @@
<h1>{{$banner}}</h1>
<script>
$(document).ready(function () {
//$('.toggle-section-content + .toggle-section-content').hide();
$('.js-section-toggler').click(function () {
$('.toggle-section-content').hide();
$(this).parents('.toggle-section').find('.toggle-section-content').toggle();
});
});
</script>
{{$default nofilter}}
<h1>{{$l10n.banner}}</h1>
<div id="profile-edit-links">
<ul>
<li><a href="settings/profile/photo" id="profile-photo_upload-link" title="{{$profpic}}">{{$profpic}}</a></li>
<li><a href="profile/{{$nickname}}/profile" id="profile-edit-view-link" title="{{$viewprof}}">{{$viewprof}}</a></li>
<li><a class="btn" href="profile/{{$nickname}}/profile" id="profile-edit-view-link">{{$l10n.viewprof}}</a></li>
</ul>
</div>
<div id="profile-edit-links-end"></div>
<div id="profile-edit-wrapper">
<form id="profile-edit-form" name="form1" action="settings/profiles" method="post">
<form enctype="multipart/form-data" action="settings/profile/photo" method="post">
<input type="hidden" name="form_security_token" value="{{$form_security_token_photo}}">
<!-- Profile picture -->
<div class="toggle-section js-toggle-section">
<h2><a class="section-caption js-section-toggler" href="javascript:;">{{$l10n.picture_section}} &raquo;</a></h2>
<div class="js-section toggle-section-content hidden">
<div id="profile-photo-upload-wrapper">
<label id="profile-photo-upload-label" for="profile-photo-upload">{{$l10n.profile_photo}}:</label>
<input name="userfile" type="file" id="profile-photo-upload" size="48"/>
</div>
<div class="profile-edit-submit-wrapper">
<button type="submit" name="submit" class="profile-edit-submit-button">{{$l10n.submit}}</button>
</div>
<div class="profile-edit-submit-end"></div>
</div>
</div>
</form>
<form id="profile-edit-form" name="form1" action="" method="post">
<input type="hidden" name="form_security_token" value="{{$form_security_token}}">
<div id="profile-edit-name-wrapper">
<label id="profile-edit-name-label" for="profile-edit-name">{{$name.1}} </label>
<input type="text" size="32" name="name" id="profile-edit-name" value="{{$name.2}}"/>
</div>
<div id="profile-edit-name-end"></div>
<div id="profile-edit-about-wrapper">
<label id="profile-edit-about-label" for="profile-edit-about">{{$about.1}} </label>
<input type="text" size="32" name="about" id="profile-edit-about" value="{{$about.1}}"/>
</div>
<div id="profile-edit-about-end"></div>
<!-- Basic information -->
<div class="toggle-section js-toggle-section">
<h2><a class="section-caption js-section-toggler" href="javascript:;">{{$l10n.personal_section}} &raquo;</a></h2>
<div class="js-section toggle-section-content hidden">
{{include file="field_input.tpl" field=$username}}
{{include file="field_textarea.tpl" field=$about}}
{{include file="field_input.tpl" field=$xmpp}}
{{include file="field_input.tpl" field=$matrix}}
{{include file="field_input.tpl" field=$homepage}}
<div id="profile-edit-dob-wrapper">
{{$dob nofilter}}
</div>
<div id="profile-edit-dob-end"></div>
{{$hide_friends nofilter}}
{{include file="field_input.tpl" field=$pub_keywords}}
{{include file="field_input.tpl" field=$prv_keywords}}
<div class="profile-edit-submit-wrapper">
<input type="submit" name="submit" class="profile-edit-submit-button" value="{{$submit}}"/>
<button type="submit" name="submit" class="profile-edit-submit-button">{{$l10n.submit}}</button>
</div>
<div class="profile-edit-submit-end"></div>
<div id="profile-edit-address-wrapper">
<label id="profile-edit-address-label" for="profile-edit-address">{{$address.1}} </label>
<input type="text" size="32" name="address" id="profile-edit-address" value="{{$address.2}}"/>
</div>
<div id="profile-edit-address-end"></div>
<div id="profile-edit-locality-wrapper">
<label id="profile-edit-locality-label" for="profile-edit-locality">{{$locality.1}} </label>
<input type="text" size="32" name="locality" id="profile-edit-locality" value="{{$locality.2}}"/>
</div>
<div id="profile-edit-locality-end"></div>
<div id="profile-edit-postal-code-wrapper">
<label id="profile-edit-postal-code-label" for="profile-edit-postal-code">{{$postal_code.1}} </label>
<input type="text" size="32" name="postal_code" id="profile-edit-postal-code" value="{{$postal_code.2}}"/>
</div>
<div id="profile-edit-postal-code-end"></div>
<!-- About you -->
<div class="toggle-section js-toggle-section">
<h2><a class="section-caption js-section-toggler" href="javascript:;">{{$l10n.location_section}} &raquo;</a></h2>
<div class="js-section toggle-section-content hidden">
{{include file="field_input.tpl" field=$address}}
{{include file="field_input.tpl" field=$locality}}
{{include file="field_input.tpl" field=$postal_code}}
<div id="profile-edit-country-name-wrapper">
<label id="profile-edit-country-name-label" for="profile-edit-country-name">{{$country_name.1}} </label>
<select name="country_name" id="profile-edit-country-name" onChange="Fill_States('{{$region.2}}');">
<option selected="selected">{{$country_name.2}}</option>
<option>temp</option>
</select>
</div>
<div id="profile-edit-country-name-end"></div>
<div id="profile-edit-region-wrapper">
<label id="profile-edit-region-label" for="profile-edit-region">{{$region.1}} </label>
<select name="region" id="profile-edit-region" onChange="Update_Globals();">
<option selected="selected">{{$region.2}}</option>
<option>temp</option>
</select>
</div>
<div id="profile-edit-region-end"></div>
<div class="profile-edit-submit-wrapper">
<input type="submit" name="submit" class="profile-edit-submit-button" value="{{$submit}}"/>
</div>
<div class="profile-edit-submit-end"></div>
<div id="profile-edit-homepage-wrapper">
<label id="profile-edit-homepage-label" for="profile-edit-homepage">{{$homepage.1}} </label>
<input type="url" size="32" name="homepage" id="profile-edit-homepage" value="{{$homepage.2}}"/>
</div>
<div id="profile-edit-homepage-desc">{{$homepage.3}}</div>
<div id="profile-edit-homepage-end"></div>
<div id="profile-edit-xmpp-wrapper">
<label id="profile-edit-xmpp-label" for="profile-edit-xmpp">{{$xmpp.1}} </label>
<input type="text" size="32" name="xmpp" id="profile-edit-xmpp" title="{{$lbl_ex2}}" value="{{$xmpp.2}}"/>
</div>
<div id="profile-edit-xmpp-desc">{{$xmpp.3}}</div>
<div id="profile-edit-xmpp-end"></div>
<div id="profile-edit-matrix-wrapper">
<label id="profile-edit-matrix-label" for="profile-edit-matrix">{{$matrix.1}} </label>
<input type="text" size="32" name="matrix" id="profile-edit-matrix" title="{{$lbl_ex2}}" value="{{$matrix.2}}"/>
</div>
<div id="profile-edit-matrix-desc">{{$matrix.3}}</div>
<div id="profile-edit-matrix-end"></div>
<div id="profile-edit-pubkeywords-wrapper">
<label id="profile-edit-pubkeywords-label" for="profile-edit-pubkeywords">{{$pub_keywords.1}} </label>
<input type="text" size="32" name="pub_keywords" id="profile-edit-pubkeywords" title="{{$lbl_ex2}}" value="{{$pub_keywords.2}}"/>
</div>
<div id="profile-edit-pubkeywords-desc">{{$pub_keywords.3}}</div>
<div id="profile-edit-pubkeywords-end"></div>
<div id="profile-edit-prvkeywords-wrapper">
<label id="profile-edit-prvkeywords-label" for="profile-edit-prvkeywords">{{$prv_keywords.1}} </label>
<input type="text" size="32" name="prv_keywords" id="profile-edit-prvkeywords" title="{{$lbl_ex2}}" value="{{$prv_keywords.2}}"/>
</div>
<div id="profile-edit-prvkeywords-desc">{{$prv_keywords.3}}</div>
<div id="profile-edit-prvkeywords-end"></div>
<div class="profile-edit-submit-wrapper">
<input type="submit" name="submit" class="profile-edit-submit-button" value="{{$submit}}"/>
</div>
<div class="profile-edit-submit-end"></div>
<h2>{{$lbl_custom_fields_section}}</h2>
<div class="profile-edit-submit-wrapper">
<button type="submit" name="submit" class="profile-edit-submit-button">{{$l10n.submit}}</button>
</div>
<div class="profile-edit-submit-end"></div>
</div>
</div>
<!-- Interests -->
<div class="toggle-section js-toggle-section">
<h2><a class="section-caption js-section-toggler" href="javascript:;">{{$l10n.custom_fields_section}} &raquo;</a></h2>
<div class="js-section toggle-section-content hidden">
{{$custom_fields_description nofilter}}
<div id="profile-custom-fields">
{{foreach $custom_fields as $custom_field}}
@ -113,9 +121,11 @@
</div>
<div class="profile-edit-submit-wrapper">
<input type="submit" name="submit" class="profile-edit-submit-button" value="{{$submit}}"/>
<button type="submit" name="submit" class="profile-edit-submit-button">{{$l10n.submit}}</button>
</div>
<div class="profile-edit-submit-end"></div>
</div>
</div>
</form>
</div>
<script type="text/javascript">

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -7,6 +7,8 @@ They are loaded into the html <head> so that js functions can use them *}}
blockAuthor : "{{$l10n.blockAuthor|escape:'javascript' nofilter}}",
ignoreAuthor : "{{$l10n.ignoreAuthor|escape:'javascript' nofilter}}",
collapseAuthor : "{{$l10n.collapseAuthor|escape:'javascript' nofilter}}",
ignoreServer : "{{$l10n.ignoreServer|escape:'javascript' nofilter}}",
ignoreServerDesc : "{{$l10n.ignoreServerDesc|escape:'javascript' nofilter}}",
};
const aActErr = {
like : "{{$l10n.likeError|escape:'javascript' nofilter}}",

View file

@ -1,18 +1,18 @@
<div class="generic-page-wrapper">
<h1>{{$banner}}</h1>
<h2>{{$l10n.banner}}</h2>
{{* The actions dropdown which can performed to the current profile *}}
<div id="profile-edit-links">
<ul class="nav nav-pills preferences">
<li class="dropdown pull-right">
<button type="button" class="btn btn-link dropdown-toggle" id="profile-edit-links-dropdown" data-toggle="dropdown" aria-expanded="false">
<i class="fa fa-angle-down" aria-hidden="true"></i>&nbsp;{{$profile_action}}
<i class="fa fa-angle-down" aria-hidden="true"></i>&nbsp;{{$l10n.profile_action}}
</button>
<ul class="dropdown-menu pull-right" role="menu" aria-labelledby="profile-edit-links-dropdown">
<li role="presentation"><a role="menuitem" href="{{$profpiclink}}" id="profile-photo_upload-link" title="{{$profpic}}"><i class="fa fa-user" aria-hidden="true"></i>&nbsp;{{$profpic}}</a></li>
<li role="presentation"><button role="menuitem" type="button" class="btn-link" id="profile-photo_upload-link-new" title="{{$lbl_profile_photo}}" onclick="openClose('profile-photo-upload-section');"><i class="fa fa-user" aria-hidden="true"></i>&nbsp;{{$lbl_profile_photo}}</button></li>
<li role="presentation"><a role="menuitem" href="{{$profpiclink}}" id="profile-photo_upload-link"><i class="fa fa-user" aria-hidden="true"></i>&nbsp;{{$l10n.profpic}}</a></li>
<li role="presentation"><button role="menuitem" type="button" class="btn-link" id="profile-photo_upload-link-new" onclick="openClose('profile-photo-upload-section');"><i class="fa fa-user" aria-hidden="true"></i>&nbsp;{{$l10n.profile_photo}}</button></li>
<li role="presentation" class="divider"></li>
<li role="presentation"><a role="menuitem" href="profile/{{$nickname}}/profile" id="profile-edit-view-link" title="{{$viewprof}}">{{$viewprof}}</a></li>
<li role="presentation"><a role="menuitem" href="profile/{{$nickname}}/profile" id="profile-edit-view-link">{{$l10n.viewprof}}</a></li>
</ul>
</li>
</ul>
@ -26,12 +26,12 @@
<div id="profile-photo-upload-section" class="panel">
<a id="profile-photo-upload-close" class="close pull-right" onclick="openClose('profile-photo-upload-section');"><i class="fa fa-times" aria-hidden="true"></i></a>
<div id="profile-photo-upload-wrapper">
<label id="profile-photo-upload-label" for="profile-photo-upload">{{$lbl_profile_photo}}:</label>
<label id="profile-photo-upload-label" for="profile-photo-upload">{{$l10n.profile_photo}}:</label>
<input name="userfile" type="file" id="profile-photo-upload" size="48" />
</div>
<div class="profile-edit-submit-wrapper pull-right">
<button type="submit" name="submit" class="profile-edit-submit-button btn btn-primary" value="{{$submit}}">{{$submit}}</button>
<button type="submit" name="submit" class="profile-edit-submit-button btn btn-primary">{{$l10n.submit}}</button>
</div>
<div class="clear"></div>
</div>
@ -53,14 +53,14 @@
<div class="section-subtitle-wrapper panel-heading" role="tab" id="personal">
<h2>
<button class="btn-link accordion-toggle" data-toggle="collapse" data-parent="#profile-edit-wrapper" href="#personal-collapse" aria-expanded="true" aria-controls="personal-collapse">
{{$lbl_personal_section}}
{{$l10n.personal_section}}
</button>
</h2>
</div>
{{* for the $detailed_profile we use bootstraps collapsable panel-groups to have expandable groups *}}
<div id="personal-collapse" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="personal">
<div class="panel-body">
{{include file="field_input.tpl" field=$name}}
{{include file="field_input.tpl" field=$username}}
{{include file="field_textarea.tpl" field=$about}}
@ -69,7 +69,7 @@
{{$hide_friends nofilter}}
</div>
<div class="panel-footer">
<button type="submit" name="submit" class="btn btn-primary" value="{{$submit}}">{{$submit}}</button>
<button type="submit" name="submit" class="btn btn-primary">{{$l10n.submit}}</button>
</div>
</div>
</div>
@ -79,7 +79,7 @@
<div class="section-subtitle-wrapper panel-heading" role="tab" id="location">
<h2>
<button class="btn-link accordion-toggle collapsed" data-toggle="collapse" data-parent="#profile-edit-wrapper" href="#location-collapse" aria-expanded="false" aria-controls="location-collapse">
{{$lbl_location_section}}
{{$l10n.location_section}}
</button>
</h2>
</div>
@ -109,7 +109,7 @@
</div>
</div>
<div class="panel-footer">
<button type="submit" name="submit" class="btn btn-primary" value="{{$submit}}">{{$submit}}</button>
<button type="submit" name="submit" class="btn btn-primary">{{$l10n.submit}}</button>
</div>
</div>
</div>
@ -119,7 +119,7 @@
<div class="section-subtitle-wrapper panel-heading" role="tab" id="miscellaneous">
<h2>
<button class="btn-link accordion-toggle collapsed" data-toggle="collapse" data-parent="#profile-edit-wrapper" href="#miscellaneous-collapse" aria-expanded="false" aria-controls="miscellaneous-collapse">
{{$lbl_miscellaneous_section}}
{{$l10n.miscellaneous_section}}
</button>
</h2>
</div>
@ -136,7 +136,7 @@
{{include file="field_input.tpl" field=$prv_keywords}}
</div>
<div class="panel-footer">
<button type="submit" name="submit" class="btn btn-primary" value="{{$submit}}">{{$submit}}</button>
<button type="submit" name="submit" class="btn btn-primary">{{$l10n.submit}}</button>
</div>
</div>
</div>
@ -146,7 +146,7 @@
<div class="section-subtitle-wrapper panel-heading" role="tab" id="custom-fields">
<h2>
<button class="btn-link accordion-toggle collapsed" data-toggle="collapse" data-parent="#profile-edit-wrapper" href="#custom-fields-collapse" aria-expanded="false" aria-controls="custom-fields-collapse">
{{$lbl_custom_fields_section}}
{{$l10n.custom_fields_section}}
</button>
</h2>
</div>
@ -160,7 +160,7 @@
</div>
</div>
<div class="panel-footer">
<button type="submit" name="submit" class="btn btn-primary" value="{{$submit}}">{{$submit}}</button>
<button type="submit" name="submit" class="btn btn-primary">{{$l10n.submit}}</button>
</div>
</div>
</div>

View file

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

View file

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

View file

@ -1,179 +0,0 @@
<script>
$(document).ready(function () {
//$('.toggle-section-content + .toggle-section-content').hide();
$('.js-section-toggler').click(function () {
$('.toggle-section-content').hide();
$(this).parents('.toggle-section').find('.toggle-section-content').toggle();
});
});
</script>
<h1>{{$banner}}</h1>
<div id="profile-edit-links">
<ul>
<li><a class="btn" href="profile/{{$nickname}}/profile" id="profile-edit-view-link" title="{{$viewprof}}">{{$viewprof}}</a></li>
</ul>
</div>
<div id="profile-edit-links-end"></div>
<div id="profile-edit-wrapper">
<form enctype="multipart/form-data" action="settings/profile/photo" method="post">
<input type="hidden" name="form_security_token" value="{{$form_security_token_photo}}">
<!-- Profile picture -->
<div class="toggle-section js-toggle-section">
<h2><a class="section-caption js-section-toggler" href="javascript:;">{{$lbl_picture_section}} &raquo;</a></h2>
<div class="js-section toggle-section-content hidden">
<div id="profile-photo-upload-wrapper">
<label id="profile-photo-upload-label" for="profile-photo-upload">{{$lbl_profile_photo}}:</label>
<input name="userfile" type="file" id="profile-photo-upload" size="48"/>
</div>
<div class="profile-edit-submit-wrapper">
<input type="submit" name="submit" class="profile-edit-submit-button" value="{{$submit}}"/>
</div>
<div class="profile-edit-submit-end"></div>
</div>
</div>
</form>
<form id="profile-edit-form" name="form1" action="" method="post">
<input type="hidden" name="form_security_token" value="{{$form_security_token}}">
<!-- Basic information -->
<div class="toggle-section js-toggle-section">
<h2><a class="section-caption js-section-toggler" href="javascript:;">{{$lbl_personal_section}} &raquo;</a></h2>
<div class="js-section toggle-section-content hidden">
<div id="profile-edit-name-wrapper">
<label id="profile-edit-name-label" for="profile-edit-name">{{$name.1}} </label>
<input type="text" size="32" name="name" id="profile-edit-name" value="{{$name.2}}"/>
</div>
<div id="profile-edit-name-end"></div>
<div id="profile-edit-about-wrapper">
<label id="profile-edit-about-label" for="profile-edit-about">{{$about.1}} </label>
<input type="text" size="32" name="about" id="profile-edit-about" value="{{$about.2}}"/>
</div>
<div id="profile-edit-about-end"></div>
<div id="profile-edit-xmpp-wrapper">
<label id="profile-edit-xmpp-label" for="profile-edit-xmpp">{{$xmpp.1}} </label>
<input type="text" size="32" name="xmpp" id="profile-edit-xmpp" value="{{$xmpp.2}}"/>
</div>
<div id="profile-edit-xmpp-desc">{{$xmpp.3}}</div>
<div id="profile-edit-xmpp-end"></div>
<div id="profile-edit-matrix-wrapper">
<label id="profile-edit-matrix-label" for="profile-edit-matrix">{{$matrix.1}} </label>
<input type="text" size="32" name="matrix" id="profile-edit-matrix" value="{{$matrix.2}}"/>
</div>
<div id="profile-edit-matrix-desc">{{$matrix.3}}</div>
<div id="profile-edit-matrix-end"></div>
<div id="profile-edit-homepage-wrapper">
<label id="profile-edit-homepage-label" for="profile-edit-homepage">{{$homepage.1}} </label>
<input type="text" size="32" name="homepage" id="profile-edit-homepage" value="{{$homepage.2}}"/>
</div>
<div id="profile-edit-homepage-desc">{{$homepage.3}}</div>
<div id="profile-edit-homepage-end"></div>
<div id="profile-edit-dob-wrapper">
{{$dob nofilter}}
</div>
<div id="profile-edit-dob-end"></div>
{{$hide_friends nofilter}}
<div id="profile-edit-pubkeywords-wrapper">
<label id="profile-edit-pubkeywords-label" for="profile-edit-pubkeywords">{{$pub_keywords.1}} </label>
<input type="text" size="32" name="pub_keywords" id="profile-edit-pubkeywords" title="{{$lbl_ex2}}" value="{{$pub_keywords.2}}"/>
</div>
<div id="profile-edit-pubkeywords-desc">{{$pub_keywords.3}}</div>
<div id="profile-edit-pubkeywords-end"></div>
<div id="profile-edit-prvkeywords-wrapper">
<label id="profile-edit-prvkeywords-label" for="profile-edit-prvkeywords">{{$prv_keywords.1}} </label>
<input type="text" size="32" name="prv_keywords" id="profile-edit-prvkeywords" title="{{$lbl_ex2}}" value="{{$prv_keywords.2}}"/>
</div>
<div id="profile-edit-prvkeywords-desc">{{$prv_keywords.3}}</div>
<div id="profile-edit-prvkeywords-end"></div>
<div class="profile-edit-submit-wrapper">
<input type="submit" name="submit" class="profile-edit-submit-button" value="{{$submit}}"/>
</div>
<div class="profile-edit-submit-end"></div>
</div>
</div>
<!-- About you -->
<div class="toggle-section js-toggle-section">
<h2><a class="section-caption js-section-toggler" href="javascript:;">{{$lbl_location_section}} &raquo;</a></h2>
<div class="js-section toggle-section-content hidden">
<div id="profile-edit-address-wrapper">
<label id="profile-edit-address-label" for="profile-edit-address">{{$address.1}} </label>
<input type="text" size="32" name="address" id="profile-edit-address" value="{{$address.2}}"/>
</div>
<div id="profile-edit-address-end"></div>
<div id="profile-edit-locality-wrapper">
<label id="profile-edit-locality-label" for="profile-edit-locality">{{$locality.1}} </label>
<input type="text" size="32" name="locality" id="profile-edit-locality" value="{{$locality.2}}"/>
</div>
<div id="profile-edit-locality-end"></div>
<div id="profile-edit-postal-code-wrapper">
<label id="profile-edit-postal-code-label" for="profile-edit-postal-code">{{$postal_code.1}} </label>
<input type="text" size="32" name="postal_code" id="profile-edit-postal-code" value="{{$postal_code.2}}"/>
</div>
<div id="profile-edit-postal-code-end"></div>
<div id="profile-edit-country-name-wrapper">
<label id="profile-edit-country-name-label" for="profile-edit-country-name">{{$country_name.1}} </label>
<select name="country_name" id="profile-edit-country-name" onChange="Fill_States('{{$region.2}}');">
<option selected="selected">{{$country_name.2}}</option>
</select>
</div>
<div id="profile-edit-country-name-end"></div>
<div id="profile-edit-region-wrapper">
<label id="profile-edit-region-label" for="profile-edit-region">{{$region.1}} </label>
<select name="region" id="profile-edit-region" onChange="Update_Globals();">
<option selected="selected">{{$region.2}}</option>
</select>
</div>
<div id="profile-edit-region-end"></div>
<div class="profile-edit-submit-wrapper">
<input type="submit" name="submit" class="profile-edit-submit-button" value="{{$submit}}"/>
</div>
<div class="profile-edit-submit-end"></div>
</div>
</div>
<!-- Interests -->
<div class="toggle-section js-toggle-section">
<h2><a class="section-caption js-section-toggler" href="javascript:;">{{$lbl_custom_fields_section}} &raquo;</a></h2>
<div class="js-section toggle-section-content hidden">
{{$custom_fields_description nofilter}}
<div id="profile-custom-fields">
{{foreach $custom_fields as $custom_field}}
{{include file="settings/profile/field/edit.tpl" profile_field=$custom_field}}
{{/foreach}}
</div>
<div class="profile-edit-submit-wrapper">
<input type="submit" name="submit" class="profile-edit-submit-button" value="{{$submit}}"/>
</div>
<div class="profile-edit-submit-end"></div>
</div>
</div>
</form>
</div>
<script type="text/javascript">
Fill_Country('{{$country_name.2}}');
Fill_States('{{$region.2}}');
</script>