diff --git a/database.sql b/database.sql index 2d53b194ac..9abd088383 100644 --- a/database.sql +++ b/database.sql @@ -1,6 +1,6 @@ -- ------------------------------------------ -- Friendica 2025.07-rc (Interrupted Fern) --- DB_UPDATE_VERSION 1580 +-- DB_UPDATE_VERSION 1581 -- ------------------------------------------ @@ -1441,6 +1441,9 @@ CREATE TABLE IF NOT EXISTS `post-media` ( `publisher-url` varbinary(383) COMMENT 'URL of the publisher of the media', `publisher-name` varchar(255) COMMENT 'Name of the publisher of the media', `publisher-image` varbinary(383) COMMENT 'Image of the publisher of the media', + `player-url` varbinary(383) COMMENT 'URL of the embedded player for this media', + `player-height` smallint unsigned COMMENT 'Height of the embedded player', + `player-width` smallint unsigned COMMENT 'Width of the embedded player', `language` char(3) COMMENT 'Language information about this media in the ISO 639 format', `published` datetime COMMENT 'Publification date of this media', `modified` datetime COMMENT 'Modification date of this media', diff --git a/doc/database/db_post-media.md b/doc/database/db_post-media.md index acbd1f75cb..66abde57f3 100644 --- a/doc/database/db_post-media.md +++ b/doc/database/db_post-media.md @@ -30,6 +30,9 @@ Fields | publisher-url | URL of the publisher of the media | varbinary(383) | YES | | NULL | | | publisher-name | Name of the publisher of the media | varchar(255) | YES | | NULL | | | publisher-image | Image of the publisher of the media | varbinary(383) | YES | | NULL | | +| player-url | URL of the embedded player for this media | varbinary(383) | YES | | NULL | | +| player-height | Height of the embedded player | smallint unsigned | YES | | NULL | | +| player-width | Width of the embedded player | smallint unsigned | YES | | NULL | | | language | Language information about this media in the ISO 639 format | char(3) | YES | | NULL | | | published | Publification date of this media | datetime | YES | | NULL | | | modified | Modification date of this media | datetime | YES | | NULL | | diff --git a/src/Content/Item.php b/src/Content/Item.php index 4b0791fe3a..9d3dc4878f 100644 --- a/src/Content/Item.php +++ b/src/Content/Item.php @@ -8,17 +8,16 @@ namespace Friendica\Content; use Friendica\App\BaseURL; -use Friendica\AppHelper; use Friendica\Content\Text\BBCode; use Friendica\Content\Text\BBCode\Video; use Friendica\Content\Text\HTML; +use Friendica\Core\Config\Capability\IManageConfigValues; use Friendica\Core\L10n; use Friendica\Core\PConfig\Capability\IManagePersonalConfigValues; use Friendica\Core\Protocol; use Friendica\Core\Session\Capability\IHandleUserSessions; use Friendica\Core\System; use Friendica\Database\DBA; -use Friendica\DI; use Friendica\Event\ArrayFilterEvent; use Friendica\Model\Attach; use Friendica\Model\Circle; @@ -66,17 +65,17 @@ class Item private $aclFormatter; /** @var IManagePersonalConfigValues */ private $pConfig; + /** @var IManageConfigValues */ + private $config; /** @var BaseURL */ private $baseURL; /** @var Emailer */ private $emailer; - /** @var AppHelper */ - private $appHelper; private EventDispatcherInterface $eventDispatcher; /** @var LoggerInterface */ protected $logger; - public function __construct(LoggerInterface $logger, Profiler $profiler, Activity $activity, L10n $l10n, IHandleUserSessions $userSession, Video $bbCodeVideo, ACLFormatter $aclFormatter, IManagePersonalConfigValues $pConfig, BaseURL $baseURL, Emailer $emailer, AppHelper $appHelper, EventDispatcherInterface $eventDispatcher) + public function __construct(LoggerInterface $logger, Profiler $profiler, Activity $activity, L10n $l10n, IHandleUserSessions $userSession, Video $bbCodeVideo, ACLFormatter $aclFormatter, IManagePersonalConfigValues $pConfig, IManageConfigValues $config, BaseURL $baseURL, Emailer $emailer, EventDispatcherInterface $eventDispatcher) { $this->profiler = $profiler; $this->activity = $activity; @@ -86,8 +85,8 @@ class Item $this->aclFormatter = $aclFormatter; $this->baseURL = $baseURL; $this->pConfig = $pConfig; + $this->config = $config; $this->emailer = $emailer; - $this->appHelper = $appHelper; $this->eventDispatcher = $eventDispatcher; $this->logger = $logger; } @@ -1091,7 +1090,7 @@ class Item public function isTooOld(string $created, int $uid = 0): bool { // check for create date and expire time - $expire_interval = DI::config()->get('system', 'dbclean-expire-days', 0); + $expire_interval = $this->config->get('system', 'dbclean-expire-days', 0); if ($uid) { $user = DBA::selectFirst('user', ['expire'], ['uid' => $uid]); @@ -1205,8 +1204,6 @@ class Item $result = []; - $eventDispatcher = DI::eventDispatcher(); - foreach ($this->splitByBlocks($searchtext) as $block) { $languages = $ld->detect($block)->close() ?: []; @@ -1217,7 +1214,7 @@ class Item 'author-id' => $author_id, ]; - $hook_data = $eventDispatcher->dispatch( + $hook_data = $this->eventDispatcher->dispatch( new ArrayFilterEvent(ArrayFilterEvent::DETECT_LANGUAGES, $hook_data), )->getArray(); @@ -1355,4 +1352,38 @@ class Item $used_languages = $this->l10n->t("Detected languages in this post:\n%s", $used_languages); return $used_languages; } + + /** + * Returns the HTML code for an iframe player for embedded content like videos. + * The iframe will automatically adjust its height based on the aspect ratio. + * + * @param string $player_url URL of the embedded player + * @param int|null $width Player width + * @param int|null $height Player height + * @return string + */ + public function getPlayerIframe(string $player_url, ?int $width, ?int $height): string + { + $attributes = ' src="' . $player_url . '"'; + $max_height = $this->config->get('system', 'max_video_height') ?: $height; + + if ($width != 0 && $height != 0) { + if ($height > $width && $height > $max_height) { + $factor = 100; + $height_attr = $max_height; + } else { + $factor = round($height / $width, 2) * 100; + $height_attr = '100%'; + } + $attributes .= ' height="' . $height_attr. '" style="position:absolute;left:0px;top:0px"'; + $return = '
'; + } else { + $height = min($max_height, $height); + $attributes .= ' height="' . $height . '"'; + $return = '
'; + } + + $return .= '
'; + return $return; + } } diff --git a/src/Content/Post/Entity/PostMedia.php b/src/Content/Post/Entity/PostMedia.php index b06e258710..1c8ed55927 100644 --- a/src/Content/Post/Entity/PostMedia.php +++ b/src/Content/Post/Entity/PostMedia.php @@ -35,6 +35,9 @@ use Psr\Http\Message\UriInterface; * @property-read ?string $publisherName * @property-read ?UriInterface $publisherImage * @property-read ?string $blurhash + * @property-read ?UriInterface $playerUrl + * @property-read ?int $playerWidth + * @property-read ?int $playerHeight */ class PostMedia extends BaseEntity { @@ -98,6 +101,12 @@ class PostMedia extends BaseEntity * @see https://blurha.sh/ */ protected $blurhash; + /** @var ?UriInterface Player URL */ + protected $playerUrl; + /** @var ?int In pixels */ + protected $playerWidth; + /** @var ?int In pixels */ + protected $playerHeight; public function __construct( int $uriId, @@ -120,7 +129,10 @@ class PostMedia extends BaseEntity ?string $publisherName = null, ?UriInterface $publisherImage = null, ?string $blurhash = null, - int $id = null + ?UriInterface $playerUrl = null, + ?int $playerWidth = null, + ?int $playerHeight = null, + ?int $id = null ) { $this->uriId = $uriId; $this->url = $url; @@ -142,6 +154,9 @@ class PostMedia extends BaseEntity $this->publisherName = $publisherName; $this->publisherImage = $publisherImage; $this->blurhash = $blurhash; + $this->playerUrl = $playerUrl; + $this->playerWidth = $playerWidth; + $this->playerHeight = $playerHeight; $this->id = $id; } @@ -247,6 +262,9 @@ class PostMedia extends BaseEntity $this->publisherName, $this->publisherImage, $this->blurhash, + $this->playerUrl, + $this->playerWidth, + $this->playerHeight, $this->id, ); } @@ -274,6 +292,9 @@ class PostMedia extends BaseEntity $this->publisherName, $this->publisherImage, $this->blurhash, + $this->playerUrl, + $this->playerWidth, + $this->playerHeight, $this->id, ); } diff --git a/src/Content/Post/Factory/PostMedia.php b/src/Content/Post/Factory/PostMedia.php index 1ebedda72e..e1e1a58dd1 100644 --- a/src/Content/Post/Factory/PostMedia.php +++ b/src/Content/Post/Factory/PostMedia.php @@ -55,6 +55,9 @@ class PostMedia extends BaseFactory implements ICanCreateFromTableRow $row['publisher-name'], UtilNetwork::createUriFromString($row['publisher-image']), $row['blurhash'], + UtilNetwork::createUriFromString($row['player-url']), + $row['player-width'], + $row['player-height'], $row['id'] ); } diff --git a/src/Content/Post/Repository/PostMedia.php b/src/Content/Post/Repository/PostMedia.php index 72e337b211..d0c847858a 100644 --- a/src/Content/Post/Repository/PostMedia.php +++ b/src/Content/Post/Repository/PostMedia.php @@ -79,6 +79,9 @@ class PostMedia extends BaseRepository 'publisher-image' => $PostMedia->publisherImage ? $PostMedia->publisherImage->__toString() : null, 'media-uri-id' => $PostMedia->activityUriId, 'blurhash' => $PostMedia->blurhash, + 'player-url' => $PostMedia->playerUrl, + 'player-height' => $PostMedia->playerHeight, + 'player-width' => $PostMedia->playerWidth, ]; if ($PostMedia->id) { diff --git a/src/Content/Text/BBCode.php b/src/Content/Text/BBCode.php index f4eeb8a764..c42964901b 100644 --- a/src/Content/Text/BBCode.php +++ b/src/Content/Text/BBCode.php @@ -414,7 +414,7 @@ class BBCode * @return string * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - public static function convertAttachment(string $text, int $simplehtml = self::INTERNAL, bool $tryoembed = true, array $data = [], int $uriid = 0, int $preview_mode = self::PREVIEW_LARGE): string + public static function convertAttachment(string $text, int $simplehtml = self::INTERNAL, bool $tryoembed = true, array $data = [], int $uriid = 0, int $preview_mode = self::PREVIEW_LARGE, bool $embed = false): string { DI::profiler()->startRecording('rendering'); $data = $data ?: self::getAttachmentData($text); @@ -451,6 +451,11 @@ class BBCode $return = sprintf('
', $data['type']); } + if ($embed && $data['player_url'] != '' && $data['player_height'] != 0) { + $return .= DI::contentItem()->getPlayerIframe($data['player_url'], $data['player_width'], $data['player_height']); + $preview_mode = self::PREVIEW_NO_IMAGE; + } + if ($preview_mode == self::PREVIEW_NO_IMAGE) { unset($data['image']); unset($data['preview']); diff --git a/src/Model/Item.php b/src/Model/Item.php index 47f96c5cb6..a288d9f3f4 100644 --- a/src/Model/Item.php +++ b/src/Model/Item.php @@ -610,7 +610,7 @@ class Item /** * Inserts item record * - * @param array $item Item array to be inserted + * @param array $item Item array to be inserted * @param int $notify Notification (type?) * @param bool $post_local (???) * @return int Zero means error, otherwise primary key (id) is being returned @@ -3033,8 +3033,8 @@ class Item if (!empty($sharedSplitAttachments)) { $s = self::addGallery($s, $sharedSplitAttachments['visual']); - $s = self::addVisualAttachments($sharedSplitAttachments['visual'], $shared_item, $s, true); - $s = self::addLinkAttachment($shared_uri_id ?: $item['uri-id'], $sharedSplitAttachments, $body, $s, true, $quote_shared_links); + $s = self::addVisualAttachments($sharedSplitAttachments['visual'], $shared_item, $s, true, $uid); + $s = self::addLinkAttachment($shared_uri_id ?: $item['uri-id'], $sharedSplitAttachments, $body, $s, true, $quote_shared_links, $uid); $s = self::addNonVisualAttachments($sharedSplitAttachments['additional'], $item, $s); $body = BBCode::removeSharedData($body); } @@ -3046,8 +3046,8 @@ class Item } $s = self::addGallery($s, $itemSplitAttachments['visual']); - $s = self::addVisualAttachments($itemSplitAttachments['visual'], $item, $s, false); - $s = self::addLinkAttachment($item['uri-id'], $itemSplitAttachments, $body, $s, false, $shared_links); + $s = self::addVisualAttachments($itemSplitAttachments['visual'], $item, $s, false, $uid); + $s = self::addLinkAttachment($item['uri-id'], $itemSplitAttachments, $body, $s, false, $shared_links, $uid); $s = self::addNonVisualAttachments($itemSplitAttachments['additional'], $item, $s); $s = self::addQuestions($item, $s); @@ -3246,10 +3246,11 @@ class Item * @param array $item * @param string $content * @param bool $shared + * @param int $uid * @return string modified content * @throws ServiceUnavailableException */ - private static function addVisualAttachments(PostMedias $PostMedias, array $item, string $content, bool $shared): string + private static function addVisualAttachments(PostMedias $PostMedias, array $item, string $content, bool $shared, int $uid): string { DI::profiler()->startRecording('rendering'); $leading = ''; @@ -3282,19 +3283,25 @@ class Item $height = 'auto'; $width = '100%'; } - /// @todo Move the template to /content as well - $media = Renderer::replaceMacros(Renderer::getMarkupTemplate($PostMedia->type == Post\Media::HLS ? 'hls_top.tpl' : 'video_top.tpl'), [ - '$video' => [ - 'id' => $PostMedia->id, - 'src' => (string)$PostMedia->url, - 'name' => $PostMedia->name ?: $PostMedia->url, - 'preview' => $preview_url, - 'mime' => (string)$PostMedia->mimetype, - 'height' => $height, - 'width' => $width, - 'description' => $PostMedia->description, - ], - ]); + + if (DI::pConfig()->get($uid, 'system', 'embed_media', false) && ($PostMedia->playerUrl != '') && ($PostMedia->playerHeight > 0)) { + $media = DI::contentItem()->getPlayerIframe($PostMedia->playerUrl, $PostMedia->playerWidth, $PostMedia->playerHeight); + } else { + /// @todo Move the template to /content as well + $media = Renderer::replaceMacros(Renderer::getMarkupTemplate($PostMedia->type == Post\Media::HLS ? 'hls_top.tpl' : 'video_top.tpl'), [ + '$video' => [ + 'id' => $PostMedia->id, + 'src' => (string)$PostMedia->url, + 'name' => $PostMedia->name ?: $PostMedia->url, + 'preview' => $preview_url, + 'mime' => (string)$PostMedia->mimetype, + 'height' => $height, + 'width' => $width, + 'description' => $PostMedia->description, + ], + ]); + } + if (($item['post-type'] ?? null) == Item::PT_VIDEO) { $leading .= $media; } else { @@ -3320,7 +3327,7 @@ class Item continue; } - if (empty($PostMedia->description) && DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'accessibility', 'hide_empty_descriptions')) { + if (empty($PostMedia->description) && DI::pConfig()->get($uid, 'accessibility', 'hide_empty_descriptions')) { continue; } $images[] = $PostMedia->withUrl(new Uri($src_url))->withPreview(new Uri($preview_url), $preview_size); @@ -3362,11 +3369,12 @@ class Item * @param string $content * @param bool $shared * @param array $ignore_links A list of URLs to ignore + * @param int $uid * @return string modified content * @throws InternalServerErrorException * @throws ServiceUnavailableException */ - private static function addLinkAttachment(int $uriid, array $attachments, string $body, string $content, bool $shared, array $ignore_links): string + private static function addLinkAttachment(int $uriid, array $attachments, string $body, string $content, bool $shared, array $ignore_links, int $uid): string { DI::profiler()->startRecording('rendering'); // Don't show a preview when there is a visual attachment (audio or video) @@ -3405,6 +3413,10 @@ class Item 'title' => $attachment->name ?? '', 'type' => 'link', 'url' => (string)$attachment->url, + 'player_url' => (string)$attachment->playerUrl, + 'player_width' => $attachment->playerWidth, + 'player_height' => $attachment->playerHeight, + ]; if ($preview && $attachment->preview) { @@ -3455,9 +3467,9 @@ class Item } // @todo Use a template - $preview_mode = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'system', 'preview_mode', BBCode::PREVIEW_LARGE); + $preview_mode = DI::pConfig()->get($uid, 'system', 'preview_mode', BBCode::PREVIEW_LARGE); if ($preview_mode != BBCode::PREVIEW_NONE) { - $rendered = BBCode::convertAttachment('', BBCode::INTERNAL, false, $data, $uriid, $preview_mode); + $rendered = BBCode::convertAttachment('', BBCode::INTERNAL, false, $data, $uriid, $preview_mode, DI::pConfig()->get($uid, 'system', 'embed_remote_media', false)); } elseif (!self::containsLink($content, $data['url'], Post\Media::HTML)) { $rendered = Renderer::replaceMacros(Renderer::getMarkupTemplate('content/link.tpl'), [ '$url' => $data['url'], diff --git a/src/Model/Post/Media.php b/src/Model/Post/Media.php index d069ef15cc..7400505d47 100644 --- a/src/Model/Post/Media.php +++ b/src/Model/Post/Media.php @@ -459,16 +459,19 @@ class Media } $media['type'] = self::HTML; - $media['size'] = $data['size'] ?? null; - $media['author-url'] = $data['author_url'] ?? null; - $media['author-name'] = $data['author_name'] ?? null; - $media['author-image'] = $data['author_img'] ?? null; - $media['publisher-url'] = $data['publisher_url'] ?? null; - $media['publisher-name'] = $data['publisher_name'] ?? null; - $media['publisher-image'] = $data['publisher_img'] ?? null; - $media['language'] = $data['language'] ?? null; - $media['published'] = $data['published'] ?? null; - $media['modified'] = $data['modified'] ?? null; + $media['size'] = $data['size'] ?? null; + $media['author-url'] = $data['author_url'] ?? null; + $media['author-name'] = $data['author_name'] ?? null; + $media['author-image'] = $data['author_img'] ?? null; + $media['publisher-url'] = $data['publisher_url'] ?? null; + $media['publisher-name'] = $data['publisher_name'] ?? null; + $media['publisher-image'] = $data['publisher_img'] ?? null; + $media['player-url'] = $data['player']['embed'] ?? null; + $media['player-height'] = $data['player']['height'] ?? null; + $media['player-width'] = $data['player']['width'] ?? null; + $media['language'] = $data['language'] ?? null; + $media['published'] = $data['published'] ?? null; + $media['modified'] = $data['modified'] ?? null; if (DI::config()->get('system', 'add_page_media')) { if (!empty($data['audio'])) { @@ -624,7 +627,8 @@ class Media /** * Fetch video dimensions using getID3 * - * @param array $media + * @param array $media Media array + * @param bool $full_file If true, the whole video will be fetched * @return array media with added dimensions */ private static function getVideoDimensions(array $media, bool $full_file): array diff --git a/src/Module/Settings/Display.php b/src/Module/Settings/Display.php index 95a6cbc8c2..12da8f79eb 100644 --- a/src/Module/Settings/Display.php +++ b/src/Module/Settings/Display.php @@ -104,6 +104,8 @@ class Display extends BaseSettings $display_eventlist = (bool)$request['display_eventlist']; $preview_mode = (int)$request['preview_mode']; $update_content = (int)$request['update_content']; + $embed_remote_media = (bool)$request['embed_remote_media']; + $embed_media = (bool)$request['embed_media']; $enabled_timelines = []; foreach ($enable as $code => $enabled) { @@ -148,6 +150,8 @@ class Display extends BaseSettings $this->pConfig->set($uid, 'system', 'show_page_drop', $show_page_drop); $this->pConfig->set($uid, 'system', 'display_eventlist', $display_eventlist); $this->pConfig->set($uid, 'system', 'preview_mode', $preview_mode); + $this->pConfig->set($uid, 'system', 'embed_remote_media', $embed_remote_media); + $this->pConfig->set($uid, 'system', 'embed_media', $embed_media); $this->pConfig->set($uid, 'system', 'network_timelines', $network_timelines); $this->pConfig->set($uid, 'system', 'enabled_timelines', $enabled_timelines); @@ -241,6 +245,8 @@ class Display extends BaseSettings $stay_local = $this->pConfig->get($uid, 'system', 'stay_local', true); $show_page_drop = $this->pConfig->get($uid, 'system', 'show_page_drop', true); $display_eventlist = $this->pConfig->get($uid, 'system', 'display_eventlist', true); + $embed_remote_media = $this->pConfig->get($uid, 'system', 'embed_remote_media', false); + $embed_media = $this->pConfig->get($uid, 'system', 'embed_media', false); $hide_empty_descriptions = $this->pConfig->get($uid, 'accessibility', 'hide_empty_descriptions', false); $hide_custom_emojis = $this->pConfig->get($uid, 'accessibility', 'hide_custom_emojis', false); @@ -335,6 +341,8 @@ class Display extends BaseSettings '$hide_empty_descriptions' => ['hide_empty_descriptions', $this->t('Hide pictures with empty alternative text'), $hide_empty_descriptions, $this->t("Don't display pictures that are missing the alternative text.")], '$hide_custom_emojis' => ['hide_custom_emojis', $this->t('Hide custom emojis'), $hide_custom_emojis, $this->t("Don't display custom emojis.")], '$platform_icon_style' => ['platform_icon_style', $this->t('Platform icons style'), $platform_icon_style, $this->t('Style of the platform icons'), $platform_icon_styles, false], + '$embed_remote_media' => ['embed_remote_media', $this->t('Embed remote media'), $embed_remote_media, $this->t('When enabled, remote media will be embedded in the post, like for example YouTube videos.')], + '$embed_media' => ['embed_media', $this->t('Embed supported media'), $embed_media, $this->t('When enabled, remote media will be embedded in the post instead of using the local player if this is supported by the remote system. This is useful for media where the remote player is better than the local one, like for example Peertube videos.')], '$timeline_label' => $this->t('Label'), '$timeline_descriptiom' => $this->t('Description'), diff --git a/src/Protocol/ActivityPub/Processor.php b/src/Protocol/ActivityPub/Processor.php index 9d3ab19b1b..f21ca48d1a 100644 --- a/src/Protocol/ActivityPub/Processor.php +++ b/src/Protocol/ActivityPub/Processor.php @@ -145,15 +145,18 @@ class Processor return; } - $data = ['uri-id' => $uriid]; - $data['type'] = Post\Media::UNKNOWN; - $data['url'] = $attachment['url']; - $data['mimetype'] = $attachment['mediaType'] ?? null; - $data['height'] = $attachment['height'] ?? null; - $data['width'] = $attachment['width'] ?? null; - $data['size'] = $attachment['size'] ?? null; - $data['preview'] = $attachment['image'] ?? null; - $data['description'] = $attachment['name'] ?? null; + $data = ['uri-id' => $uriid]; + $data['type'] = Post\Media::UNKNOWN; + $data['url'] = $attachment['url']; + $data['mimetype'] = $attachment['mediaType'] ?? null; + $data['height'] = $attachment['height'] ?? null; + $data['width'] = $attachment['width'] ?? null; + $data['size'] = $attachment['size'] ?? null; + $data['preview'] = $attachment['image'] ?? null; + $data['description'] = $attachment['name'] ?? null; + $data['player-url'] = $attachment['player-url'] ?? null; + $data['player-height'] = $attachment['player-height'] ?? null; + $data['player-width'] = $attachment['player-width'] ?? null; Post\Media::insert($data); } diff --git a/src/Protocol/ActivityPub/Receiver.php b/src/Protocol/ActivityPub/Receiver.php index f5d11d5cca..1392ec7869 100644 --- a/src/Protocol/ActivityPub/Receiver.php +++ b/src/Protocol/ActivityPub/Receiver.php @@ -28,6 +28,7 @@ use Friendica\Util\HTTPSignature; use Friendica\Util\JsonLD; use Friendica\Util\LDSignature; use Friendica\Util\Network; +use Friendica\Util\ParseUrl; use Friendica\Util\Strings; /** @@ -1861,11 +1862,12 @@ class Receiver * This is the case with audio and video posts. * Then the links are added as attachments * - * @param array $urls The object URL list - * @param string|null $icon The icon URL to use for the attachments + * @param array $urls The object URL list + * @param string|null $icon The icon URL to use for the attachments + * @param array $player Embedded player data (url, width, height) * @return array an array of attachments */ - private static function processAttachmentUrls(array $urls, ?string $icon): array + private static function processAttachmentUrls(array $urls, ?string $icon, array $player): array { $attachments = []; foreach ($urls as $key => $url) { @@ -1890,32 +1892,53 @@ class Receiver $filetype = strtolower(substr($mediatype, 0, strpos($mediatype, '/'))); + $height = JsonLD::fetchElement($url, 'as:height', '@value'); + $width = JsonLD::fetchElement($url, 'as:width', '@value'); + if ($filetype == 'audio') { - $attachments[] = ['type' => $filetype, 'mediaType' => $mediatype, 'url' => $href, 'height' => null, 'size' => null, 'name' => '', 'image' => $icon]; + $attachments[] = ['type' => $filetype, 'mediaType' => $mediatype, 'url' => $href, 'height' => $height, 'width' => $width, 'size' => null, 'name' => '', 'image' => $icon]; } elseif ($filetype == 'video') { - $height = (int)JsonLD::fetchElement($url, 'as:height', '@value'); // PeerTube audio-only track - if ($height === 0) { + if (!$height) { continue; } $size = (int)JsonLD::fetchElement($url, 'pt:size', '@value'); - $attachments[] = ['type' => $filetype, 'mediaType' => $mediatype, 'url' => $href, 'height' => $height, 'size' => $size, 'name' => '', 'image' => $icon]; + $attachments[] = ['type' => $filetype, 'mediaType' => $mediatype, 'url' => $href, 'height' => $height, 'width' => $width, 'size' => $size, 'name' => '', 'image' => $icon]; } elseif (in_array($mediatype, ['application/x-bittorrent', 'application/x-bittorrent;x-scheme-handler/magnet'])) { - $height = (int)JsonLD::fetchElement($url, 'as:height', '@value'); - // For Torrent links we always store the highest resolution if (!empty($attachments[$mediatype]['height']) && ($height < $attachments[$mediatype]['height'])) { continue; } - $attachments[$mediatype] = ['type' => $mediatype, 'mediaType' => $mediatype, 'url' => $href, 'height' => $height, 'size' => null, 'name' => '']; + $attachments[$mediatype] = ['type' => $mediatype, 'mediaType' => $mediatype, 'url' => $href, 'height' => $height, 'width' => $width, 'size' => null, 'name' => '']; } elseif ($mediatype == 'application/x-mpegURL') { // PeerTube uses HLS streams for video. We prefer HLS streams over the video file itself. // But we still store the video file as an attachment to be used by the API which currently does not support HLS streams. - $attachments = array_merge($attachments, self::processAttachmentUrls($url['as:tag'], $icon)); - $attachments[] = ['type' => $filetype, 'mediaType' => $mediatype, 'url' => $href, 'height' => null, 'size' => null, 'name' => '', 'image' => $icon]; + $attachments = array_merge($attachments, self::processAttachmentUrls($url['as:tag'], $icon, [])); + + $attachment = ['type' => $filetype, 'mediaType' => $mediatype, 'url' => $href, 'height' => $height, 'width' => $width, 'size' => null, 'name' => '', 'image' => $icon]; + if (!empty($player)) { + $attachment['player-url'] = $player['embed'] ?? null; + $attachment['player-height'] = $player['height'] ?? null; + $attachment['player-width'] = $player['width'] ?? null; + + foreach ($attachments as $media) { + if (isset($media['height']) && isset($media['width'])) { + if ($media['height'] > $attachment['player-height'] || $media['width'] > $attachment['player-width']) { + $attachment['player-height'] = $media['height']; + $attachment['player-width'] = $media['width']; + } + } + } + if (!$height && !$width) { + $attachment['height'] = $attachment['player-height']; + $attachment['width'] = $attachment['player-width']; + } + } + DI::logger()->info('Adding video attachment', ['attachment' => $attachment]); + $attachments[] = $attachment; } } @@ -2095,7 +2118,15 @@ class Receiver if (in_array($object_data['object_type'], ['as:Audio', 'as:Video'])) { $object_data['alternate-url'] = self::extractAlternateUrl($object['as:url'] ?? []) ?: $object_data['alternate-url']; - $object_data['attachments'] = array_merge($object_data['attachments'], self::processAttachmentUrls($object['as:url'] ?? [], self::processIcon($object))); + + $siteinfo = ParseUrl::getSiteinfoCached($object_data['alternate-url']); + if (isset($siteinfo['player'])) { + $player = $siteinfo['player']; + } else { + $player = []; + } + + $object_data['attachments'] = array_merge($object_data['attachments'], self::processAttachmentUrls($object['as:url'] ?? [], self::processIcon($object), $player)); } $object_data['can-comment'] = JsonLD::fetchElement($object, 'pt:commentsEnabled', '@value'); diff --git a/static/dbstructure.config.php b/static/dbstructure.config.php index 183b2281d3..031cef6174 100644 --- a/static/dbstructure.config.php +++ b/static/dbstructure.config.php @@ -44,7 +44,7 @@ use Friendica\Database\DBA; // This file is required several times during the test in DbaDefinition which justifies this condition if (!defined('DB_UPDATE_VERSION')) { - define('DB_UPDATE_VERSION', 1580); + define('DB_UPDATE_VERSION', 1581); } return [ @@ -1447,6 +1447,9 @@ return [ "publisher-url" => ["type" => "varbinary(383)", "comment" => "URL of the publisher of the media"], "publisher-name" => ["type" => "varchar(255)", "comment" => "Name of the publisher of the media"], "publisher-image" => ["type" => "varbinary(383)", "comment" => "Image of the publisher of the media"], + "player-url" => ["type" => "varbinary(383)", "comment" => "URL of the embedded player for this media"], + "player-height" => ["type" => "smallint unsigned", "comment" => "Height of the embedded player"], + "player-width" => ["type" => "smallint unsigned", "comment" => "Width of the embedded player"], "language" => ["type" => "char(3)", "comment" => "Language information about this media in the ISO 639 format"], "published" => ["type" => "datetime", "comment" => "Publification date of this media"], "modified" => ["type" => "datetime", "comment" => "Modification date of this media"], diff --git a/tests/src/Content/Text/BBCodeTest.php b/tests/src/Content/Text/BBCodeTest.php index 1717ae5aa1..46fe865212 100644 --- a/tests/src/Content/Text/BBCodeTest.php +++ b/tests/src/Content/Text/BBCodeTest.php @@ -722,4 +722,42 @@ Lucas: For the right price, yes.[/share]', self::assertEquals($expected, $actual); } + + public function dataConvertAttachment(): array + { + return [ + 'player' => [ + 'expected' => 'text ', + 'data' => [ + 'author_name' => 'author_name', + 'author_url' => 'http://domain.tld/author_url', + 'description' => 'description', + 'image' => 'http://domain.tld/image', + 'preview' => 'http://domain.tld/preview', + 'provider_name' => 'provider_name', + 'provider_url' => 'http://domain.tld/provider_url', + 'text' => 'text', + 'title' => 'title', + 'type' => 'link', + 'url' => 'http://domain.tld/page', + 'player_url' => 'http://domain.tld/player', + 'player_width' => 640, + 'player_height' => 480, + ], + ], + ]; + } + + /** + * @dataProvider dataConvertAttachment + * + * @param string $expected Expected BBCode output + * @param string $text Input text + */ + public function testConvertAttachment(string $expected, array $data) + { + $actual = BBCode::convertAttachment('', BBCode::INTERNAL, true, $data, 0, BBCode::PREVIEW_LARGE, true); + + self::assertEquals($expected, $actual); + } } diff --git a/view/lang/C/messages.po b/view/lang/C/messages.po index 9709f96044..5d72c3cde6 100644 --- a/view/lang/C/messages.po +++ b/view/lang/C/messages.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: 2025.07-rc\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-09-03 21:32+0200\n" +"POT-Creation-Date: 2025-09-05 02:58+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -70,7 +70,7 @@ msgstr "" #: src/Module/Settings/ContactImport.php:49 #: src/Module/Settings/ContactImport.php:96 #: src/Module/Settings/Delegation.php:76 src/Module/Settings/Display.php:80 -#: src/Module/Settings/Display.php:188 +#: src/Module/Settings/Display.php:192 #: src/Module/Settings/Profile/Photo/Crop.php:148 #: src/Module/Settings/Profile/Photo/Index.php:96 #: src/Module/Settings/RemoveMe.php:103 src/Module/Settings/UserExport.php:64 @@ -1756,7 +1756,7 @@ msgstr "" #: src/Content/Feature.php:131 src/Content/Widget.php:613 #: src/Module/Admin/Site.php:463 src/Module/BaseSettings.php:113 -#: src/Module/Settings/Channels.php:216 src/Module/Settings/Display.php:313 +#: src/Module/Settings/Channels.php:216 src/Module/Settings/Display.php:319 msgid "Channels" msgstr "" @@ -1845,57 +1845,57 @@ msgstr "" msgid "Create new group" msgstr "" -#: src/Content/Item.php:329 src/Model/Item.php:2780 +#: src/Content/Item.php:328 src/Model/Item.php:2780 msgid "event" msgstr "" -#: src/Content/Item.php:332 src/Content/Item.php:342 +#: src/Content/Item.php:331 src/Content/Item.php:341 msgid "status" msgstr "" -#: src/Content/Item.php:338 src/Model/Item.php:2782 +#: src/Content/Item.php:337 src/Model/Item.php:2782 #: src/Module/Post/Tag/Add.php:112 msgid "photo" msgstr "" -#: src/Content/Item.php:352 src/Module/Post/Tag/Add.php:130 +#: src/Content/Item.php:351 src/Module/Post/Tag/Add.php:130 #, php-format msgid "%1$s tagged %2$s's %3$s with %4$s" msgstr "" -#: src/Content/Item.php:426 view/theme/frio/theme.php:251 +#: src/Content/Item.php:425 view/theme/frio/theme.php:251 msgid "Follow Thread" msgstr "" -#: src/Content/Item.php:427 src/Model/Contact.php:1299 +#: src/Content/Item.php:426 src/Model/Contact.php:1299 msgid "View Status" msgstr "" -#: src/Content/Item.php:428 src/Content/Item.php:451 src/Model/Contact.php:1234 +#: src/Content/Item.php:427 src/Content/Item.php:450 src/Model/Contact.php:1234 #: src/Model/Contact.php:1290 src/Model/Contact.php:1300 #: src/Module/Directory.php:143 src/Module/Settings/Profile/Index.php:275 msgid "View Profile" msgstr "" -#: src/Content/Item.php:429 src/Model/Contact.php:1301 +#: src/Content/Item.php:428 src/Model/Contact.php:1301 msgid "View Photos" msgstr "" -#: src/Content/Item.php:430 src/Model/Contact.php:1268 +#: src/Content/Item.php:429 src/Model/Contact.php:1268 #: src/Model/Profile.php:443 msgid "Network Posts" msgstr "" -#: src/Content/Item.php:431 src/Model/Contact.php:1292 +#: src/Content/Item.php:430 src/Model/Contact.php:1292 #: src/Model/Contact.php:1303 msgid "View Contact" msgstr "" -#: src/Content/Item.php:432 src/Model/Contact.php:1304 +#: src/Content/Item.php:431 src/Model/Contact.php:1304 msgid "Send PM" msgstr "" -#: src/Content/Item.php:433 src/Module/Contact.php:453 +#: src/Content/Item.php:432 src/Module/Contact.php:453 #: src/Module/Contact/Profile.php:562 #: src/Module/Moderation/Blocklist/Contact.php:104 #: src/Module/Moderation/Users/Active.php:93 @@ -1903,7 +1903,7 @@ msgstr "" msgid "Block" msgstr "" -#: src/Content/Item.php:434 src/Module/Contact.php:454 +#: src/Content/Item.php:433 src/Module/Contact.php:454 #: src/Module/Contact/Profile.php:570 #: src/Module/Notifications/Introductions.php:126 #: src/Module/Notifications/Introductions.php:199 @@ -1911,50 +1911,50 @@ msgstr "" msgid "Ignore" msgstr "" -#: src/Content/Item.php:435 src/Module/Contact.php:455 +#: src/Content/Item.php:434 src/Module/Contact.php:455 #: src/Module/Contact/Profile.php:578 msgid "Collapse" msgstr "" -#: src/Content/Item.php:436 src/Object/Post.php:287 +#: src/Content/Item.php:435 src/Object/Post.php:287 #, php-format msgid "Ignore %s server" msgstr "" -#: src/Content/Item.php:440 src/Module/Settings/Channels.php:188 +#: src/Content/Item.php:439 src/Module/Settings/Channels.php:188 #: src/Module/Settings/Channels.php:214 src/Object/Post.php:508 msgid "Languages" msgstr "" -#: src/Content/Item.php:443 src/Object/Post.php:591 +#: src/Content/Item.php:442 src/Object/Post.php:591 msgid "Search Text" msgstr "" -#: src/Content/Item.php:448 src/Content/Widget.php:65 +#: src/Content/Item.php:447 src/Content/Widget.php:65 #: src/Model/Contact.php:1293 src/Model/Contact.php:1305 #: src/Module/Contact/Follow.php:152 view/theme/vier/theme.php:182 msgid "Connect/Follow" msgstr "" -#: src/Content/Item.php:879 +#: src/Content/Item.php:878 msgid "Unable to fetch user." msgstr "" -#: src/Content/Item.php:1343 src/Core/L10n.php:453 +#: src/Content/Item.php:1340 src/Core/L10n.php:453 msgid "Undetermined" msgstr "" -#: src/Content/Item.php:1350 +#: src/Content/Item.php:1347 #, php-format msgid "%s (%s - %s): %s" msgstr "" -#: src/Content/Item.php:1352 +#: src/Content/Item.php:1349 #, php-format msgid "%s (%s): %s" msgstr "" -#: src/Content/Item.php:1355 +#: src/Content/Item.php:1352 #, php-format msgid "" "Detected languages in this post:\n" @@ -2041,7 +2041,7 @@ msgstr "" #: src/Content/Nav.php:230 src/Content/Nav.php:290 #: src/Module/BaseProfile.php:70 src/Module/BaseProfile.php:73 #: src/Module/BaseProfile.php:81 src/Module/BaseProfile.php:84 -#: src/Module/Settings/Display.php:314 view/theme/frio/theme.php:225 +#: src/Module/Settings/Display.php:320 view/theme/frio/theme.php:225 #: view/theme/frio/theme.php:229 msgid "Calendar" msgstr "" @@ -2273,33 +2273,33 @@ msgstr "" msgid "last" msgstr "" -#: src/Content/Text/BBCode.php:903 +#: src/Content/Text/BBCode.php:908 #, php-format msgid "%2$s %3$s" msgstr "" -#: src/Content/Text/BBCode.php:931 src/Model/Item.php:3618 -#: src/Model/Item.php:3624 src/Model/Item.php:3625 +#: src/Content/Text/BBCode.php:936 src/Model/Item.php:3630 +#: src/Model/Item.php:3636 src/Model/Item.php:3637 msgid "Link to source" msgstr "" -#: src/Content/Text/BBCode.php:1753 src/Content/Text/HTML.php:900 +#: src/Content/Text/BBCode.php:1758 src/Content/Text/HTML.php:900 msgid "Click to open/close" msgstr "" -#: src/Content/Text/BBCode.php:1808 +#: src/Content/Text/BBCode.php:1813 msgid "$1 wrote:" msgstr "" -#: src/Content/Text/BBCode.php:1882 src/Content/Text/BBCode.php:1883 +#: src/Content/Text/BBCode.php:1887 src/Content/Text/BBCode.php:1888 msgid "Encrypted content" msgstr "" -#: src/Content/Text/BBCode.php:2229 +#: src/Content/Text/BBCode.php:2234 msgid "Invalid source protocol" msgstr "" -#: src/Content/Text/BBCode.php:2248 +#: src/Content/Text/BBCode.php:2253 msgid "Invalid link protocol" msgstr "" @@ -2885,37 +2885,37 @@ msgid "%s (%s)" msgstr "" #: src/Core/L10n.php:512 src/Model/Event.php:421 -#: src/Module/Settings/Display.php:282 +#: src/Module/Settings/Display.php:288 msgid "Monday" msgstr "" #: src/Core/L10n.php:512 src/Model/Event.php:422 -#: src/Module/Settings/Display.php:283 +#: src/Module/Settings/Display.php:289 msgid "Tuesday" msgstr "" #: src/Core/L10n.php:512 src/Model/Event.php:423 -#: src/Module/Settings/Display.php:284 +#: src/Module/Settings/Display.php:290 msgid "Wednesday" msgstr "" #: src/Core/L10n.php:512 src/Model/Event.php:424 -#: src/Module/Settings/Display.php:285 +#: src/Module/Settings/Display.php:291 msgid "Thursday" msgstr "" #: src/Core/L10n.php:512 src/Model/Event.php:425 -#: src/Module/Settings/Display.php:286 +#: src/Module/Settings/Display.php:292 msgid "Friday" msgstr "" #: src/Core/L10n.php:512 src/Model/Event.php:426 -#: src/Module/Settings/Display.php:287 +#: src/Module/Settings/Display.php:293 msgid "Saturday" msgstr "" #: src/Core/L10n.php:512 src/Model/Event.php:420 -#: src/Module/Settings/Display.php:281 +#: src/Module/Settings/Display.php:287 msgid "Sunday" msgstr "" @@ -3344,17 +3344,17 @@ msgid "today" msgstr "" #: src/Model/Event.php:454 src/Module/Calendar/Show.php:118 -#: src/Module/Settings/Display.php:292 src/Util/Temporal.php:343 +#: src/Module/Settings/Display.php:298 src/Util/Temporal.php:343 msgid "month" msgstr "" #: src/Model/Event.php:455 src/Module/Calendar/Show.php:119 -#: src/Module/Settings/Display.php:293 src/Util/Temporal.php:344 +#: src/Module/Settings/Display.php:299 src/Util/Temporal.php:344 msgid "week" msgstr "" #: src/Model/Event.php:456 src/Module/Calendar/Show.php:120 -#: src/Module/Settings/Display.php:294 src/Util/Temporal.php:345 +#: src/Module/Settings/Display.php:300 src/Util/Temporal.php:345 msgid "day" msgstr "" @@ -3448,44 +3448,44 @@ msgstr "" msgid "Sensitive content" msgstr "" -#: src/Model/Item.php:3518 +#: src/Model/Item.php:3530 msgid "bytes" msgstr "" -#: src/Model/Item.php:3549 +#: src/Model/Item.php:3561 #, php-format msgid "%2$s (%3$d%%, %1$d vote)" msgid_plural "%2$s (%3$d%%, %1$d votes)" msgstr[0] "" msgstr[1] "" -#: src/Model/Item.php:3551 +#: src/Model/Item.php:3563 #, php-format msgid "%2$s (%1$d vote)" msgid_plural "%2$s (%1$d votes)" msgstr[0] "" msgstr[1] "" -#: src/Model/Item.php:3556 +#: src/Model/Item.php:3568 #, php-format msgid "%d voter. Poll end: %s" msgid_plural "%d voters. Poll end: %s" msgstr[0] "" msgstr[1] "" -#: src/Model/Item.php:3558 +#: src/Model/Item.php:3570 #, php-format msgid "%d voter." msgid_plural "%d voters." msgstr[0] "" msgstr[1] "" -#: src/Model/Item.php:3560 +#: src/Model/Item.php:3572 #, php-format msgid "Poll end: %s" msgstr "" -#: src/Model/Item.php:3601 src/Model/Item.php:3602 +#: src/Model/Item.php:3613 src/Model/Item.php:3614 msgid "View on separate page" msgstr "" @@ -3897,7 +3897,7 @@ msgid "Disable" msgstr "" #: src/Module/Admin/Addons/Details.php:78 -#: src/Module/Admin/Themes/Details.php:41 src/Module/Settings/Display.php:341 +#: src/Module/Admin/Themes/Details.php:41 src/Module/Settings/Display.php:349 msgid "Enable" msgstr "" @@ -3952,7 +3952,7 @@ msgstr "" #: src/Module/Settings/Connectors.php:143 #: src/Module/Settings/Connectors.php:228 #: src/Module/Settings/ContactImport.php:110 -#: src/Module/Settings/Delegation.php:179 src/Module/Settings/Display.php:307 +#: src/Module/Settings/Delegation.php:179 src/Module/Settings/Display.php:313 #: src/Module/Settings/Features.php:61 #: src/Module/Settings/Profile/Index.php:272 msgid "Save Settings" @@ -4304,11 +4304,11 @@ msgstr "" msgid "%s is no valid input for maximum image size" msgstr "" -#: src/Module/Admin/Site.php:361 src/Module/Settings/Display.php:206 +#: src/Module/Admin/Site.php:361 src/Module/Settings/Display.php:210 msgid "No special theme for mobile devices" msgstr "" -#: src/Module/Admin/Site.php:378 src/Module/Settings/Display.php:216 +#: src/Module/Admin/Site.php:378 src/Module/Settings/Display.php:220 #, php-format msgid "%s - (Experimental)" msgstr "" @@ -5211,7 +5211,7 @@ msgid "Can be \"all\" or \"tags\". \"all\" means that every public post should b msgstr "" #: src/Module/Admin/Site.php:584 src/Module/Contact/Profile.php:348 -#: src/Module/Settings/Display.php:249 +#: src/Module/Settings/Display.php:255 #: src/Module/Settings/TwoFactor/Index.php:132 msgid "Disabled" msgstr "" @@ -5950,7 +5950,7 @@ msgstr "" msgid "New Event" msgstr "" -#: src/Module/Calendar/Show.php:121 src/Module/Settings/Display.php:295 +#: src/Module/Calendar/Show.php:121 src/Module/Settings/Display.php:301 msgid "list" msgstr "" @@ -9592,12 +9592,12 @@ msgid "When selected, the channel results are reshared. This only works for publ msgstr "" #: src/Module/Settings/Channels.php:176 src/Module/Settings/Channels.php:202 -#: src/Module/Settings/Display.php:339 +#: src/Module/Settings/Display.php:347 msgid "Label" msgstr "" #: src/Module/Settings/Channels.php:177 src/Module/Settings/Channels.php:203 -#: src/Module/Settings/Display.php:340 +#: src/Module/Settings/Display.php:348 #: src/Module/Settings/TwoFactor/AppSpecific.php:123 msgid "Description" msgstr "" @@ -9980,218 +9980,234 @@ msgstr "" msgid "No entries." msgstr "" -#: src/Module/Settings/Display.php:174 +#: src/Module/Settings/Display.php:178 msgid "The theme you chose isn't available." msgstr "" -#: src/Module/Settings/Display.php:214 +#: src/Module/Settings/Display.php:218 #, php-format msgid "%s - (Unsupported)" msgstr "" -#: src/Module/Settings/Display.php:250 +#: src/Module/Settings/Display.php:256 msgid "Color/Black" msgstr "" -#: src/Module/Settings/Display.php:251 view/theme/frio/php/scheme.php:95 +#: src/Module/Settings/Display.php:257 view/theme/frio/php/scheme.php:95 msgid "Black" msgstr "" -#: src/Module/Settings/Display.php:252 +#: src/Module/Settings/Display.php:258 msgid "Color/White" msgstr "" -#: src/Module/Settings/Display.php:253 +#: src/Module/Settings/Display.php:259 msgid "White" msgstr "" -#: src/Module/Settings/Display.php:258 +#: src/Module/Settings/Display.php:264 msgid "No preview" msgstr "" -#: src/Module/Settings/Display.php:259 +#: src/Module/Settings/Display.php:265 msgid "No image" msgstr "" -#: src/Module/Settings/Display.php:260 +#: src/Module/Settings/Display.php:266 msgid "Small Image" msgstr "" -#: src/Module/Settings/Display.php:261 +#: src/Module/Settings/Display.php:267 msgid "Large Image" msgstr "" -#: src/Module/Settings/Display.php:306 +#: src/Module/Settings/Display.php:312 msgid "Display Settings" msgstr "" -#: src/Module/Settings/Display.php:308 +#: src/Module/Settings/Display.php:314 msgid "General Theme Settings" msgstr "" -#: src/Module/Settings/Display.php:309 +#: src/Module/Settings/Display.php:315 msgid "Custom Theme Settings" msgstr "" -#: src/Module/Settings/Display.php:310 +#: src/Module/Settings/Display.php:316 msgid "Content Settings" msgstr "" -#: src/Module/Settings/Display.php:311 view/theme/duepuntozero/config.php:74 +#: src/Module/Settings/Display.php:317 view/theme/duepuntozero/config.php:74 #: view/theme/frio/config.php:156 view/theme/quattro/config.php:76 #: view/theme/vier/config.php:124 msgid "Theme settings" msgstr "" -#: src/Module/Settings/Display.php:312 +#: src/Module/Settings/Display.php:318 msgid "Timelines" msgstr "" -#: src/Module/Settings/Display.php:319 +#: src/Module/Settings/Display.php:325 msgid "Display Theme:" msgstr "" -#: src/Module/Settings/Display.php:320 +#: src/Module/Settings/Display.php:326 msgid "Mobile Theme:" msgstr "" -#: src/Module/Settings/Display.php:323 +#: src/Module/Settings/Display.php:329 msgid "Number of items to display per page:" msgstr "" -#: src/Module/Settings/Display.php:323 src/Module/Settings/Display.php:324 +#: src/Module/Settings/Display.php:329 src/Module/Settings/Display.php:330 msgid "Maximum of 100 items" msgstr "" -#: src/Module/Settings/Display.php:324 +#: src/Module/Settings/Display.php:330 msgid "Number of items to display per page when viewed from mobile device:" msgstr "" -#: src/Module/Settings/Display.php:325 +#: src/Module/Settings/Display.php:331 msgid "Regularly update the page content" msgstr "" -#: src/Module/Settings/Display.php:325 +#: src/Module/Settings/Display.php:331 msgid "When enabled, new content on network, community and channels are added on top." msgstr "" -#: src/Module/Settings/Display.php:326 +#: src/Module/Settings/Display.php:332 msgid "Display emoticons" msgstr "" -#: src/Module/Settings/Display.php:326 +#: src/Module/Settings/Display.php:332 msgid "When enabled, emoticons are replaced with matching symbols." msgstr "" -#: src/Module/Settings/Display.php:327 +#: src/Module/Settings/Display.php:333 msgid "Infinite scroll" msgstr "" -#: src/Module/Settings/Display.php:327 +#: src/Module/Settings/Display.php:333 msgid "Automatic fetch new items when reaching the page end." msgstr "" -#: src/Module/Settings/Display.php:328 +#: src/Module/Settings/Display.php:334 msgid "Enable Smart Threading" msgstr "" -#: src/Module/Settings/Display.php:328 +#: src/Module/Settings/Display.php:334 msgid "Enable the automatic suppression of extraneous thread indentation." msgstr "" -#: src/Module/Settings/Display.php:329 +#: src/Module/Settings/Display.php:335 msgid "Display the Dislike feature" msgstr "" -#: src/Module/Settings/Display.php:329 +#: src/Module/Settings/Display.php:335 msgid "Display the Dislike button and dislike reactions on posts and comments." msgstr "" -#: src/Module/Settings/Display.php:330 +#: src/Module/Settings/Display.php:336 msgid "Display the resharer" msgstr "" -#: src/Module/Settings/Display.php:330 +#: src/Module/Settings/Display.php:336 msgid "Display the first resharer as icon and text on a reshared item." msgstr "" -#: src/Module/Settings/Display.php:331 +#: src/Module/Settings/Display.php:337 msgid "Stay local" msgstr "" -#: src/Module/Settings/Display.php:331 +#: src/Module/Settings/Display.php:337 msgid "Don't go to a remote system when following a contact link." msgstr "" -#: src/Module/Settings/Display.php:332 +#: src/Module/Settings/Display.php:338 msgid "Show the post deletion checkbox" msgstr "" -#: src/Module/Settings/Display.php:332 +#: src/Module/Settings/Display.php:338 msgid "Display the checkbox for the post deletion on the network page." msgstr "" -#: src/Module/Settings/Display.php:333 +#: src/Module/Settings/Display.php:339 msgid "DIsplay the event list" msgstr "" -#: src/Module/Settings/Display.php:333 +#: src/Module/Settings/Display.php:339 msgid "Display the birthday reminder and event list on the network page." msgstr "" -#: src/Module/Settings/Display.php:334 +#: src/Module/Settings/Display.php:340 msgid "Link preview mode" msgstr "" -#: src/Module/Settings/Display.php:334 +#: src/Module/Settings/Display.php:340 msgid "Appearance of the link preview that is added to each post with a link." msgstr "" -#: src/Module/Settings/Display.php:335 +#: src/Module/Settings/Display.php:341 msgid "Hide pictures with empty alternative text" msgstr "" -#: src/Module/Settings/Display.php:335 +#: src/Module/Settings/Display.php:341 msgid "Don't display pictures that are missing the alternative text." msgstr "" -#: src/Module/Settings/Display.php:336 +#: src/Module/Settings/Display.php:342 msgid "Hide custom emojis" msgstr "" -#: src/Module/Settings/Display.php:336 +#: src/Module/Settings/Display.php:342 msgid "Don't display custom emojis." msgstr "" -#: src/Module/Settings/Display.php:337 +#: src/Module/Settings/Display.php:343 msgid "Platform icons style" msgstr "" -#: src/Module/Settings/Display.php:337 +#: src/Module/Settings/Display.php:343 msgid "Style of the platform icons" msgstr "" -#: src/Module/Settings/Display.php:342 -msgid "Bookmark" +#: src/Module/Settings/Display.php:344 +msgid "Embed remote media" msgstr "" #: src/Module/Settings/Display.php:344 +msgid "When enabled, remote media will be embedded in the post, like for example YouTube videos." +msgstr "" + +#: src/Module/Settings/Display.php:345 +msgid "Embed supported media" +msgstr "" + +#: src/Module/Settings/Display.php:345 +msgid "When enabled, remote media will be embedded in the post instead of using the local player if this is supported by the remote system. This is useful for media where the remote player is better than the local one, like for example Peertube videos." +msgstr "" + +#: src/Module/Settings/Display.php:350 +msgid "Bookmark" +msgstr "" + +#: src/Module/Settings/Display.php:352 msgid "Enable timelines that you want to see in the channels widget. Bookmark timelines that you want to see in the top menu." msgstr "" -#: src/Module/Settings/Display.php:346 +#: src/Module/Settings/Display.php:354 msgid "Channel languages:" msgstr "" -#: src/Module/Settings/Display.php:346 +#: src/Module/Settings/Display.php:354 msgid "Select all the languages you want to see in your channels. \"Unspecified\" describes all posts for which no language information was detected (e.g. posts with just an image or too little text to be sure of the language). If you want to see all languages, you will need to select all items in the list." msgstr "" -#: src/Module/Settings/Display.php:348 +#: src/Module/Settings/Display.php:356 msgid "Beginning of week:" msgstr "" -#: src/Module/Settings/Display.php:349 +#: src/Module/Settings/Display.php:357 msgid "Default calendar view:" msgstr "" @@ -11798,7 +11814,7 @@ msgstr "" msgid "Quote shared by: %s" msgstr "" -#: src/Protocol/ActivityPub/Receiver.php:568 +#: src/Protocol/ActivityPub/Receiver.php:569 msgid "Chat" msgstr "" diff --git a/view/templates/settings/display.tpl b/view/templates/settings/display.tpl index 500300dde0..289ace6dcd 100644 --- a/view/templates/settings/display.tpl +++ b/view/templates/settings/display.tpl @@ -31,6 +31,8 @@ {{include file="field_checkbox.tpl" field=$hide_empty_descriptions}} {{include file="field_checkbox.tpl" field=$hide_custom_emojis}} {{include file="field_select.tpl" field=$platform_icon_style}} + {{include file="field_checkbox.tpl" field=$embed_remote_media}} + {{include file="field_checkbox.tpl" field=$embed_media}}

{{$timeline_title}}

{{$timeline_explanation}} diff --git a/view/theme/frio/templates/settings/display.tpl b/view/theme/frio/templates/settings/display.tpl index 7fdbd89260..f3e19c3c9c 100644 --- a/view/theme/frio/templates/settings/display.tpl +++ b/view/theme/frio/templates/settings/display.tpl @@ -78,6 +78,8 @@ {{include file="field_checkbox.tpl" field=$hide_empty_descriptions}} {{include file="field_checkbox.tpl" field=$hide_custom_emojis}} {{include file="field_select.tpl" field=$platform_icon_style}} + {{include file="field_checkbox.tpl" field=$embed_remote_media}} + {{include file="field_checkbox.tpl" field=$embed_media}}