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) -- 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 FOREIGN KEY (`parent-uid`) REFERENCES `user` (`uid`) ON UPDATE RESTRICT ON DELETE CASCADE
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='The local users'; ) DEFAULT COLLATE utf8mb4_general_ci COMMENT='The local users';
--
-- TABLE user-gserver
--
CREATE TABLE IF NOT EXISTS `user-gserver` (
`uid` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'Owner User id',
`gsid` int unsigned NOT NULL DEFAULT 0 COMMENT 'Gserver id',
`ignored` boolean NOT NULL DEFAULT '0' COMMENT 'server accounts are ignored for the user',
PRIMARY KEY(`uid`,`gsid`),
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 -- TABLE item-uri
-- --
@ -160,8 +173,8 @@ CREATE TABLE IF NOT EXISTS `contact` (
`archive` boolean NOT NULL DEFAULT '0' COMMENT '', `archive` boolean NOT NULL DEFAULT '0' COMMENT '',
`unsearchable` boolean NOT NULL DEFAULT '0' COMMENT 'Contact prefers to not be searchable', `unsearchable` boolean NOT NULL DEFAULT '0' COMMENT 'Contact prefers to not be searchable',
`sensitive` boolean NOT NULL DEFAULT '0' COMMENT 'Contact posts sensitive content', `sensitive` boolean NOT NULL DEFAULT '0' COMMENT 'Contact posts sensitive content',
`baseurl` varbinary(383) DEFAULT '' COMMENT 'baseurl of the contact', `baseurl` varbinary(383) DEFAULT '' COMMENT 'baseurl of the contact from the gserver record, can be missing',
`gsid` int unsigned COMMENT 'Global Server ID', `gsid` int unsigned COMMENT 'Global Server ID, can be missing',
`bd` date NOT NULL DEFAULT '0001-01-01' COMMENT '', `bd` date NOT NULL DEFAULT '0001-01-01' COMMENT '',
`reason` text COMMENT '', `reason` text COMMENT '',
`self` boolean NOT NULL DEFAULT '0' COMMENT '1 if the contact is the user him/her self', `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', `profile-name` varchar(255) COMMENT 'Deprecated',
`is-default` boolean COMMENT 'Deprecated', `is-default` boolean COMMENT 'Deprecated',
`hide-friends` boolean NOT NULL DEFAULT '0' COMMENT 'Hide friend list from viewers of this profile', `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', `pdesc` varchar(255) COMMENT 'Deprecated',
`dob` varchar(32) NOT NULL DEFAULT '0000-00-00' COMMENT 'Day of birth', `dob` varchar(32) NOT NULL DEFAULT '0000-00-00' COMMENT 'Day of birth',
`address` varchar(255) NOT NULL DEFAULT '' COMMENT '', `address` varchar(255) NOT NULL DEFAULT '' COMMENT '',
@ -2032,6 +2045,7 @@ CREATE VIEW `post-user-view` AS SELECT
`author`.`hidden` AS `author-hidden`, `author`.`hidden` AS `author-hidden`,
`author`.`updated` AS `author-updated`, `author`.`updated` AS `author-updated`,
`author`.`gsid` AS `author-gsid`, `author`.`gsid` AS `author-gsid`,
`author`.`baseurl` AS `author-baseurl`,
`post-user`.`owner-id` AS `owner-id`, `post-user`.`owner-id` AS `owner-id`,
`owner`.`uri-id` AS `owner-uri-id`, `owner`.`uri-id` AS `owner-uri-id`,
`owner`.`url` AS `owner-link`, `owner`.`url` AS `owner-link`,
@ -2044,6 +2058,7 @@ CREATE VIEW `post-user-view` AS SELECT
`owner`.`blocked` AS `owner-blocked`, `owner`.`blocked` AS `owner-blocked`,
`owner`.`hidden` AS `owner-hidden`, `owner`.`hidden` AS `owner-hidden`,
`owner`.`updated` AS `owner-updated`, `owner`.`updated` AS `owner-updated`,
`owner`.`gsid` AS `owner-gsid`,
`owner`.`contact-type` AS `owner-contact-type`, `owner`.`contact-type` AS `owner-contact-type`,
`post-user`.`causer-id` AS `causer-id`, `post-user`.`causer-id` AS `causer-id`,
`causer`.`uri-id` AS `causer-uri-id`, `causer`.`uri-id` AS `causer-uri-id`,
@ -2056,6 +2071,7 @@ CREATE VIEW `post-user-view` AS SELECT
`causer`.`network` AS `causer-network`, `causer`.`network` AS `causer-network`,
`causer`.`blocked` AS `causer-blocked`, `causer`.`blocked` AS `causer-blocked`,
`causer`.`hidden` AS `causer-hidden`, `causer`.`hidden` AS `causer-hidden`,
`causer`.`gsid` AS `causer-gsid`,
`causer`.`contact-type` AS `causer-contact-type`, `causer`.`contact-type` AS `causer-contact-type`,
`post-delivery-data`.`postopts` AS `postopts`, `post-delivery-data`.`postopts` AS `postopts`,
`post-delivery-data`.`inform` AS `inform`, `post-delivery-data`.`inform` AS `inform`,
@ -2189,6 +2205,7 @@ CREATE VIEW `post-thread-user-view` AS SELECT
`contact`.`pending` AS `contact-pending`, `contact`.`pending` AS `contact-pending`,
`contact`.`rel` AS `contact-rel`, `contact`.`rel` AS `contact-rel`,
`contact`.`uid` AS `contact-uid`, `contact`.`uid` AS `contact-uid`,
`contact`.`gsid` AS `contact-gsid`,
`contact`.`contact-type` AS `contact-contact-type`, `contact`.`contact-type` AS `contact-contact-type`,
IF (`post-user`.`network` IN ('apub', 'dfrn', 'dspr', 'stat'), true, `contact`.`writable`) AS `writable`, IF (`post-user`.`network` IN ('apub', 'dfrn', 'dspr', 'stat'), true, `contact`.`writable`) AS `writable`,
`contact`.`self` AS `self`, `contact`.`self` AS `self`,
@ -2224,6 +2241,7 @@ CREATE VIEW `post-thread-user-view` AS SELECT
`owner`.`blocked` AS `owner-blocked`, `owner`.`blocked` AS `owner-blocked`,
`owner`.`hidden` AS `owner-hidden`, `owner`.`hidden` AS `owner-hidden`,
`owner`.`updated` AS `owner-updated`, `owner`.`updated` AS `owner-updated`,
`owner`.`gsid` AS `owner-gsid`,
`owner`.`contact-type` AS `owner-contact-type`, `owner`.`contact-type` AS `owner-contact-type`,
`post-thread-user`.`causer-id` AS `causer-id`, `post-thread-user`.`causer-id` AS `causer-id`,
`causer`.`uri-id` AS `causer-uri-id`, `causer`.`uri-id` AS `causer-uri-id`,
@ -2236,6 +2254,7 @@ CREATE VIEW `post-thread-user-view` AS SELECT
`causer`.`network` AS `causer-network`, `causer`.`network` AS `causer-network`,
`causer`.`blocked` AS `causer-blocked`, `causer`.`blocked` AS `causer-blocked`,
`causer`.`hidden` AS `causer-hidden`, `causer`.`hidden` AS `causer-hidden`,
`causer`.`gsid` AS `causer-gsid`,
`causer`.`contact-type` AS `causer-contact-type`, `causer`.`contact-type` AS `causer-contact-type`,
`post-delivery-data`.`postopts` AS `postopts`, `post-delivery-data`.`postopts` AS `postopts`,
`post-delivery-data`.`inform` AS `inform`, `post-delivery-data`.`inform` AS `inform`,
@ -2391,6 +2410,7 @@ CREATE VIEW `post-view` AS SELECT
`owner`.`hidden` AS `owner-hidden`, `owner`.`hidden` AS `owner-hidden`,
`owner`.`updated` AS `owner-updated`, `owner`.`updated` AS `owner-updated`,
`owner`.`contact-type` AS `owner-contact-type`, `owner`.`contact-type` AS `owner-contact-type`,
`owner`.`gsid` AS `owner-gsid`,
`post`.`causer-id` AS `causer-id`, `post`.`causer-id` AS `causer-id`,
`causer`.`uri-id` AS `causer-uri-id`, `causer`.`uri-id` AS `causer-uri-id`,
`causer`.`url` AS `causer-link`, `causer`.`url` AS `causer-link`,
@ -2403,6 +2423,7 @@ CREATE VIEW `post-view` AS SELECT
`causer`.`blocked` AS `causer-blocked`, `causer`.`blocked` AS `causer-blocked`,
`causer`.`hidden` AS `causer-hidden`, `causer`.`hidden` AS `causer-hidden`,
`causer`.`contact-type` AS `causer-contact-type`, `causer`.`contact-type` AS `causer-contact-type`,
`causer`.`gsid` AS `causer-gsid`,
`post-question`.`id` AS `question-id`, `post-question`.`id` AS `question-id`,
`post-question`.`multiple` AS `question-multiple`, `post-question`.`multiple` AS `question-multiple`,
`post-question`.`voters` AS `question-voters`, `post-question`.`voters` AS `question-voters`,
@ -2533,6 +2554,7 @@ CREATE VIEW `post-thread-view` AS SELECT
`owner`.`blocked` AS `owner-blocked`, `owner`.`blocked` AS `owner-blocked`,
`owner`.`hidden` AS `owner-hidden`, `owner`.`hidden` AS `owner-hidden`,
`owner`.`updated` AS `owner-updated`, `owner`.`updated` AS `owner-updated`,
`owner`.`gsid` AS `owner-gsid`,
`owner`.`contact-type` AS `owner-contact-type`, `owner`.`contact-type` AS `owner-contact-type`,
`post-thread`.`causer-id` AS `causer-id`, `post-thread`.`causer-id` AS `causer-id`,
`causer`.`uri-id` AS `causer-uri-id`, `causer`.`uri-id` AS `causer-uri-id`,
@ -2545,6 +2567,7 @@ CREATE VIEW `post-thread-view` AS SELECT
`causer`.`network` AS `causer-network`, `causer`.`network` AS `causer-network`,
`causer`.`blocked` AS `causer-blocked`, `causer`.`blocked` AS `causer-blocked`,
`causer`.`hidden` AS `causer-hidden`, `causer`.`hidden` AS `causer-hidden`,
`causer`.`gsid` AS `causer-gsid`,
`causer`.`contact-type` AS `causer-contact-type`, `causer`.`contact-type` AS `causer-contact-type`,
`post-question`.`id` AS `question-id`, `post-question`.`id` AS `question-id`,
`post-question`.`multiple` AS `question-multiple`, `post-question`.`multiple` AS `question-multiple`,
@ -2666,7 +2689,7 @@ CREATE VIEW `network-item-view` AS SELECT
`post-user`.`contact-id` AS `contact-id`, `post-user`.`contact-id` AS `contact-id`,
`ownercontact`.`contact-type` AS `contact-type` `ownercontact`.`contact-type` AS `contact-type`
FROM `post-user` FROM `post-user`
INNER JOIN `post-thread-user` ON `post-thread-user`.`uri-id` = `post-user`.`parent-uri-id` AND `post-thread-user`.`uid` = `post-user`.`uid` INNER JOIN `post-thread-user` ON `post-thread-user`.`uri-id` = `post-user`.`parent-uri-id` AND `post-thread-user`.`uid` = `post-user`.`uid`
STRAIGHT_JOIN `contact` ON `contact`.`id` = `post-thread-user`.`contact-id` STRAIGHT_JOIN `contact` ON `contact`.`id` = `post-thread-user`.`contact-id`
STRAIGHT_JOIN `contact` AS `authorcontact` ON `authorcontact`.`id` = `post-thread-user`.`author-id` STRAIGHT_JOIN `contact` AS `authorcontact` ON `authorcontact`.`id` = `post-thread-user`.`author-id`
STRAIGHT_JOIN `contact` AS `ownercontact` ON `ownercontact`.`id` = `post-thread-user`.`owner-id` STRAIGHT_JOIN `contact` AS `ownercontact` ON `ownercontact`.`id` = `post-thread-user`.`owner-id`
@ -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 (`post-thread-user`.`hidden` IS NULL OR NOT `post-thread-user`.`hidden`)
AND NOT `authorcontact`.`blocked` AND NOT `ownercontact`.`blocked` AND NOT `authorcontact`.`blocked` AND NOT `ownercontact`.`blocked`
AND (`author`.`blocked` IS NULL OR NOT `author`.`blocked`) AND (`author`.`blocked` IS NULL OR NOT `author`.`blocked`)
AND (`owner`.`blocked` IS NULL OR NOT `owner`.`blocked`); AND (`owner`.`blocked` IS NULL OR NOT `owner`.`blocked`)
AND NOT EXISTS(SELECT `gsid` FROM `user-gserver` WHERE `uid` = `post-thread-user`.`uid` AND `gsid` IN (`authorcontact`.`gsid`, `ownercontact`.`gsid`) AND `ignored`);
-- --
-- VIEW owner-view -- VIEW owner-view

View file

@ -10,8 +10,10 @@ If you installed Friendica in the ``path/to/friendica`` folder:
1. Unpack the new Friendica archive in ``path/to/friendica_new``. 1. Unpack the new Friendica archive in ``path/to/friendica_new``.
2. Copy the following items from ``path/to/friendica`` to ``path/to/friendica_new``: 2. Copy the following items from ``path/to/friendica`` to ``path/to/friendica_new``:
* ``config/local.config.php`` * ``config/local.config.php``
* ``proxy/`` * ``proxy/``
The following items only need to be copied if they are located inside your friendica path: * ``.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 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** * your item cache as set in **Admin -> Site -> Performance -> Path to item cache**
* your temp folder as set in **Admin -> Site -> Advanced -> Temp path** * your temp folder as set in **Admin -> Site -> Advanced -> Temp path**

View file

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

View file

@ -51,8 +51,8 @@ Fields
| archive | | boolean | NO | | 0 | | | archive | | boolean | NO | | 0 | |
| unsearchable | Contact prefers to not be searchable | boolean | NO | | 0 | | | unsearchable | Contact prefers to not be searchable | boolean | NO | | 0 | |
| sensitive | Contact posts sensitive content | boolean | NO | | 0 | | | sensitive | Contact posts sensitive content | boolean | NO | | 0 | |
| baseurl | baseurl of the contact | varbinary(383) | YES | | | | | baseurl | baseurl of the contact from the gserver record, can be missing | varbinary(383) | YES | | | |
| gsid | Global Server ID | int unsigned | YES | | NULL | | | gsid | Global Server ID, can be missing | int unsigned | YES | | NULL | |
| bd | | date | NO | | 0001-01-01 | | | bd | | date | NO | | 0001-01-01 | |
| reason | | text | YES | | NULL | | | reason | | text | YES | | NULL | |
| self | 1 if the contact is the user him/her self | boolean | NO | | 0 | | | 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 | | | profile-name | Deprecated | varchar(255) | YES | | NULL | |
| is-default | Deprecated | boolean | YES | | NULL | | | is-default | Deprecated | boolean | YES | | NULL | |
| hide-friends | Hide friend list from viewers of this profile | boolean | NO | | 0 | | | 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 | | | pdesc | Deprecated | varchar(255) | YES | | NULL | |
| dob | Day of birth | varchar(32) | NO | | 0000-00-00 | | | dob | Day of birth | varchar(32) | NO | | 0000-00-00 | |
| address | | varchar(255) | NO | | | | | 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

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

View file

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

View file

@ -34,15 +34,16 @@ use Friendica\Core\Protocol;
use Friendica\Core\Session\Capability\IHandleUserSessions; use Friendica\Core\Session\Capability\IHandleUserSessions;
use Friendica\Core\System; use Friendica\Core\System;
use Friendica\Database\DBA; use Friendica\Database\DBA;
use Friendica\DI;
use Friendica\Model\Attach; use Friendica\Model\Attach;
use Friendica\Model\Circle;
use Friendica\Model\Contact; use Friendica\Model\Contact;
use Friendica\Model\Conversation; use Friendica\Model\Conversation;
use Friendica\Model\FileTag; use Friendica\Model\FileTag;
use Friendica\Model\Circle;
use Friendica\Model\Item as ItemModel; use Friendica\Model\Item as ItemModel;
use Friendica\Model\Photo; use Friendica\Model\Photo;
use Friendica\Model\Tag;
use Friendica\Model\Post; use Friendica\Model\Post;
use Friendica\Model\Tag;
use Friendica\Model\User; use Friendica\Model\User;
use Friendica\Network\HTTPException; use Friendica\Network\HTTPException;
use Friendica\Object\EMail\ItemCCEMail; use Friendica\Object\EMail\ItemCCEMail;
@ -54,6 +55,7 @@ use Friendica\Util\ParseUrl;
use Friendica\Util\Profiler; use Friendica\Util\Profiler;
use Friendica\Util\Proxy; use Friendica\Util\Proxy;
use Friendica\Util\XML; use Friendica\Util\XML;
use GuzzleHttp\Psr7\Uri;
/** /**
* A content helper class for displaying items * A content helper class for displaying items
@ -367,7 +369,7 @@ class Item
{ {
$this->profiler->startRecording('rendering'); $this->profiler->startRecording('rendering');
$sub_link = $contact_url = $pm_url = $status_link = ''; $sub_link = $contact_url = $pm_url = $status_link = '';
$photos_link = $posts_link = $block_link = $ignore_link = ''; $photos_link = $posts_link = $block_link = $ignore_link = $collapse_link = $ignoreserver_link = '';
if ($this->userSession->getLocalUserId() && $this->userSession->getLocalUserId() == $item['uid'] && $item['gravity'] == ItemModel::GRAVITY_PARENT && !$item['self'] && !$item['mention']) { if ($this->userSession->getLocalUserId() && $this->userSession->getLocalUserId() == $item['uid'] && $item['gravity'] == ItemModel::GRAVITY_PARENT && !$item['self'] && !$item['mention']) {
$sub_link = 'javascript:doFollowThread(' . $item['id'] . '); return false;'; $sub_link = 'javascript:doFollowThread(' . $item['id'] . '); return false;';
@ -407,6 +409,11 @@ class Item
$collapse_link = $item['self'] ? '' : $contact_url . '/collapse?t=' . $formSecurityToken; $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']) { if ($cid && !$item['self']) {
$contact_url = 'contact/' . $cid; $contact_url = 'contact/' . $cid;
$posts_link = $contact_url . '/posts'; $posts_link = $contact_url . '/posts';
@ -427,7 +434,8 @@ class Item
$this->l10n->t('Send PM') => $pm_url, $this->l10n->t('Send PM') => $pm_url,
$this->l10n->t('Block') => $block_link, $this->l10n->t('Block') => $block_link,
$this->l10n->t('Ignore') => $ignore_link, $this->l10n->t('Ignore') => $ignore_link,
$this->l10n->t('Collapse') => $collapse_link $this->l10n->t('Collapse') => $collapse_link,
$this->l10n->t("Ignore %s server", $authorBaseUri->getHost()) => $ignoreserver_link,
]; ];
if (!empty($item['language'])) { if (!empty($item['language'])) {

View file

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

View file

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

View file

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

View file

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

View file

@ -788,10 +788,10 @@ class Contact
/** /**
* Updates the self-contact for the provided user id * Updates the self-contact for the provided user id
* *
* @param int $uid * @param int $uid
* @param bool $update_avatar Force the avatar update * @param bool $update_avatar Force the avatar update
* @return bool "true" if updated * @return bool "true" if updated
* @throws HTTPException\InternalServerErrorException * @throws \Exception
*/ */
public static function updateSelfFromUserID(int $uid, bool $update_avatar = false): bool 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', 'wall', 'private', 'starred', 'origin', 'parent-origin', 'title', 'body', 'language',
'content-warning', 'location', 'coord', 'app', 'rendered-hash', 'rendered-html', 'object', 'content-warning', 'location', 'coord', 'app', 'rendered-hash', 'rendered-html', 'object',
'quote-uri', 'quote-uri-id', 'allow_cid', 'allow_gid', 'deny_cid', 'deny_gid', 'mention', 'global', 'quote-uri', 'quote-uri-id', 'allow_cid', 'allow_gid', 'deny_cid', 'deny_gid', 'mention', 'global',
'author-id', 'author-link', 'author-alias', 'author-name', 'author-avatar', 'author-network', 'author-updated', 'author-gsid', 'author-addr', 'author-uri-id', 'author-id', 'author-link', 'author-alias', 'author-name', 'author-avatar', 'author-network', 'author-updated', 'author-gsid', 'author-baseurl', 'author-addr', 'author-uri-id',
'owner-id', 'owner-link', 'owner-alias', 'owner-name', 'owner-avatar', 'owner-network', 'owner-contact-type', 'owner-updated', 'owner-id', 'owner-link', 'owner-alias', 'owner-name', 'owner-avatar', 'owner-network', 'owner-contact-type', 'owner-updated', 'owner-gsid',
'causer-id', 'causer-link', 'causer-alias', 'causer-name', 'causer-avatar', 'causer-contact-type', 'causer-network', 'causer-id', 'causer-link', 'causer-alias', 'causer-name', 'causer-avatar', 'causer-contact-type', 'causer-network', 'causer-gsid',
'contact-id', 'contact-uid', 'contact-link', 'contact-name', 'contact-avatar', 'contact-id', 'contact-uid', 'contact-link', 'contact-name', 'contact-avatar',
'writable', 'self', 'cid', 'alias', 'writable', 'self', 'cid', 'alias',
'event-created', 'event-edited', 'event-start', 'event-finish', 'event-created', 'event-edited', 'event-start', 'event-finish',

View file

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

View file

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

View file

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

View file

@ -37,6 +37,7 @@ use Friendica\Database\DBA;
use Friendica\DI; use Friendica\DI;
use Friendica\Module; use Friendica\Module;
use Friendica\Network\HTTPClient\Client\HttpClientAccept; use Friendica\Network\HTTPClient\Client\HttpClientAccept;
use Friendica\Network\HTTPException\InternalServerErrorException;
use Friendica\Security\TwoFactor\Model\AppSpecificPassword; use Friendica\Security\TwoFactor\Model\AppSpecificPassword;
use Friendica\Network\HTTPException; use Friendica\Network\HTTPException;
use Friendica\Object\Image; use Friendica\Object\Image;
@ -1328,33 +1329,18 @@ class User
/** /**
* Update a user entry and distribute the changes if needed * Update a user entry and distribute the changes if needed
* *
* @param array $fields * @param array $fields
* @param integer $uid * @param integer $uid
* @return boolean * @return boolean
* @throws Exception
*/ */
public static function update(array $fields, int $uid): bool 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])) { if (!DBA::update('user', $fields, ['uid' => $uid])) {
return false; return false;
} }
$update = Contact::updateSelfFromUserID($uid); if (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) {
Profile::publishUpdate($uid); Profile::publishUpdate($uid);
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -573,7 +573,7 @@ class Account extends BaseSettings
'$delete_openid' => ['delete_openid', DI::l10n()->t('Delete OpenID URL'), false, ''], '$delete_openid' => ['delete_openid', DI::l10n()->t('Delete OpenID URL'), false, ''],
'$h_basic' => DI::l10n()->t('Basic Settings'), '$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'], '$email' => ['email', DI::l10n()->t('Email Address:'), $email, '', '', 'autocomplete="off"', 'email'],
'$timezone' => ['timezone_select', DI::l10n()->t('Your Timezone:'), Temporal::getTimezoneSelect($timezone), ''], '$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], '$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; namespace Friendica\Module\Settings\Profile;
use Friendica\App;
use Friendica\Core\ACL; use Friendica\Core\ACL;
use Friendica\Core\Hook; use Friendica\Core\Hook;
use Friendica\Core\L10n;
use Friendica\Core\Protocol; use Friendica\Core\Protocol;
use Friendica\Core\Renderer; use Friendica\Core\Renderer;
use Friendica\Core\Session\Capability\IHandleUserSessions;
use Friendica\Core\Theme; use Friendica\Core\Theme;
use Friendica\Database\DBA; use Friendica\Database\DBA;
use Friendica\DI;
use Friendica\Model\Contact; use Friendica\Model\Contact;
use Friendica\Model\Profile; use Friendica\Model\Profile;
use Friendica\Profile\ProfileField\Collection\ProfileFields; use Friendica\Module\Response;
use Friendica\Profile\ProfileField\Entity\ProfileField; use Friendica\Navigation\SystemMessages;
use Friendica\Profile\ProfileField;
use Friendica\Model\User; use Friendica\Model\User;
use Friendica\Module\BaseSettings; use Friendica\Module\BaseSettings;
use Friendica\Module\Security\Login; use Friendica\Module\Security\Login;
use Friendica\Network\HTTPException; use Friendica\Network\HTTPException;
use Friendica\Security\PermissionSet;
use Friendica\Util\ACLFormatter;
use Friendica\Util\DateTimeFormat; use Friendica\Util\DateTimeFormat;
use Friendica\Util\Profiler;
use Friendica\Util\Temporal; use Friendica\Util\Temporal;
use Friendica\Core\Worker; use Friendica\Core\Worker;
use Psr\Log\LoggerInterface;
class Index extends BaseSettings 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 = []) protected function post(array $request = [])
{ {
if (!DI::userSession()->getLocalUserId()) { if (!$this->session->getLocalUserId()) {
return; return;
} }
$profile = Profile::getByUID(DI::userSession()->getLocalUserId()); $profile = Profile::getByUID($this->session->getLocalUserId());
if (!DBA::isResult($profile)) { if (!$profile) {
return; return;
} }
self::checkFormSecurityTokenRedirectOnError('/settings/profile', 'settings_profile'); 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])) { if ($dob && !in_array($dob, ['0000-00-00', DBA::NULL_DATE])) {
$y = substr($dob, 0, 4); $y = substr($dob, 0, 4);
@ -79,39 +111,40 @@ class Index extends BaseSettings
} }
} }
$name = trim($_POST['name'] ?? ''); $username = trim($request['username'] ?? '');
if (!strlen($name)) { if (!$username) {
DI::sysmsg()->addNotice(DI::l10n()->t('Profile Name is required.')); $this->systemMessages->addNotice($this->t('Display Name is required.'));
return; return;
} }
$about = trim($_POST['about']); $about = trim($request['about']);
$address = trim($_POST['address']); $address = trim($request['address']);
$locality = trim($_POST['locality']); $locality = trim($request['locality']);
$region = trim($_POST['region']); $region = trim($request['region']);
$postal_code = trim($_POST['postal_code']); $postal_code = trim($request['postal_code']);
$country_name = trim($_POST['country_name']); $country_name = trim($request['country_name']);
$pub_keywords = self::cleanKeywords(trim($_POST['pub_keywords'])); $pub_keywords = self::cleanKeywords(trim($request['pub_keywords']));
$prv_keywords = self::cleanKeywords(trim($_POST['prv_keywords'])); $prv_keywords = self::cleanKeywords(trim($request['prv_keywords']));
$xmpp = trim($_POST['xmpp']); $xmpp = trim($request['xmpp']);
$matrix = trim($_POST['matrix']); $matrix = trim($request['matrix']);
$homepage = trim($_POST['homepage']); $homepage = trim($request['homepage']);
if ((strpos($homepage, 'http') !== 0) && (strlen($homepage))) { if ((strpos($homepage, 'http') !== 0) && (strlen($homepage))) {
// neither http nor https in URL, add them // neither http nor https in URL, add them
$homepage = 'http://' . $homepage; $homepage = 'http://' . $homepage;
} }
$profileFieldsNew = self::getProfileFieldsFromInput( $profileFieldsNew = $this->getProfileFieldsFromInput(
DI::userSession()->getLocalUserId(), $this->session->getLocalUserId(),
$_REQUEST['profile_field'], $request['profile_field'],
$_REQUEST['profile_field_order'] $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( $result = Profile::update(
[ [
'name' => $name,
'about' => $about, 'about' => $about,
'dob' => $dob, 'dob' => $dob,
'address' => $address, 'address' => $address,
@ -125,23 +158,23 @@ class Index extends BaseSettings
'pub_keywords' => $pub_keywords, 'pub_keywords' => $pub_keywords,
'prv_keywords' => $prv_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) { if (!$result) {
DI::sysmsg()->addNotice(DI::l10n()->t('Profile couldn\'t be updated.')); $this->systemMessages->addNotice($this->t("Profile couldn't be updated."));
return; return;
} }
DI::baseUrl()->redirect('settings/profile'); $this->baseUrl->redirect('settings/profile');
} }
protected function content(array $request = []): string protected function content(array $request = []): string
{ {
if (!DI::userSession()->getLocalUserId()) { if (!$this->session->getLocalUserId()) {
DI::sysmsg()->addNotice(DI::l10n()->t('You must be logged in to use this module')); $this->systemMessages->addNotice($this->t('You must be logged in to use this module'));
return Login::form(); return Login::form();
} }
@ -149,147 +182,145 @@ class Index extends BaseSettings
$o = ''; $o = '';
$profile = User::getOwnerDataById(DI::userSession()->getLocalUserId()); $owner = User::getOwnerDataById($this->session->getLocalUserId());
if (!DBA::isResult($profile)) { if (!$owner) {
throw new HTTPException\NotFoundException(); throw new HTTPException\NotFoundException();
} }
$a = DI::app(); $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'));
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'));
$custom_fields = []; $custom_fields = [];
$profileFields = DI::profileField()->selectByUserId(DI::userSession()->getLocalUserId()); $profileFields = $this->profileFieldRepo->selectByUserId($this->session->getLocalUserId());
foreach ($profileFields as $profileField) { foreach ($profileFields as $profileField) {
/** @var ProfileField $profileField */
$defaultPermissions = $profileField->permissionSet->withAllowedContacts( $defaultPermissions = $profileField->permissionSet->withAllowedContacts(
Contact::pruneUnavailable($profileField->permissionSet->allow_cid) Contact::pruneUnavailable($profileField->permissionSet->allow_cid)
); );
$custom_fields[] = [ $custom_fields[] = [
'id' => $profileField->id, 'id' => $profileField->id,
'legend' => $profileField->label, 'legend' => $profileField->label,
'fields' => [ 'fields' => [
'label' => ['profile_field[' . $profileField->id . '][label]', DI::l10n()->t('Label:'), $profileField->label], 'label' => ['profile_field[' . $profileField->id . '][label]', $this->t('Label:'), $profileField->label],
'value' => ['profile_field[' . $profileField->id . '][value]', DI::l10n()->t('Value:'), $profileField->value], 'value' => ['profile_field[' . $profileField->id . '][value]', $this->t('Value:'), $profileField->value],
'acl' => ACL::getFullSelectorHTML( 'acl' => ACL::getFullSelectorHTML(
DI::page(), $this->page,
$a->getLoggedInUserId(), $this->session->getLocalUserId(),
false, false,
$defaultPermissions->toArray(), $defaultPermissions->toArray(),
['network' => Protocol::DFRN], ['network' => Protocol::DFRN],
'profile_field[' . $profileField->id . ']' '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[] = [ $custom_fields[] = [
'id' => 'new', 'id' => 'new',
'legend' => DI::l10n()->t('Add a new profile field'), 'legend' => $this->t('Add a new profile field'),
'fields' => [ 'fields' => [
'label' => ['profile_field[new][label]', DI::l10n()->t('Label:')], 'label' => ['profile_field[new][label]', $this->t('Label:')],
'value' => ['profile_field[new][value]', DI::l10n()->t('Value:')], 'value' => ['profile_field[new][value]', $this->t('Value:')],
'acl' => ACL::getFullSelectorHTML( 'acl' => ACL::getFullSelectorHTML(
DI::page(), $this->page,
$a->getLoggedInUserId(), $this->session->getLocalUserId(),
false, false,
['allow_cid' => []], ['allow_cid' => []],
['network' => Protocol::DFRN], ['network' => Protocol::DFRN],
'profile_field[new]' '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']) { if ($owner['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.'); $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 { } 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'); $tpl = Renderer::getMarkupTemplate('settings/profile/index.tpl');
$o .= Renderer::replaceMacros($tpl, [ $o .= Renderer::replaceMacros($tpl, [
'$personal_account' => $personal_account, '$l10n' => [
'profile_action' => $this->t('Profile Actions'),
'$form_security_token' => self::getFormSecurityToken('settings_profile'), 'banner' => $this->t('Edit Profile Details'),
'$form_security_token_photo' => self::getFormSecurityToken('settings_profile_photo'), 'submit' => $this->t('Submit'),
'profpic' => $this->t('Change Profile Photo'),
'$profile_action' => DI::l10n()->t('Profile Actions'), 'viewprof' => $this->t('View Profile'),
'$banner' => DI::l10n()->t('Edit Profile Details'), 'personal_section' => $this->t('Personal'),
'$submit' => DI::l10n()->t('Submit'), 'picture_section' => $this->t('Profile picture'),
'$profpic' => DI::l10n()->t('Change Profile Photo'), 'location_section' => $this->t('Location'),
'$profpiclink' => '/profile/' . $profile['nickname'] . '/photos', 'miscellaneous_section' => $this->t('Miscellaneous'),
'$viewprof' => DI::l10n()->t('View Profile'), 'custom_fields_section' => $this->t('Custom Profile Fields'),
'profile_photo' => $this->t('Upload Profile Photo'),
'$lbl_personal_section' => DI::l10n()->t('Personal'), 'custom_fields_description' => $this->t('<p>Custom fields appear on <a href="%s">your profile page</a>.</p>
'$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>You can use BBCodes in the field values.</p>
<p>Reorder by dragging the field title.</p> <p>Reorder by dragging the field title.</p>
<p>Empty the label field to remove a custom field.</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>", <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' 'profile/' . $owner['nickname'] . '/profile'
), ),
],
'$personal_account' => $personal_account,
'$form_security_token' => self::getFormSecurityToken('settings_profile'),
'$form_security_token_photo' => self::getFormSecurityToken('settings_profile_photo'),
'$profpiclink' => '/profile/' . $owner['nickname'] . '/photos',
'$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, '$custom_fields' => $custom_fields,
]); ]);
$arr = ['profile' => $profile, 'entry' => $o]; $arr = ['profile' => $owner, 'entry' => $o];
Hook::callAll('profile_edit', $arr); Hook::callAll('profile_edit', $arr);
return $o; 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 // Returns an associative array of id => order values
$profileFieldOrder = array_flip($profileFieldOrder); $profileFieldOrder = array_flip($profileFieldOrder);
// Creation of the new field // Creation of the new field
if (!empty($profileFieldInputs['new']['label'])) { if (!empty($profileFieldInputs['new']['label'])) {
$permissionSet = DI::permissionSet()->selectOrCreate(DI::permissionSetFactory()->createFromString( $permissionSet = $this->permissionSetRepo->selectOrCreate($this->permissionSetFactory->createFromString(
$uid, $uid,
DI::aclFormatter()->toString($profileFieldInputs['new']['contact_allow'] ?? ''), $this->aclFormatter->toString($profileFieldInputs['new']['contact_allow'] ?? ''),
DI::aclFormatter()->toString($profileFieldInputs['new']['circle_allow'] ?? ''), $this->aclFormatter->toString($profileFieldInputs['new']['circle_allow'] ?? ''),
DI::aclFormatter()->toString($profileFieldInputs['new']['contact_deny'] ?? ''), $this->aclFormatter->toString($profileFieldInputs['new']['contact_deny'] ?? ''),
DI::aclFormatter()->toString($profileFieldInputs['new']['circle_deny'] ?? '') $this->aclFormatter->toString($profileFieldInputs['new']['circle_deny'] ?? '')
)); ));
$profileFields->append(DI::profileFieldFactory()->createFromValues( $profileFields->append($this->profileFieldFactory->createFromValues(
$uid, $uid,
$profileFieldOrder['new'], $profileFieldOrder['new'],
$profileFieldInputs['new']['label'], $profileFieldInputs['new']['label'],
@ -302,15 +333,15 @@ class Index extends BaseSettings
unset($profileFieldOrder['new']); unset($profileFieldOrder['new']);
foreach ($profileFieldInputs as $id => $profileFieldInput) { foreach ($profileFieldInputs as $id => $profileFieldInput) {
$permissionSet = DI::permissionSet()->selectOrCreate(DI::permissionSetFactory()->createFromString( $permissionSet = $this->permissionSetRepo->selectOrCreate($this->permissionSetFactory->createFromString(
$uid, $uid,
DI::aclFormatter()->toString($profileFieldInput['contact_allow'] ?? ''), $this->aclFormatter->toString($profileFieldInput['contact_allow'] ?? ''),
DI::aclFormatter()->toString($profileFieldInput['circle_allow'] ?? ''), $this->aclFormatter->toString($profileFieldInput['circle_allow'] ?? ''),
DI::aclFormatter()->toString($profileFieldInput['contact_deny'] ?? ''), $this->aclFormatter->toString($profileFieldInput['contact_deny'] ?? ''),
DI::aclFormatter()->toString($profileFieldInput['circle_deny'] ?? '') $this->aclFormatter->toString($profileFieldInput['circle_deny'] ?? '')
)); ));
$profileFields->append(DI::profileFieldFactory()->createFromValues( $profileFields->append($this->profileFieldFactory->createFromValues(
$uid, $uid,
$profileFieldOrder[$id], $profileFieldOrder[$id],
$profileFieldInput['label'], $profileFieldInput['label'],
@ -322,22 +353,20 @@ class Index extends BaseSettings
return $profileFields; return $profileFields;
} }
private static function cleanKeywords($keywords) private static function cleanKeywords($keywords): string
{ {
$keywords = str_replace(',', ' ', $keywords); $keywords = str_replace(',', ' ', $keywords);
$keywords = explode(' ', $keywords); $keywords = explode(' ', $keywords);
$cleaned = []; $cleaned = [];
foreach ($keywords as $keyword) { foreach ($keywords as $keyword) {
$keyword = trim(strtolower($keyword)); $keyword = trim($keyword);
$keyword = trim($keyword, '#'); $keyword = trim($keyword, '#');
if ($keyword != '') { if ($keyword != '') {
$cleaned[] = $keyword; $cleaned[] = $keyword;
} }
} }
$keywords = implode(', ', $cleaned); return implode(', ', $cleaned);
return $keywords;
} }
} }

View file

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

View file

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

View file

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

View file

@ -31,16 +31,15 @@ use Friendica\Core\Renderer;
use Friendica\DI; use Friendica\DI;
use Friendica\Model\Contact; use Friendica\Model\Contact;
use Friendica\Model\Item; use Friendica\Model\Item;
use Friendica\Model\Photo;
use Friendica\Model\Post as PostModel; use Friendica\Model\Post as PostModel;
use Friendica\Model\Tag; use Friendica\Model\Tag;
use Friendica\Model\User; use Friendica\Model\User;
use Friendica\Protocol\Activity; use Friendica\Protocol\Activity;
use Friendica\Util\Crypto; use Friendica\Util\Crypto;
use Friendica\Util\DateTimeFormat; use Friendica\Util\DateTimeFormat;
use Friendica\Util\Proxy;
use Friendica\Util\Strings; use Friendica\Util\Strings;
use Friendica\Util\Temporal; use Friendica\Util\Temporal;
use GuzzleHttp\Psr7\Uri;
use InvalidArgumentException; use InvalidArgumentException;
/** /**
@ -248,11 +247,12 @@ class Post
$pinned = DI::l10n()->t('Pinned item'); $pinned = DI::l10n()->t('Pinned item');
} }
$drop = false; $drop = false;
$block = false; $block = false;
$ignore = false; $ignore = false;
$collapse = false; $collapse = false;
$report = false; $report = false;
$ignoreServer = false;
if (DI::userSession()->getLocalUserId()) { if (DI::userSession()->getLocalUserId()) {
$drop = [ $drop = [
'dropping' => $dropping, 'dropping' => $dropping,
@ -282,6 +282,12 @@ class Post
'label' => DI::l10n()->t('Report post'), 'label' => DI::l10n()->t('Report post'),
'href' => 'moderation/report/create?' . http_build_query(['cid' => $item['author-id'], 'uri-ids' => [$item['uri-id']]]), 'href' => 'moderation/report/create?' . http_build_query(['cid' => $item['author-id'], 'uri-ids' => [$item['uri-id']]]),
]; ];
$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; $filer = DI::userSession()->getLocalUserId() ? DI::l10n()->t('Save to folder') : false;
@ -557,6 +563,7 @@ class Post
'ignore_author' => $ignore, 'ignore_author' => $ignore,
'collapse' => $collapse, 'collapse' => $collapse,
'report' => $report, 'report' => $report,
'ignore_server' => $ignoreServer,
'vote' => $buttons, 'vote' => $buttons,
'like_html' => $responses['like']['output'], 'like_html' => $responses['like']['output'],
'dislike_html' => $responses['dislike']['output'], 'dislike_html' => $responses['dislike']['output'],
@ -571,6 +578,7 @@ class Post
'wait' => DI::l10n()->t('Please wait'), 'wait' => DI::l10n()->t('Please wait'),
'thread_level' => $thread_level, 'thread_level' => $thread_level,
'edited' => $edited, 'edited' => $edited,
'author_gsid' => $item['author-gsid'],
'network' => $item['network'], 'network' => $item['network'],
'network_name' => ContactSelector::networkToName($item['author-network'], $item['author-link'], $item['network'], $item['author-gsid']), 'network_name' => ContactSelector::networkToName($item['author-network'], $item['author-link'], $item['network'], $item['author-gsid']),
'network_icon' => ContactSelector::networkToIcon($item['network'], $item['author-link'], $item['author-gsid']), 'network_icon' => ContactSelector::networkToIcon($item['network'], $item['author-link'], $item['author-gsid']),

View file

@ -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 * @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 // This file is required several times during the test in DbaDefinition which justifies this condition
if (!defined('DB_UPDATE_VERSION')) { if (!defined('DB_UPDATE_VERSION')) {
define('DB_UPDATE_VERSION', 1524); define('DB_UPDATE_VERSION', 1529);
} }
return [ return [
@ -159,6 +159,18 @@ return [
"email" => ["email(64)"], "email" => ["email(64)"],
] ]
], ],
"user-gserver" => [
"comment" => "User settings about remote servers",
"fields" => [
"uid" => ["type" => "mediumint unsigned", "not null" => "1", "default" => "0", "foreign" => ["user" => "uid"], "comment" => "Owner User id"],
"gsid" => ["type" => "int unsigned", "not null" => "1", "default" => "0", "foreign" => ["gserver" => "id"], "comment" => "Gserver id"],
"ignored" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "server accounts are ignored for the user"],
],
"indexes" => [
"PRIMARY" => ["uid", "gsid"],
"gsid" => ["gsid"]
],
],
"item-uri" => [ "item-uri" => [
"comment" => "URI and GUID for items", "comment" => "URI and GUID for items",
"fields" => [ "fields" => [
@ -218,8 +230,8 @@ return [
"archive" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => ""], "archive" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => ""],
"unsearchable" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "Contact prefers to not be searchable"], "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"], "sensitive" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "Contact posts sensitive content"],
"baseurl" => ["type" => "varbinary(383)", "default" => "", "comment" => "baseurl of the contact"], "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"], "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" => ""], "bd" => ["type" => "date", "not null" => "1", "default" => DBA::NULL_DATE, "comment" => ""],
// User depending fields // User depending fields
"reason" => ["type" => "text", "comment" => ""], "reason" => ["type" => "text", "comment" => ""],
@ -1583,7 +1595,7 @@ return [
"profile-name" => ["type" => "varchar(255)", "comment" => "Deprecated"], "profile-name" => ["type" => "varchar(255)", "comment" => "Deprecated"],
"is-default" => ["type" => "boolean", "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"], "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"], "pdesc" => ["type" => "varchar(255)", "comment" => "Deprecated"],
"dob" => ["type" => "varchar(32)", "not null" => "1", "default" => "0000-00-00", "comment" => "Day of birth"], "dob" => ["type" => "varchar(32)", "not null" => "1", "default" => "0000-00-00", "comment" => "Day of birth"],
"address" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""], "address" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""],

View file

@ -185,6 +185,7 @@
"author-hidden" => ["author", "hidden"], "author-hidden" => ["author", "hidden"],
"author-updated" => ["author", "updated"], "author-updated" => ["author", "updated"],
"author-gsid" => ["author", "gsid"], "author-gsid" => ["author", "gsid"],
"author-baseurl" => ["author", "baseurl"],
"owner-id" => ["post-user", "owner-id"], "owner-id" => ["post-user", "owner-id"],
"owner-uri-id" => ["owner", "uri-id"], "owner-uri-id" => ["owner", "uri-id"],
"owner-link" => ["owner", "url"], "owner-link" => ["owner", "url"],
@ -197,6 +198,7 @@
"owner-blocked" => ["owner", "blocked"], "owner-blocked" => ["owner", "blocked"],
"owner-hidden" => ["owner", "hidden"], "owner-hidden" => ["owner", "hidden"],
"owner-updated" => ["owner", "updated"], "owner-updated" => ["owner", "updated"],
"owner-gsid" => ["owner", "gsid"],
"owner-contact-type" => ["owner", "contact-type"], "owner-contact-type" => ["owner", "contact-type"],
"causer-id" => ["post-user", "causer-id"], "causer-id" => ["post-user", "causer-id"],
"causer-uri-id" => ["causer", "uri-id"], "causer-uri-id" => ["causer", "uri-id"],
@ -209,6 +211,7 @@
"causer-network" => ["causer", "network"], "causer-network" => ["causer", "network"],
"causer-blocked" => ["causer", "blocked"], "causer-blocked" => ["causer", "blocked"],
"causer-hidden" => ["causer", "hidden"], "causer-hidden" => ["causer", "hidden"],
"causer-gsid" => ["causer", "gsid"],
"causer-contact-type" => ["causer", "contact-type"], "causer-contact-type" => ["causer", "contact-type"],
"postopts" => ["post-delivery-data", "postopts"], "postopts" => ["post-delivery-data", "postopts"],
"inform" => ["post-delivery-data", "inform"], "inform" => ["post-delivery-data", "inform"],
@ -340,6 +343,7 @@
"contact-pending" => ["contact", "pending"], "contact-pending" => ["contact", "pending"],
"contact-rel" => ["contact", "rel"], "contact-rel" => ["contact", "rel"],
"contact-uid" => ["contact", "uid"], "contact-uid" => ["contact", "uid"],
"contact-gsid" => ["contact", "gsid"],
"contact-contact-type" => ["contact", "contact-type"], "contact-contact-type" => ["contact", "contact-type"],
"writable" => "IF (`post-user`.`network` IN ('apub', 'dfrn', 'dspr', 'stat'), true, `contact`.`writable`)", "writable" => "IF (`post-user`.`network` IN ('apub', 'dfrn', 'dspr', 'stat'), true, `contact`.`writable`)",
"self" => ["contact", "self"], "self" => ["contact", "self"],
@ -375,6 +379,7 @@
"owner-blocked" => ["owner", "blocked"], "owner-blocked" => ["owner", "blocked"],
"owner-hidden" => ["owner", "hidden"], "owner-hidden" => ["owner", "hidden"],
"owner-updated" => ["owner", "updated"], "owner-updated" => ["owner", "updated"],
"owner-gsid" => ["owner", "gsid"],
"owner-contact-type" => ["owner", "contact-type"], "owner-contact-type" => ["owner", "contact-type"],
"causer-id" => ["post-thread-user", "causer-id"], "causer-id" => ["post-thread-user", "causer-id"],
"causer-uri-id" => ["causer", "uri-id"], "causer-uri-id" => ["causer", "uri-id"],
@ -387,6 +392,7 @@
"causer-network" => ["causer", "network"], "causer-network" => ["causer", "network"],
"causer-blocked" => ["causer", "blocked"], "causer-blocked" => ["causer", "blocked"],
"causer-hidden" => ["causer", "hidden"], "causer-hidden" => ["causer", "hidden"],
"causer-gsid" => ["causer", "gsid"],
"causer-contact-type" => ["causer", "contact-type"], "causer-contact-type" => ["causer", "contact-type"],
"postopts" => ["post-delivery-data", "postopts"], "postopts" => ["post-delivery-data", "postopts"],
"inform" => ["post-delivery-data", "inform"], "inform" => ["post-delivery-data", "inform"],
@ -540,6 +546,7 @@
"owner-hidden" => ["owner", "hidden"], "owner-hidden" => ["owner", "hidden"],
"owner-updated" => ["owner", "updated"], "owner-updated" => ["owner", "updated"],
"owner-contact-type" => ["owner", "contact-type"], "owner-contact-type" => ["owner", "contact-type"],
"owner-gsid" => ["owner", "gsid"],
"causer-id" => ["post", "causer-id"], "causer-id" => ["post", "causer-id"],
"causer-uri-id" => ["causer", "uri-id"], "causer-uri-id" => ["causer", "uri-id"],
"causer-link" => ["causer", "url"], "causer-link" => ["causer", "url"],
@ -552,6 +559,7 @@
"causer-blocked" => ["causer", "blocked"], "causer-blocked" => ["causer", "blocked"],
"causer-hidden" => ["causer", "hidden"], "causer-hidden" => ["causer", "hidden"],
"causer-contact-type" => ["causer", "contact-type"], "causer-contact-type" => ["causer", "contact-type"],
"causer-gsid" => ["causer", "gsid"],
"question-id" => ["post-question", "id"], "question-id" => ["post-question", "id"],
"question-multiple" => ["post-question", "multiple"], "question-multiple" => ["post-question", "multiple"],
"question-voters" => ["post-question", "voters"], "question-voters" => ["post-question", "voters"],
@ -680,6 +688,7 @@
"owner-blocked" => ["owner", "blocked"], "owner-blocked" => ["owner", "blocked"],
"owner-hidden" => ["owner", "hidden"], "owner-hidden" => ["owner", "hidden"],
"owner-updated" => ["owner", "updated"], "owner-updated" => ["owner", "updated"],
"owner-gsid" => ["owner", "gsid"],
"owner-contact-type" => ["owner", "contact-type"], "owner-contact-type" => ["owner", "contact-type"],
"causer-id" => ["post-thread", "causer-id"], "causer-id" => ["post-thread", "causer-id"],
"causer-uri-id" => ["causer", "uri-id"], "causer-uri-id" => ["causer", "uri-id"],
@ -692,6 +701,7 @@
"causer-network" => ["causer", "network"], "causer-network" => ["causer", "network"],
"causer-blocked" => ["causer", "blocked"], "causer-blocked" => ["causer", "blocked"],
"causer-hidden" => ["causer", "hidden"], "causer-hidden" => ["causer", "hidden"],
"causer-gsid" => ["causer", "gsid"],
"causer-contact-type" => ["causer", "contact-type"], "causer-contact-type" => ["causer", "contact-type"],
"question-id" => ["post-question", "id"], "question-id" => ["post-question", "id"],
"question-multiple" => ["post-question", "multiple"], "question-multiple" => ["post-question", "multiple"],
@ -804,7 +814,7 @@
"contact-type" => ["ownercontact", "contact-type"], "contact-type" => ["ownercontact", "contact-type"],
], ],
"query" => "FROM `post-user` "query" => "FROM `post-user`
INNER JOIN `post-thread-user` ON `post-thread-user`.`uri-id` = `post-user`.`parent-uri-id` AND `post-thread-user`.`uid` = `post-user`.`uid` INNER JOIN `post-thread-user` ON `post-thread-user`.`uri-id` = `post-user`.`parent-uri-id` AND `post-thread-user`.`uid` = `post-user`.`uid`
STRAIGHT_JOIN `contact` ON `contact`.`id` = `post-thread-user`.`contact-id` STRAIGHT_JOIN `contact` ON `contact`.`id` = `post-thread-user`.`contact-id`
STRAIGHT_JOIN `contact` AS `authorcontact` ON `authorcontact`.`id` = `post-thread-user`.`author-id` STRAIGHT_JOIN `contact` AS `authorcontact` ON `authorcontact`.`id` = `post-thread-user`.`author-id`
STRAIGHT_JOIN `contact` AS `ownercontact` ON `ownercontact`.`id` = `post-thread-user`.`owner-id` STRAIGHT_JOIN `contact` AS `ownercontact` ON `ownercontact`.`id` = `post-thread-user`.`owner-id`
@ -843,7 +853,8 @@
AND (`post-thread-user`.`hidden` IS NULL OR NOT `post-thread-user`.`hidden`) AND (`post-thread-user`.`hidden` IS NULL OR NOT `post-thread-user`.`hidden`)
AND NOT `authorcontact`.`blocked` AND NOT `ownercontact`.`blocked` AND NOT `authorcontact`.`blocked` AND NOT `ownercontact`.`blocked`
AND (`author`.`blocked` IS NULL OR NOT `author`.`blocked`) AND (`author`.`blocked` IS NULL OR NOT `author`.`blocked`)
AND (`owner`.`blocked` IS NULL OR NOT `owner`.`blocked`)" AND (`owner`.`blocked` IS NULL OR NOT `owner`.`blocked`)
AND NOT EXISTS(SELECT `gsid` FROM `user-gserver` WHERE `uid` = `post-thread-user`.`uid` AND `gsid` IN (`authorcontact`.`gsid`, `ownercontact`.`gsid`) AND `ignored`)"
], ],
"owner-view" => [ "owner-view" => [
"fields" => [ "fields" => [

View file

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

View file

@ -1349,3 +1349,31 @@ function update_1524(): int
return Update::SUCCESS; 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 "" msgstr ""
"Project-Id-Version: 2023.09-dev\n" "Project-Id-Version: 2023.09-dev\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-08-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" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -38,13 +38,13 @@ msgstr ""
msgid "Empty post discarded." msgid "Empty post discarded."
msgstr "" 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/Admin/Themes/Index.php:59 src/Module/Debug/ItemBody.php:42
#: src/Module/Debug/ItemBody.php:57 src/Module/Item/Feed.php:80 #: src/Module/Debug/ItemBody.php:57 src/Module/Item/Feed.php:80
msgid "Item not found." msgid "Item not found."
msgstr "" 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 #: 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/Attach.php:55 src/Module/BaseApi.php:99
#: src/Module/BaseNotifications.php:98 src/Module/BaseSettings.php:52 #: src/Module/BaseNotifications.php:98 src/Module/BaseSettings.php:52
@ -281,7 +281,7 @@ msgstr ""
msgid "Your message:" msgid "Your message:"
msgstr "" msgstr ""
#: mod/message.php:199 mod/message.php:354 src/Content/Conversation.php:361 #: mod/message.php:199 mod/message.php:354 src/Content/Conversation.php:366
#: src/Module/Post/Edit.php:131 #: src/Module/Post/Edit.php:131
msgid "Upload photo" msgid "Upload photo"
msgstr "" msgstr ""
@ -292,9 +292,9 @@ msgid "Insert web link"
msgstr "" msgstr ""
#: mod/message.php:201 mod/message.php:357 mod/photos.php:1301 #: mod/message.php:201 mod/message.php:357 mod/photos.php:1301
#: src/Content/Conversation.php:392 src/Content/Conversation.php:1508 #: src/Content/Conversation.php:397 src/Content/Conversation.php:1528
#: src/Module/Item/Compose.php:206 src/Module/Post/Edit.php:145 #: src/Module/Item/Compose.php:206 src/Module/Post/Edit.php:145
#: src/Module/Profile/UnkMail.php:154 src/Object/Post.php:571 #: src/Module/Profile/UnkMail.php:154 src/Object/Post.php:578
msgid "Please wait" msgid "Please wait"
msgstr "" msgstr ""
@ -302,7 +302,7 @@ msgstr ""
#: mod/photos.php:824 mod/photos.php:1101 mod/photos.php:1142 #: mod/photos.php:824 mod/photos.php:1101 mod/photos.php:1142
#: mod/photos.php:1198 mod/photos.php:1278 #: mod/photos.php:1198 mod/photos.php:1278
#: src/Module/Calendar/Event/Form.php:250 src/Module/Contact/Advanced.php:132 #: src/Module/Calendar/Event/Form.php:250 src/Module/Contact/Advanced.php:132
#: src/Module/Contact/Profile.php:339 #: src/Module/Contact/Profile.php:358
#: src/Module/Debug/ActivityPubConversion.php:140 #: src/Module/Debug/ActivityPubConversion.php:140
#: src/Module/Debug/Babel.php:313 src/Module/Debug/Localtime.php:64 #: src/Module/Debug/Babel.php:313 src/Module/Debug/Localtime.php:64
#: src/Module/Debug/Probe.php:54 src/Module/Debug/WebFinger.php:51 #: src/Module/Debug/Probe.php:54 src/Module/Debug/WebFinger.php:51
@ -315,7 +315,8 @@ msgstr ""
#: src/Module/Moderation/Report/Create.php:211 #: src/Module/Moderation/Report/Create.php:211
#: src/Module/Moderation/Report/Create.php:263 #: src/Module/Moderation/Report/Create.php:263
#: src/Module/Profile/Profile.php:274 src/Module/Profile/UnkMail.php:155 #: src/Module/Profile/Profile.php:274 src/Module/Profile/UnkMail.php:155
#: src/Module/Settings/Profile/Index.php: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/duepuntozero/config.php:85 view/theme/frio/config.php:171
#: view/theme/quattro/config.php:87 view/theme/vier/config.php:135 #: view/theme/quattro/config.php:87 view/theme/vier/config.php:135
msgid "Submit" msgid "Submit"
@ -388,7 +389,7 @@ msgid "Save"
msgstr "" msgstr ""
#: mod/photos.php:67 mod/photos.php:132 mod/photos.php:578 #: 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/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/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 #: 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" msgid "Do not show a status post for this upload"
msgstr "" msgstr ""
#: mod/photos.php:736 mod/photos.php:1097 src/Content/Conversation.php:394 #: mod/photos.php:736 mod/photos.php:1097 src/Content/Conversation.php:399
#: src/Module/Calendar/Event/Form.php:253 src/Module/Post/Edit.php:183 #: src/Module/Calendar/Event/Form.php:253 src/Module/Post/Edit.php:183
msgid "Permissions" msgid "Permissions"
msgstr "" msgstr ""
@ -492,7 +493,7 @@ msgstr ""
msgid "Delete Album" msgid "Delete Album"
msgstr "" msgstr ""
#: mod/photos.php:803 mod/photos.php:903 src/Content/Conversation.php:410 #: mod/photos.php:803 mod/photos.php:903 src/Content/Conversation.php:415
#: src/Module/Contact/Follow.php:173 src/Module/Contact/Revoke.php:109 #: src/Module/Contact/Follow.php:173 src/Module/Contact/Revoke.php:109
#: src/Module/Contact/Unfollow.php:126 #: src/Module/Contact/Unfollow.php:126
#: src/Module/Media/Attachment/Browser.php:77 #: src/Module/Media/Attachment/Browser.php:77
@ -600,53 +601,54 @@ msgstr ""
#: mod/photos.php:1139 mod/photos.php:1195 mod/photos.php:1275 #: mod/photos.php:1139 mod/photos.php:1195 mod/photos.php:1275
#: src/Module/Contact.php:619 src/Module/Item/Compose.php:188 #: src/Module/Contact.php:619 src/Module/Item/Compose.php:188
#: src/Object/Post.php:1084 #: src/Object/Post.php:1092
msgid "This is you" msgid "This is you"
msgstr "" msgstr ""
#: mod/photos.php:1141 mod/photos.php:1197 mod/photos.php:1277 #: mod/photos.php:1141 mod/photos.php:1197 mod/photos.php:1277
#: src/Object/Post.php:565 src/Object/Post.php:1086 #: src/Object/Post.php:572 src/Object/Post.php:1094
msgid "Comment" msgid "Comment"
msgstr "" msgstr ""
#: mod/photos.php:1143 mod/photos.php:1199 mod/photos.php:1279 #: mod/photos.php:1143 mod/photos.php:1199 mod/photos.php:1279
#: src/Content/Conversation.php:407 src/Module/Calendar/Event/Form.php:248 #: src/Content/Conversation.php:412 src/Module/Calendar/Event/Form.php:248
#: src/Module/Item/Compose.php:201 src/Module/Post/Edit.php:165 #: src/Module/Item/Compose.php:201 src/Module/Post/Edit.php:165
#: src/Object/Post.php:1100 #: src/Object/Post.php:1108
msgid "Preview" msgid "Preview"
msgstr "" msgstr ""
#: mod/photos.php:1144 src/Content/Conversation.php:360 #: mod/photos.php:1144 src/Content/Conversation.php:365
#: src/Module/Post/Edit.php:130 src/Object/Post.php:1088 #: src/Module/Post/Edit.php:130 src/Object/Post.php:1096
msgid "Loading..." msgid "Loading..."
msgstr "" msgstr ""
#: mod/photos.php:1236 src/Content/Conversation.php:1424 #: mod/photos.php:1236 src/Content/Conversation.php:1443
#: src/Object/Post.php:260 #: src/Object/Post.php:260
msgid "Select" msgid "Select"
msgstr "" msgstr ""
#: mod/photos.php:1237 src/Content/Conversation.php:1425 #: mod/photos.php:1237 src/Content/Conversation.php:1444
#: src/Module/Moderation/Users/Active.php:136 #: src/Module/Moderation/Users/Active.php:136
#: src/Module/Moderation/Users/Blocked.php:136 #: src/Module/Moderation/Users/Blocked.php:136
#: src/Module/Moderation/Users/Index.php:151 #: src/Module/Moderation/Users/Index.php:151
#: src/Module/Settings/Connectors.php:244 #: src/Module/Settings/Connectors.php:244
#: src/Module/Settings/Server/Index.php:109
msgid "Delete" msgid "Delete"
msgstr "" msgstr ""
#: mod/photos.php:1298 src/Object/Post.php:402 #: mod/photos.php:1298 src/Object/Post.php:408
msgid "Like" msgid "Like"
msgstr "" msgstr ""
#: mod/photos.php:1299 src/Object/Post.php:402 #: mod/photos.php:1299 src/Object/Post.php:408
msgid "I like this (toggle)" msgid "I like this (toggle)"
msgstr "" msgstr ""
#: mod/photos.php:1300 src/Object/Post.php:403 #: mod/photos.php:1300 src/Object/Post.php:409
msgid "Dislike" msgid "Dislike"
msgstr "" 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)" msgid "I don't like this (toggle)"
msgstr "" msgstr ""
@ -682,77 +684,88 @@ msgstr ""
msgid "Collapse this author's posts?" msgid "Collapse this author's posts?"
msgstr "" msgstr ""
#: src/App/Page.php:253 #: src/App/Page.php:252
msgid "Like not successful" msgid "Ignore this author's server?"
msgstr "" msgstr ""
#: src/App/Page.php:254 #: src/App/Page.php:253 src/Module/Settings/Server/Action.php:61
msgid "Dislike not successful" #: src/Module/Settings/Server/Index.php:108
msgid ""
"You won't see any content from this server including reshares in your "
"Network page, the community pages and individual conversations."
msgstr "" msgstr ""
#: src/App/Page.php:255 #: src/App/Page.php:255
msgid "Sharing not successful" msgid "Like not successful"
msgstr "" msgstr ""
#: src/App/Page.php:256 #: src/App/Page.php:256
msgid "Attendance unsuccessful" msgid "Dislike not successful"
msgstr "" msgstr ""
#: src/App/Page.php:257 #: src/App/Page.php:257
msgid "Backend error" msgid "Sharing not successful"
msgstr "" msgstr ""
#: src/App/Page.php:258 #: src/App/Page.php:258
msgid "Attendance unsuccessful"
msgstr ""
#: src/App/Page.php:259
msgid "Backend error"
msgstr ""
#: src/App/Page.php:260
msgid "Network error" msgid "Network error"
msgstr "" msgstr ""
#: src/App/Page.php:261 #: src/App/Page.php:263
msgid "Drop files here to upload" msgid "Drop files here to upload"
msgstr "" msgstr ""
#: src/App/Page.php:262 #: src/App/Page.php:264
msgid "Your browser does not support drag and drop file uploads." msgid "Your browser does not support drag and drop file uploads."
msgstr "" msgstr ""
#: src/App/Page.php:263 #: src/App/Page.php:265
msgid "" msgid ""
"Please use the fallback form below to upload your files like in the olden " "Please use the fallback form below to upload your files like in the olden "
"days." "days."
msgstr "" msgstr ""
#: src/App/Page.php:264 #: src/App/Page.php:266
msgid "File is too big ({{filesize}}MiB). Max filesize: {{maxFilesize}}MiB." msgid "File is too big ({{filesize}}MiB). Max filesize: {{maxFilesize}}MiB."
msgstr "" msgstr ""
#: src/App/Page.php:265 #: src/App/Page.php:267
msgid "You can't upload files of this type." msgid "You can't upload files of this type."
msgstr "" msgstr ""
#: src/App/Page.php:266 #: src/App/Page.php:268
msgid "Server responded with {{statusCode}} code." msgid "Server responded with {{statusCode}} code."
msgstr "" msgstr ""
#: src/App/Page.php:267 #: src/App/Page.php:269
msgid "Cancel upload" msgid "Cancel upload"
msgstr "" msgstr ""
#: src/App/Page.php:268 #: src/App/Page.php:270
msgid "Upload canceled." msgid "Upload canceled."
msgstr "" msgstr ""
#: src/App/Page.php:269 #: src/App/Page.php:271
msgid "Are you sure you want to cancel this upload?" msgid "Are you sure you want to cancel this upload?"
msgstr "" msgstr ""
#: src/App/Page.php:270 #: src/App/Page.php:272
msgid "Remove file" msgid "Remove file"
msgstr "" msgstr ""
#: src/App/Page.php:271 #: src/App/Page.php:273
msgid "You can't upload any more files." msgid "You can't upload any more files."
msgstr "" msgstr ""
#: src/App/Page.php:349 #: src/App/Page.php:351
msgid "toggle mobile" msgid "toggle mobile"
msgstr "" msgstr ""
@ -779,17 +792,17 @@ msgstr ""
msgid "All contacts" msgid "All contacts"
msgstr "" 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/Contact.php:415 src/Module/PermissionTooltip.php:127
#: src/Module/PermissionTooltip.php:149 #: src/Module/PermissionTooltip.php:149
msgid "Followers" msgid "Followers"
msgstr "" 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" msgid "Following"
msgstr "" 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" msgid "Mutual friends"
msgstr "" msgstr ""
@ -943,7 +956,7 @@ msgstr ""
msgid "Enter user nickname: " msgid "Enter user nickname: "
msgstr "" 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/Api/Twitter/ContactEndpoint.php:74
#: src/Module/Moderation/Users/Active.php:71 #: src/Module/Moderation/Users/Active.php:71
#: src/Module/Moderation/Users/Blocked.php:71 #: src/Module/Moderation/Users/Blocked.php:71
@ -1127,65 +1140,65 @@ msgstr ""
msgid "%s (via %s)" msgid "%s (via %s)"
msgstr "" msgstr ""
#: src/Content/Conversation.php:219 #: src/Content/Conversation.php:224
msgid "and" msgid "and"
msgstr "" msgstr ""
#: src/Content/Conversation.php:222 #: src/Content/Conversation.php:227
#, php-format #, php-format
msgid "and %d other people" msgid "and %d other people"
msgstr "" msgstr ""
#: src/Content/Conversation.php:228 #: src/Content/Conversation.php:233
#, php-format #, php-format
msgid "%2$s likes this." msgid "%2$s likes this."
msgid_plural "%2$s like this." msgid_plural "%2$s like this."
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#: src/Content/Conversation.php:230 #: src/Content/Conversation.php:235
#, php-format #, php-format
msgid "%2$s doesn't like this." msgid "%2$s doesn't like this."
msgid_plural "%2$s don't like this." msgid_plural "%2$s don't like this."
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#: src/Content/Conversation.php:232 #: src/Content/Conversation.php:237
#, php-format #, php-format
msgid "%2$s attends." msgid "%2$s attends."
msgid_plural "%2$s attend." msgid_plural "%2$s attend."
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#: src/Content/Conversation.php:234 #: src/Content/Conversation.php:239
#, php-format #, php-format
msgid "%2$s doesn't attend." msgid "%2$s doesn't attend."
msgid_plural "%2$s don't attend." msgid_plural "%2$s don't attend."
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#: src/Content/Conversation.php:236 #: src/Content/Conversation.php:241
#, php-format #, php-format
msgid "%2$s attends maybe." msgid "%2$s attends maybe."
msgid_plural "%2$s attend maybe." msgid_plural "%2$s attend maybe."
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#: src/Content/Conversation.php:238 #: src/Content/Conversation.php:243
#, php-format #, php-format
msgid "%2$s reshared this." msgid "%2$s reshared this."
msgid_plural "%2$s reshared this." msgid_plural "%2$s reshared this."
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#: src/Content/Conversation.php:267 #: src/Content/Conversation.php:272
#, php-format #, php-format
msgid "<button type=\"button\" %2$s>%1$d person</button> likes this" msgid "<button type=\"button\" %2$s>%1$d person</button> likes this"
msgid_plural "<button type=\"button\" %2$s>%1$d people</button> like this" msgid_plural "<button type=\"button\" %2$s>%1$d people</button> like this"
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#: src/Content/Conversation.php:270 #: src/Content/Conversation.php:275
#, php-format #, php-format
msgid "<button type=\"button\" %2$s>%1$d person</button> doesn't like this" msgid "<button type=\"button\" %2$s>%1$d person</button> doesn't like this"
msgid_plural "" msgid_plural ""
@ -1193,304 +1206,304 @@ msgid_plural ""
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#: src/Content/Conversation.php:273 #: src/Content/Conversation.php:278
#, php-format #, php-format
msgid "<button type=\"button\" %2$s>%1$d person</button> attends" msgid "<button type=\"button\" %2$s>%1$d person</button> attends"
msgid_plural "<button type=\"button\" %2$s>%1$d people</button> attend" msgid_plural "<button type=\"button\" %2$s>%1$d people</button> attend"
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#: src/Content/Conversation.php:276 #: src/Content/Conversation.php:281
#, php-format #, php-format
msgid "<button type=\"button\" %2$s>%1$d person</button> doesn't attend" msgid "<button type=\"button\" %2$s>%1$d person</button> doesn't attend"
msgid_plural "<button type=\"button\" %2$s>%1$d people</button> don't attend" msgid_plural "<button type=\"button\" %2$s>%1$d people</button> don't attend"
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#: src/Content/Conversation.php:279 #: src/Content/Conversation.php:284
#, php-format #, php-format
msgid "<button type=\"button\" %2$s>%1$d person</button> attends maybe" msgid "<button type=\"button\" %2$s>%1$d person</button> attends maybe"
msgid_plural "<button type=\"button\" %2$s>%1$d people</button> attend maybe" msgid_plural "<button type=\"button\" %2$s>%1$d people</button> attend maybe"
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#: src/Content/Conversation.php:282 #: src/Content/Conversation.php:287
#, php-format #, php-format
msgid "<button type=\"button\" %2$s>%1$d person</button> reshared this" msgid "<button type=\"button\" %2$s>%1$d person</button> reshared this"
msgid_plural "<button type=\"button\" %2$s>%1$d people</button> reshared this" msgid_plural "<button type=\"button\" %2$s>%1$d people</button> reshared this"
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#: src/Content/Conversation.php:329 #: src/Content/Conversation.php:334
msgid "Visible to <strong>everybody</strong>" msgid "Visible to <strong>everybody</strong>"
msgstr "" msgstr ""
#: src/Content/Conversation.php:330 src/Module/Item/Compose.php:200 #: src/Content/Conversation.php:335 src/Module/Item/Compose.php:200
#: src/Object/Post.php:1099 #: src/Object/Post.php:1107
msgid "Please enter a image/video/audio/webpage URL:" msgid "Please enter a image/video/audio/webpage URL:"
msgstr "" msgstr ""
#: src/Content/Conversation.php:331 #: src/Content/Conversation.php:336
msgid "Tag term:" msgid "Tag term:"
msgstr "" msgstr ""
#: src/Content/Conversation.php:332 src/Module/Filer/SaveTag.php:73 #: src/Content/Conversation.php:337 src/Module/Filer/SaveTag.php:73
msgid "Save to Folder:" msgid "Save to Folder:"
msgstr "" msgstr ""
#: src/Content/Conversation.php:333 #: src/Content/Conversation.php:338
msgid "Where are you right now?" msgid "Where are you right now?"
msgstr "" msgstr ""
#: src/Content/Conversation.php:334 #: src/Content/Conversation.php:339
msgid "Delete item(s)?" msgid "Delete item(s)?"
msgstr "" msgstr ""
#: src/Content/Conversation.php:346 src/Module/Item/Compose.php:175 #: src/Content/Conversation.php:351 src/Module/Item/Compose.php:175
msgid "Created at" msgid "Created at"
msgstr "" msgstr ""
#: src/Content/Conversation.php:356 #: src/Content/Conversation.php:361
msgid "New Post" msgid "New Post"
msgstr "" msgstr ""
#: src/Content/Conversation.php:359 #: src/Content/Conversation.php:364
msgid "Share" msgid "Share"
msgstr "" msgstr ""
#: src/Content/Conversation.php:362 src/Module/Post/Edit.php:132 #: src/Content/Conversation.php:367 src/Module/Post/Edit.php:132
msgid "upload photo" msgid "upload photo"
msgstr "" msgstr ""
#: src/Content/Conversation.php:363 src/Module/Post/Edit.php:133 #: src/Content/Conversation.php:368 src/Module/Post/Edit.php:133
msgid "Attach file" msgid "Attach file"
msgstr "" msgstr ""
#: src/Content/Conversation.php:364 src/Module/Post/Edit.php:134 #: src/Content/Conversation.php:369 src/Module/Post/Edit.php:134
msgid "attach file" msgid "attach file"
msgstr "" msgstr ""
#: src/Content/Conversation.php:365 src/Module/Item/Compose.php:190 #: src/Content/Conversation.php:370 src/Module/Item/Compose.php:190
#: src/Module/Post/Edit.php:171 src/Object/Post.php:1089 #: src/Module/Post/Edit.php:171 src/Object/Post.php:1097
msgid "Bold" msgid "Bold"
msgstr "" msgstr ""
#: src/Content/Conversation.php:366 src/Module/Item/Compose.php:191 #: src/Content/Conversation.php:371 src/Module/Item/Compose.php:191
#: src/Module/Post/Edit.php:172 src/Object/Post.php:1090 #: src/Module/Post/Edit.php:172 src/Object/Post.php:1098
msgid "Italic" msgid "Italic"
msgstr "" msgstr ""
#: src/Content/Conversation.php:367 src/Module/Item/Compose.php:192 #: src/Content/Conversation.php:372 src/Module/Item/Compose.php:192
#: src/Module/Post/Edit.php:173 src/Object/Post.php:1091 #: src/Module/Post/Edit.php:173 src/Object/Post.php:1099
msgid "Underline" msgid "Underline"
msgstr "" msgstr ""
#: src/Content/Conversation.php:368 src/Module/Item/Compose.php:193 #: src/Content/Conversation.php:373 src/Module/Item/Compose.php:193
#: src/Module/Post/Edit.php:174 src/Object/Post.php:1093 #: src/Module/Post/Edit.php:174 src/Object/Post.php:1101
msgid "Quote" msgid "Quote"
msgstr "" msgstr ""
#: src/Content/Conversation.php:369 src/Module/Item/Compose.php:194 #: src/Content/Conversation.php:374 src/Module/Item/Compose.php:194
#: src/Module/Post/Edit.php:175 src/Object/Post.php:1094 #: src/Module/Post/Edit.php:175 src/Object/Post.php:1102
msgid "Add emojis" msgid "Add emojis"
msgstr "" msgstr ""
#: src/Content/Conversation.php:370 src/Module/Item/Compose.php:195 #: src/Content/Conversation.php:375 src/Module/Item/Compose.php:195
#: src/Object/Post.php:1092 #: src/Object/Post.php:1100
msgid "Content Warning" msgid "Content Warning"
msgstr "" msgstr ""
#: src/Content/Conversation.php:371 src/Module/Item/Compose.php:196 #: src/Content/Conversation.php:376 src/Module/Item/Compose.php:196
#: src/Module/Post/Edit.php:176 src/Object/Post.php:1095 #: src/Module/Post/Edit.php:176 src/Object/Post.php:1103
msgid "Code" msgid "Code"
msgstr "" msgstr ""
#: src/Content/Conversation.php:372 src/Module/Item/Compose.php:197 #: src/Content/Conversation.php:377 src/Module/Item/Compose.php:197
#: src/Object/Post.php:1096 #: src/Object/Post.php:1104
msgid "Image" msgid "Image"
msgstr "" msgstr ""
#: src/Content/Conversation.php:373 src/Module/Item/Compose.php:198 #: src/Content/Conversation.php:378 src/Module/Item/Compose.php:198
#: src/Module/Post/Edit.php:177 src/Object/Post.php:1097 #: src/Module/Post/Edit.php:177 src/Object/Post.php:1105
msgid "Link" msgid "Link"
msgstr "" msgstr ""
#: src/Content/Conversation.php:374 src/Module/Item/Compose.php:199 #: src/Content/Conversation.php:379 src/Module/Item/Compose.php:199
#: src/Module/Post/Edit.php:178 src/Object/Post.php:1098 #: src/Module/Post/Edit.php:178 src/Object/Post.php:1106
msgid "Link or Media" msgid "Link or Media"
msgstr "" msgstr ""
#: src/Content/Conversation.php:375 #: src/Content/Conversation.php:380
msgid "Video" msgid "Video"
msgstr "" msgstr ""
#: src/Content/Conversation.php:376 src/Module/Item/Compose.php:202 #: src/Content/Conversation.php:381 src/Module/Item/Compose.php:202
#: src/Module/Post/Edit.php:141 #: src/Module/Post/Edit.php:141
msgid "Set your location" msgid "Set your location"
msgstr "" msgstr ""
#: src/Content/Conversation.php:377 src/Module/Post/Edit.php:142 #: src/Content/Conversation.php:382 src/Module/Post/Edit.php:142
msgid "set location" msgid "set location"
msgstr "" msgstr ""
#: src/Content/Conversation.php:378 src/Module/Post/Edit.php:143 #: src/Content/Conversation.php:383 src/Module/Post/Edit.php:143
msgid "Clear browser location" msgid "Clear browser location"
msgstr "" msgstr ""
#: src/Content/Conversation.php:379 src/Module/Post/Edit.php:144 #: src/Content/Conversation.php:384 src/Module/Post/Edit.php:144
msgid "clear location" msgid "clear location"
msgstr "" msgstr ""
#: src/Content/Conversation.php:381 src/Module/Item/Compose.php:207 #: src/Content/Conversation.php:386 src/Module/Item/Compose.php:207
#: src/Module/Post/Edit.php:157 #: src/Module/Post/Edit.php:157
msgid "Set title" msgid "Set title"
msgstr "" msgstr ""
#: src/Content/Conversation.php:383 src/Module/Item/Compose.php:208 #: src/Content/Conversation.php:388 src/Module/Item/Compose.php:208
#: src/Module/Post/Edit.php:159 #: src/Module/Post/Edit.php:159
msgid "Categories (comma-separated list)" msgid "Categories (comma-separated list)"
msgstr "" msgstr ""
#: src/Content/Conversation.php:388 src/Module/Item/Compose.php:224 #: src/Content/Conversation.php:393 src/Module/Item/Compose.php:224
msgid "Scheduled at" msgid "Scheduled at"
msgstr "" msgstr ""
#: src/Content/Conversation.php:393 src/Module/Post/Edit.php:146 #: src/Content/Conversation.php:398 src/Module/Post/Edit.php:146
msgid "Permission settings" msgid "Permission settings"
msgstr "" msgstr ""
#: src/Content/Conversation.php:403 src/Module/Post/Edit.php:155 #: src/Content/Conversation.php:408 src/Module/Post/Edit.php:155
msgid "Public post" msgid "Public post"
msgstr "" msgstr ""
#: src/Content/Conversation.php:417 src/Content/Widget/VCard.php:120 #: src/Content/Conversation.php:422 src/Content/Widget/VCard.php:120
#: src/Model/Profile.php:469 src/Module/Admin/Logs/View.php:92 #: src/Model/Profile.php:467 src/Module/Admin/Logs/View.php:92
#: src/Module/Post/Edit.php:181 #: src/Module/Post/Edit.php:181
msgid "Message" msgid "Message"
msgstr "" msgstr ""
#: src/Content/Conversation.php:418 src/Module/Post/Edit.php:182 #: src/Content/Conversation.php:423 src/Module/Post/Edit.php:182
#: src/Module/Settings/TwoFactor/Trusted.php:140 #: src/Module/Settings/TwoFactor/Trusted.php:140
msgid "Browser" msgid "Browser"
msgstr "" msgstr ""
#: src/Content/Conversation.php:420 src/Module/Post/Edit.php:185 #: src/Content/Conversation.php:425 src/Module/Post/Edit.php:185
msgid "Open Compose page" msgid "Open Compose page"
msgstr "" msgstr ""
#: src/Content/Conversation.php:569 #: src/Content/Conversation.php:580
msgid "remove" msgid "remove"
msgstr "" msgstr ""
#: src/Content/Conversation.php:573 #: src/Content/Conversation.php:584
msgid "Delete Selected Items" msgid "Delete Selected Items"
msgstr "" msgstr ""
#: src/Content/Conversation.php:728 src/Content/Conversation.php:731 #: src/Content/Conversation.php:739 src/Content/Conversation.php:742
#: src/Content/Conversation.php:734 src/Content/Conversation.php:737 #: src/Content/Conversation.php:745 src/Content/Conversation.php:748
#: src/Content/Conversation.php:740 #: src/Content/Conversation.php:751
#, php-format #, php-format
msgid "You had been addressed (%s)." msgid "You had been addressed (%s)."
msgstr "" msgstr ""
#: src/Content/Conversation.php:743 #: src/Content/Conversation.php:754
#, php-format #, php-format
msgid "You are following %s." msgid "You are following %s."
msgstr "" msgstr ""
#: src/Content/Conversation.php:746 #: src/Content/Conversation.php:757
msgid "You subscribed to one or more tags in this post." msgid "You subscribed to one or more tags in this post."
msgstr "" msgstr ""
#: src/Content/Conversation.php:765 #: src/Content/Conversation.php:776
#, php-format #, php-format
msgid "%s reshared this." msgid "%s reshared this."
msgstr "" msgstr ""
#: src/Content/Conversation.php:767 #: src/Content/Conversation.php:778
msgid "Reshared" msgid "Reshared"
msgstr "" msgstr ""
#: src/Content/Conversation.php:767 #: src/Content/Conversation.php:778
#, php-format #, php-format
msgid "Reshared by %s <%s>" msgid "Reshared by %s <%s>"
msgstr "" msgstr ""
#: src/Content/Conversation.php:770 #: src/Content/Conversation.php:781
#, php-format #, php-format
msgid "%s is participating in this thread." msgid "%s is participating in this thread."
msgstr "" msgstr ""
#: src/Content/Conversation.php:773 #: src/Content/Conversation.php:784
msgid "Stored for general reasons" msgid "Stored for general reasons"
msgstr "" msgstr ""
#: src/Content/Conversation.php:776 #: src/Content/Conversation.php:787
msgid "Global post" msgid "Global post"
msgstr "" msgstr ""
#: src/Content/Conversation.php:779 #: src/Content/Conversation.php:790
msgid "Sent via an relay server" msgid "Sent via an relay server"
msgstr "" msgstr ""
#: src/Content/Conversation.php:779 #: src/Content/Conversation.php:790
#, php-format #, php-format
msgid "Sent via the relay server %s <%s>" msgid "Sent via the relay server %s <%s>"
msgstr "" msgstr ""
#: src/Content/Conversation.php:782 #: src/Content/Conversation.php:793
msgid "Fetched" msgid "Fetched"
msgstr "" msgstr ""
#: src/Content/Conversation.php:782 #: src/Content/Conversation.php:793
#, php-format #, php-format
msgid "Fetched because of %s <%s>" msgid "Fetched because of %s <%s>"
msgstr "" msgstr ""
#: src/Content/Conversation.php:785 #: src/Content/Conversation.php:796
msgid "Stored because of a child post to complete this thread." msgid "Stored because of a child post to complete this thread."
msgstr "" msgstr ""
#: src/Content/Conversation.php:788 #: src/Content/Conversation.php:799
msgid "Local delivery" msgid "Local delivery"
msgstr "" msgstr ""
#: src/Content/Conversation.php:791 #: src/Content/Conversation.php:802
msgid "Stored because of your activity (like, comment, star, ...)" msgid "Stored because of your activity (like, comment, star, ...)"
msgstr "" msgstr ""
#: src/Content/Conversation.php:794 #: src/Content/Conversation.php:805
msgid "Distributed" msgid "Distributed"
msgstr "" msgstr ""
#: src/Content/Conversation.php:797 #: src/Content/Conversation.php:808
msgid "Pushed to us" msgid "Pushed to us"
msgstr "" msgstr ""
#: src/Content/Conversation.php:1452 src/Object/Post.php:248 #: src/Content/Conversation.php:1471 src/Object/Post.php:247
msgid "Pinned item" msgid "Pinned item"
msgstr "" msgstr ""
#: src/Content/Conversation.php:1468 src/Object/Post.php:515 #: src/Content/Conversation.php:1488 src/Object/Post.php:521
#: src/Object/Post.php:516 #: src/Object/Post.php:522
#, php-format #, php-format
msgid "View %s's profile @ %s" msgid "View %s's profile @ %s"
msgstr "" msgstr ""
#: src/Content/Conversation.php:1481 src/Object/Post.php:503 #: src/Content/Conversation.php:1501 src/Object/Post.php:509
msgid "Categories:" msgid "Categories:"
msgstr "" msgstr ""
#: src/Content/Conversation.php:1482 src/Object/Post.php:504 #: src/Content/Conversation.php:1502 src/Object/Post.php:510
msgid "Filed under:" msgid "Filed under:"
msgstr "" msgstr ""
#: src/Content/Conversation.php:1490 src/Object/Post.php:529 #: src/Content/Conversation.php:1510 src/Object/Post.php:535
#, php-format #, php-format
msgid "%s from %s" msgid "%s from %s"
msgstr "" msgstr ""
#: src/Content/Conversation.php:1506 #: src/Content/Conversation.php:1526
msgid "View in context" msgid "View in context"
msgstr "" msgstr ""
@ -1607,8 +1620,8 @@ msgid ""
msgstr "" msgstr ""
#: src/Content/GroupManager.php:152 src/Content/Nav.php:276 #: src/Content/GroupManager.php:152 src/Content/Nav.php:276
#: src/Content/Text/HTML.php:880 src/Content/Widget.php:541 #: src/Content/Text/HTML.php:880 src/Content/Widget.php:537
#: src/Model/User.php:1254 #: src/Model/User.php:1255
msgid "Groups" msgid "Groups"
msgstr "" msgstr ""
@ -1616,12 +1629,12 @@ msgstr ""
msgid "External link to group" msgid "External link to group"
msgstr "" msgstr ""
#: src/Content/GroupManager.php:158 src/Content/Widget.php:516 #: src/Content/GroupManager.php:158 src/Content/Widget.php:512
msgid "show less" msgid "show less"
msgstr "" msgstr ""
#: src/Content/GroupManager.php:159 src/Content/Widget.php:414 #: src/Content/GroupManager.php:159 src/Content/Widget.php:410
#: src/Content/Widget.php:517 #: src/Content/Widget.php:513
msgid "show more" msgid "show more"
msgstr "" msgstr ""
@ -1629,88 +1642,93 @@ msgstr ""
msgid "Create new group" msgid "Create new group"
msgstr "" msgstr ""
#: src/Content/Item.php:329 src/Model/Item.php:2993 #: src/Content/Item.php:331 src/Model/Item.php:2998
msgid "event" msgid "event"
msgstr "" msgstr ""
#: src/Content/Item.php:332 src/Content/Item.php:342 #: src/Content/Item.php:334 src/Content/Item.php:344
msgid "status" msgid "status"
msgstr "" 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 #: src/Module/Post/Tag/Add.php:123
msgid "photo" msgid "photo"
msgstr "" msgstr ""
#: src/Content/Item.php:352 src/Module/Post/Tag/Add.php:141 #: src/Content/Item.php:354 src/Module/Post/Tag/Add.php:141
#, php-format #, php-format
msgid "%1$s tagged %2$s's %3$s with %4$s" msgid "%1$s tagged %2$s's %3$s with %4$s"
msgstr "" msgstr ""
#: src/Content/Item.php:421 view/theme/frio/theme.php:262 #: src/Content/Item.php:428 view/theme/frio/theme.php:262
msgid "Follow Thread" msgid "Follow Thread"
msgstr "" msgstr ""
#: src/Content/Item.php:422 src/Model/Contact.php:1205 #: src/Content/Item.php:429 src/Model/Contact.php:1211
msgid "View Status" msgid "View Status"
msgstr "" msgstr ""
#: src/Content/Item.php:423 src/Content/Item.php:443 src/Model/Contact.php:1154 #: src/Content/Item.php:430 src/Content/Item.php:451 src/Model/Contact.php:1160
#: src/Model/Contact.php:1197 src/Model/Contact.php:1206 #: src/Model/Contact.php:1203 src/Model/Contact.php:1212
#: src/Module/Directory.php:157 src/Module/Settings/Profile/Index.php:233 #: src/Module/Directory.php:157 src/Module/Settings/Profile/Index.php:259
msgid "View Profile" msgid "View Profile"
msgstr "" msgstr ""
#: src/Content/Item.php:424 src/Model/Contact.php:1207 #: src/Content/Item.php:431 src/Model/Contact.php:1213
msgid "View Photos" msgid "View Photos"
msgstr "" msgstr ""
#: src/Content/Item.php:425 src/Model/Contact.php:1198 #: src/Content/Item.php:432 src/Model/Contact.php:1204
#: src/Model/Contact.php:1208 #: src/Model/Contact.php:1214
msgid "Network Posts" msgid "Network Posts"
msgstr "" msgstr ""
#: src/Content/Item.php:426 src/Model/Contact.php:1199 #: src/Content/Item.php:433 src/Model/Contact.php:1205
#: src/Model/Contact.php:1209 #: src/Model/Contact.php:1215
msgid "View Contact" msgid "View Contact"
msgstr "" msgstr ""
#: src/Content/Item.php:427 src/Model/Contact.php:1210 #: src/Content/Item.php:434 src/Model/Contact.php:1216
msgid "Send PM" msgid "Send PM"
msgstr "" msgstr ""
#: src/Content/Item.php:428 src/Module/Contact.php:468 #: src/Content/Item.php:435 src/Module/Contact.php:468
#: src/Module/Contact/Profile.php:477 #: src/Module/Contact/Profile.php:498
#: src/Module/Moderation/Blocklist/Contact.php:116 #: src/Module/Moderation/Blocklist/Contact.php:116
#: src/Module/Moderation/Users/Active.php:137 #: src/Module/Moderation/Users/Active.php:137
#: src/Module/Moderation/Users/Index.php:152 #: src/Module/Moderation/Users/Index.php:152
msgid "Block" msgid "Block"
msgstr "" msgstr ""
#: src/Content/Item.php:429 src/Module/Contact.php:469 #: src/Content/Item.php:436 src/Module/Contact.php:469
#: src/Module/Contact/Profile.php:485 #: src/Module/Contact/Profile.php:506
#: src/Module/Notifications/Introductions.php:134 #: src/Module/Notifications/Introductions.php:134
#: src/Module/Notifications/Introductions.php:206 #: src/Module/Notifications/Introductions.php:206
#: src/Module/Notifications/Notification.php:89 #: src/Module/Notifications/Notification.php:89
msgid "Ignore" msgid "Ignore"
msgstr "" msgstr ""
#: src/Content/Item.php:430 src/Module/Contact.php:470 #: src/Content/Item.php:437 src/Module/Contact.php:470
#: src/Module/Contact/Profile.php:493 #: src/Module/Contact/Profile.php:514
msgid "Collapse" msgid "Collapse"
msgstr "" 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" msgid "Languages"
msgstr "" msgstr ""
#: src/Content/Item.php:440 src/Content/Widget.php:80 #: src/Content/Item.php:448 src/Content/Widget.php:80
#: src/Model/Contact.php:1200 src/Model/Contact.php:1211 #: src/Model/Contact.php:1206 src/Model/Contact.php:1217
#: src/Module/Contact/Follow.php:167 view/theme/vier/theme.php:195 #: src/Module/Contact/Follow.php:167 view/theme/vier/theme.php:195
msgid "Connect/Follow" msgid "Connect/Follow"
msgstr "" msgstr ""
#: src/Content/Item.php:874 #: src/Content/Item.php:882
msgid "Unable to fetch user." msgid "Unable to fetch user."
msgstr "" msgstr ""
@ -1758,7 +1776,7 @@ msgstr ""
#: src/Content/Nav.php:228 src/Module/BaseProfile.php:49 #: src/Content/Nav.php:228 src/Module/BaseProfile.php:49
#: src/Module/BaseSettings.php:100 src/Module/Contact.php:504 #: src/Module/BaseSettings.php:100 src/Module/Contact.php:504
#: src/Module/Contact/Profile.php:392 src/Module/Profile/Profile.php:268 #: src/Module/Contact/Profile.php:413 src/Module/Profile/Profile.php:268
#: src/Module/Welcome.php:57 view/theme/frio/theme.php:230 #: src/Module/Welcome.php:57 view/theme/frio/theme.php:230
msgid "Profile" msgid "Profile"
msgstr "" msgstr ""
@ -1961,7 +1979,7 @@ msgid "Manage other pages"
msgstr "" msgstr ""
#: src/Content/Nav.php:325 src/Module/Admin/Addons/Details.php:114 #: src/Content/Nav.php:325 src/Module/Admin/Addons/Details.php:114
#: src/Module/Admin/Themes/Details.php:93 src/Module/BaseSettings.php:170 #: src/Module/Admin/Themes/Details.php:93 src/Module/BaseSettings.php:177
#: src/Module/Welcome.php:52 view/theme/frio/theme.php:242 #: src/Module/Welcome.php:52 view/theme/frio/theme.php:242
msgid "Settings" msgid "Settings"
msgstr "" msgstr ""
@ -2043,8 +2061,8 @@ msgid ""
"<a href=\"%1$s\" target=\"_blank\" rel=\"noopener noreferrer\">%2$s</a> %3$s" "<a href=\"%1$s\" target=\"_blank\" rel=\"noopener noreferrer\">%2$s</a> %3$s"
msgstr "" msgstr ""
#: src/Content/Text/BBCode.php:939 src/Model/Item.php:3735 #: src/Content/Text/BBCode.php:939 src/Model/Item.php:3740
#: src/Model/Item.php:3741 src/Model/Item.php:3742 #: src/Model/Item.php:3746 src/Model/Item.php:3747
msgid "Link to source" msgid "Link to source"
msgstr "" msgstr ""
@ -2077,7 +2095,7 @@ msgid "The end"
msgstr "" msgstr ""
#: src/Content/Text/HTML.php:859 src/Content/Widget/VCard.php:116 #: src/Content/Text/HTML.php:859 src/Content/Widget/VCard.php:116
#: src/Model/Profile.php:463 src/Module/Contact/Profile.php:437 #: src/Model/Profile.php:461 src/Module/Contact/Profile.php:458
msgid "Follow" msgid "Follow"
msgstr "" msgstr ""
@ -2147,80 +2165,80 @@ msgstr ""
msgid "Local Directory" msgid "Local Directory"
msgstr "" 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 #: src/Module/Contact.php:401 src/Module/Welcome.php:76
msgid "Circles" msgid "Circles"
msgstr "" msgstr ""
#: src/Content/Widget.php:221 #: src/Content/Widget.php:217
msgid "Everyone" msgid "Everyone"
msgstr "" msgstr ""
#: src/Content/Widget.php:246 src/Module/Contact.php:424 #: src/Content/Widget.php:242 src/Module/Contact.php:424
msgid "No relationship" msgid "No relationship"
msgstr "" msgstr ""
#: src/Content/Widget.php:251 #: src/Content/Widget.php:247
msgid "Relationships" msgid "Relationships"
msgstr "" 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 #: src/Module/Contact.php:345
msgid "All Contacts" msgid "All Contacts"
msgstr "" msgstr ""
#: src/Content/Widget.php:292 #: src/Content/Widget.php:288
msgid "Protocols" msgid "Protocols"
msgstr "" msgstr ""
#: src/Content/Widget.php:294 #: src/Content/Widget.php:290
msgid "All Protocols" msgid "All Protocols"
msgstr "" msgstr ""
#: src/Content/Widget.php:322 #: src/Content/Widget.php:318
msgid "Saved Folders" msgid "Saved Folders"
msgstr "" msgstr ""
#: src/Content/Widget.php:324 src/Content/Widget.php:355 #: src/Content/Widget.php:320 src/Content/Widget.php:351
msgid "Everything" msgid "Everything"
msgstr "" msgstr ""
#: src/Content/Widget.php:353 #: src/Content/Widget.php:349
msgid "Categories" msgid "Categories"
msgstr "" msgstr ""
#: src/Content/Widget.php:410 #: src/Content/Widget.php:406
#, php-format #, php-format
msgid "%d contact in common" msgid "%d contact in common"
msgid_plural "%d contacts in common" msgid_plural "%d contacts in common"
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#: src/Content/Widget.php:510 #: src/Content/Widget.php:506
msgid "Archives" msgid "Archives"
msgstr "" msgstr ""
#: src/Content/Widget.php:518 #: src/Content/Widget.php:514
msgid "On this date" msgid "On this date"
msgstr "" msgstr ""
#: src/Content/Widget.php:538 #: src/Content/Widget.php:534
msgid "Persons" msgid "Persons"
msgstr "" msgstr ""
#: src/Content/Widget.php:539 #: src/Content/Widget.php:535
msgid "Organisations" msgid "Organisations"
msgstr "" msgstr ""
#: src/Content/Widget.php:540 src/Model/Contact.php:1675 #: src/Content/Widget.php:536 src/Model/Contact.php:1681
msgid "News" msgid "News"
msgstr "" 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" msgid "Account Types"
msgstr "" 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" msgid "All"
msgstr "" msgstr ""
@ -2270,32 +2288,32 @@ msgstr[1] ""
msgid "More Trending Tags" msgid "More Trending Tags"
msgstr "" msgstr ""
#: src/Content/Widget/VCard.php:109 src/Model/Profile.php:378 #: src/Content/Widget/VCard.php:109 src/Model/Profile.php:376
#: src/Module/Contact/Profile.php:381 src/Module/Profile/Profile.php:199 #: src/Module/Contact/Profile.php:402 src/Module/Profile/Profile.php:199
msgid "XMPP:" msgid "XMPP:"
msgstr "" msgstr ""
#: src/Content/Widget/VCard.php:110 src/Model/Profile.php:379 #: src/Content/Widget/VCard.php:110 src/Model/Profile.php:377
#: src/Module/Contact/Profile.php:383 src/Module/Profile/Profile.php:203 #: src/Module/Contact/Profile.php:404 src/Module/Profile/Profile.php:203
msgid "Matrix:" msgid "Matrix:"
msgstr "" msgstr ""
#: src/Content/Widget/VCard.php:111 src/Model/Event.php:82 #: src/Content/Widget/VCard.php:111 src/Model/Event.php:82
#: src/Model/Event.php:109 src/Model/Event.php:471 src/Model/Event.php:963 #: src/Model/Event.php:109 src/Model/Event.php:471 src/Model/Event.php:963
#: src/Model/Profile.php: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/Directory.php:147 src/Module/Notifications/Introductions.php:187
#: src/Module/Profile/Profile.php:221 #: src/Module/Profile/Profile.php:221
msgid "Location:" msgid "Location:"
msgstr "" 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 #: src/Module/Notifications/Introductions.php:201
msgid "Network:" msgid "Network:"
msgstr "" msgstr ""
#: src/Content/Widget/VCard.php:118 src/Model/Contact.php:1201 #: src/Content/Widget/VCard.php:118 src/Model/Contact.php:1207
#: src/Model/Contact.php:1212 src/Model/Profile.php:465 #: src/Model/Contact.php:1218 src/Model/Profile.php:463
#: src/Module/Contact/Profile.php:429 #: src/Module/Contact/Profile.php:450
msgid "Unfollow" msgid "Unfollow"
msgstr "" msgstr ""
@ -2559,8 +2577,8 @@ msgstr ""
#: src/Core/Installer.php:511 #: src/Core/Installer.php:511
msgid "" msgid ""
"The web installer needs to be able to create a file called \"local.config.php" "The web installer needs to be able to create a file called \"local.config."
"\" in the \"config\" folder of your web server and it is unable to do so." "php\" in the \"config\" folder of your web server and it is unable to do so."
msgstr "" msgstr ""
#: src/Core/Installer.php:512 #: src/Core/Installer.php:512
@ -3047,17 +3065,17 @@ msgstr ""
msgid "Edit circles" msgid "Edit circles"
msgstr "" 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:132
#: src/Module/Notifications/Introductions.php:204 #: src/Module/Notifications/Introductions.php:204
msgid "Approve" msgid "Approve"
msgstr "" msgstr ""
#: src/Model/Contact.php:1671 #: src/Model/Contact.php:1677
msgid "Organisation" msgid "Organisation"
msgstr "" msgstr ""
#: src/Model/Contact.php:1679 #: src/Model/Contact.php:1685
msgid "Group" msgid "Group"
msgstr "" msgstr ""
@ -3065,7 +3083,7 @@ msgstr ""
msgid "Disallowed profile URL." msgid "Disallowed profile URL."
msgstr "" msgstr ""
#: src/Model/Contact.php:2993 src/Module/Friendica.php:102 #: src/Model/Contact.php:2993 src/Module/Friendica.php:101
msgid "Blocked domain" msgid "Blocked domain"
msgstr "" msgstr ""
@ -3227,81 +3245,81 @@ msgstr ""
msgid "Happy Birthday %s" msgid "Happy Birthday %s"
msgstr "" msgstr ""
#: src/Model/Item.php:2056 #: src/Model/Item.php:2057
#, php-format #, php-format
msgid "Detected languages in this post:\\n%s" msgid "Detected languages in this post:\\n%s"
msgstr "" msgstr ""
#: src/Model/Item.php:2997 #: src/Model/Item.php:3002
msgid "activity" msgid "activity"
msgstr "" msgstr ""
#: src/Model/Item.php:2999 #: src/Model/Item.php:3004
msgid "comment" msgid "comment"
msgstr "" 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" msgid "post"
msgstr "" msgstr ""
#: src/Model/Item.php:3172 #: src/Model/Item.php:3177
#, php-format #, php-format
msgid "%s is blocked" msgid "%s is blocked"
msgstr "" msgstr ""
#: src/Model/Item.php:3174 #: src/Model/Item.php:3179
#, php-format #, php-format
msgid "%s is ignored" msgid "%s is ignored"
msgstr "" msgstr ""
#: src/Model/Item.php:3176 #: src/Model/Item.php:3181
#, php-format #, php-format
msgid "Content from %s is collapsed" msgid "Content from %s is collapsed"
msgstr "" msgstr ""
#: src/Model/Item.php:3180 #: src/Model/Item.php:3185
#, php-format #, php-format
msgid "Content warning: %s" msgid "Content warning: %s"
msgstr "" msgstr ""
#: src/Model/Item.php:3642 #: src/Model/Item.php:3647
msgid "bytes" msgid "bytes"
msgstr "" msgstr ""
#: src/Model/Item.php:3673 #: src/Model/Item.php:3678
#, php-format #, php-format
msgid "%2$s (%3$d%%, %1$d vote)" msgid "%2$s (%3$d%%, %1$d vote)"
msgid_plural "%2$s (%3$d%%, %1$d votes)" msgid_plural "%2$s (%3$d%%, %1$d votes)"
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#: src/Model/Item.php:3675 #: src/Model/Item.php:3680
#, php-format #, php-format
msgid "%2$s (%1$d vote)" msgid "%2$s (%1$d vote)"
msgid_plural "%2$s (%1$d votes)" msgid_plural "%2$s (%1$d votes)"
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#: src/Model/Item.php:3680 #: src/Model/Item.php:3685
#, php-format #, php-format
msgid "%d voter. Poll end: %s" msgid "%d voter. Poll end: %s"
msgid_plural "%d voters. Poll end: %s" msgid_plural "%d voters. Poll end: %s"
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#: src/Model/Item.php:3682 #: src/Model/Item.php:3687
#, php-format #, php-format
msgid "%d voter." msgid "%d voter."
msgid_plural "%d voters." msgid_plural "%d voters."
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#: src/Model/Item.php:3684 #: src/Model/Item.php:3689
#, php-format #, php-format
msgid "Poll end: %s" msgid "Poll end: %s"
msgstr "" 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" msgid "View on separate page"
msgstr "" msgstr ""
@ -3309,295 +3327,295 @@ msgstr ""
msgid "[no subject]" msgid "[no subject]"
msgstr "" 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" msgid "Wall Photos"
msgstr "" 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 #: src/Module/Profile/Profile.php:285
msgid "Edit profile" msgid "Edit profile"
msgstr "" msgstr ""
#: src/Model/Profile.php:363 #: src/Model/Profile.php:361
msgid "Change profile photo" msgid "Change profile photo"
msgstr "" 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 #: src/Module/Profile/Profile.php:209
msgid "Homepage:" msgid "Homepage:"
msgstr "" 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 #: src/Module/Notifications/Introductions.php:189
msgid "About:" msgid "About:"
msgstr "" msgstr ""
#: src/Model/Profile.php:467 #: src/Model/Profile.php:465
msgid "Atom feed" msgid "Atom feed"
msgstr "" msgstr ""
#: src/Model/Profile.php:474 #: src/Model/Profile.php:472
msgid "This website has been verified to belong to the same person." msgid "This website has been verified to belong to the same person."
msgstr "" msgstr ""
#: src/Model/Profile.php:511 #: src/Model/Profile.php:509
msgid "F d" msgid "F d"
msgstr "" msgstr ""
#: src/Model/Profile.php:575 src/Model/Profile.php:664 #: src/Model/Profile.php:573 src/Model/Profile.php:662
msgid "[today]" msgid "[today]"
msgstr "" msgstr ""
#: src/Model/Profile.php:584 #: src/Model/Profile.php:582
msgid "Birthday Reminders" msgid "Birthday Reminders"
msgstr "" msgstr ""
#: src/Model/Profile.php:585 #: src/Model/Profile.php:583
msgid "Birthdays this week:" msgid "Birthdays this week:"
msgstr "" msgstr ""
#: src/Model/Profile.php:613 #: src/Model/Profile.php:611
msgid "g A l F d" msgid "g A l F d"
msgstr "" msgstr ""
#: src/Model/Profile.php:651 #: src/Model/Profile.php:649
msgid "[No description]" msgid "[No description]"
msgstr "" msgstr ""
#: src/Model/Profile.php:677 #: src/Model/Profile.php:675
msgid "Event Reminders" msgid "Event Reminders"
msgstr "" msgstr ""
#: src/Model/Profile.php:678 #: src/Model/Profile.php:676
msgid "Upcoming events the next 7 days:" msgid "Upcoming events the next 7 days:"
msgstr "" msgstr ""
#: src/Model/Profile.php:875 #: src/Model/Profile.php:873
#, php-format #, php-format
msgid "OpenWebAuth: %1$s welcomes %2$s" msgid "OpenWebAuth: %1$s welcomes %2$s"
msgstr "" msgstr ""
#: src/Model/Profile.php:1015 #: src/Model/Profile.php:1013
msgid "Hometown:" msgid "Hometown:"
msgstr "" msgstr ""
#: src/Model/Profile.php:1016 #: src/Model/Profile.php:1014
msgid "Marital Status:" msgid "Marital Status:"
msgstr "" msgstr ""
#: src/Model/Profile.php:1017 #: src/Model/Profile.php:1015
msgid "With:" msgid "With:"
msgstr "" msgstr ""
#: src/Model/Profile.php:1018 #: src/Model/Profile.php:1016
msgid "Since:" msgid "Since:"
msgstr "" msgstr ""
#: src/Model/Profile.php:1019 #: src/Model/Profile.php:1017
msgid "Sexual Preference:" msgid "Sexual Preference:"
msgstr "" msgstr ""
#: src/Model/Profile.php:1020 #: src/Model/Profile.php:1018
msgid "Political Views:" msgid "Political Views:"
msgstr "" msgstr ""
#: src/Model/Profile.php:1021 #: src/Model/Profile.php:1019
msgid "Religious Views:" msgid "Religious Views:"
msgstr "" msgstr ""
#: src/Model/Profile.php:1022 #: src/Model/Profile.php:1020
msgid "Likes:" msgid "Likes:"
msgstr "" msgstr ""
#: src/Model/Profile.php:1023 #: src/Model/Profile.php:1021
msgid "Dislikes:" msgid "Dislikes:"
msgstr "" msgstr ""
#: src/Model/Profile.php:1024 #: src/Model/Profile.php:1022
msgid "Title/Description:" msgid "Title/Description:"
msgstr "" 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/Report/Create.php:280
#: src/Module/Moderation/Summary.php:77 #: src/Module/Moderation/Summary.php:77
msgid "Summary" msgid "Summary"
msgstr "" msgstr ""
#: src/Model/Profile.php:1026 #: src/Model/Profile.php:1024
msgid "Musical interests" msgid "Musical interests"
msgstr "" msgstr ""
#: src/Model/Profile.php:1027 #: src/Model/Profile.php:1025
msgid "Books, literature" msgid "Books, literature"
msgstr "" msgstr ""
#: src/Model/Profile.php:1028 #: src/Model/Profile.php:1026
msgid "Television" msgid "Television"
msgstr "" msgstr ""
#: src/Model/Profile.php:1029 #: src/Model/Profile.php:1027
msgid "Film/dance/culture/entertainment" msgid "Film/dance/culture/entertainment"
msgstr "" msgstr ""
#: src/Model/Profile.php:1030 #: src/Model/Profile.php:1028
msgid "Hobbies/Interests" msgid "Hobbies/Interests"
msgstr "" msgstr ""
#: src/Model/Profile.php:1031 #: src/Model/Profile.php:1029
msgid "Love/romance" msgid "Love/romance"
msgstr "" msgstr ""
#: src/Model/Profile.php:1032 #: src/Model/Profile.php:1030
msgid "Work/employment" msgid "Work/employment"
msgstr "" msgstr ""
#: src/Model/Profile.php:1033 #: src/Model/Profile.php:1031
msgid "School/education" msgid "School/education"
msgstr "" msgstr ""
#: src/Model/Profile.php:1034 #: src/Model/Profile.php:1032
msgid "Contact information and Social Networks" msgid "Contact information and Social Networks"
msgstr "" 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." msgid "SERIOUS ERROR: Generation of security keys failed."
msgstr "" msgstr ""
#: src/Model/User.php:601 src/Model/User.php:634 #: src/Model/User.php:602 src/Model/User.php:635
msgid "Login failed" msgid "Login failed"
msgstr "" msgstr ""
#: src/Model/User.php:666 #: src/Model/User.php:667
msgid "Not enough information to authenticate" msgid "Not enough information to authenticate"
msgstr "" msgstr ""
#: src/Model/User.php:787 #: src/Model/User.php:788
msgid "Password can't be empty" msgid "Password can't be empty"
msgstr "" msgstr ""
#: src/Model/User.php:829 #: src/Model/User.php:830
msgid "Empty passwords are not allowed." msgid "Empty passwords are not allowed."
msgstr "" msgstr ""
#: src/Model/User.php:833 #: src/Model/User.php:834
msgid "" msgid ""
"The new password has been exposed in a public data dump, please choose " "The new password has been exposed in a public data dump, please choose "
"another." "another."
msgstr "" msgstr ""
#: src/Model/User.php:837 #: src/Model/User.php:838
msgid "The password length is limited to 72 characters." msgid "The password length is limited to 72 characters."
msgstr "" msgstr ""
#: src/Model/User.php:841 #: src/Model/User.php:842
msgid "The password can't contain white spaces nor accentuated letters" msgid "The password can't contain white spaces nor accentuated letters"
msgstr "" msgstr ""
#: src/Model/User.php:1050 #: src/Model/User.php:1051
msgid "Passwords do not match. Password unchanged." msgid "Passwords do not match. Password unchanged."
msgstr "" msgstr ""
#: src/Model/User.php:1057 #: src/Model/User.php:1058
msgid "An invitation is required." msgid "An invitation is required."
msgstr "" msgstr ""
#: src/Model/User.php:1061 #: src/Model/User.php:1062
msgid "Invitation could not be verified." msgid "Invitation could not be verified."
msgstr "" msgstr ""
#: src/Model/User.php:1069 #: src/Model/User.php:1070
msgid "Invalid OpenID url" msgid "Invalid OpenID url"
msgstr "" msgstr ""
#: src/Model/User.php:1082 src/Security/Authentication.php:241 #: src/Model/User.php:1083 src/Security/Authentication.php:241
msgid "" msgid ""
"We encountered a problem while logging in with the OpenID you provided. " "We encountered a problem while logging in with the OpenID you provided. "
"Please check the correct spelling of the ID." "Please check the correct spelling of the ID."
msgstr "" 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:" msgid "The error message was:"
msgstr "" msgstr ""
#: src/Model/User.php:1088 #: src/Model/User.php:1089
msgid "Please enter the required information." msgid "Please enter the required information."
msgstr "" msgstr ""
#: src/Model/User.php:1102 #: src/Model/User.php:1103
#, php-format #, php-format
msgid "" msgid ""
"system.username_min_length (%s) and system.username_max_length (%s) are " "system.username_min_length (%s) and system.username_max_length (%s) are "
"excluding each other, swapping values." "excluding each other, swapping values."
msgstr "" msgstr ""
#: src/Model/User.php:1109 #: src/Model/User.php:1110
#, php-format #, php-format
msgid "Username should be at least %s character." msgid "Username should be at least %s character."
msgid_plural "Username should be at least %s characters." msgid_plural "Username should be at least %s characters."
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#: src/Model/User.php:1113 #: src/Model/User.php:1114
#, php-format #, php-format
msgid "Username should be at most %s character." msgid "Username should be at most %s character."
msgid_plural "Username should be at most %s characters." msgid_plural "Username should be at most %s characters."
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#: src/Model/User.php:1121 #: src/Model/User.php:1122
msgid "That doesn't appear to be your full (First Last) name." msgid "That doesn't appear to be your full (First Last) name."
msgstr "" msgstr ""
#: src/Model/User.php:1126 #: src/Model/User.php:1127
msgid "Your email domain is not among those allowed on this site." msgid "Your email domain is not among those allowed on this site."
msgstr "" msgstr ""
#: src/Model/User.php:1130 #: src/Model/User.php:1131
msgid "Not a valid email address." msgid "Not a valid email address."
msgstr "" msgstr ""
#: src/Model/User.php:1133 #: src/Model/User.php:1134
msgid "The nickname was blocked from registration by the nodes admin." msgid "The nickname was blocked from registration by the nodes admin."
msgstr "" 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." msgid "Cannot use that email."
msgstr "" msgstr ""
#: src/Model/User.php:1149 #: src/Model/User.php:1150
msgid "Your nickname can only contain a-z, 0-9 and _." msgid "Your nickname can only contain a-z, 0-9 and _."
msgstr "" 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." msgid "Nickname is already registered. Please choose another."
msgstr "" 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." msgid "An error occurred during registration. Please try again."
msgstr "" msgstr ""
#: src/Model/User.php:1228 #: src/Model/User.php:1229
msgid "An error occurred creating your default profile. Please try again." msgid "An error occurred creating your default profile. Please try again."
msgstr "" msgstr ""
#: src/Model/User.php:1235 #: src/Model/User.php:1236
msgid "An error occurred creating your self contact. Please try again." msgid "An error occurred creating your self contact. Please try again."
msgstr "" msgstr ""
#: src/Model/User.php:1240 #: src/Model/User.php:1241
msgid "Friends" msgid "Friends"
msgstr "" msgstr ""
#: src/Model/User.php:1244 #: src/Model/User.php:1245
msgid "" msgid ""
"An error occurred creating your default contact circle. Please try again." "An error occurred creating your default contact circle. Please try again."
msgstr "" msgstr ""
#: src/Model/User.php:1288 #: src/Model/User.php:1289
msgid "Profile Photos" msgid "Profile Photos"
msgstr "" msgstr ""
#: src/Model/User.php:1483 #: src/Model/User.php:1469
#, php-format #, php-format
msgid "" msgid ""
"\n" "\n"
@ -3605,7 +3623,7 @@ msgid ""
"\t\t\tthe administrator of %2$s has set up an account for you." "\t\t\tthe administrator of %2$s has set up an account for you."
msgstr "" msgstr ""
#: src/Model/User.php:1486 #: src/Model/User.php:1472
#, php-format #, php-format
msgid "" msgid ""
"\n" "\n"
@ -3643,12 +3661,12 @@ msgid ""
"\t\tThank you and welcome to %4$s." "\t\tThank you and welcome to %4$s."
msgstr "" msgstr ""
#: src/Model/User.php:1519 src/Model/User.php:1626 #: src/Model/User.php:1505 src/Model/User.php:1612
#, php-format #, php-format
msgid "Registration details for %s" msgid "Registration details for %s"
msgstr "" msgstr ""
#: src/Model/User.php:1539 #: src/Model/User.php:1525
#, php-format #, php-format
msgid "" msgid ""
"\n" "\n"
@ -3664,12 +3682,12 @@ msgid ""
"\t\t" "\t\t"
msgstr "" msgstr ""
#: src/Model/User.php:1558 #: src/Model/User.php:1544
#, php-format #, php-format
msgid "Registration at %s" msgid "Registration at %s"
msgstr "" msgstr ""
#: src/Model/User.php:1582 #: src/Model/User.php:1568
#, php-format #, php-format
msgid "" msgid ""
"\n" "\n"
@ -3678,7 +3696,7 @@ msgid ""
"\t\t\t" "\t\t\t"
msgstr "" msgstr ""
#: src/Model/User.php:1590 #: src/Model/User.php:1576
#, php-format #, php-format
msgid "" msgid ""
"\n" "\n"
@ -5039,7 +5057,7 @@ msgid ""
"received." "received."
msgstr "" msgstr ""
#: src/Module/Admin/Site.php:513 src/Module/Contact/Profile.php:286 #: src/Module/Admin/Site.php:513 src/Module/Contact/Profile.php:305
#: src/Module/Settings/TwoFactor/Index.php:125 #: src/Module/Settings/TwoFactor/Index.php:125
msgid "Disabled" msgid "Disabled"
msgstr "" msgstr ""
@ -5185,9 +5203,9 @@ msgstr ""
#: src/Module/Admin/Summary.php:98 #: src/Module/Admin/Summary.php:98
msgid "" msgid ""
"The last update failed. Please run \"php bin/console.php dbstructure update" "The last update failed. Please run \"php bin/console.php dbstructure "
"\" from the command line and have a look at the errors that might appear. " "update\" from the command line and have a look at the errors that might "
"(Some of the errors are possibly inside the logfile.)" "appear. (Some of the errors are possibly inside the logfile.)"
msgstr "" msgstr ""
#: src/Module/Admin/Summary.php:102 #: src/Module/Admin/Summary.php:102
@ -5338,8 +5356,8 @@ msgstr ""
#, php-format #, php-format
msgid "" msgid ""
"Show some informations regarding the needed information to operate the node " "Show some informations regarding the needed information to operate the node "
"according e.g. to <a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer" "according e.g. to <a href=\"%s\" target=\"_blank\" rel=\"noopener "
"\">EU-GDPR</a>." "noreferrer\">EU-GDPR</a>."
msgstr "" msgstr ""
#: src/Module/Admin/Tos.php:81 #: src/Module/Admin/Tos.php:81
@ -5628,11 +5646,15 @@ msgstr ""
msgid "Connected apps" msgid "Connected apps"
msgstr "" msgstr ""
#: src/Module/BaseSettings.php:155 src/Module/Settings/UserExport.php:98 #: src/Module/BaseSettings.php:155
msgid "Remote servers"
msgstr ""
#: src/Module/BaseSettings.php:162 src/Module/Settings/UserExport.php:98
msgid "Export personal data" msgid "Export personal data"
msgstr "" msgstr ""
#: src/Module/BaseSettings.php:162 #: src/Module/BaseSettings.php:169
msgid "Remove account" msgid "Remove account"
msgstr "" msgstr ""
@ -5778,8 +5800,8 @@ msgstr ""
#: src/Module/Contact/Conversations.php:89 #: src/Module/Contact/Conversations.php:89
#: src/Module/Contact/Conversations.php:94 src/Module/Contact/Media.php:43 #: src/Module/Contact/Conversations.php:94 src/Module/Contact/Media.php:43
#: src/Module/Contact/Posts.php:78 src/Module/Contact/Posts.php:83 #: src/Module/Contact/Posts.php:78 src/Module/Contact/Posts.php:83
#: src/Module/Contact/Posts.php:88 src/Module/Contact/Profile.php:142 #: src/Module/Contact/Posts.php:88 src/Module/Contact/Profile.php:150
#: src/Module/Contact/Profile.php:147 src/Module/Contact/Profile.php:152 #: src/Module/Contact/Profile.php:155 src/Module/Contact/Profile.php:160
#: src/Module/Contact/Redir.php:94 src/Module/Contact/Redir.php:140 #: src/Module/Contact/Redir.php:94 src/Module/Contact/Redir.php:140
#: src/Module/FriendSuggest.php:71 src/Module/FriendSuggest.php:109 #: src/Module/FriendSuggest.php:71 src/Module/FriendSuggest.php:109
msgid "Contact not found." msgid "Contact not found."
@ -5888,7 +5910,7 @@ msgid "Only show blocked contacts"
msgstr "" msgstr ""
#: src/Module/Contact.php:369 src/Module/Contact.php:441 #: src/Module/Contact.php:369 src/Module/Contact.php:441
#: src/Object/Post.php:362 #: src/Module/Settings/Server/Index.php:107 src/Object/Post.php:368
msgid "Ignored" msgid "Ignored"
msgstr "" msgstr ""
@ -5937,18 +5959,18 @@ msgstr ""
msgid "Update" msgid "Update"
msgstr "" msgstr ""
#: src/Module/Contact.php:468 src/Module/Contact/Profile.php:477 #: src/Module/Contact.php:468 src/Module/Contact/Profile.php:498
#: src/Module/Moderation/Blocklist/Contact.php:117 #: src/Module/Moderation/Blocklist/Contact.php:117
#: src/Module/Moderation/Users/Blocked.php:138 #: src/Module/Moderation/Users/Blocked.php:138
#: src/Module/Moderation/Users/Index.php:154 #: src/Module/Moderation/Users/Index.php:154
msgid "Unblock" msgid "Unblock"
msgstr "" msgstr ""
#: src/Module/Contact.php:469 src/Module/Contact/Profile.php:485 #: src/Module/Contact.php:469 src/Module/Contact/Profile.php:506
msgid "Unignore" msgid "Unignore"
msgstr "" msgstr ""
#: src/Module/Contact.php:470 src/Module/Contact/Profile.php:493 #: src/Module/Contact.php:470 src/Module/Contact/Profile.php:514
msgid "Uncollapse" msgid "Uncollapse"
msgstr "" msgstr ""
@ -6000,7 +6022,7 @@ msgstr ""
msgid "Pending incoming contact request" msgid "Pending incoming contact request"
msgstr "" msgstr ""
#: src/Module/Contact.php:627 src/Module/Contact/Profile.php:346 #: src/Module/Contact.php:627 src/Module/Contact/Profile.php:365
#, php-format #, php-format
msgid "Visit %s's profile [%s]" msgid "Visit %s's profile [%s]"
msgstr "" msgstr ""
@ -6135,7 +6157,7 @@ msgstr ""
msgid "Your Identity Address:" msgid "Your Identity Address:"
msgstr "" msgstr ""
#: src/Module/Contact/Follow.php:170 src/Module/Contact/Profile.php:375 #: src/Module/Contact/Follow.php:170 src/Module/Contact/Profile.php:396
#: src/Module/Contact/Unfollow.php:129 #: src/Module/Contact/Unfollow.php:129
#: src/Module/Moderation/Blocklist/Contact.php:133 #: src/Module/Moderation/Blocklist/Contact.php:133
#: src/Module/Notifications/Introductions.php:129 #: src/Module/Notifications/Introductions.php:129
@ -6143,7 +6165,7 @@ msgstr ""
msgid "Profile URL" msgid "Profile URL"
msgstr "" msgstr ""
#: src/Module/Contact/Follow.php:171 src/Module/Contact/Profile.php:387 #: src/Module/Contact/Follow.php:171 src/Module/Contact/Profile.php:408
#: src/Module/Notifications/Introductions.php:191 #: src/Module/Notifications/Introductions.php:191
#: src/Module/Profile/Profile.php:234 #: src/Module/Profile/Profile.php:234
msgid "Tags:" msgid "Tags:"
@ -6182,249 +6204,257 @@ msgstr ""
msgid "Profile Match" msgid "Profile Match"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:128 #: src/Module/Contact/Profile.php:136
msgid "Failed to update contact record." msgid "Failed to update contact record."
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:178 #: src/Module/Contact/Profile.php:186
msgid "Contact has been unblocked" msgid "Contact has been unblocked"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:182 #: src/Module/Contact/Profile.php:190
msgid "Contact has been blocked" msgid "Contact has been blocked"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:194 #: src/Module/Contact/Profile.php:202
msgid "Contact has been unignored" msgid "Contact has been unignored"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:198 #: src/Module/Contact/Profile.php:206
msgid "Contact has been ignored" msgid "Contact has been ignored"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:210 #: src/Module/Contact/Profile.php:218
msgid "Contact has been uncollapsed" msgid "Contact has been uncollapsed"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:214 #: src/Module/Contact/Profile.php:222
msgid "Contact has been collapsed" msgid "Contact has been collapsed"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:242 #: src/Module/Contact/Profile.php:250
#, php-format #, php-format
msgid "You are mutual friends with %s" msgid "You are mutual friends with %s"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:243 #: src/Module/Contact/Profile.php:251
#, php-format #, php-format
msgid "You are sharing with %s" msgid "You are sharing with %s"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:244 #: src/Module/Contact/Profile.php:252
#, php-format #, php-format
msgid "%s is sharing with you" msgid "%s is sharing with you"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:260 #: src/Module/Contact/Profile.php:268
msgid "Private communications are not available for this contact." msgid "Private communications are not available for this contact."
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:262 #: src/Module/Contact/Profile.php:278
msgid "This contact is on a server you ignored."
msgstr ""
#: src/Module/Contact/Profile.php:281
msgid "Never" msgid "Never"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:265 #: src/Module/Contact/Profile.php:284
msgid "(Update was not successful)" msgid "(Update was not successful)"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:265 #: src/Module/Contact/Profile.php:284
msgid "(Update was successful)" msgid "(Update was successful)"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:267 src/Module/Contact/Profile.php:448 #: src/Module/Contact/Profile.php:286 src/Module/Contact/Profile.php:469
msgid "Suggest friends" msgid "Suggest friends"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:271 #: src/Module/Contact/Profile.php:290
#, php-format #, php-format
msgid "Network type: %s" msgid "Network type: %s"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:276 #: src/Module/Contact/Profile.php:295
msgid "Communications lost with this contact!" msgid "Communications lost with this contact!"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:282 #: src/Module/Contact/Profile.php:301
msgid "Fetch further information for feeds" msgid "Fetch further information for feeds"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:284 #: src/Module/Contact/Profile.php:303
msgid "" msgid ""
"Fetch information like preview pictures, title and teaser from the feed " "Fetch information like preview pictures, title and teaser from the feed "
"item. You can activate this if the feed doesn't contain much text. Keywords " "item. You can activate this if the feed doesn't contain much text. Keywords "
"are taken from the meta header in the feed item and are posted as hash tags." "are taken from the meta header in the feed item and are posted as hash tags."
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:287 #: src/Module/Contact/Profile.php:306
msgid "Fetch information" msgid "Fetch information"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:288 #: src/Module/Contact/Profile.php:307
msgid "Fetch keywords" msgid "Fetch keywords"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:289 #: src/Module/Contact/Profile.php:308
msgid "Fetch information and keywords" msgid "Fetch information and keywords"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:299 src/Module/Contact/Profile.php:304 #: src/Module/Contact/Profile.php:318 src/Module/Contact/Profile.php:323
#: src/Module/Contact/Profile.php:309 src/Module/Contact/Profile.php:315 #: src/Module/Contact/Profile.php:328 src/Module/Contact/Profile.php:334
msgid "No mirroring" msgid "No mirroring"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:300 src/Module/Contact/Profile.php:310 #: src/Module/Contact/Profile.php:319 src/Module/Contact/Profile.php:329
#: src/Module/Contact/Profile.php:316 #: src/Module/Contact/Profile.php:335
msgid "Mirror as my own posting" msgid "Mirror as my own posting"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:305 src/Module/Contact/Profile.php:311 #: src/Module/Contact/Profile.php:324 src/Module/Contact/Profile.php:330
msgid "Native reshare" msgid "Native reshare"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:328 #: src/Module/Contact/Profile.php:347
msgid "Contact Information / Notes" msgid "Contact Information / Notes"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:329 #: src/Module/Contact/Profile.php:348
msgid "Contact Settings" msgid "Contact Settings"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:337 #: src/Module/Contact/Profile.php:356
msgid "Contact" msgid "Contact"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:341 #: src/Module/Contact/Profile.php:360
msgid "Their personal note" msgid "Their personal note"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:343 #: src/Module/Contact/Profile.php:362
msgid "Edit contact notes" msgid "Edit contact notes"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:347 #: src/Module/Contact/Profile.php:366
msgid "Block/Unblock contact" msgid "Block/Unblock contact"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:348 #: src/Module/Contact/Profile.php:367
#: src/Module/Moderation/Report/Create.php:293 #: src/Module/Moderation/Report/Create.php:293
msgid "Ignore contact" msgid "Ignore contact"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:349 #: src/Module/Contact/Profile.php:368
msgid "View conversations" msgid "View conversations"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:354 #: src/Module/Contact/Profile.php:373
msgid "Last update:" msgid "Last update:"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:356 #: src/Module/Contact/Profile.php:375
msgid "Update public posts" msgid "Update public posts"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:358 src/Module/Contact/Profile.php:458 #: src/Module/Contact/Profile.php:377 src/Module/Contact/Profile.php:479
msgid "Update now" msgid "Update now"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:360 #: src/Module/Contact/Profile.php:379
msgid "Awaiting connection acknowledge" msgid "Awaiting connection acknowledge"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:361 #: src/Module/Contact/Profile.php:380
msgid "Currently blocked" msgid "Currently blocked"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:362 #: src/Module/Contact/Profile.php:381
msgid "Currently ignored" msgid "Currently ignored"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:363 #: src/Module/Contact/Profile.php:382
msgid "Currently collapsed" msgid "Currently collapsed"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:364 #: src/Module/Contact/Profile.php:383
msgid "Currently archived" msgid "Currently archived"
msgstr "" 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 #: src/Module/Notifications/Introductions.php:192
msgid "Hide this contact from others" msgid "Hide this contact from others"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:367 #: src/Module/Contact/Profile.php:388
msgid "" msgid ""
"Replies/likes to your public posts <strong>may</strong> still be visible" "Replies/likes to your public posts <strong>may</strong> still be visible"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:368 #: src/Module/Contact/Profile.php:389
msgid "Notification for new posts" msgid "Notification for new posts"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:368 #: src/Module/Contact/Profile.php:389
msgid "Send a notification of every new post of this contact" msgid "Send a notification of every new post of this contact"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:370 #: src/Module/Contact/Profile.php:391
msgid "Keyword Deny List" msgid "Keyword Deny List"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:370 #: src/Module/Contact/Profile.php:391
msgid "" msgid ""
"Comma separated list of keywords that should not be converted to hashtags, " "Comma separated list of keywords that should not be converted to hashtags, "
"when \"Fetch information and keywords\" is selected" "when \"Fetch information and keywords\" is selected"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:388 #: src/Module/Contact/Profile.php:409
#: src/Module/Settings/TwoFactor/Index.php:139 #: src/Module/Settings/TwoFactor/Index.php:139
msgid "Actions" msgid "Actions"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:390 #: src/Module/Contact/Profile.php:411
#: src/Module/Settings/TwoFactor/Index.php:119 view/theme/frio/theme.php:229 #: src/Module/Settings/TwoFactor/Index.php:119 view/theme/frio/theme.php:229
msgid "Status" msgid "Status"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:396 #: src/Module/Contact/Profile.php:417
msgid "Mirror postings from this contact" msgid "Mirror postings from this contact"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:398 #: src/Module/Contact/Profile.php:419
msgid "" msgid ""
"Mark this contact as remote_self, this will cause friendica to repost new " "Mark this contact as remote_self, this will cause friendica to repost new "
"entries from this contact." "entries from this contact."
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:468 #: src/Module/Contact/Profile.php:489
msgid "Refetch contact data" msgid "Refetch contact data"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:479 #: src/Module/Contact/Profile.php:500
msgid "Toggle Blocked status" msgid "Toggle Blocked status"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:487 #: src/Module/Contact/Profile.php:508
msgid "Toggle Ignored status" msgid "Toggle Ignored status"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:495 #: src/Module/Contact/Profile.php:516
msgid "Toggle Collapsed status" msgid "Toggle Collapsed status"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:502 src/Module/Contact/Revoke.php:106 #: src/Module/Contact/Profile.php:523 src/Module/Contact/Revoke.php:106
msgid "Revoke Follow" msgid "Revoke Follow"
msgstr "" msgstr ""
#: src/Module/Contact/Profile.php:504 #: src/Module/Contact/Profile.php:525
msgid "Revoke the follow from this contact" msgid "Revoke the follow from this contact"
msgstr "" msgstr ""
@ -6564,7 +6594,7 @@ msgid "Sort by post creation date"
msgstr "" msgstr ""
#: src/Module/Conversation/Network.php:281 #: src/Module/Conversation/Network.php:281
#: src/Module/Settings/Profile/Index.php:235 #: src/Module/Settings/Profile/Index.php:260
msgid "Personal" msgid "Personal"
msgstr "" msgstr ""
@ -6572,7 +6602,7 @@ msgstr ""
msgid "Posts that mention or involve you" msgid "Posts that mention or involve you"
msgstr "" msgstr ""
#: src/Module/Conversation/Network.php:289 src/Object/Post.php:374 #: src/Module/Conversation/Network.php:289 src/Object/Post.php:380
msgid "Starred" msgid "Starred"
msgstr "" msgstr ""
@ -6796,7 +6826,7 @@ msgid "Twitter Source / Tweet URL (requires API key)"
msgstr "" msgstr ""
#: src/Module/Debug/Feed.php:52 src/Module/Filer/SaveTag.php:47 #: 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" msgid "You must be logged in to use this module"
msgstr "" msgstr ""
@ -6938,42 +6968,42 @@ msgstr ""
msgid "Read about the <a href=\"%1$s/tos\">Terms of Service</a> of this node." msgid "Read about the <a href=\"%1$s/tos\">Terms of Service</a> of this node."
msgstr "" msgstr ""
#: src/Module/Friendica.php:100 #: src/Module/Friendica.php:99
msgid "On this server the following remote servers are blocked." msgid "On this server the following remote servers are blocked."
msgstr "" msgstr ""
#: src/Module/Friendica.php:103 #: src/Module/Friendica.php:102
#: src/Module/Moderation/Blocklist/Server/Index.php:87 #: src/Module/Moderation/Blocklist/Server/Index.php:87
#: src/Module/Moderation/Blocklist/Server/Index.php:111 #: src/Module/Moderation/Blocklist/Server/Index.php:111
msgid "Reason for the block" msgid "Reason for the block"
msgstr "" msgstr ""
#: src/Module/Friendica.php:105 #: src/Module/Friendica.php:104
msgid "Download this list in CSV format" msgid "Download this list in CSV format"
msgstr "" msgstr ""
#: src/Module/Friendica.php:119 #: src/Module/Friendica.php:118
#, php-format #, php-format
msgid "" msgid ""
"This is Friendica, version %s that is running at the web location %s. The " "This is Friendica, version %s that is running at the web location %s. The "
"database version is %s, the post update version is %s." "database version is %s, the post update version is %s."
msgstr "" msgstr ""
#: src/Module/Friendica.php:124 #: src/Module/Friendica.php:123
msgid "" msgid ""
"Please visit <a href=\"https://friendi.ca\">Friendi.ca</a> to learn more " "Please visit <a href=\"https://friendi.ca\">Friendi.ca</a> to learn more "
"about the Friendica project." "about the Friendica project."
msgstr "" msgstr ""
#: src/Module/Friendica.php:125 #: src/Module/Friendica.php:124
msgid "Bug reports and issues: please visit" msgid "Bug reports and issues: please visit"
msgstr "" msgstr ""
#: src/Module/Friendica.php:125 #: src/Module/Friendica.php:124
msgid "the bugtracker at github" msgid "the bugtracker at github"
msgstr "" msgstr ""
#: src/Module/Friendica.php:126 #: src/Module/Friendica.php:125
msgid "" msgid ""
"Suggestions, praise, etc. - please email \"info\" at \"friendi - dot - ca" "Suggestions, praise, etc. - please email \"info\" at \"friendi - dot - ca"
msgstr "" msgstr ""
@ -7288,10 +7318,6 @@ msgid ""
"<a href=\"/settings/display\">Theme Customization settings</a>." "<a href=\"/settings/display\">Theme Customization settings</a>."
msgstr "" msgstr ""
#: src/Module/Item/Display.php:136 src/Module/Update/Display.php:55
msgid "The requested item doesn't exist or has been deleted."
msgstr ""
#: src/Module/Item/Feed.php:86 #: src/Module/Item/Feed.php:86
msgid "The feed for this item is unavailable." msgid "The feed for this item is unavailable."
msgstr "" msgstr ""
@ -7550,6 +7576,8 @@ msgid "Matching known servers"
msgstr "" msgstr ""
#: src/Module/Moderation/Blocklist/Server/Add.php:130 #: src/Module/Moderation/Blocklist/Server/Add.php:130
#: src/Module/Settings/Server/Action.php:76
#: src/Module/Settings/Server/Index.php:106
msgid "Server Name" msgid "Server Name"
msgstr "" msgstr ""
@ -8520,21 +8548,21 @@ msgstr ""
msgid "<b>Attributed To:</b> %s<br>" msgid "<b>Attributed To:</b> %s<br>"
msgstr "" msgstr ""
#: src/Module/Photo.php:129 #: src/Module/Photo.php:130
msgid "The Photo is not available." msgid "The Photo is not available."
msgstr "" msgstr ""
#: src/Module/Photo.php:154 #: src/Module/Photo.php:155
#, php-format #, php-format
msgid "The Photo with id %s is not available." msgid "The Photo with id %s is not available."
msgstr "" msgstr ""
#: src/Module/Photo.php:191 #: src/Module/Photo.php:192
#, php-format #, php-format
msgid "Invalid external resource with url %s." msgid "Invalid external resource with url %s."
msgstr "" msgstr ""
#: src/Module/Photo.php:193 #: src/Module/Photo.php:194
#, php-format #, php-format
msgid "Invalid photo with id %s." msgid "Invalid photo with id %s."
msgstr "" msgstr ""
@ -8586,20 +8614,20 @@ msgstr ""
#: src/Module/Profile/Conversations.php:106 #: src/Module/Profile/Conversations.php:106
#: src/Module/Profile/Conversations.php:109 src/Module/Profile/Profile.php:351 #: 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 #: src/Protocol/OStatus.php:1009
#, php-format #, php-format
msgid "%s's timeline" msgid "%s's timeline"
msgstr "" msgstr ""
#: src/Module/Profile/Conversations.php:107 src/Module/Profile/Profile.php:352 #: 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 #, php-format
msgid "%s's posts" msgid "%s's posts"
msgstr "" msgstr ""
#: src/Module/Profile/Conversations.php:108 src/Module/Profile/Profile.php:353 #: 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 #, php-format
msgid "%s's comments" msgid "%s's comments"
msgstr "" msgstr ""
@ -8640,11 +8668,11 @@ msgstr ""
#: src/Module/Profile/Profile.php:158 #: src/Module/Profile/Profile.php:158
#, php-format #, php-format
msgid "" msgid ""
"You're currently viewing your profile as <b>%s</b> <a href=\"%s\" class=" "You're currently viewing your profile as <b>%s</b> <a href=\"%s\" "
"\"btn btn-sm pull-right\">Cancel</a>" "class=\"btn btn-sm pull-right\">Cancel</a>"
msgstr "" msgstr ""
#: src/Module/Profile/Profile.php:167 src/Module/Settings/Account.php:576 #: src/Module/Profile/Profile.php:167
msgid "Full Name:" msgid "Full Name:"
msgstr "" msgstr ""
@ -8664,12 +8692,12 @@ msgstr ""
msgid "Birthday:" msgid "Birthday:"
msgstr "" 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 #: src/Util/Temporal.php:170
msgid "Age: " msgid "Age: "
msgstr "" 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 #: src/Util/Temporal.php:170
#, php-format #, php-format
msgid "%d year old" msgid "%d year old"
@ -8677,7 +8705,7 @@ msgid_plural "%d years old"
msgstr[0] "" msgstr[0] ""
msgstr[1] "" 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:" msgid "Description:"
msgstr "" msgstr ""
@ -9189,8 +9217,8 @@ msgstr ""
#: src/Module/Security/TwoFactor/Verify.php:100 #: src/Module/Security/TwoFactor/Verify.php:100
#, php-format #, php-format
msgid "" msgid ""
"If you do not have access to your authentication code you can use a <a href=" "If you do not have access to your authentication code you can use a <a "
"\"%s\">two-factor recovery code</a>." "href=\"%s\">two-factor recovery code</a>."
msgstr "" msgstr ""
#: src/Module/Security/TwoFactor/Verify.php:101 #: src/Module/Security/TwoFactor/Verify.php:101
@ -9362,6 +9390,11 @@ msgstr ""
msgid "Basic Settings" msgid "Basic Settings"
msgstr "" msgstr ""
#: src/Module/Settings/Account.php:576
#: src/Module/Settings/Profile/Index.php:283
msgid "Display name:"
msgstr ""
#: src/Module/Settings/Account.php:577 #: src/Module/Settings/Account.php:577
msgid "Email Address:" msgid "Email Address:"
msgstr "" msgstr ""
@ -10126,146 +10159,85 @@ msgstr ""
msgid "Remove authorization" msgid "Remove authorization"
msgstr "" msgstr ""
#: src/Module/Settings/Profile/Index.php:84 #: src/Module/Settings/Profile/Index.php:116
msgid "Profile Name is required." msgid "Display Name is required."
msgstr "" msgstr ""
#: src/Module/Settings/Profile/Index.php:134 #: src/Module/Settings/Profile/Index.php:167
msgid "Profile couldn't be updated." msgid "Profile couldn't be updated."
msgstr "" msgstr ""
#: src/Module/Settings/Profile/Index.php:175 #: src/Module/Settings/Profile/Index.php:205
#: src/Module/Settings/Profile/Index.php:195 #: src/Module/Settings/Profile/Index.php:226
msgid "Label:" msgid "Label:"
msgstr "" msgstr ""
#: src/Module/Settings/Profile/Index.php:176 #: src/Module/Settings/Profile/Index.php:206
#: src/Module/Settings/Profile/Index.php:196 #: src/Module/Settings/Profile/Index.php:227
msgid "Value:" msgid "Value:"
msgstr "" msgstr ""
#: src/Module/Settings/Profile/Index.php:186 #: src/Module/Settings/Profile/Index.php:217
#: src/Module/Settings/Profile/Index.php:206 #: src/Module/Settings/Profile/Index.php:238
msgid "Field Permissions" msgid "Field Permissions"
msgstr "" msgstr ""
#: src/Module/Settings/Profile/Index.php:187 #: src/Module/Settings/Profile/Index.php:218
#: src/Module/Settings/Profile/Index.php:207 #: src/Module/Settings/Profile/Index.php:239
msgid "(click to open/close)" msgid "(click to open/close)"
msgstr "" msgstr ""
#: src/Module/Settings/Profile/Index.php:193 #: src/Module/Settings/Profile/Index.php:224
msgid "Add a new profile field" msgid "Add a new profile field"
msgstr "" msgstr ""
#: src/Module/Settings/Profile/Index.php:216 #: src/Module/Settings/Profile/Index.php:247
msgid "" msgid ""
"The homepage is verified. A rel=\"me\" link back to your Friendica profile " "The homepage is verified. A rel=\"me\" link back to your Friendica profile "
"page was found on the homepage." "page was found on the homepage."
msgstr "" msgstr ""
#: src/Module/Settings/Profile/Index.php:218 #: src/Module/Settings/Profile/Index.php:249
#, php-format #, php-format
msgid "" msgid ""
"To verify your homepage, add a rel=\"me\" link to it, pointing to your " "To verify your homepage, add a rel=\"me\" link to it, pointing to your "
"profile URL (%s)." "profile URL (%s)."
msgstr "" msgstr ""
#: src/Module/Settings/Profile/Index.php:228 #: src/Module/Settings/Profile/Index.php:255
msgid "Profile Actions" msgid "Profile Actions"
msgstr "" msgstr ""
#: src/Module/Settings/Profile/Index.php:229 #: src/Module/Settings/Profile/Index.php:256
msgid "Edit Profile Details" msgid "Edit Profile Details"
msgstr "" msgstr ""
#: src/Module/Settings/Profile/Index.php:231 #: src/Module/Settings/Profile/Index.php:258
msgid "Change Profile Photo" msgid "Change Profile Photo"
msgstr "" msgstr ""
#: src/Module/Settings/Profile/Index.php:236 #: src/Module/Settings/Profile/Index.php:261
msgid "Profile picture" msgid "Profile picture"
msgstr "" msgstr ""
#: src/Module/Settings/Profile/Index.php:237 #: src/Module/Settings/Profile/Index.php:262
msgid "Location" msgid "Location"
msgstr "" 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 #: src/Util/Temporal.php:99
msgid "Miscellaneous" msgid "Miscellaneous"
msgstr "" msgstr ""
#: src/Module/Settings/Profile/Index.php:239 #: src/Module/Settings/Profile/Index.php:264
msgid "Custom Profile Fields" msgid "Custom Profile Fields"
msgstr "" 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" msgid "Upload Profile Photo"
msgstr "" msgstr ""
#: src/Module/Settings/Profile/Index.php:245 #: src/Module/Settings/Profile/Index.php:266
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
#, php-format #, php-format
msgid "" msgid ""
"<p>Custom fields appear on <a href=\"%s\">your profile page</a>.</p>\n" "<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>" "contacts or the Friendica contacts in the selected circles.</p>"
msgstr "" 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:107
#: src/Module/Settings/Profile/Photo/Crop.php:125 #: src/Module/Settings/Profile/Photo/Crop.php:125
#: src/Module/Settings/Profile/Photo/Crop.php:143 #: src/Module/Settings/Profile/Photo/Crop.php:143
@ -10386,6 +10415,42 @@ msgstr ""
msgid "Please enter your password for verification:" msgid "Please enter your password for verification:"
msgstr "" msgstr ""
#: src/Module/Settings/Server/Action.php:60
msgid "Do you want to ignore this server?"
msgstr ""
#: src/Module/Settings/Server/Action.php:64
msgid "Do you want to unignore this server?"
msgstr ""
#: src/Module/Settings/Server/Action.php:74
#: src/Module/Settings/Server/Index.php:104
msgid "Remote server settings"
msgstr ""
#: src/Module/Settings/Server/Action.php:77
msgid "Server URL"
msgstr ""
#: src/Module/Settings/Server/Index.php:78
msgid "Settings saved"
msgstr ""
#: src/Module/Settings/Server/Index.php:105
msgid ""
"Here you can find all the remote servers you have taken individual "
"moderation actions against. For a list of servers your node has blocked, "
"please check out the <a href=\"friendica\">Information</a> page."
msgstr ""
#: src/Module/Settings/Server/Index.php:110
msgid "Delete all your settings for the remote server"
msgstr ""
#: src/Module/Settings/Server/Index.php:111
msgid "Save changes"
msgstr ""
#: src/Module/Settings/TwoFactor/AppSpecific.php:66 #: src/Module/Settings/TwoFactor/AppSpecific.php:66
#: src/Module/Settings/TwoFactor/Recovery.php:64 #: src/Module/Settings/TwoFactor/Recovery.php:64
#: src/Module/Settings/TwoFactor/Trusted.php:67 #: src/Module/Settings/TwoFactor/Trusted.php:67
@ -10667,8 +10732,8 @@ msgstr ""
#: src/Module/Settings/TwoFactor/Verify.php:149 #: src/Module/Settings/TwoFactor/Verify.php:149
#, php-format #, php-format
msgid "" msgid ""
"<p>Or you can open the following URL in your mobile device:</p><p><a href=" "<p>Or you can open the following URL in your mobile device:</p><p><a "
"\"%s\">%s</a></p>" "href=\"%s\">%s</a></p>"
msgstr "" msgstr ""
#: src/Module/Settings/TwoFactor/Verify.php:156 #: src/Module/Settings/TwoFactor/Verify.php:156
@ -10706,22 +10771,41 @@ msgid ""
"e.g. Mastodon." "e.g. Mastodon."
msgstr "" msgstr ""
#: src/Module/Special/DisplayNotFound.php:35
msgid "The top-level post isn't visible."
msgstr ""
#: src/Module/Special/DisplayNotFound.php:36
msgid "The top-level post was deleted."
msgstr ""
#: src/Module/Special/DisplayNotFound.php:37 #: src/Module/Special/DisplayNotFound.php:37
msgid "Not Found" msgid ""
"This node has blocked the top-level author or the author of the shared post."
msgstr "" msgstr ""
#: src/Module/Special/DisplayNotFound.php:38 #: src/Module/Special/DisplayNotFound.php:38
msgid "" msgid ""
"<p>Unfortunately, the requested conversation isn't available to you.</p>\n" "You have ignored or blocked the top-level author or the author of the shared "
"<p>Possible reasons include:</p>\n" "post."
"<ul>\n" msgstr ""
"\t<li>The top-level post isn't visible.</li>\n"
"\t<li>The top-level post was deleted.</li>\n" #: src/Module/Special/DisplayNotFound.php:39
"\t<li>The node has blocked the top-level author or the author of the shared " msgid ""
"post.</li>\n" "You have ignored the top-level author's server or the shared post author's "
"\t<li>You have ignored or blocked the top-level author or the author of the " "server."
"shared post.</li>\n" msgstr ""
"</ul>"
#: src/Module/Special/DisplayNotFound.php:45
msgid "Conversation Not Found"
msgstr ""
#: src/Module/Special/DisplayNotFound.php:46
msgid "Unfortunately, the requested conversation isn't available to you."
msgstr ""
#: src/Module/Special/DisplayNotFound.php:47
msgid "Possible reasons include:"
msgstr "" msgstr ""
#: src/Module/Special/HTTPException.php:78 #: src/Module/Special/HTTPException.php:78
@ -10758,9 +10842,9 @@ msgstr ""
msgid "" msgid ""
"At any point in time a logged in user can export their account data from the " "At any point in time a logged in user can export their account data from the "
"<a href=\"%1$s/settings/userexport\">account settings</a>. If the user wants " "<a href=\"%1$s/settings/userexport\">account settings</a>. If the user wants "
"to delete their account they can do so at <a href=\"%1$s/settings/removeme\">" "to delete their account they can do so at <a href=\"%1$s/settings/"
"%1$s/settings/removeme</a>. The deletion of the account will be permanent. " "removeme\">%1$s/settings/removeme</a>. The deletion of the account will be "
"Deletion of the data will also be requested from the nodes of the " "permanent. Deletion of the data will also be requested from the nodes of the "
"communication partners." "communication partners."
msgstr "" msgstr ""
@ -10776,6 +10860,10 @@ msgstr ""
msgid "Parameter uri_id is missing." msgid "Parameter uri_id is missing."
msgstr "" msgstr ""
#: src/Module/Update/Display.php:55
msgid "The requested item doesn't exist or has been deleted."
msgstr ""
#: src/Module/User/Import.php:103 #: src/Module/User/Import.php:103
msgid "User imports on closed servers can only be done by an administrator." msgid "User imports on closed servers can only be done by an administrator."
msgstr "" msgstr ""
@ -11486,27 +11574,27 @@ msgstr ""
msgid "%s posted an update." msgid "%s posted an update."
msgstr "" msgstr ""
#: src/Object/Post.php:139 #: src/Object/Post.php:138
msgid "Private Message" msgid "Private Message"
msgstr "" msgstr ""
#: src/Object/Post.php:143 #: src/Object/Post.php:142
msgid "Public Message" msgid "Public Message"
msgstr "" msgstr ""
#: src/Object/Post.php:147 #: src/Object/Post.php:146
msgid "Unlisted Message" msgid "Unlisted Message"
msgstr "" msgstr ""
#: src/Object/Post.php:182 #: src/Object/Post.php:181
msgid "This entry was edited" msgid "This entry was edited"
msgstr "" msgstr ""
#: src/Object/Post.php:210 #: src/Object/Post.php:209
msgid "Connector Message" msgid "Connector Message"
msgstr "" msgstr ""
#: src/Object/Post.php:226 src/Object/Post.php:228 #: src/Object/Post.php:225 src/Object/Post.php:227
msgid "Edit" msgid "Edit"
msgstr "" msgstr ""
@ -11537,207 +11625,207 @@ msgstr ""
msgid "Report post" msgid "Report post"
msgstr "" msgstr ""
#: src/Object/Post.php:287 #: src/Object/Post.php:293
msgid "Save to folder" msgid "Save to folder"
msgstr "" msgstr ""
#: src/Object/Post.php:327 #: src/Object/Post.php:333
msgid "I will attend" msgid "I will attend"
msgstr "" msgstr ""
#: src/Object/Post.php:327 #: src/Object/Post.php:333
msgid "I will not attend" msgid "I will not attend"
msgstr "" msgstr ""
#: src/Object/Post.php:327 #: src/Object/Post.php:333
msgid "I might attend" msgid "I might attend"
msgstr "" msgstr ""
#: src/Object/Post.php:357 #: src/Object/Post.php:363
msgid "Ignore thread" msgid "Ignore thread"
msgstr "" msgstr ""
#: src/Object/Post.php:358 #: src/Object/Post.php:364
msgid "Unignore thread" msgid "Unignore thread"
msgstr "" msgstr ""
#: src/Object/Post.php:359 #: src/Object/Post.php:365
msgid "Toggle ignore status" msgid "Toggle ignore status"
msgstr "" msgstr ""
#: src/Object/Post.php:369 #: src/Object/Post.php:375
msgid "Add star" msgid "Add star"
msgstr "" msgstr ""
#: src/Object/Post.php:370 #: src/Object/Post.php:376
msgid "Remove star" msgid "Remove star"
msgstr "" msgstr ""
#: src/Object/Post.php:371 #: src/Object/Post.php:377
msgid "Toggle star status" msgid "Toggle star status"
msgstr "" msgstr ""
#: src/Object/Post.php:382 #: src/Object/Post.php:388
msgid "Pin" msgid "Pin"
msgstr "" msgstr ""
#: src/Object/Post.php:383 #: src/Object/Post.php:389
msgid "Unpin" msgid "Unpin"
msgstr "" msgstr ""
#: src/Object/Post.php:384 #: src/Object/Post.php:390
msgid "Toggle pin status" msgid "Toggle pin status"
msgstr "" msgstr ""
#: src/Object/Post.php:387 #: src/Object/Post.php:393
msgid "Pinned" msgid "Pinned"
msgstr "" msgstr ""
#: src/Object/Post.php:392 #: src/Object/Post.php:398
msgid "Add tag" msgid "Add tag"
msgstr "" msgstr ""
#: src/Object/Post.php:405 #: src/Object/Post.php:411
msgid "Quote share this" msgid "Quote share this"
msgstr "" msgstr ""
#: src/Object/Post.php:405 #: src/Object/Post.php:411
msgid "Quote Share" msgid "Quote Share"
msgstr "" msgstr ""
#: src/Object/Post.php:408 #: src/Object/Post.php:414
msgid "Reshare this" msgid "Reshare this"
msgstr "" msgstr ""
#: src/Object/Post.php:408 #: src/Object/Post.php:414
msgid "Reshare" msgid "Reshare"
msgstr "" msgstr ""
#: src/Object/Post.php:409 #: src/Object/Post.php:415
msgid "Cancel your Reshare" msgid "Cancel your Reshare"
msgstr "" msgstr ""
#: src/Object/Post.php:409 #: src/Object/Post.php:415
msgid "Unshare" msgid "Unshare"
msgstr "" msgstr ""
#: src/Object/Post.php:460 #: src/Object/Post.php:466
#, php-format #, php-format
msgid "%s (Received %s)" msgid "%s (Received %s)"
msgstr "" msgstr ""
#: src/Object/Post.php:466 #: src/Object/Post.php:472
msgid "Comment this item on your system" msgid "Comment this item on your system"
msgstr "" msgstr ""
#: src/Object/Post.php:466 #: src/Object/Post.php:472
msgid "Remote comment" msgid "Remote comment"
msgstr "" msgstr ""
#: src/Object/Post.php:488 #: src/Object/Post.php:494
msgid "Share via ..." msgid "Share via ..."
msgstr "" msgstr ""
#: src/Object/Post.php:488 #: src/Object/Post.php:494
msgid "Share via external services" msgid "Share via external services"
msgstr "" msgstr ""
#: src/Object/Post.php:517 #: src/Object/Post.php:523
msgid "to" msgid "to"
msgstr "" msgstr ""
#: src/Object/Post.php:518 #: src/Object/Post.php:524
msgid "via" msgid "via"
msgstr "" msgstr ""
#: src/Object/Post.php:519 #: src/Object/Post.php:525
msgid "Wall-to-Wall" msgid "Wall-to-Wall"
msgstr "" msgstr ""
#: src/Object/Post.php:520 #: src/Object/Post.php:526
msgid "via Wall-To-Wall:" msgid "via Wall-To-Wall:"
msgstr "" msgstr ""
#: src/Object/Post.php:566 #: src/Object/Post.php:573
#, php-format #, php-format
msgid "Reply to %s" msgid "Reply to %s"
msgstr "" msgstr ""
#: src/Object/Post.php:569 #: src/Object/Post.php:576
msgid "More" msgid "More"
msgstr "" msgstr ""
#: src/Object/Post.php:587 #: src/Object/Post.php:595
msgid "Notifier task is pending" msgid "Notifier task is pending"
msgstr "" msgstr ""
#: src/Object/Post.php:588 #: src/Object/Post.php:596
msgid "Delivery to remote servers is pending" msgid "Delivery to remote servers is pending"
msgstr "" msgstr ""
#: src/Object/Post.php:589 #: src/Object/Post.php:597
msgid "Delivery to remote servers is underway" msgid "Delivery to remote servers is underway"
msgstr "" msgstr ""
#: src/Object/Post.php:590 #: src/Object/Post.php:598
msgid "Delivery to remote servers is mostly done" msgid "Delivery to remote servers is mostly done"
msgstr "" msgstr ""
#: src/Object/Post.php:591 #: src/Object/Post.php:599
msgid "Delivery to remote servers is done" msgid "Delivery to remote servers is done"
msgstr "" msgstr ""
#: src/Object/Post.php:611 #: src/Object/Post.php:619
#, php-format #, php-format
msgid "%d comment" msgid "%d comment"
msgid_plural "%d comments" msgid_plural "%d comments"
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#: src/Object/Post.php:612 #: src/Object/Post.php:620
msgid "Show more" msgid "Show more"
msgstr "" msgstr ""
#: src/Object/Post.php:613 #: src/Object/Post.php:621
msgid "Show fewer" msgid "Show fewer"
msgstr "" msgstr ""
#: src/Object/Post.php:649 #: src/Object/Post.php:657
#, php-format #, php-format
msgid "Reshared by: %s" msgid "Reshared by: %s"
msgstr "" msgstr ""
#: src/Object/Post.php:654 #: src/Object/Post.php:662
#, php-format #, php-format
msgid "Viewed by: %s" msgid "Viewed by: %s"
msgstr "" msgstr ""
#: src/Object/Post.php:659 #: src/Object/Post.php:667
#, php-format #, php-format
msgid "Liked by: %s" msgid "Liked by: %s"
msgstr "" msgstr ""
#: src/Object/Post.php:664 #: src/Object/Post.php:672
#, php-format #, php-format
msgid "Disliked by: %s" msgid "Disliked by: %s"
msgstr "" msgstr ""
#: src/Object/Post.php:669 #: src/Object/Post.php:677
#, php-format #, php-format
msgid "Attended by: %s" msgid "Attended by: %s"
msgstr "" msgstr ""
#: src/Object/Post.php:674 #: src/Object/Post.php:682
#, php-format #, php-format
msgid "Maybe attended by: %s" msgid "Maybe attended by: %s"
msgstr "" msgstr ""
#: src/Object/Post.php:679 #: src/Object/Post.php:687
#, php-format #, php-format
msgid "Not attended by: %s" msgid "Not attended by: %s"
msgstr "" msgstr ""
#: src/Object/Post.php:684 #: src/Object/Post.php:692
#, php-format #, php-format
msgid "Reacted with %s by: %s" msgid "Reacted with %s by: %s"
msgstr "" msgstr ""

View file

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

View file

@ -1,121 +1,131 @@
<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"> <div id="profile-edit-links">
<ul> <ul>
<li><a href="settings/profile/photo" id="profile-photo_upload-link" title="{{$profpic}}">{{$profpic}}</a></li> <li><a class="btn" href="profile/{{$nickname}}/profile" id="profile-edit-view-link">{{$l10n.viewprof}}</a></li>
<li><a href="profile/{{$nickname}}/profile" id="profile-edit-view-link" title="{{$viewprof}}">{{$viewprof}}</a></li>
</ul> </ul>
</div> </div>
<div id="profile-edit-links-end"></div> <div id="profile-edit-links-end"></div>
<div id="profile-edit-wrapper"> <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}}"> <input type="hidden" name="form_security_token" value="{{$form_security_token}}">
<div id="profile-edit-name-wrapper"> <!-- Basic information -->
<label id="profile-edit-name-label" for="profile-edit-name">{{$name.1}} </label> <div class="toggle-section js-toggle-section">
<input type="text" size="32" name="name" id="profile-edit-name" value="{{$name.2}}"/> <h2><a class="section-caption js-section-toggler" href="javascript:;">{{$l10n.personal_section}} &raquo;</a></h2>
</div> <div class="js-section toggle-section-content hidden">
<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>
<div id="profile-edit-dob-wrapper">
{{$dob nofilter}}
</div>
<div id="profile-edit-dob-end"></div>
{{$hide_friends nofilter}}
<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-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>
<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> {{include file="field_input.tpl" field=$username}}
{{$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"> {{include file="field_textarea.tpl" field=$about}}
<input type="submit" name="submit" class="profile-edit-submit-button" value="{{$submit}}"/>
{{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">
<button type="submit" name="submit" class="profile-edit-submit-button">{{$l10n.submit}}</button>
</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:;">{{$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>
</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">
<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}}
{{include file="settings/profile/field/edit.tpl" profile_field=$custom_field}}
{{/foreach}}
</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> </div>
<div class="profile-edit-submit-end"></div>
</form> </form>
</div> </div>
<script type="text/javascript"> <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"> <div id="exception" class="generic-page-wrapper">
<img class="hare" src="images/friendica-404_svg_flexy-o-hare.png"/> <img class="hare" src="images/friendica-404_svg_flexy-o-hare.png"/>
<h1>{{$title}}</h1> <h1>{{$l10n.title}}</h1>
{{$message nofilter}} <p>{{$l10n.desc1}}</p>
<p>{{$l10n.desc2}}</p>
<ul>
{{foreach $l10n.reasons as $reason}}
<li>{{$reason}}</li>
{{/foreach}}
</ul>
</div> </div>

View file

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

View file

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

View file

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

View file

@ -1,18 +1,18 @@
<div class="generic-page-wrapper"> <div class="generic-page-wrapper">
<h1>{{$banner}}</h1> <h2>{{$l10n.banner}}</h2>
{{* The actions dropdown which can performed to the current profile *}} {{* The actions dropdown which can performed to the current profile *}}
<div id="profile-edit-links"> <div id="profile-edit-links">
<ul class="nav nav-pills preferences"> <ul class="nav nav-pills preferences">
<li class="dropdown pull-right"> <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"> <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> </button>
<ul class="dropdown-menu pull-right" role="menu" aria-labelledby="profile-edit-links-dropdown"> <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"><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" 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"><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" 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> </ul>
</li> </li>
</ul> </ul>
@ -26,12 +26,12 @@
<div id="profile-photo-upload-section" class="panel"> <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> <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"> <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" /> <input name="userfile" type="file" id="profile-photo-upload" size="48" />
</div> </div>
<div class="profile-edit-submit-wrapper pull-right"> <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>
<div class="clear"></div> <div class="clear"></div>
</div> </div>
@ -53,14 +53,14 @@
<div class="section-subtitle-wrapper panel-heading" role="tab" id="personal"> <div class="section-subtitle-wrapper panel-heading" role="tab" id="personal">
<h2> <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"> <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> </button>
</h2> </h2>
</div> </div>
{{* for the $detailed_profile we use bootstraps collapsable panel-groups to have expandable groups *}} {{* 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 id="personal-collapse" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="personal">
<div class="panel-body"> <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}} {{include file="field_textarea.tpl" field=$about}}
@ -69,7 +69,7 @@
{{$hide_friends nofilter}} {{$hide_friends nofilter}}
</div> </div>
<div class="panel-footer"> <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> </div>
</div> </div>
@ -79,7 +79,7 @@
<div class="section-subtitle-wrapper panel-heading" role="tab" id="location"> <div class="section-subtitle-wrapper panel-heading" role="tab" id="location">
<h2> <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"> <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> </button>
</h2> </h2>
</div> </div>
@ -109,7 +109,7 @@
</div> </div>
</div> </div>
<div class="panel-footer"> <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> </div>
</div> </div>
@ -119,7 +119,7 @@
<div class="section-subtitle-wrapper panel-heading" role="tab" id="miscellaneous"> <div class="section-subtitle-wrapper panel-heading" role="tab" id="miscellaneous">
<h2> <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"> <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> </button>
</h2> </h2>
</div> </div>
@ -136,7 +136,7 @@
{{include file="field_input.tpl" field=$prv_keywords}} {{include file="field_input.tpl" field=$prv_keywords}}
</div> </div>
<div class="panel-footer"> <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> </div>
</div> </div>
@ -146,7 +146,7 @@
<div class="section-subtitle-wrapper panel-heading" role="tab" id="custom-fields"> <div class="section-subtitle-wrapper panel-heading" role="tab" id="custom-fields">
<h2> <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"> <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> </button>
</h2> </h2>
</div> </div>
@ -160,7 +160,7 @@
</div> </div>
</div> </div>
<div class="panel-footer"> <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> </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}}
{{if $item.ignore_author}} {{if $item.ignore_author}}
<li role="menuitem"> <li role="menuitem">
<a class="btn-link navicon ignore" href="javascript:ignoreAuthor('item/ignore/{{$item.id}}', 'item-{{$item.guid}}');" title="{{$item.ignore_author.label}}"><i class="fa fa-ban" aria-hidden="true"></i> {{$item.ignore_author.label}}</a> <a class="btn-link navicon ignore" href="javascript:ignoreAuthor('item/ignore/{{$item.id}}', 'item-{{$item.guid}}');" title="{{$item.ignore_author.label}}"><i class="fa fa-eye-slash" aria-hidden="true"></i> {{$item.ignore_author.label}}</a>
</li> </li>
{{/if}} {{/if}}
{{if $item.collapse}} {{if $item.collapse}}
<li role="menuitem"> <li role="menuitem">
<a class="btn-link navicon collapse" href="javascript:collapseAuthor('item/collapse/{{$item.id}}', 'item-{{$item.guid}}');" title="{{$item.collapse.label}}"><i class="fa fa-ban" aria-hidden="true"></i> {{$item.collapse.label}}</a> <a class="btn-link navicon collapse" href="javascript:collapseAuthor('item/collapse/{{$item.id}}', 'item-{{$item.guid}}');" title="{{$item.collapse.label}}"><i class="fa fa-minus-square" aria-hidden="true"></i> {{$item.collapse.label}}</a>
</li> </li>
{{/if}}
{{if $item.ignore_server}}
<li role="menuitem">
<a class="btn-link navicon ignoreServer" href="javascript:ignoreServer('settings/server/{{$item.author_gsid}}/ignore', 'item-{{$item.guid}}');" title="{{$item.ignore_server.label}}"><i class="fa fa-eye-slash" aria-hidden="true"></i> {{$item.ignore_server.label}}</a>
</li> </li>
{{/if}} {{/if}}
{{if $item.report}} {{if $item.report}}

View file

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

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>