diff options
| author | 2025-06-30 12:01:56 +0200 | |
|---|---|---|
| committer | 2025-06-30 12:01:56 +0200 | |
| commit | 7915abd833e1ab7a72ad27b3ec52020ac9ab7051 (patch) | |
| tree | 293bb99058186a541cb8f6e97ad404de25653f9e /app | |
| parent | 7d9fc0ce0c31f22457485a9ff33e0839aaca1254 (diff) | |
Implement custom feed favicons (#7646)
Closes #3789, #6503
Icon setting when no custom icon is set yet:

- `Change...` button opens a file dialog, and after selecting a file shows the chosen icon in the preview on the left. `Submit` must be clicked after selecting the icon.
- `Reset to default` changes the preview icon to the default one, and also requires `Submit` to be clicked to apply the changes.
Full list of changes:
- CSP now includes `blob:` in `img-src` for
- `indexAction()` and `feedAction()` in `subscriptionController.php`
- all of the view actions in `indexController.php`
- Introduce new attribute `customFavicon (boolean)` for feeds that indicates if the feed has a custom favicon
- `hashFavicon()` in `Feed.php` is dependent on this attribute
- `hashFavicon()` has a new parameter called `skipCache (boolean)` that allows the reset of the favicon hash for the Feed object
- `resetFaviconHash()` just calls `hashFavicon(skipCache: true)`
- `f.php` URLs now have the format of `/f.php?h=XXXXX&t=cachebuster`, where the `t` parameter is only used for serving custom favicons
- if `t` parameter is set, `f.php` returns a `Cache-Control: immutable` header
- `stripos` and `strpos` were changed to `str_contains` in various places (refactor)
- JS for handling the custom favicon configuration logic is in `extra.js` inside `init_update_feed()` which is called when feed configuration is opened from the aside or when the subscription management page with the feed is loaded
- Server-side code for uploading the icon in `subscriptionController.php` under `feedAction()`
- Errors that may occur during the setting of a custom favicon:
- Unsupported image file type (handled only server-side with `isImgMime()`)
- When the file is bigger than 1 MiB (default), handled both client-side and server-side
- Standard feed error when `updateFeed()` fails
- JS vars `javascript_vars.phtml` are no longer escaped with `htmlspecialchars()`, instead with json encoding,
- CSS for disabled buttons was added
- Max favicon file size is configurable with the `max_favicon_upload_size` option in `config.php` (not exposed via UI)
- Custom favicons are currently deleted only when they are either reset to the default icon, or the feed gets deleted. They do not get deleted when the user deletes their account without removing their feeds first.
- ` faviconPrepare()` and `faviconRebuild()` are not allowed to be called when the `customFavicon` attribute is `true`
- New i18n strings:
- `'sub.feed.icon' => 'Icon'`
- `'sub.feed.change_favicon' => 'Change…'`
- `'sub.feed.reset_favicon' => 'Reset to default'`
- `'sub.feed.favicon_changed_by_ext' => 'The icon has been set by the <b>%s</b> extension.'`
- `'feedback.sub.feed.favicon.too_large' => 'Uploaded icon is too large. The maximum file size is <em>%s</em>.'`
- `'feedback.sub.feed.favicon.unsupported_format' => 'Unsupported image file format!'`
- Extension hook `custom_favicon_hash`
- `setCustomFavicon()` method
- `resetCustomFavicon()` method
- `customFaviconExt` and `customFaviconDisallowDel` attributes
- example of usage: https://github.com/FreshRSS/Extensions/pull/337
- Extension hook `custom_favicon_btn_url`
- Allows extensions to implement a button for setting a custom favicon for individual feeds by providing an URL. The URL will be sent a POST request with the `extAction` field set to either `query_icon_info` or `update_icon`, along with an `id` field which describes the feed's ID.
Diffstat (limited to 'app')
63 files changed, 509 insertions, 32 deletions
diff --git a/app/Controllers/feedController.php b/app/Controllers/feedController.php index 37a403ba8..075ecb5e6 100755 --- a/app/Controllers/feedController.php +++ b/app/Controllers/feedController.php @@ -998,8 +998,16 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController { public static function deleteFeed(int $feed_id): bool { FreshRSS_UserDAO::touch(); $feedDAO = FreshRSS_Factory::createFeedDao(); + $feed = $feedDAO->searchById($feed_id); + if ($feed === null) { + return false; + } + if ($feedDAO->deleteFeed($feed_id)) { - // TODO: Delete old favicon + // TODO: Delete old favicon (non-custom) + if ($feed->customFavicon() && !$feed->attributeBoolean('customFaviconDisallowDel')) { + FreshRSS_Feed::faviconDelete($feed->hashFavicon()); + } // Remove related queries $queries = remove_query_by_get('f_' . $feed_id, FreshRSS_Context::userConf()->queries); diff --git a/app/Controllers/indexController.php b/app/Controllers/indexController.php index d5d9db778..bcc659d8a 100644 --- a/app/Controllers/indexController.php +++ b/app/Controllers/indexController.php @@ -57,7 +57,7 @@ class FreshRSS_index_Controller extends FreshRSS_ActionController { $this->_csp([ 'default-src' => "'self'", 'frame-src' => '*', - 'img-src' => '* data:', + 'img-src' => '* data: blob:', 'frame-ancestors' => "'none'", 'media-src' => '*', ]); @@ -146,7 +146,7 @@ class FreshRSS_index_Controller extends FreshRSS_ActionController { $this->_csp([ 'default-src' => "'self'", 'frame-src' => '*', - 'img-src' => '* data:', + 'img-src' => '* data: blob:', 'frame-ancestors' => "'none'", 'media-src' => '*', ]); diff --git a/app/Controllers/subscriptionController.php b/app/Controllers/subscriptionController.php index 7d41edfa7..58cda4b9b 100644 --- a/app/Controllers/subscriptionController.php +++ b/app/Controllers/subscriptionController.php @@ -46,6 +46,12 @@ class FreshRSS_subscription_Controller extends FreshRSS_ActionController { FreshRSS_View::appendScript(Minz_Url::display('/scripts/feed.js?' . @filemtime(PUBLIC_PATH . '/scripts/feed.js'))); FreshRSS_View::prependTitle(_t('sub.title') . ' · '); + $this->_csp([ + 'default-src' => "'self'", + 'frame-ancestors' => "'none'", + 'img-src' => "'self' blob:", + ]); + $this->view->onlyFeedsWithError = Minz_Request::paramBoolean('error'); $id = Minz_Request::paramInt('id'); @@ -80,6 +86,7 @@ class FreshRSS_subscription_Controller extends FreshRSS_ActionController { * - feed URL * - category id (default: default category id) * - CSS path to article on website + * - favicon * - display in main stream (default: 0) * - HTTP authentication * - number of article to retain (default: -2) @@ -109,6 +116,12 @@ class FreshRSS_subscription_Controller extends FreshRSS_ActionController { FreshRSS_View::prependTitle($feed->name() . ' · ' . _t('sub.title.feed_management') . ' · '); + $this->_csp([ + 'default-src' => "'self'", + 'frame-ancestors' => "'none'", + 'img-src' => "'self' blob:", + ]); + if (Minz_Request::isPost()) { $unicityCriteria = Minz_Request::paramString('unicityCriteria'); if (in_array($unicityCriteria, ['id', '', null], strict: true)) { @@ -309,6 +322,18 @@ class FreshRSS_subscription_Controller extends FreshRSS_ActionController { $feed->_attribute('path_entries_conditions', empty($conditions) ? null : $conditions); $feed->_attribute('path_entries_filter', Minz_Request::paramString('path_entries_filter', true)); + // @phpstan-ignore offsetAccess.nonOffsetAccessible + $favicon_path = isset($_FILES['newFavicon']) ? $_FILES['newFavicon']['tmp_name'] : ''; + // @phpstan-ignore offsetAccess.nonOffsetAccessible + $favicon_size = isset($_FILES['newFavicon']) ? $_FILES['newFavicon']['size'] : 0; + + $favicon_uploaded = $favicon_path !== ''; + + $resetFavicon = Minz_Request::paramBoolean('resetFavicon'); + if ($resetFavicon) { + $feed->resetCustomFavicon(); + } + $values = [ 'name' => Minz_Request::paramString('name'), 'kind' => $feed->kind(), @@ -343,7 +368,24 @@ class FreshRSS_subscription_Controller extends FreshRSS_ActionController { $url_redirect = ['c' => 'subscription', 'params' => ['id' => $id]]; } - if ($values['url'] != '' && $feedDAO->updateFeed($id, $values) !== false) { + if ($favicon_uploaded && !$resetFavicon) { + require_once(LIB_PATH . '/favicons.php'); + $max_size = FreshRSS_Context::systemConf()->limits['max_favicon_upload_size']; + if ($favicon_size > $max_size) { + Minz_Request::bad(_t('feedback.sub.feed.favicon.too_large', format_bytes($max_size)), $url_redirect); + return; + } + try { + $feed->setCustomFavicon(tmpPath: is_string($favicon_path) ? $favicon_path : '', values: $values); + } catch (FreshRSS_UnsupportedImageFormat_Exception $_) { + Minz_Request::bad(_t('feedback.sub.feed.favicon.unsupported_format'), $url_redirect); + return; + } catch (FreshRSS_Feed_Exception $_) { + Minz_Request::bad(_t('feedback.sub.feed.error'), $url_redirect); + return; + } + Minz_Request::good(_t('feedback.sub.feed.updated'), $url_redirect); + } elseif ($values['url'] != '' && $feedDAO->updateFeed($id, $values) !== false) { $feed->_categoryId($values['category']); // update url and website values for faviconPrepare $feed->_url($values['url'], false); diff --git a/app/Exceptions/UnsupportedImageFormatException.php b/app/Exceptions/UnsupportedImageFormatException.php new file mode 100644 index 000000000..9735cc4d6 --- /dev/null +++ b/app/Exceptions/UnsupportedImageFormatException.php @@ -0,0 +1,6 @@ +<?php +declare(strict_types=1); + +class FreshRSS_UnsupportedImageFormat_Exception extends Minz_Exception { + +} diff --git a/app/Models/CategoryDAO.php b/app/Models/CategoryDAO.php index 3a714afed..49d461dd3 100644 --- a/app/Models/CategoryDAO.php +++ b/app/Models/CategoryDAO.php @@ -89,9 +89,9 @@ class FreshRSS_CategoryDAO extends Minz_ModelPdo { protected function autoUpdateDb(array $errorInfo): bool { if (isset($errorInfo[0])) { if ($errorInfo[0] === FreshRSS_DatabaseDAO::ER_BAD_FIELD_ERROR || $errorInfo[0] === FreshRSS_DatabaseDAOPGSQL::UNDEFINED_COLUMN) { - $errorLines = explode("\n", (string)$errorInfo[2], 2); // The relevant column name is on the first line, other lines are noise + $errorLines = explode("\n", $errorInfo[2], 2); // The relevant column name is on the first line, other lines are noise foreach (['kind', 'lastUpdate', 'error', 'attributes'] as $column) { - if (stripos($errorLines[0], $column) !== false) { + if (str_contains($errorLines[0], $column)) { return $this->addColumn($column); } } diff --git a/app/Models/EntryDAO.php b/app/Models/EntryDAO.php index fecf02cf8..aea6e6f65 100644 --- a/app/Models/EntryDAO.php +++ b/app/Models/EntryDAO.php @@ -123,9 +123,9 @@ SQL; protected function autoUpdateDb(array $errorInfo): bool { if (isset($errorInfo[0])) { if ($errorInfo[0] === FreshRSS_DatabaseDAO::ER_BAD_FIELD_ERROR || $errorInfo[0] === FreshRSS_DatabaseDAOPGSQL::UNDEFINED_COLUMN) { - $errorLines = explode("\n", (string)$errorInfo[2], 2); // The relevant column name is on the first line, other lines are noise + $errorLines = explode("\n", $errorInfo[2], 2); // The relevant column name is on the first line, other lines are noise foreach (['attributes'] as $column) { - if (stripos($errorLines[0], $column) !== false) { + if (str_contains($errorLines[0], $column)) { return $this->addColumn($column); } } @@ -134,7 +134,7 @@ SQL; if (isset($errorInfo[1])) { // May be a string or an int if ($errorInfo[1] == FreshRSS_DatabaseDAO::ER_DATA_TOO_LONG) { - if (stripos((string)$errorInfo[2], 'content_bin') !== false) { + if (str_contains($errorInfo[2], 'content_bin')) { return $this->updateToMediumBlob(); //v1.15.0 } } diff --git a/app/Models/EntryDAOPGSQL.php b/app/Models/EntryDAOPGSQL.php index c42c2cec1..e7999f601 100644 --- a/app/Models/EntryDAOPGSQL.php +++ b/app/Models/EntryDAOPGSQL.php @@ -59,9 +59,9 @@ class FreshRSS_EntryDAOPGSQL extends FreshRSS_EntryDAOSQLite { protected function autoUpdateDb(array $errorInfo): bool { if (isset($errorInfo[0])) { if ($errorInfo[0] === FreshRSS_DatabaseDAO::ER_BAD_FIELD_ERROR || $errorInfo[0] === FreshRSS_DatabaseDAOPGSQL::UNDEFINED_COLUMN) { - $errorLines = explode("\n", (string)$errorInfo[2], 2); // The relevant column name is on the first line, other lines are noise + $errorLines = explode("\n", $errorInfo[2], 2); // The relevant column name is on the first line, other lines are noise foreach (['attributes'] as $column) { - if (stripos($errorLines[0], $column) !== false) { + if (str_contains($errorLines[0], $column)) { return $this->addColumn($column); } } diff --git a/app/Models/Feed.php b/app/Models/Feed.php index 3c5fed507..b91d1af75 100644 --- a/app/Models/Feed.php +++ b/app/Models/Feed.php @@ -92,27 +92,171 @@ class FreshRSS_Feed extends Minz_Model { public function hash(): string { if ($this->hash == '') { $salt = FreshRSS_Context::systemConf()->salt; - $params = $this->url; - $curl_params = $this->attributeArray('curl_params'); - if (is_array($curl_params)) { - // Content provided through a proxy may be completely different - $params .= is_string($curl_params[CURLOPT_PROXY] ?? null) ? $curl_params[CURLOPT_PROXY] : ''; - } + $params = $this->url . $this->proxyParam(); $this->hash = sha1($salt . $params); } return $this->hash; } - public function hashFavicon(): string { - if ($this->hashFavicon == '') { + public function resetFaviconHash(): void { + $this->hashFavicon(skipCache: true); + } + + public function proxyParam(): string { + $curl_params = $this->attributeArray('curl_params'); + if (is_array($curl_params)) { + // Content provided through a proxy may be completely different + return is_string($curl_params[CURLOPT_PROXY] ?? null) ? $curl_params[CURLOPT_PROXY] : ''; + } + return ''; + } + + /** + * Resets the custom favicon to the default one. Also deletes the favicon when allowed by extension. + * + * @param array{'url'?:string,'kind'?:int,'category'?:int,'name'?:string,'website'?:string,'description'?:string,'lastUpdate'?:int,'priority'?:int, + * 'pathEntries'?:string,'httpAuth'?:string,'error'?:int,'ttl'?:int,'attributes'?:string|array<string,mixed>} &$values &$values + * + * @param bool $updateFeed Whether `updateFeed()` should be called immediately. If false, it must be handled manually. + * + * @return void + * + * @throws FreshRSS_Feed_Exception + */ + public function resetCustomFavicon(?array &$values = null, bool $updateFeed = true) { + if (!$this->customFavicon()) { + return; + } + if (!$this->attributeBoolean('customFaviconDisallowDel')) { + FreshRSS_Feed::faviconDelete($this->hashFavicon()); + } + $this->_attribute('customFavicon', false); + $this->_attribute('customFaviconExt', null); + $this->_attribute('customFaviconDisallowDel', false); + if ($values !== null) { + $values['attributes'] = $this->attributes(); + $feedDAO = FreshRSS_Factory::createFeedDao(); + if ($updateFeed && !$feedDAO->updateFeed($this->id(), $values)) { + throw new FreshRSS_Feed_Exception(); + } + } + $this->resetFaviconHash(); + } + + /** + * Set a custom favicon for the feed. + * + * @param string $contents Contents of the favicon file. Optional if $tmpPath is set. + * @param string $tmpPath Use only when handling file uploads. (value from `tmp_name` goes here) + * + * @param array{'url'?:string,'kind'?:int,'category'?:int,'name'?:string,'website'?:string,'description'?:string,'lastUpdate'?:int,'priority'?:int, + * 'pathEntries'?:string,'httpAuth'?:string,'error'?:int,'ttl'?:int,'attributes'?:string|array<string,mixed>} &$values &$values + * + * @param bool $updateFeed Whether `updateFeed()` should be called immediately. If false, it must be handled manually. + * @param string $extName The extension name of the calling extension. + * @param bool $disallowDelete Whether the icon can be later deleted when it's being reset. Intended for use by extensions. + * @param bool $overrideCustomIcon Whether a custom favicon set by a user can be overridden. + * + * @return string|null Path where the favicon can be found. Useful for checking if the favicon already exists, before downloading it for example. + * + * @throws FreshRSS_UnsupportedImageFormat_Exception + * @throws FreshRSS_Feed_Exception + */ + public function setCustomFavicon( + ?string $contents = null, + string $tmpPath = '', + ?array &$values = null, + bool $updateFeed = true, + ?string $extName = null, + bool $disallowDelete = false, + bool $overrideCustomIcon = false + ): ?string { + if ($contents === null && $tmpPath !== '') { + $contents = file_get_contents($tmpPath); + } + + $attributesOnly = $contents === null && $tmpPath === ''; + if (!$attributesOnly && !isImgMime(is_string($contents) ? $contents : '')) { + throw new FreshRSS_UnsupportedImageFormat_Exception(); + } + + $oldHash = ''; + $oldDisallowDelete = false; + if ($this->customFavicon()) { + /* If $overrideCustomFavicon is true, custom favicons set by extensions can be overridden, + * but not ones explicitly set by the user */ + if (!$overrideCustomIcon && $this->customFaviconExt() === null) { + return null; + } + $oldHash = $this->hashFavicon(skipCache: true); + $oldDisallowDelete = $this->attributeBoolean('customFaviconDisallowDel'); + } + $this->_attribute('customFavicon', true); + $this->_attribute('customFaviconExt', $extName); + $this->_attribute('customFaviconDisallowDel', $disallowDelete); + + require_once(LIB_PATH . '/favicons.php'); + $newPath = FAVICONS_DIR . $this->hashFavicon(skipCache: true) . '.ico'; + if ($attributesOnly && !file_exists($newPath)) { + $updateFeed = false; + } + + if ($values !== null) { + $values['attributes'] = $this->attributes(); + $feedDAO = FreshRSS_Factory::createFeedDao(); + if ($updateFeed && !$feedDAO->updateFeed($this->id(), $values)) { + throw new FreshRSS_Feed_Exception(); + } + } + + if ($tmpPath !== '') { + move_uploaded_file($tmpPath, $newPath); + } elseif ($contents !== null) { + file_put_contents($newPath, $contents); + } + + if ($oldHash !== '' && !$oldDisallowDelete) { + FreshRSS_Feed::faviconDelete($oldHash); + } + + return $newPath; + } + + /** + * Checks if the feed has a custom favicon set by an extension. + * Additionally, it also checks if the extension that set the icon is still enabled + * And if not, it resets attributes related to custom favicons. + * + * @return string|null The name of the extension that set the icon. + */ + public function customFaviconExt(): ?string { + $customFaviconExt = $this->attributeString('customFaviconExt'); + if ($customFaviconExt !== null && !Minz_ExtensionManager::isExtensionEnabled($customFaviconExt)) { + $this->_attribute('customFavicon', false); + $this->_attribute('customFaviconExt', null); + $this->_attribute('customFaviconDisallowDel', false); + $customFaviconExt = null; + } + return $customFaviconExt; + } + + public function customFavicon(): bool { + $this->customFaviconExt(); + return $this->attributeBoolean('customFavicon') ?? false; + } + + public function hashFavicon(bool $skipCache = false): string { + if ($this->hashFavicon == '' || $skipCache) { $salt = FreshRSS_Context::systemConf()->salt; - $params = $this->website(fallback: true); - $curl_params = $this->attributeArray('curl_params'); - if (is_array($curl_params)) { - // Content provided through a proxy may be completely different - $params .= is_string($curl_params[CURLOPT_PROXY] ?? null) ? $curl_params[CURLOPT_PROXY] : ''; + $params = ''; + if ($this->customFavicon()) { + $current = $this->id . Minz_User::name(); + $hookParams = Minz_ExtensionManager::callHook('custom_favicon_hash', $this); + $params = $hookParams !== null ? $hookParams : $current; + } else { + $params = $this->website(fallback: true) . $this->proxyParam(); } - $this->hashFavicon = hash('crc32b', $salt . $params); + $this->hashFavicon = hash('crc32b', $salt . (is_string($params) ? $params : '')); } return $this->hashFavicon; } @@ -257,6 +401,9 @@ class FreshRSS_Feed extends Minz_Model { public function faviconPrepare(bool $force = false): void { require_once(LIB_PATH . '/favicons.php'); + if ($this->customFavicon()) { + return; + } $url = $this->website(fallback: true); $txt = FAVICONS_DIR . $this->hashFavicon() . '.txt'; if (@file_get_contents($txt) !== $url) { @@ -286,7 +433,14 @@ class FreshRSS_Feed extends Minz_Model { @unlink($path . '.txt'); } public function favicon(): string { - return Minz_Url::display('/f.php?' . $this->hashFavicon()); + $hash = $this->hashFavicon(); + $url = '/f.php?h=' . $hash; + if ($this->customFavicon() + // when the below attribute is set, icon won't be changing frequently so cache buster is not needed + && !$this->attributeBoolean('customFaviconDisallowDel')) { + $url .= '&t=' . @filemtime(DATA_PATH . '/favicons/' . $hash . '.ico'); + } + return Minz_Url::display($url); } public function _id(int $value): void { @@ -1069,6 +1223,9 @@ class FreshRSS_Feed extends Minz_Model { } private function faviconRebuild(): void { + if ($this->customFavicon()) { + return; + } FreshRSS_Feed::faviconDelete($this->hashFavicon()); $this->faviconPrepare(true); } diff --git a/app/Models/FeedDAO.php b/app/Models/FeedDAO.php index e6e5d2940..a81c38eef 100644 --- a/app/Models/FeedDAO.php +++ b/app/Models/FeedDAO.php @@ -22,9 +22,9 @@ class FreshRSS_FeedDAO extends Minz_ModelPdo { protected function autoUpdateDb(array $errorInfo): bool { if (isset($errorInfo[0])) { if ($errorInfo[0] === FreshRSS_DatabaseDAO::ER_BAD_FIELD_ERROR || $errorInfo[0] === FreshRSS_DatabaseDAOPGSQL::UNDEFINED_COLUMN) { - $errorLines = explode("\n", (string)$errorInfo[2], 2); // The relevant column name is on the first line, other lines are noise + $errorLines = explode("\n", $errorInfo[2], 2); // The relevant column name is on the first line, other lines are noise foreach (['kind'] as $column) { - if (stripos($errorLines[0], $column) !== false) { + if (str_contains($errorLines[0], $column)) { return $this->addColumn($column); } } diff --git a/app/i18n/cs/feedback.php b/app/i18n/cs/feedback.php index 3f0866e0c..e396ab84a 100644 --- a/app/i18n/cs/feedback.php +++ b/app/i18n/cs/feedback.php @@ -95,6 +95,10 @@ return array( 'cache_cleared' => '<em>%s</em> mezipaměť byla vymazána', 'deleted' => 'Kanál byl odstraněn', 'error' => 'Kanál nelze aktualizovat', + 'favicon' => array( + 'too_large' => 'Uploaded icon is too large. The maximum file size is <em>%s</em>.', // TODO + 'unsupported_format' => 'Unsupported image file format!', // TODO + ), 'internal_problem' => 'Informační kanál nelze přidat. Pro podrobnosti <a href="%s">zkontrolujte protokoly FreshRSS</a>. Můžete zkusit vynucení přidání připojením <code>#force_feed</code> k adrese URL.', 'invalid_url' => 'Adresa URL <em>%s</em> je neplatná', 'n_actualized' => '%d kanálů bylo aktualizováno', diff --git a/app/i18n/cs/sub.php b/app/i18n/cs/sub.php index 2ee7e830d..aee11fb22 100644 --- a/app/i18n/cs/sub.php +++ b/app/i18n/cs/sub.php @@ -50,6 +50,7 @@ return array( 'password' => 'HTTP heslo', 'username' => 'HTTP uživatelské jméno', ), + 'change_favicon' => 'Change…', // TODO 'clear_cache' => 'Vždy vymazat mezipaměť', 'content_action' => array( '_' => 'Akce obsahu při načítání obsahu článku', @@ -74,12 +75,15 @@ return array( 'help' => 'Soubor XML (data subset. <a href="https://freshrss.github.io/FreshRSS/en/developers/OPML.html" target="_blank">See documentation</a>)', // DIRTY 'label' => 'Exportovat jako OPML', ), + 'ext_favicon' => 'Set automatically', // TODO + 'favicon_changed_by_ext' => 'The icon has been set by the <b>%s</b> extension.', // TODO 'filteractions' => array( '_' => 'Akce filtrování', 'help' => 'Zapište jeden filtr hledání na řádek. Operátoři <a href="https://freshrss.github.io/FreshRSS/en/users/10_filter.html#with-the-search-field" target="_blank">viz dokumentace</a>.', ), 'http_headers' => 'HTTP Headers', // TODO 'http_headers_help' => 'Headers are separated by a newline, and the name and value of a header are separated by a colon (e.g: <kbd><code>Accept: application/atom+xml<br />Authorization: Bearer some-token</code></kbd>).', // TODO + 'icon' => 'Icon', // TODO 'information' => 'Informace', 'keep_min' => 'Minimální počet článků pro ponechání', 'kind' => array( @@ -212,6 +216,7 @@ return array( ), 'proxy' => 'Nastavete proxy pro načítání tohoto kanálu', 'proxy_help' => 'Vyberte protokol (např.: SOCKS5) a zadejte adresu proxy (např.: <kbd>127.0.0.1:1080</kbd> nebo <kbd>username:password@127.0.0.1:1080</kbd>)', + 'reset_favicon' => 'Reset to default', // TODO 'selector_preview' => array( 'show_raw' => 'Zobrazit zdrojový kód', 'show_rendered' => 'Zobrazit obsah', diff --git a/app/i18n/de/feedback.php b/app/i18n/de/feedback.php index 201d75f80..0d0638f0f 100644 --- a/app/i18n/de/feedback.php +++ b/app/i18n/de/feedback.php @@ -95,6 +95,10 @@ return array( 'cache_cleared' => '<em>%s</em> Zwischenspeicher wurde geleert', 'deleted' => 'Der Feed ist gelöscht worden', 'error' => 'Der Feed kann nicht aktualisiert werden', + 'favicon' => array( + 'too_large' => 'Uploaded icon is too large. The maximum file size is <em>%s</em>.', // TODO + 'unsupported_format' => 'Unsupported image file format!', // TODO + ), 'internal_problem' => 'Der RSS-Feed konnte nicht hinzugefügt werden. Für Details <a href="%s">prüfen Sie die FreshRSS-Protokolle</a>. Mit <code>#force_feed</code> am Ende der Feed-URL kann das Hinzufügen erzwungen werden.', 'invalid_url' => 'Die URL <em>%s</em> ist ungültig', 'n_actualized' => 'Die %d Feeds sind aktualisiert worden', diff --git a/app/i18n/de/sub.php b/app/i18n/de/sub.php index 2a9f495c7..710c8e1d1 100644 --- a/app/i18n/de/sub.php +++ b/app/i18n/de/sub.php @@ -50,6 +50,7 @@ return array( 'password' => 'HTTP-Passwort', 'username' => 'HTTP-Nutzername', ), + 'change_favicon' => 'Change…', // TODO 'clear_cache' => 'Nicht cachen (für defekte Feeds)', 'content_action' => array( '_' => 'Behandlung von Feed-Inhalt beim Herunterladen von Artikelinhalt', @@ -74,12 +75,15 @@ return array( 'help' => 'XML Datei (ausgewählte Daten. <a href="https://freshrss.github.io/FreshRSS/en/developers/OPML.html" target="_blank">Siehe Dokumentation</a>)', 'label' => 'Export als OPML', ), + 'ext_favicon' => 'Set automatically', // TODO + 'favicon_changed_by_ext' => 'The icon has been set by the <b>%s</b> extension.', // TODO 'filteractions' => array( '_' => 'Filteraktionen', 'help' => 'Ein Suchfilter pro Zeile. Operatoren <a href="https://freshrss.github.io/FreshRSS/en/users/10_filter.html#with-the-search-field" target="_blank">siehe Dokumentation</a>.', ), 'http_headers' => 'HTTP Headers', // IGNORE 'http_headers_help' => 'Headers werden durch einen Zeilenumbruch getrennt. Name und Wert des Headers werden per Doppelpunkt getrennt (z.B: <kbd><code>Accept: application/atom+xml<br />Authorization: Bearer some-token</code></kbd>).', + 'icon' => 'Icon', // TODO 'information' => 'Informationen', 'keep_min' => 'Minimale Anzahl an Artikeln, die behalten wird', 'kind' => array( @@ -212,6 +216,7 @@ return array( ), 'proxy' => 'Verwende einen Proxy, um den Feed abzuholen', 'proxy_help' => 'Wähle ein Protokoll (z.B. SOCKS5) und einen Proxy mit Port (z.B. <kbd>127.0.0.1:1080</kbd> or <kbd>username:password@127.0.0.1:1080</kbd>)', // DIRTY + 'reset_favicon' => 'Reset to default', // TODO 'selector_preview' => array( 'show_raw' => 'Quellcode anzeigen', 'show_rendered' => 'Inhalt anzeigen', diff --git a/app/i18n/el/feedback.php b/app/i18n/el/feedback.php index f1cd8ecc8..ce6b1d7a9 100644 --- a/app/i18n/el/feedback.php +++ b/app/i18n/el/feedback.php @@ -95,6 +95,10 @@ return array( 'cache_cleared' => '<em>%s</em> cache has been cleared', // TODO 'deleted' => 'Feed has been deleted', // TODO 'error' => 'Feed cannot be updated', // TODO + 'favicon' => array( + 'too_large' => 'Uploaded icon is too large. The maximum file size is <em>%s</em>.', // TODO + 'unsupported_format' => 'Unsupported image file format!', // TODO + ), 'internal_problem' => 'The newsfeed could not be added. <a href="%s">Check FreshRSS logs</a> for details. You can try force adding by appending <code>#force_feed</code> to the URL.', // TODO 'invalid_url' => 'URL <em>%s</em> is invalid', // TODO 'n_actualized' => '%d feeds have been updated', // TODO diff --git a/app/i18n/el/sub.php b/app/i18n/el/sub.php index 9147e2357..50be23da9 100644 --- a/app/i18n/el/sub.php +++ b/app/i18n/el/sub.php @@ -50,6 +50,7 @@ return array( 'password' => 'HTTP password', // TODO 'username' => 'HTTP username', // TODO ), + 'change_favicon' => 'Change…', // TODO 'clear_cache' => 'Always clear cache', // TODO 'content_action' => array( '_' => 'Content action when fetching the article content', // TODO @@ -74,12 +75,15 @@ return array( 'help' => 'XML file (data subset. <a href="https://freshrss.github.io/FreshRSS/en/developers/OPML.html" target="_blank">See documentation</a>)', // TODO 'label' => 'Export as OPML', // TODO ), + 'ext_favicon' => 'Set automatically', // TODO + 'favicon_changed_by_ext' => 'The icon has been set by the <b>%s</b> extension.', // TODO 'filteractions' => array( '_' => 'Filter actions', // TODO 'help' => 'Write one search filter per line. Operators <a href="https://freshrss.github.io/FreshRSS/en/users/10_filter.html#with-the-search-field" target="_blank">see documentation</a>.', // TODO ), 'http_headers' => 'HTTP Headers', // TODO 'http_headers_help' => 'Headers are separated by a newline, and the name and value of a header are separated by a colon (e.g: <kbd><code>Accept: application/atom+xml<br />Authorization: Bearer some-token</code></kbd>).', // TODO + 'icon' => 'Icon', // TODO 'information' => 'Information', // TODO 'keep_min' => 'Minimum number of articles to keep', // TODO 'kind' => array( @@ -212,6 +216,7 @@ return array( ), 'proxy' => 'Set a proxy for fetching this feed', // TODO 'proxy_help' => 'Select a protocol (e.g: SOCKS5) and enter the proxy address (e.g: <kbd>127.0.0.1:1080</kbd> or <kbd>username:password@127.0.0.1:1080</kbd>)', // TODO + 'reset_favicon' => 'Reset to default', // TODO 'selector_preview' => array( 'show_raw' => 'Show source code', // TODO 'show_rendered' => 'Show content', // TODO diff --git a/app/i18n/en-us/feedback.php b/app/i18n/en-us/feedback.php index 2e2dad8ea..12ca6e2b6 100644 --- a/app/i18n/en-us/feedback.php +++ b/app/i18n/en-us/feedback.php @@ -95,6 +95,10 @@ return array( 'cache_cleared' => '<em>%s</em> cache has been cleared', // IGNORE 'deleted' => 'Feed has been deleted', // IGNORE 'error' => 'Feed cannot be updated', // IGNORE + 'favicon' => array( + 'too_large' => 'Uploaded icon is too large. The maximum file size is <em>%s</em>.', // IGNORE + 'unsupported_format' => 'Unsupported image file format!', // IGNORE + ), 'internal_problem' => 'The newsfeed could not be added. <a href="%s">Check FreshRSS logs</a> for details. You can try force adding by appending <code>#force_feed</code> to the URL.', // IGNORE 'invalid_url' => 'URL <em>%s</em> is invalid', // IGNORE 'n_actualized' => '%d feeds have been updated', // IGNORE diff --git a/app/i18n/en-us/sub.php b/app/i18n/en-us/sub.php index 16cbd6fd2..4c0b42ab9 100644 --- a/app/i18n/en-us/sub.php +++ b/app/i18n/en-us/sub.php @@ -50,6 +50,7 @@ return array( 'password' => 'HTTP password', // IGNORE 'username' => 'HTTP username', // IGNORE ), + 'change_favicon' => 'Change…', // IGNORE 'clear_cache' => 'Always clear cache', // IGNORE 'content_action' => array( '_' => 'Content action when fetching the article content', // IGNORE @@ -74,12 +75,15 @@ return array( 'help' => 'XML file (data subset. <a href="https://freshrss.github.io/FreshRSS/en/developers/OPML.html" target="_blank">See documentation</a>)', // IGNORE 'label' => 'Export as OPML', // IGNORE ), + 'ext_favicon' => 'Set automatically', // IGNORE + 'favicon_changed_by_ext' => 'The icon has been set by the <b>%s</b> extension.', // IGNORE 'filteractions' => array( '_' => 'Filter actions', // IGNORE 'help' => 'Write one search filter per line. Operators <a href="https://freshrss.github.io/FreshRSS/en/users/10_filter.html#with-the-search-field" target="_blank">see documentation</a>.', // IGNORE ), 'http_headers' => 'HTTP Headers', // IGNORE 'http_headers_help' => 'Headers are separated by a newline, and the name and value of a header are separated by a colon (e.g: <kbd><code>Accept: application/atom+xml<br />Authorization: Bearer some-token</code></kbd>).', // IGNORE + 'icon' => 'Icon', // IGNORE 'information' => 'Information', // IGNORE 'keep_min' => 'Minimum number of articles to keep', // IGNORE 'kind' => array( @@ -212,6 +216,7 @@ return array( ), 'proxy' => 'Set a proxy for fetching this feed', // IGNORE 'proxy_help' => 'Select a protocol (e.g: SOCKS5) and enter the proxy address (e.g: <kbd>127.0.0.1:1080</kbd> or <kbd>username:password@127.0.0.1:1080</kbd>)', // IGNORE + 'reset_favicon' => 'Reset to default', // IGNORE 'selector_preview' => array( 'show_raw' => 'Show source code', // IGNORE 'show_rendered' => 'Show content', // IGNORE diff --git a/app/i18n/en/feedback.php b/app/i18n/en/feedback.php index e5f0123d1..d40589858 100644 --- a/app/i18n/en/feedback.php +++ b/app/i18n/en/feedback.php @@ -95,6 +95,10 @@ return array( 'cache_cleared' => '<em>%s</em> cache has been cleared', 'deleted' => 'Feed has been deleted', 'error' => 'Feed cannot be updated', + 'favicon' => array( + 'too_large' => 'Uploaded icon is too large. The maximum file size is <em>%s</em>.', + 'unsupported_format' => 'Unsupported image file format!', + ), 'internal_problem' => 'The newsfeed could not be added. <a href="%s">Check FreshRSS logs</a> for details. You can try force adding by appending <code>#force_feed</code> to the URL.', 'invalid_url' => 'URL <em>%s</em> is invalid', 'n_actualized' => '%d feeds have been updated', diff --git a/app/i18n/en/sub.php b/app/i18n/en/sub.php index dfb59bfc3..a392a52af 100644 --- a/app/i18n/en/sub.php +++ b/app/i18n/en/sub.php @@ -50,6 +50,7 @@ return array( 'password' => 'HTTP password', 'username' => 'HTTP username', ), + 'change_favicon' => 'Change…', 'clear_cache' => 'Always clear cache', 'content_action' => array( '_' => 'Content action when fetching the article content', @@ -74,12 +75,15 @@ return array( 'help' => 'XML file (data subset. <a href="https://freshrss.github.io/FreshRSS/en/developers/OPML.html" target="_blank">See documentation</a>)', 'label' => 'Export as OPML', ), + 'ext_favicon' => 'Set automatically', + 'favicon_changed_by_ext' => 'The icon has been set by the <b>%s</b> extension.', 'filteractions' => array( '_' => 'Filter actions', 'help' => 'Write one search filter per line. Operators <a href="https://freshrss.github.io/FreshRSS/en/users/10_filter.html#with-the-search-field" target="_blank">see documentation</a>.', ), 'http_headers' => 'HTTP Headers', 'http_headers_help' => 'Headers are separated by a newline, and the name and value of a header are separated by a colon (e.g: <kbd><code>Accept: application/atom+xml<br />Authorization: Bearer some-token</code></kbd>).', + 'icon' => 'Icon', 'information' => 'Information', 'keep_min' => 'Minimum number of articles to keep', 'kind' => array( @@ -212,6 +216,7 @@ return array( ), 'proxy' => 'Set a proxy for fetching this feed', 'proxy_help' => 'Select a protocol (e.g: SOCKS5) and enter the proxy address (e.g: <kbd>127.0.0.1:1080</kbd> or <kbd>username:password@127.0.0.1:1080</kbd>)', + 'reset_favicon' => 'Reset to default', 'selector_preview' => array( 'show_raw' => 'Show source code', 'show_rendered' => 'Show content', diff --git a/app/i18n/es/feedback.php b/app/i18n/es/feedback.php index 84712d16b..df781d599 100644 --- a/app/i18n/es/feedback.php +++ b/app/i18n/es/feedback.php @@ -95,6 +95,10 @@ return array( 'cache_cleared' => '<em>%s</em> se ha borrado la caché', 'deleted' => 'Fuente eliminada', 'error' => 'No es posible actualizar la fuente', + 'favicon' => array( + 'too_large' => 'Uploaded icon is too large. The maximum file size is <em>%s</em>.', // TODO + 'unsupported_format' => 'Unsupported image file format!', // TODO + ), 'internal_problem' => 'No ha sido posible agregar la fuente RSS. <a href="%s">Revisa el registro de FreshRSS </a> para más información. Puedes probar de forzarlo añadiendo la etiqueta <code>#force_feed</code> a la URL.', 'invalid_url' => 'La URL <em>%s</em> es inválida', 'n_actualized' => 'Se han actualizado %d fuentes', diff --git a/app/i18n/es/sub.php b/app/i18n/es/sub.php index 0518b6b11..d57bb0a9f 100644 --- a/app/i18n/es/sub.php +++ b/app/i18n/es/sub.php @@ -50,6 +50,7 @@ return array( 'password' => 'Contraseña HTTP', 'username' => 'Nombre de usuario HTTP', ), + 'change_favicon' => 'Change…', // TODO 'clear_cache' => 'Borrar siempre la memoria caché', 'content_action' => array( '_' => 'Acción de contenido al obtener el contenido del artículo', @@ -74,12 +75,15 @@ return array( 'help' => 'archivo XML (conjunto de datos. <a href="https://freshrss.github.io/FreshRSS/en/developers/OPML.html" target="_blank">Ver la documentación</a>)', 'label' => 'Exportar como OPML', ), + 'ext_favicon' => 'Set automatically', // TODO + 'favicon_changed_by_ext' => 'The icon has been set by the <b>%s</b> extension.', // TODO 'filteractions' => array( '_' => 'Filtrar acciones', 'help' => 'Escribir un filtro de búsqueda por línea. Ver <a href="https://freshrss.github.io/FreshRSS/en/users/10_filter.html#with-the-search-field" target="_blank">documentación de operadores de búsqueda</a>.', ), 'http_headers' => 'HTTP Headers', // IGNORE 'http_headers_help' => 'Los Headers son separados por un salto de linea, y el nombre y valor de un Header son separados con dos puntos (e.g: <kbd><code>Accept: application/atom+xml<br />Authorization: Bearer some-token</code></kbd>).', + 'icon' => 'Icon', // TODO 'information' => 'Información', 'keep_min' => 'Número mínimo de artículos a conservar', 'kind' => array( @@ -212,6 +216,7 @@ return array( ), 'proxy' => 'Establecer un proxy para obtener esta fuente', 'proxy_help' => 'Seleccione un protocolo (e.g: SOCKS5) e introduzca la dirección del proxy (e.g: <kbd>127.0.0.1:1080</kbd> o <kbd>username:password@127.0.0.1:1080</kbd>)', + 'reset_favicon' => 'Reset to default', // TODO 'selector_preview' => array( 'show_raw' => 'Mostrar código fuente', 'show_rendered' => 'Mostrar contenido', diff --git a/app/i18n/fa/feedback.php b/app/i18n/fa/feedback.php index 57a69a8a7..0c3bd7853 100644 --- a/app/i18n/fa/feedback.php +++ b/app/i18n/fa/feedback.php @@ -95,6 +95,10 @@ return array( 'cache_cleared' => '<em>%s</em> کش پاک شده است', 'deleted' => ' فید حذف شده است', 'error' => ' فید را نمی توان به روز کرد', + 'favicon' => array( + 'too_large' => 'Uploaded icon is too large. The maximum file size is <em>%s</em>.', // TODO + 'unsupported_format' => 'Unsupported image file format!', // TODO + ), 'internal_problem' => ' فید خبری اضافه نشد. برای جزئیات <a href="%s">گزارشهای FreshRSS</a> را بررسی کنید. میتوانید با اضافه کردن <code>#force_feed</code> به URL', 'invalid_url' => ' URL <em>%s</em> نامعتبر است', 'n_actualized' => ' %d فید به روز شده است', diff --git a/app/i18n/fa/sub.php b/app/i18n/fa/sub.php index c6dab87d2..2a7e96f6d 100644 --- a/app/i18n/fa/sub.php +++ b/app/i18n/fa/sub.php @@ -50,6 +50,7 @@ return array( 'password' => ' رمز عبور HTTP', 'username' => ' نام کاربری HTTP', ), + 'change_favicon' => 'Change…', // TODO 'clear_cache' => ' همیشه حافظه پنهان را پاک کنید', 'content_action' => array( '_' => ' اقدام محتوا هنگام واکشی محتوای مقاله', @@ -74,12 +75,15 @@ return array( 'help' => 'XML file (data subset. <a href="https://freshrss.github.io/FreshRSS/en/developers/OPML.html" target="_blank">See documentation</a>)', // TODO 'label' => 'Export as OPML', // TODO ), + 'ext_favicon' => 'Set automatically', // TODO + 'favicon_changed_by_ext' => 'The icon has been set by the <b>%s</b> extension.', // TODO 'filteractions' => array( '_' => ' اعمال فیلتر', 'help' => ' در هر خط یک فیلتر جستجو بنویسید. اپراتورها <a href="https://freshrss.github.io/FreshRSS/en/users/10_filter.html#with-the-search-field" target="_blank">مستندات را ببینید</a>.', ), 'http_headers' => 'HTTP Headers', // TODO 'http_headers_help' => 'Headers are separated by a newline, and the name and value of a header are separated by a colon (e.g: <kbd><code>Accept: application/atom+xml<br />Authorization: Bearer some-token</code></kbd>).', // TODO + 'icon' => 'Icon', // TODO 'information' => ' اطلاعات', 'keep_min' => ' حداقل تعداد مقالات برای نگهداری', 'kind' => array( @@ -212,6 +216,7 @@ return array( ), 'proxy' => ' یک پروکسی برای واکشی این فید تنظیم کنید', 'proxy_help' => ' یک پروتکل (به عنوان مثال: SOCKS5) انتخاب کنید و آدرس پراکسی را وارد کنید (به عنوان مثال: <kbd>127.0.0.1:1080</kbd> or <kbd>username:password@127.0.0.1:1080</kbd>)', // DIRTY + 'reset_favicon' => 'Reset to default', // TODO 'selector_preview' => array( 'show_raw' => ' نمایش کد منبع', 'show_rendered' => 'نمایش محتوا', diff --git a/app/i18n/fi/feedback.php b/app/i18n/fi/feedback.php index d2e694ed5..320495160 100644 --- a/app/i18n/fi/feedback.php +++ b/app/i18n/fi/feedback.php @@ -95,6 +95,10 @@ return array( 'cache_cleared' => 'Välimuisti <em>%s</em> on tyhjennetty', 'deleted' => 'Syöte on poistettu', 'error' => 'Syötteen päivitys ei onnistu', + 'favicon' => array( + 'too_large' => 'Uploaded icon is too large. The maximum file size is <em>%s</em>.', // TODO + 'unsupported_format' => 'Unsupported image file format!', // TODO + ), 'internal_problem' => 'Uutissyötettä ei voinut lisätä. Lisätietoja on <a href="%s">FreshRSS-lokeissa</a>. Voit yrittää pakottaa lisäämisen liittämällä tekstin <code>#force_feed</code> URL-osoitteen loppuun.', 'invalid_url' => 'URL-osoite <em>%s</em> on virheellinen', 'n_actualized' => '%d syötettä on päivitetty', diff --git a/app/i18n/fi/sub.php b/app/i18n/fi/sub.php index ce7481af9..6e852e10f 100644 --- a/app/i18n/fi/sub.php +++ b/app/i18n/fi/sub.php @@ -50,6 +50,7 @@ return array( 'password' => 'HTTP-salasana', 'username' => 'HTTP-käyttäjätunnus', ), + 'change_favicon' => 'Change…', // TODO 'clear_cache' => 'Tyhjennä välimuisti aina', 'content_action' => array( '_' => 'Toiminto noudettaessa artikkelin sisältö', @@ -74,12 +75,15 @@ return array( 'help' => 'XML-tiedosto (osa tiedoista. <a href="https://freshrss.github.io/FreshRSS/en/developers/OPML.html" target="_blank">Katso ohje</a>)', 'label' => 'Vie OPML-tiedostoksi', ), + 'ext_favicon' => 'Set automatically', // TODO + 'favicon_changed_by_ext' => 'The icon has been set by the <b>%s</b> extension.', // TODO 'filteractions' => array( '_' => 'Suodatustoiminnot', 'help' => 'Kirjoita kukin hakusuodatin omalle rivilleen. Lisätietoja operaattoreista <a href="https://freshrss.github.io/FreshRSS/en/users/10_filter.html#with-the-search-field" target="_blank">ohjeissa</a>.', ), 'http_headers' => 'HTTP-otsikot', 'http_headers_help' => 'Otsikot erotellaan rivinvaihdoin, ja nimi ja arvo erotellaan kaksoispisteellä. Esimerkki: <kbd><code>Accept: application/atom+xml<br />Authorization: Bearer some-token</code></kbd>).', + 'icon' => 'Icon', // TODO 'information' => 'Tiedot', 'keep_min' => 'Säilytettävien artikkeleiden vähimmäismäärä', 'kind' => array( @@ -212,6 +216,7 @@ return array( ), 'proxy' => 'Nouda syöte käyttämällä välityspalvelinta', 'proxy_help' => 'Valitse protokolla (esimerkki: SOCKS5) ja kirjoita välityspalvelimen osoite (esimerkki: <kbd>127.0.0.1:1080</kbd> tai <kbd>käyttäjätunnus:salasana@127.0.0.1:1080</kbd>)', + 'reset_favicon' => 'Reset to default', // TODO 'selector_preview' => array( 'show_raw' => 'Näytä lähdekoodi', 'show_rendered' => 'Näytä sisältö', diff --git a/app/i18n/fr/feedback.php b/app/i18n/fr/feedback.php index 99edb39bf..f6388bf59 100644 --- a/app/i18n/fr/feedback.php +++ b/app/i18n/fr/feedback.php @@ -95,6 +95,10 @@ return array( 'cache_cleared' => 'Le cache de <em>%s</em> a été vidée.', 'deleted' => 'Le flux a été supprimé.', 'error' => 'Une erreur est survenue', + 'favicon' => array( + 'too_large' => 'L’icône téléversée est trop grosse ! La taille maximale du fichier est de <em>%s</em>.', + 'unsupported_format' => 'Format d’image non pris en charge !', + ), 'internal_problem' => 'Le flux ne peut pas être ajouté. <a href="%s">Consulter les logs de FreshRSS</a> pour plus de détails. Vous pouvez essayer de forcer l’ajout par addition de <code>#force_feed</code> à l’URL.', 'invalid_url' => 'L’url <em>%s</em> est invalide.', 'n_actualized' => '%d flux ont été mis à jour.', diff --git a/app/i18n/fr/sub.php b/app/i18n/fr/sub.php index fc88d9e5c..19b1348e0 100644 --- a/app/i18n/fr/sub.php +++ b/app/i18n/fr/sub.php @@ -50,6 +50,7 @@ return array( 'password' => 'Mot de passe HTTP', 'username' => 'Identifiant HTTP', ), + 'change_favicon' => 'Changer…', 'clear_cache' => 'Toujours vider le cache', 'content_action' => array( '_' => 'Action à effectuer pour la réception du contenu des articles', @@ -74,12 +75,15 @@ return array( 'help' => 'Fichier XML (données partielles. <a href="https://freshrss.github.io/FreshRSS/en/developers/OPML.html" target="_blank">Voir documentation</a>)', 'label' => 'Exporter en OPML', ), + 'ext_favicon' => 'Définie automatiquement', + 'favicon_changed_by_ext' => 'L’icône a été définie par l’extension <b>%s</b>.', 'filteractions' => array( '_' => 'Filtres d’action', 'help' => 'Écrivez une recherche par ligne. Voir la <a href="https://freshrss.github.io/FreshRSS/fr/users/03_Main_view.html#gr%C3%A2ce-au-champ-de-recherche" target="_blank">documentation des opérateurs</a>.', ), 'http_headers' => 'Entêtes HTTP', 'http_headers_help' => 'Un entête HTTP par ligne, avec le nom et la valeur séparés par un deux-points (ex. : <kbd><code>Accept: application/atom+xml<br />Authorization: Bearer some-token</code></kbd>).', + 'icon' => 'Icône', 'information' => 'Informations', 'keep_min' => 'Nombre minimum d’articles à conserver', 'kind' => array( @@ -212,6 +216,7 @@ return array( ), 'proxy' => 'Utiliser un proxy pour télécharger ce flux', 'proxy_help' => 'Sélectionner un protocole (ex : SOCKS5) et entrer l’adresse du proxy (ex. : <kbd>127.0.0.1:1080</kbd> ou <kbd>utilisateur:mot-de-passe@127.0.0.1:1080</kbd>)', + 'reset_favicon' => 'Réinitialiser', 'selector_preview' => array( 'show_raw' => 'Afficher le code source', 'show_rendered' => 'Afficher le contenu', diff --git a/app/i18n/he/feedback.php b/app/i18n/he/feedback.php index dcc2c413c..f4c8132ab 100644 --- a/app/i18n/he/feedback.php +++ b/app/i18n/he/feedback.php @@ -95,6 +95,10 @@ return array( 'cache_cleared' => '<em>%s</em> cache has been cleared', // TODO 'deleted' => 'ההזנה נמחקה', 'error' => 'Feed cannot be updated', // TODO + 'favicon' => array( + 'too_large' => 'Uploaded icon is too large. The maximum file size is <em>%s</em>.', // TODO + 'unsupported_format' => 'Unsupported image file format!', // TODO + ), 'internal_problem' => 'אין אפשרות להוסיף את ההזנה. <a href="%s">בדקו את הלוגים</a> לפרטים. You can try force adding by appending <code>#force_feed</code> to the URL.', // DIRTY 'invalid_url' => 'URL <em>%s</em> אינו תקין', 'n_actualized' => '%d הזנות עודכנו', diff --git a/app/i18n/he/sub.php b/app/i18n/he/sub.php index fe9779b67..076945003 100644 --- a/app/i18n/he/sub.php +++ b/app/i18n/he/sub.php @@ -50,6 +50,7 @@ return array( 'password' => 'HTTP סיסמה', 'username' => 'HTTP שם משתמש', ), + 'change_favicon' => 'Change…', // TODO 'clear_cache' => 'Always clear cache', // TODO 'content_action' => array( '_' => 'Content action when fetching the article content', // TODO @@ -74,12 +75,15 @@ return array( 'help' => 'XML file (data subset. <a href="https://freshrss.github.io/FreshRSS/en/developers/OPML.html" target="_blank">See documentation</a>)', // TODO 'label' => 'Export as OPML', // TODO ), + 'ext_favicon' => 'Set automatically', // TODO + 'favicon_changed_by_ext' => 'The icon has been set by the <b>%s</b> extension.', // TODO 'filteractions' => array( '_' => 'Filter actions', // TODO 'help' => 'Write one search filter per line. Operators <a href="https://freshrss.github.io/FreshRSS/en/users/10_filter.html#with-the-search-field" target="_blank">see documentation</a>.', // TODO ), 'http_headers' => 'HTTP Headers', // TODO 'http_headers_help' => 'Headers are separated by a newline, and the name and value of a header are separated by a colon (e.g: <kbd><code>Accept: application/atom+xml<br />Authorization: Bearer some-token</code></kbd>).', // TODO + 'icon' => 'Icon', // TODO 'information' => 'מידע', 'keep_min' => 'מסםר מינימלי של מאמרים לשמור', 'kind' => array( @@ -212,6 +216,7 @@ return array( ), 'proxy' => 'Set a proxy for fetching this feed', // TODO 'proxy_help' => 'Select a protocol (e.g: SOCKS5) and enter the proxy address (e.g: <kbd>127.0.0.1:1080</kbd> or <kbd>username:password@127.0.0.1:1080</kbd>)', // TODO + 'reset_favicon' => 'Reset to default', // TODO 'selector_preview' => array( 'show_raw' => 'Show source code', // TODO 'show_rendered' => 'Show content', // TODO diff --git a/app/i18n/hu/feedback.php b/app/i18n/hu/feedback.php index db0e1907a..6a9ac9ae4 100755 --- a/app/i18n/hu/feedback.php +++ b/app/i18n/hu/feedback.php @@ -95,6 +95,10 @@ return array( 'cache_cleared' => '<em>%s</em> gyorsítótára kiürítve', 'deleted' => 'Hírforrás törlése megtörtént', 'error' => 'Hírforrás frissítése nem lehetséges', + 'favicon' => array( + 'too_large' => 'Uploaded icon is too large. The maximum file size is <em>%s</em>.', // TODO + 'unsupported_format' => 'Unsupported image file format!', // TODO + ), 'internal_problem' => 'A hírforrást nem sikerült hozzáadni. <a href="%s">Nézd meg a FreshRSS logokat</a> a részletekért. Megpróbálhatod mindenképp hozzáadni, ha az <code>#force_feed</code> szöveget az URL után írod.', 'invalid_url' => 'URL <em>%s</em> érvénytelen', 'n_actualized' => '%d hírforrások frissítése kész', diff --git a/app/i18n/hu/sub.php b/app/i18n/hu/sub.php index b9595e73d..d4f21a813 100755 --- a/app/i18n/hu/sub.php +++ b/app/i18n/hu/sub.php @@ -50,6 +50,7 @@ return array( 'password' => 'HTTP jelszó', 'username' => 'HTTP felhasználónév', ), + 'change_favicon' => 'Change…', // TODO 'clear_cache' => 'Mindig törölje a cache-t', 'content_action' => array( '_' => 'Tartalom művelet, amikor cikk tartalma beszerzésre kerül', @@ -74,12 +75,15 @@ return array( 'help' => 'XML fájl (adat részhalmaz. <a href="https://freshrss.github.io/FreshRSS/en/developers/OPML.html" target="_blank">Lásd dokumentáció</a>)', 'label' => 'Exportálás OPML formátumban', ), + 'ext_favicon' => 'Set automatically', // TODO + 'favicon_changed_by_ext' => 'The icon has been set by the <b>%s</b> extension.', // TODO 'filteractions' => array( '_' => 'Szűrő műveletek', 'help' => 'Írj egy szűrőt soronként. Műveletek <a href="https://freshrss.github.io/FreshRSS/en/users/10_filter.html#with-the-search-field" target="_blank">a dokumentációban</a>.', ), 'http_headers' => 'HTTP Fejlécek', 'http_headers_help' => 'A fejléceket újsor választja el, a fejléc nevét és értékét kettőspont választja el (pl: <kbd><code>Accept: application/atom+xml<br />Authorization: Bearer some-token</code></kbd>).', + 'icon' => 'Icon', // TODO 'information' => 'Információ', 'keep_min' => 'Megtartandó cikkek minimális száma', 'kind' => array( @@ -212,6 +216,7 @@ return array( ), 'proxy' => 'Állíts be egy proxy-t a hírforráshoz ', 'proxy_help' => 'Válassz egy protokollt (pl.: SOCKS5) és add meg a proxy címét (pl.: <kbd>127.0.0.1:1080</kbd> vagy <kbd>felhasználónév:jelszó@127.0.0.1:1080</kbd>)', + 'reset_favicon' => 'Reset to default', // TODO 'selector_preview' => array( 'show_raw' => 'Forráskód mutatása', 'show_rendered' => 'Tartalom mutatása', diff --git a/app/i18n/id/feedback.php b/app/i18n/id/feedback.php index 6e2e8efa6..ff4a19226 100644 --- a/app/i18n/id/feedback.php +++ b/app/i18n/id/feedback.php @@ -95,6 +95,10 @@ return array( 'cache_cleared' => '<em>%s</em> cache has been cleared', // TODO 'deleted' => 'Feed has been deleted', // TODO 'error' => 'Feed cannot be updated', // TODO + 'favicon' => array( + 'too_large' => 'Uploaded icon is too large. The maximum file size is <em>%s</em>.', // TODO + 'unsupported_format' => 'Unsupported image file format!', // TODO + ), 'internal_problem' => 'The newsfeed could not be added. <a href="%s">Check FreshRSS logs</a> for details. You can try force adding by appending <code>#force_feed</code> to the URL.', // TODO 'invalid_url' => 'URL <em>%s</em> is invalid', // TODO 'n_actualized' => '%d feeds have been updated', // TODO diff --git a/app/i18n/id/sub.php b/app/i18n/id/sub.php index e6e79c8e9..91db20b18 100644 --- a/app/i18n/id/sub.php +++ b/app/i18n/id/sub.php @@ -50,6 +50,7 @@ return array( 'password' => 'Kata sandi HTTP', 'username' => 'Nama pengguna HTTP', ), + 'change_favicon' => 'Change…', // TODO 'clear_cache' => 'Selalu bersihkan tembolok', 'content_action' => array( '_' => 'Yang dilakukan ketika mengambil konten artikel', @@ -74,12 +75,15 @@ return array( 'help' => 'Berkas XML (subset data. <a href="https://freshrss.github.io/FreshRSS/en/developers/OPML.html" target="_blank">Lihat dokumentasi</a>)', 'label' => 'Unduh dalam bentuk OPML', ), + 'ext_favicon' => 'Set automatically', // TODO + 'favicon_changed_by_ext' => 'The icon has been set by the <b>%s</b> extension.', // TODO 'filteractions' => array( '_' => 'Tindakan penyaringan', 'help' => 'Tulis satu penyaringan pencarian per baris. Operator <a href="https://freshrss.github.io/FreshRSS/en/users/10_filter.html#with-the-search-field" target="_blank">lihat dokumentasi</a>.', ), 'http_headers' => 'Tajuk HTTP', 'http_headers_help' => 'Tajuk dipisahkan dengan baris baru dan nama dan nilai dari tajuk dipisahkan dengan titik dua (contoh: <kbd><code>Accept: application/atom+xml<br />Authorization: Bearer some-token</code></kbd>).', + 'icon' => 'Icon', // TODO 'information' => 'Informasi', 'keep_min' => 'Jumlah minimum artikel yang harus disimpan', 'kind' => array( @@ -212,6 +216,7 @@ return array( ), 'proxy' => 'Atur proksi untuk mengambil umpan ini', 'proxy_help' => 'Pilih protokol (contoh: SOCKS5) dan masukkan alamat proksi (contoh: <kbd>127.0.0.1:1080</kbd> atau <kbd>username:password@127.0.0.1:1080</kbd>)', + 'reset_favicon' => 'Reset to default', // TODO 'selector_preview' => array( 'show_raw' => 'Tampilkan kode sumber', 'show_rendered' => 'Tampilkan konten', diff --git a/app/i18n/it/feedback.php b/app/i18n/it/feedback.php index 5b6092e7f..a85e91f7e 100644 --- a/app/i18n/it/feedback.php +++ b/app/i18n/it/feedback.php @@ -95,6 +95,10 @@ return array( 'cache_cleared' => 'La cache di <em>%s</em> è stata svuotata', 'deleted' => 'Feed cancellato', 'error' => 'Feed non aggiornato', + 'favicon' => array( + 'too_large' => 'Uploaded icon is too large. The maximum file size is <em>%s</em>.', // TODO + 'unsupported_format' => 'Unsupported image file format!', // TODO + ), 'internal_problem' => 'Feed RSS non aggiunto. <a href="%s">Verifica i log</a> per dettagli. Puoi provare l’aggiunta forzata aggiungendo <code>#force_feed</code> all’URL.', 'invalid_url' => 'URL <em>%s</em> non valido', 'n_actualized' => '%d feed aggiornati', diff --git a/app/i18n/it/sub.php b/app/i18n/it/sub.php index fad888ff1..3d4b29c40 100644 --- a/app/i18n/it/sub.php +++ b/app/i18n/it/sub.php @@ -50,6 +50,7 @@ return array( 'password' => 'Password HTTP', 'username' => 'Nome utente HTTP', ), + 'change_favicon' => 'Change…', // TODO 'clear_cache' => 'Cancella sempre la cache', 'content_action' => array( '_' => 'Azione da effettuare quando viene recuperato il contenuto di un articolo', @@ -74,12 +75,15 @@ return array( 'help' => 'File XML (sottoinsieme di dati. <a href="https://freshrss.github.io/FreshRSS/en/developers/OPML.html" target="_blank">Leggi la documentazione</a>)', 'label' => 'Esporta come OPML', ), + 'ext_favicon' => 'Set automatically', // TODO + 'favicon_changed_by_ext' => 'The icon has been set by the <b>%s</b> extension.', // TODO 'filteractions' => array( '_' => 'Azioni di filtro', 'help' => 'Scrivi un filtro di ricerca per riga. Per li operatori <a href="https://freshrss.github.io/FreshRSS/en/users/10_filter.html#with-the-search-field" target="_blank">vedi la documentazione</a>.', ), 'http_headers' => 'HTTP Headers', // IGNORE 'http_headers_help' => 'Le intestazioni sono separate da una linea e il nome e il valore di un’intestazione sono separati da due punti (p.es: <kbd><code>Accept: application/atom+xml<br />Authorization: Bearer some-token</code></kbd>).', + 'icon' => 'Icon', // TODO 'information' => 'Informazioni', 'keep_min' => 'Numero minimo di articoli da mantenere', 'kind' => array( @@ -212,6 +216,7 @@ return array( ), 'proxy' => 'Imposta un proxy per recuperare questo feed', 'proxy_help' => 'Seleziona un protocollo (e.g: SOCKS5) ed inserisci l’indirizzo del proxy (es.: <kbd>127.0.0.1:1080</kbd> o <kbd>username:password@127.0.0.1:1080</kbd>)', + 'reset_favicon' => 'Reset to default', // TODO 'selector_preview' => array( 'show_raw' => 'Mostra codice sorgente', 'show_rendered' => 'Mostra contenuto', diff --git a/app/i18n/ja/feedback.php b/app/i18n/ja/feedback.php index 13bbd5fab..5a474b27a 100644 --- a/app/i18n/ja/feedback.php +++ b/app/i18n/ja/feedback.php @@ -95,6 +95,10 @@ return array( 'cache_cleared' => '<em>%s</em>キャッシュは作られました', 'deleted' => 'フィードは消去されました', 'error' => 'フィードを更新することができません', + 'favicon' => array( + 'too_large' => 'Uploaded icon is too large. The maximum file size is <em>%s</em>.', // TODO + 'unsupported_format' => 'Unsupported image file format!', // TODO + ), 'internal_problem' => 'newsfeedを追加することはできません。<a href="%s">FreshRSSログの詳細を</a>確かめてください。強制的に追加することを試せます <code>#force_feed</code>このURLを確認ください。', 'invalid_url' => 'URL <em>%s</em>は無効です', 'n_actualized' => '%d フィードはアップデートされました', diff --git a/app/i18n/ja/sub.php b/app/i18n/ja/sub.php index d59e0d032..cd9ff501e 100644 --- a/app/i18n/ja/sub.php +++ b/app/i18n/ja/sub.php @@ -50,6 +50,7 @@ return array( 'password' => 'HTTP パスワード', 'username' => 'HTTP ユーザー名', ), + 'change_favicon' => 'Change…', // TODO 'clear_cache' => '常にキャッシュをクリアする', 'content_action' => array( '_' => '記事のコンテンツを取得するときの動作', @@ -74,12 +75,15 @@ return array( 'help' => 'XMLファイル (データのサブセット。<a href="https://freshrss.github.io/FreshRSS/en/developers/OPML.html" target="_blank">ドキュメントを参照してください</a>。)', 'label' => 'OPMLとしてエクスポート', ), + 'ext_favicon' => 'Set automatically', // TODO + 'favicon_changed_by_ext' => 'The icon has been set by the <b>%s</b> extension.', // TODO 'filteractions' => array( '_' => 'フィルターアクション', 'help' => '1行に1つの検索フィルターを設定してください。演算子は<a href="https://freshrss.github.io/FreshRSS/en/users/10_filter.html#with-the-search-field" target="_blank">ドキュメントを参照してください</a>。', ), 'http_headers' => 'HTTPヘッダ', 'http_headers_help' => 'ヘッダは開業で区切られ、ヘッダの名前と値はコロンで区切られます (例: <kbd><code>Accept: application/atom+xml<br />Authorization: Bearer some-token</code></kbd>).', + 'icon' => 'Icon', // TODO 'information' => 'インフォメーション', 'keep_min' => '最小数の記事は保持されます', 'kind' => array( @@ -212,6 +216,7 @@ return array( ), 'proxy' => 'フィードを取得するときのプロキシ', 'proxy_help' => 'プロトコルを選択し (例: SOCKS5) プロキシアドレスを入力してください (例: <kbd>127.0.0.1:1080</kbd> や <kbd>username:password@127.0.0.1:1080</kbd>)', + 'reset_favicon' => 'Reset to default', // TODO 'selector_preview' => array( 'show_raw' => 'ソースコードを表示する', 'show_rendered' => 'コンテンツを表示する', diff --git a/app/i18n/ko/feedback.php b/app/i18n/ko/feedback.php index 457731a97..63d05c02c 100644 --- a/app/i18n/ko/feedback.php +++ b/app/i18n/ko/feedback.php @@ -95,6 +95,10 @@ return array( 'cache_cleared' => '<em>%s</em> 캐쉬 지움', 'deleted' => '피드가 삭제되었습니다', 'error' => '피드를 변경할 수 없습니다', + 'favicon' => array( + 'too_large' => 'Uploaded icon is too large. The maximum file size is <em>%s</em>.', // TODO + 'unsupported_format' => 'Unsupported image file format!', // TODO + ), 'internal_problem' => 'RSS 피드를 추가할 수 없습니다. 자세한 내용은 <a href="%s">FreshRSS 로그</a>를 참고하세요. <code>#force_feed</code>를 URL에 추가하여 강제로 추가 시도 할 수 있습니다.', 'invalid_url' => 'URL (<em>%s</em>)이 유효하지 않습니다', 'n_actualized' => '%d 개의 피드에서 새 글을 가져왔습니다', diff --git a/app/i18n/ko/sub.php b/app/i18n/ko/sub.php index d2f993d38..41d06dc19 100644 --- a/app/i18n/ko/sub.php +++ b/app/i18n/ko/sub.php @@ -50,6 +50,7 @@ return array( 'password' => 'HTTP 암호', 'username' => 'HTTP 사용자 이름', ), + 'change_favicon' => 'Change…', // TODO 'clear_cache' => '항상 캐시 지우기', 'content_action' => array( '_' => '글 콘텐츠를 가져올 때의 동작', @@ -74,12 +75,15 @@ return array( 'help' => 'XML 파일 (data subset. <a href="https://freshrss.github.io/FreshRSS/en/developers/OPML.html" target="_blank">See documentation</a>)', // DIRTY 'label' => 'OPML로 내보내기', ), + 'ext_favicon' => 'Set automatically', // TODO + 'favicon_changed_by_ext' => 'The icon has been set by the <b>%s</b> extension.', // TODO 'filteractions' => array( '_' => '필터 동작', 'help' => '한 줄에 한 검색 필터를 작성해 주세요. 실행시 <a href="https://freshrss.github.io/FreshRSS/en/users/10_filter.html#with-the-search-field" target="_blank">문서 참고</a>.', ), 'http_headers' => 'HTTP Headers', // TODO 'http_headers_help' => 'Headers are separated by a newline, and the name and value of a header are separated by a colon (e.g: <kbd><code>Accept: application/atom+xml<br />Authorization: Bearer some-token</code></kbd>).', // TODO + 'icon' => 'Icon', // TODO 'information' => '정보', 'keep_min' => '최소 유지 글 개수', 'kind' => array( @@ -212,6 +216,7 @@ return array( ), 'proxy' => '이 피드를 가져올 때 사용할 프록시 설정', 'proxy_help' => '프로토콜 선택 (예: SOCKS5) 그리고 프록시 주소 입력 (예: <kbd>127.0.0.1:1080</kbd> 혹은 <kbd>username:password@127.0.0.1:1080</kbd>)', + 'reset_favicon' => 'Reset to default', // TODO 'selector_preview' => array( 'show_raw' => '소스코드 표시', 'show_rendered' => '콘텐츠 표시', diff --git a/app/i18n/lv/feedback.php b/app/i18n/lv/feedback.php index 861cf1e06..6e3a6013b 100644 --- a/app/i18n/lv/feedback.php +++ b/app/i18n/lv/feedback.php @@ -95,6 +95,10 @@ return array( 'cache_cleared' => '<em>%s</em> kešatmiņa tika iztukšota', 'deleted' => 'Barortne tika izdzēsta', 'error' => 'Barotne nevar būt atjaunināta', + 'favicon' => array( + 'too_large' => 'Uploaded icon is too large. The maximum file size is <em>%s</em>.', // TODO + 'unsupported_format' => 'Unsupported image file format!', // TODO + ), 'internal_problem' => 'Barotni nevarēja pievienot. <a href="%s">Apskataties FreshRSS žurnālu</a> priekš papildus informācijas. Jūs varat izmēģināt piespiedu pievienošanu, URL pievienojot <code>#force_feed</code>.', 'invalid_url' => 'URL <em>%s</em> ir nepareizs', 'n_actualized' => '%d barotnes tika atjaunotas', diff --git a/app/i18n/lv/sub.php b/app/i18n/lv/sub.php index f22afb5c0..f597f5747 100644 --- a/app/i18n/lv/sub.php +++ b/app/i18n/lv/sub.php @@ -50,6 +50,7 @@ return array( 'password' => 'HTTP parole', 'username' => 'HTTP lietotājvārds', ), + 'change_favicon' => 'Change…', // TODO 'clear_cache' => 'Vienmēr iztīrīt kešatmiņu', 'content_action' => array( '_' => 'Satura darbība, kad tiek iegūts raksta saturs', @@ -74,12 +75,15 @@ return array( 'help' => 'XML file (data subset. <a href="https://freshrss.github.io/FreshRSS/en/developers/OPML.html" target="_blank">See documentation</a>)', // TODO 'label' => 'Export as OPML', // TODO ), + 'ext_favicon' => 'Set automatically', // TODO + 'favicon_changed_by_ext' => 'The icon has been set by the <b>%s</b> extension.', // TODO 'filteractions' => array( '_' => 'Filtra darbības', 'help' => 'Uzrakstiet vienu meklēšanas filtru katrā rindā. Operators <a href="https://freshrss.github.io/FreshRSS/en/users/10_filter.html#with-the-search-field" target="_blank">see documentation</a>.', // DIRTY ), 'http_headers' => 'HTTP Headers', // TODO 'http_headers_help' => 'Headers are separated by a newline, and the name and value of a header are separated by a colon (e.g: <kbd><code>Accept: application/atom+xml<br />Authorization: Bearer some-token</code></kbd>).', // TODO + 'icon' => 'Icon', // TODO 'information' => 'Informācija', 'keep_min' => 'Minimālais saglabājamo izstrādājumu skaits', 'kind' => array( @@ -212,6 +216,7 @@ return array( ), 'proxy' => 'Iestatīt starpniekserveri šīs plūsmas iegūšanai', 'proxy_help' => 'Izvēlieties protokolu (piemēram, SOCKS5) un ievadiet starpniekservera adresi (piemēram, <kbd>127.0.0.0.1:1080</kbd>).', + 'reset_favicon' => 'Reset to default', // TODO 'selector_preview' => array( 'show_raw' => 'Rādīt avota kodu', 'show_rendered' => 'Rādīt saturu', diff --git a/app/i18n/nl/feedback.php b/app/i18n/nl/feedback.php index 39ed01e28..46f532d5c 100644 --- a/app/i18n/nl/feedback.php +++ b/app/i18n/nl/feedback.php @@ -95,6 +95,10 @@ return array( 'cache_cleared' => '<em>%s</em> cache verwijderd', 'deleted' => 'Feed verwijderd', 'error' => 'Feed kan niet worden vernieuwd', + 'favicon' => array( + 'too_large' => 'Uploaded icon is too large. The maximum file size is <em>%s</em>.', // TODO + 'unsupported_format' => 'Unsupported image file format!', // TODO + ), 'internal_problem' => 'De feed kon niet worden toegevoegd. <a href="%s">Controleer de FreshRSS-logbestanden</a> voor details. Toevoegen forceren kan worden geprobeerd door <code>#force_feed</code> aan de URL toe te voegen.', 'invalid_url' => 'URL <em>%s</em> is ongeldig', 'n_actualized' => '%d feeds zijn vernieuwd', diff --git a/app/i18n/nl/sub.php b/app/i18n/nl/sub.php index 9a1c6ab50..968bef419 100644 --- a/app/i18n/nl/sub.php +++ b/app/i18n/nl/sub.php @@ -50,6 +50,7 @@ return array( 'password' => 'HTTP wachtwoord', 'username' => 'HTTP gebruikers naam', ), + 'change_favicon' => 'Change…', // TODO 'clear_cache' => 'Cache altijd leegmaken', 'content_action' => array( '_' => 'Inhoudsactie bij ophalen artikelinhoud', @@ -74,12 +75,15 @@ return array( 'help' => 'XML-bestand (data subset. <a href="https://freshrss.github.io/FreshRSS/en/developers/OPML.html" target="_blank">See documentation</a>)', // DIRTY 'label' => 'Als OPML exporteren', ), + 'ext_favicon' => 'Set automatically', // TODO + 'favicon_changed_by_ext' => 'The icon has been set by the <b>%s</b> extension.', // TODO 'filteractions' => array( '_' => 'Filteracties', 'help' => 'Voer één zoekfilter per lijn in. Operators <a href="https://freshrss.github.io/FreshRSS/en/users/10_filter.html#with-the-search-field" target="_blank">see documentation</a>.', // DIRTY ), 'http_headers' => 'HTTP Headers', // TODO 'http_headers_help' => 'Headers are separated by a newline, and the name and value of a header are separated by a colon (e.g: <kbd><code>Accept: application/atom+xml<br />Authorization: Bearer some-token</code></kbd>).', // TODO + 'icon' => 'Icon', // TODO 'information' => 'Informatie', 'keep_min' => 'Minimum aantal artikelen om te houden', 'kind' => array( @@ -212,6 +216,7 @@ return array( ), 'proxy' => 'Proxy instellen om deze feed op te halen', 'proxy_help' => 'Selecteer een protocol (bv. SOCKS5) en voer een proxy-adres in (b.v. <kbd>127.0.0.1:1080</kbd> or <kbd>username:password@127.0.0.1:1080</kbd>)', // DIRTY + 'reset_favicon' => 'Reset to default', // TODO 'selector_preview' => array( 'show_raw' => 'Broncode tonen', 'show_rendered' => 'Inhoud tonen', diff --git a/app/i18n/oc/feedback.php b/app/i18n/oc/feedback.php index e158cc299..a9b9b88a8 100644 --- a/app/i18n/oc/feedback.php +++ b/app/i18n/oc/feedback.php @@ -95,6 +95,10 @@ return array( 'cache_cleared' => '<em>%s</em> cache escafat', 'deleted' => 'Lo flux es suprimit', 'error' => 'Error en actualizar', + 'favicon' => array( + 'too_large' => 'Uploaded icon is too large. The maximum file size is <em>%s</em>.', // TODO + 'unsupported_format' => 'Unsupported image file format!', // TODO + ), 'internal_problem' => 'Lo flux pòt pas èsser ajustat. <a href="%s">Consultatz los jornals d’audit de FreshRSS</a> per ne saber mai. Podètz forçar l’apondon en ajustant <code>#force_feed</code> a l’URL.', 'invalid_url' => 'L’URL <em>%s</em> es invalida', 'n_actualized' => '%s fluxes son estats actualizats', diff --git a/app/i18n/oc/sub.php b/app/i18n/oc/sub.php index 2cfe454fe..c342fe9e7 100644 --- a/app/i18n/oc/sub.php +++ b/app/i18n/oc/sub.php @@ -50,6 +50,7 @@ return array( 'password' => 'Senhal HTTP', 'username' => 'Identificant HTTP', ), + 'change_favicon' => 'Change…', // TODO 'clear_cache' => 'Totjorn escafar lo cache', 'content_action' => array( '_' => 'Accion sul contengut en recuperant lo contengut de l’article', @@ -74,12 +75,15 @@ return array( 'help' => 'XML file (data subset. <a href="https://freshrss.github.io/FreshRSS/en/developers/OPML.html" target="_blank">See documentation</a>)', // TODO 'label' => 'Export as OPML', // TODO ), + 'ext_favicon' => 'Set automatically', // TODO + 'favicon_changed_by_ext' => 'The icon has been set by the <b>%s</b> extension.', // TODO 'filteractions' => array( '_' => 'Filtre d’accion', 'help' => 'Escrivètz una recèrca per linha. Operators <a href="https://freshrss.github.io/FreshRSS/en/users/10_filter.html#with-the-search-field" target="_blank">see documentation</a>.', // DIRTY ), 'http_headers' => 'HTTP Headers', // TODO 'http_headers_help' => 'Headers are separated by a newline, and the name and value of a header are separated by a colon (e.g: <kbd><code>Accept: application/atom+xml<br />Authorization: Bearer some-token</code></kbd>).', // TODO + 'icon' => 'Icon', // TODO 'information' => 'Informacions', 'keep_min' => 'Nombre minimum d’articles de servar', 'kind' => array( @@ -212,6 +216,7 @@ return array( ), 'proxy' => 'Definir un servidor proxy per trapar aqueste flux', 'proxy_help' => 'Seleccionatz un protocòl (ex : SOCKS5) e picatz l’adreça del proxy (ex : <kbd>127.0.0.1:1080</kbd> or <kbd>username:password@127.0.0.1:1080</kbd>)', // DIRTY + 'reset_favicon' => 'Reset to default', // TODO 'selector_preview' => array( 'show_raw' => 'Veire lo còdi font', 'show_rendered' => 'Veire lo contengut', diff --git a/app/i18n/pl/feedback.php b/app/i18n/pl/feedback.php index 70a6842f1..2da80b952 100644 --- a/app/i18n/pl/feedback.php +++ b/app/i18n/pl/feedback.php @@ -95,6 +95,10 @@ return array( 'cache_cleared' => 'Pamięć podręczna kanału <em>%s</em> została wyczyszczona', 'deleted' => 'Kanał został usunięty', 'error' => 'Nie udało się zaktualizować kanału', + 'favicon' => array( + 'too_large' => 'Przesłana ikona jest zbyt wielka. Maksymalny rozmiar pliku to <em>%s</em>.', + 'unsupported_format' => 'Nieobsługiwany format pliku obrazka!', + ), 'internal_problem' => 'Wystąpił błąd podczas dodawania kanału. <a href="%s">Sprawdź dziennik</a> w celu uzyskania szczegółowych informacji. Można spróbować wymusić dodanie kanału przez dodanie <code>#force_feed</code> na końcu adresu URL.', 'invalid_url' => 'Adres URL <em>%s</em> nie jest prawidłowy', 'n_actualized' => 'Liczba zaktualizowanych kanałów: %d', diff --git a/app/i18n/pl/sub.php b/app/i18n/pl/sub.php index f7e54a430..b334265bc 100644 --- a/app/i18n/pl/sub.php +++ b/app/i18n/pl/sub.php @@ -50,6 +50,7 @@ return array( 'password' => 'Hasło HTTP', 'username' => 'Użytkownik HTTP', ), + 'change_favicon' => 'Zmień…', 'clear_cache' => 'Zawsze czyść pamięć podręczną', 'content_action' => array( '_' => 'Sposób zachowania zawartości pobranej z pierwotnej strony', @@ -74,12 +75,15 @@ return array( 'help' => 'Plik XML (podzbiór danych. <a href="https://freshrss.github.io/FreshRSS/en/developers/OPML.html" target="_blank">Zobacz dokumentację</a>)', 'label' => 'Eksportuj OPML', ), + 'ext_favicon' => 'Ustaw automatycznie', + 'favicon_changed_by_ext' => 'Ikona została ustawiona przez rozszerzenie <b>%s</b>.', 'filteractions' => array( '_' => 'Akcje filtrowania', 'help' => 'Jedno zapytanie na linię. Operatory opisane są w <a href="https://freshrss.github.io/FreshRSS/en/users/10_filter.html#with-the-search-field" target="_blank">dokumentacji</a>.', ), 'http_headers' => 'Nagłówki HTTP', 'http_headers_help' => 'Nagłówki są oddzielane przez nową linię, a nazwa i wartość nagłówka są oddzielane przez dwukropek (np: <kbd><code>Accept: application/atom+xml<br />Authorization: Bearer jakiś-token</code></kbd>).', + 'icon' => 'Ikona', 'information' => 'Informacja', 'keep_min' => 'Minimalna liczba wiadomości do przechowywania', 'kind' => array( @@ -212,6 +216,7 @@ return array( ), 'proxy' => 'Serwer proxy używany podczas pobierania kanału', 'proxy_help' => 'Wybierz protokół (np. SOCKS5) i podaj adres serwera proxy (np. <kbd>127.0.0.1:1080</kbd> lub <kbd>username:password@127.0.0.1:1080</kbd>)', + 'reset_favicon' => 'Przywróć domyślną', 'selector_preview' => array( 'show_raw' => 'Pokaż źródło', 'show_rendered' => 'Pokaż zawartość', diff --git a/app/i18n/pt-br/feedback.php b/app/i18n/pt-br/feedback.php index 562efb0b6..027304ed7 100644 --- a/app/i18n/pt-br/feedback.php +++ b/app/i18n/pt-br/feedback.php @@ -95,6 +95,10 @@ return array( 'cache_cleared' => 'O cache do feed <em>%s</em> foi limpo', 'deleted' => 'o feed foi deletado', 'error' => 'O feed não pode ser atualizado', + 'favicon' => array( + 'too_large' => 'Uploaded icon is too large. The maximum file size is <em>%s</em>.', // TODO + 'unsupported_format' => 'Unsupported image file format!', // TODO + ), 'internal_problem' => 'O feed RSS não pôde ser adicionado. <a href="%s">Verifique os logs do FreshRSS</a> para detalhes. You can try force adding by appending <code>#force_feed</code> to the URL.', // DIRTY 'invalid_url' => 'URL <em>%s</em> é inválida', 'n_actualized' => '%d feeds foram atualizados', diff --git a/app/i18n/pt-br/sub.php b/app/i18n/pt-br/sub.php index a54be7569..f26f8afc4 100644 --- a/app/i18n/pt-br/sub.php +++ b/app/i18n/pt-br/sub.php @@ -50,6 +50,7 @@ return array( 'password' => 'Senha HTTP', 'username' => 'Usuário HTTP', ), + 'change_favicon' => 'Change…', // TODO 'clear_cache' => 'Sempre limpar o cache', 'content_action' => array( '_' => 'Ações ao buscar pelo conteúdo de artigos', @@ -74,12 +75,15 @@ return array( 'help' => 'Arquivo XML (data subset. <a href="https://freshrss.github.io/FreshRSS/en/developers/OPML.html" target="_blank">See documentation</a>)', // DIRTY 'label' => 'Exportar como OPML', ), + 'ext_favicon' => 'Set automatically', // TODO + 'favicon_changed_by_ext' => 'The icon has been set by the <b>%s</b> extension.', // TODO 'filteractions' => array( '_' => 'Ações do filtro', 'help' => 'Escreva um filtro de pesquisa por linha. Operators <a href="https://freshrss.github.io/FreshRSS/en/users/10_filter.html#with-the-search-field" target="_blank">see documentation</a>.', // DIRTY ), 'http_headers' => 'HTTP Headers', // TODO 'http_headers_help' => 'Headers are separated by a newline, and the name and value of a header are separated by a colon (e.g: <kbd><code>Accept: application/atom+xml<br />Authorization: Bearer some-token</code></kbd>).', // TODO + 'icon' => 'Icon', // TODO 'information' => 'Informações', 'keep_min' => 'Número mínimo de artigos para manter', 'kind' => array( @@ -212,6 +216,7 @@ return array( ), 'proxy' => 'Defina um proxy para buscar esse feed', 'proxy_help' => 'Selecione um protocolo (e.g: SOCKS5) e digite o endereço do proxy (e.g: <kbd>127.0.0.1:1080</kbd> or <kbd>username:password@127.0.0.1:1080</kbd>)', + 'reset_favicon' => 'Reset to default', // TODO 'selector_preview' => array( 'show_raw' => 'Mostrar fonte', 'show_rendered' => 'Mostrar conteúdo', diff --git a/app/i18n/pt-pt/feedback.php b/app/i18n/pt-pt/feedback.php index 995947f9f..761b6e43c 100644 --- a/app/i18n/pt-pt/feedback.php +++ b/app/i18n/pt-pt/feedback.php @@ -95,6 +95,10 @@ return array( 'cache_cleared' => 'O cache do feed <em>%s</em> foi limpo', 'deleted' => 'o feed foi apagado', 'error' => 'O feed não pode ser atualizado', + 'favicon' => array( + 'too_large' => 'Uploaded icon is too large. The maximum file size is <em>%s</em>.', // TODO + 'unsupported_format' => 'Unsupported image file format!', // TODO + ), 'internal_problem' => 'O feed RSS não pôde ser adicionado. <a href="%s">Verifique os logs do FreshRSS</a> para detalhes. Pode forçar a atualização no link <code>#force_feed</code> .', 'invalid_url' => 'URL <em>%s</em> é inválida', 'n_actualized' => '%d feeds foram atualizados', diff --git a/app/i18n/pt-pt/sub.php b/app/i18n/pt-pt/sub.php index 8d19764c6..12c5c2b5b 100644 --- a/app/i18n/pt-pt/sub.php +++ b/app/i18n/pt-pt/sub.php @@ -50,6 +50,7 @@ return array( 'password' => 'Senha HTTP', 'username' => 'Utilizador HTTP', ), + 'change_favicon' => 'Change…', // TODO 'clear_cache' => 'Sempre limpar o cache', 'content_action' => array( '_' => 'Ações ao buscar pelo conteúdo de artigos', @@ -74,12 +75,15 @@ return array( 'help' => 'Arquivo XML (. <a href="https://freshrss.github.io/FreshRSS/en/developers/OPML.html" target="_blank">Ver documentação</a>)', 'label' => 'Exportar como OPML', ), + 'ext_favicon' => 'Set automatically', // TODO + 'favicon_changed_by_ext' => 'The icon has been set by the <b>%s</b> extension.', // TODO 'filteractions' => array( '_' => 'Ações do filtro', 'help' => 'Escreva um filtro de pesquisa por linha. <a href="https://freshrss.github.io/FreshRSS/en/users/10_filter.html#with-the-search-field" target="_blank">Ver documentação</a>.', ), 'http_headers' => 'HTTP Headers', // TODO 'http_headers_help' => 'Headers are separated by a newline, and the name and value of a header are separated by a colon (e.g: <kbd><code>Accept: application/atom+xml<br />Authorization: Bearer some-token</code></kbd>).', // TODO + 'icon' => 'Icon', // TODO 'information' => 'Informações', 'keep_min' => 'Número mínimo de artigos para manter', 'kind' => array( @@ -212,6 +216,7 @@ return array( ), 'proxy' => 'Defina um proxy para buscar esse feed', 'proxy_help' => 'Selecione um protocolo (e.g: SOCKS5) e digite o endereço do proxy (e.g: <kbd>127.0.0.1:1080</kbd> or <kbd>username:password@127.0.0.1:1080</kbd>)', + 'reset_favicon' => 'Reset to default', // TODO 'selector_preview' => array( 'show_raw' => 'Mostrar fonte', 'show_rendered' => 'Mostrar conteúdo', diff --git a/app/i18n/ru/feedback.php b/app/i18n/ru/feedback.php index 4e3e61c57..c0613cbb7 100644 --- a/app/i18n/ru/feedback.php +++ b/app/i18n/ru/feedback.php @@ -95,6 +95,10 @@ return array( 'cache_cleared' => 'Кэш <em>%s</em> очищен', 'deleted' => 'Лента удалена', 'error' => 'Лента не может быть изменена', + 'favicon' => array( + 'too_large' => 'Uploaded icon is too large. The maximum file size is <em>%s</em>.', // TODO + 'unsupported_format' => 'Unsupported image file format!', // TODO + ), 'internal_problem' => 'Новостная лента не может быть добавлена. <a href="%s">Проверьте логи FreshRSS</a> для подробностей. Вы можете попробовать принудительно добавить ленту, добавив <code>#force_feed</code> к URL.', 'invalid_url' => 'URL <em>%s</em> неверный', 'n_actualized' => '%d лент обновлено', diff --git a/app/i18n/ru/sub.php b/app/i18n/ru/sub.php index 7a782df47..3b5ca6ca0 100644 --- a/app/i18n/ru/sub.php +++ b/app/i18n/ru/sub.php @@ -50,6 +50,7 @@ return array( 'password' => 'Пароль HTTP', 'username' => 'Имя пользователя HTTP', ), + 'change_favicon' => 'Change…', // TODO 'clear_cache' => 'Всегда очищать кэш', 'content_action' => array( '_' => 'Действие с содержимым, когда извлекается содержимое статьи', @@ -74,12 +75,15 @@ return array( 'help' => 'XML файл (data subset. <a href="https://freshrss.github.io/FreshRSS/en/developers/OPML.html" target="_blank">See documentation</a>)', // DIRTY 'label' => 'Экспортировать как OPML', ), + 'ext_favicon' => 'Set automatically', // TODO + 'favicon_changed_by_ext' => 'The icon has been set by the <b>%s</b> extension.', // TODO 'filteractions' => array( '_' => 'Действия фильтрации', 'help' => 'Введите по одному поисковому фильтру в строке. См. <a href="https://freshrss.github.io/FreshRSS/en/users/10_filter.html#with-the-search-field" target="_blank">документацию</a>.', ), 'http_headers' => 'HTTP Headers', // TODO 'http_headers_help' => 'Headers are separated by a newline, and the name and value of a header are separated by a colon (e.g: <kbd><code>Accept: application/atom+xml<br />Authorization: Bearer some-token</code></kbd>).', // TODO + 'icon' => 'Icon', // TODO 'information' => 'Информация', 'keep_min' => 'Оставлять статей не менее', 'kind' => array( @@ -212,6 +216,7 @@ return array( ), 'proxy' => 'Указать прокси для извлечения этой ленты', 'proxy_help' => 'Выберите протокол (например, SOCKS5) и введите адрес прокси (например, <kbd>127.0.0.1:1080</kbd> или <kbd>username:password@127.0.0.1:1080</kbd>)', // DIRTY + 'reset_favicon' => 'Reset to default', // TODO 'selector_preview' => array( 'show_raw' => 'Показать исходный код', 'show_rendered' => 'Показать содержимое', diff --git a/app/i18n/sk/feedback.php b/app/i18n/sk/feedback.php index a1d63cca9..bca5437e3 100644 --- a/app/i18n/sk/feedback.php +++ b/app/i18n/sk/feedback.php @@ -95,6 +95,10 @@ return array( 'cache_cleared' => '<em>%s</em> vyrovnávacia pamäť bola vymazaná', 'deleted' => 'Kanál bol vymazaný', 'error' => 'Kanál sa nepodarilo aktualizovať', + 'favicon' => array( + 'too_large' => 'Uploaded icon is too large. The maximum file size is <em>%s</em>.', // TODO + 'unsupported_format' => 'Unsupported image file format!', // TODO + ), 'internal_problem' => 'Kanál sa nepodarilo pridať. <a href="%s">Prečítajte si záznamy FreshRSS</a>, ak chcete poznať podrobnosti. Skúste pridať kanál pomocou <code>#force_feed</code> v odkaze (URL).', 'invalid_url' => 'Odkaz <em>%s</em> je neplatný', 'n_actualized' => 'Počet aktualizovaných kanálov: %d', diff --git a/app/i18n/sk/sub.php b/app/i18n/sk/sub.php index 8ed64adda..b603e8d9e 100644 --- a/app/i18n/sk/sub.php +++ b/app/i18n/sk/sub.php @@ -50,6 +50,7 @@ return array( 'password' => 'Heslo pre HTTP', 'username' => 'Používateľské meno pre HTTP', ), + 'change_favicon' => 'Change…', // TODO 'clear_cache' => 'Vždy vymazať vyrovnávaciu pamäť', 'content_action' => array( '_' => 'Akcia obsahu pri sťahovaní obsahu článku', @@ -74,12 +75,15 @@ return array( 'help' => 'XML súbor (data subset. <a href="https://freshrss.github.io/FreshRSS/en/developers/OPML.html" target="_blank">See documentation</a>)', // DIRTY 'label' => 'Exportovať ako OPML', ), + 'ext_favicon' => 'Set automatically', // TODO + 'favicon_changed_by_ext' => 'The icon has been set by the <b>%s</b> extension.', // TODO 'filteractions' => array( '_' => 'Filtrovať akcie', 'help' => 'Napíšte jeden výraz hľadania na riadok. Operators <a href="https://freshrss.github.io/FreshRSS/en/users/10_filter.html#with-the-search-field" target="_blank">see documentation</a>.', // DIRTY ), 'http_headers' => 'HTTP Headers', // TODO 'http_headers_help' => 'Headers are separated by a newline, and the name and value of a header are separated by a colon (e.g: <kbd><code>Accept: application/atom+xml<br />Authorization: Bearer some-token</code></kbd>).', // TODO + 'icon' => 'Icon', // TODO 'information' => 'Informácia', 'keep_min' => 'Minimálny počet článkov na uchovanie', 'kind' => array( @@ -212,6 +216,7 @@ return array( ), 'proxy' => 'Na sťahovanie tohto kanálu nastaviť proxy', 'proxy_help' => 'Vyberte protokol (napr.: SOCKS5) a zadajte adresu proxy servera (napr.: <kbd>127.0.0.1:1080</kbd> or <kbd>username:password@127.0.0.1:1080</kbd>)', // DIRTY + 'reset_favicon' => 'Reset to default', // TODO 'selector_preview' => array( 'show_raw' => 'Zobraziť zdrojový kód', 'show_rendered' => 'Zobraziť obsah', diff --git a/app/i18n/tr/feedback.php b/app/i18n/tr/feedback.php index 19ac11e3b..f9331982b 100644 --- a/app/i18n/tr/feedback.php +++ b/app/i18n/tr/feedback.php @@ -95,6 +95,10 @@ return array( 'cache_cleared' => '<em>%s</em> önbelleği temizlendi', 'deleted' => 'Besleme silindi', 'error' => 'Besleme güncellenemedi', + 'favicon' => array( + 'too_large' => 'Uploaded icon is too large. The maximum file size is <em>%s</em>.', // TODO + 'unsupported_format' => 'Unsupported image file format!', // TODO + ), 'internal_problem' => 'Haber akışı eklenemedi. Ayrıntılar için <a href="%s">FreshRSS günlüklerini kontrol edin</a>. URL’ye <code>#force_feed</code> ekleyerek zorla eklemeyi deneyebilirsiniz.', 'invalid_url' => '<em>%s</em> URL’si geçersiz', 'n_actualized' => '%d besleme güncellendi', diff --git a/app/i18n/tr/sub.php b/app/i18n/tr/sub.php index f6ba8b9c2..5c92c8e8c 100644 --- a/app/i18n/tr/sub.php +++ b/app/i18n/tr/sub.php @@ -50,6 +50,7 @@ return array( 'password' => 'HTTP parolası', 'username' => 'HTTP kullanıcı adı', ), + 'change_favicon' => 'Change…', // TODO 'clear_cache' => 'Önbelleği her zaman temizle', 'content_action' => array( '_' => 'Makale içeriği getirilirken içerik eylemi', @@ -74,12 +75,15 @@ return array( 'help' => 'XML dosyası (veri alt kümesi. <a href="https://freshrss.github.io/FreshRSS/en/developers/OPML.html" target="_blank">Belgelere bakın</a>)', 'label' => 'OPML olarak dışa aktar', ), + 'ext_favicon' => 'Set automatically', // TODO + 'favicon_changed_by_ext' => 'The icon has been set by the <b>%s</b> extension.', // TODO 'filteractions' => array( '_' => 'Filtre eylemleri', 'help' => 'Her satıra bir arama filtresi yazın. Operatörler için <a href="https://freshrss.github.io/FreshRSS/en/users/10_filter.html#with-the-search-field" target="_blank">belgelere bakın</a>.', ), 'http_headers' => 'HTTP Başlıkları', 'http_headers_help' => 'Başlıklar yeni bir satırla ayrılır ve bir başlığın adı ile değeri iki nokta üst üste ile ayrılır (örneğin: <kbd><code>Accept: application/atom+xml<br />Authorization: Bearer some-token</code></kbd>).', + 'icon' => 'Icon', // TODO 'information' => 'Bilgi', 'keep_min' => 'Saklanacak minimum makale sayısı', 'kind' => array( @@ -212,6 +216,7 @@ return array( ), 'proxy' => 'Bu beslemeyi almak için bir proxy ayarlayın', 'proxy_help' => 'Bir protokol seçin (örneğin: SOCKS5) ve proxy adresini girin (örneğin: <kbd>127.0.0.1:1080</kbd> veya <kbd>kullanıcıadı:parola@127.0.0.1:1080</kbd>).', + 'reset_favicon' => 'Reset to default', // TODO 'selector_preview' => array( 'show_raw' => 'Kaynak kodu göster', 'show_rendered' => 'İçeriği göster', diff --git a/app/i18n/zh-cn/feedback.php b/app/i18n/zh-cn/feedback.php index 2d726d22a..47abcb59b 100644 --- a/app/i18n/zh-cn/feedback.php +++ b/app/i18n/zh-cn/feedback.php @@ -95,6 +95,10 @@ return array( 'cache_cleared' => '<em>%s</em> 缓存已清理', 'deleted' => '已删除订阅源', 'error' => '订阅源更新失败', + 'favicon' => array( + 'too_large' => 'Uploaded icon is too large. The maximum file size is <em>%s</em>.', // TODO + 'unsupported_format' => 'Unsupported image file format!', // TODO + ), 'internal_problem' => '订阅源添加失败,<a href="%s">检查 FreshRSS 日志</a> 查看详情。你可以在 URL 后添加 <code>#force_feed</code> 尝试强制添加。', 'invalid_url' => 'URL <em>%s</em> 无效', 'n_actualized' => '已更新 %d 个订阅源', diff --git a/app/i18n/zh-cn/sub.php b/app/i18n/zh-cn/sub.php index 75f082d08..07af113a9 100644 --- a/app/i18n/zh-cn/sub.php +++ b/app/i18n/zh-cn/sub.php @@ -50,6 +50,7 @@ return array( 'password' => 'HTTP 密码', 'username' => 'HTTP 用户名', ), + 'change_favicon' => 'Change…', // TODO 'clear_cache' => '总是清除缓存', 'content_action' => array( '_' => '获取原文后的操作', @@ -74,12 +75,15 @@ return array( 'help' => 'XML 文件 (data subset. <a href="https://freshrss.github.io/FreshRSS/en/developers/OPML.html" target="_blank">See documentation</a>)', // DIRTY 'label' => '导出为 OPML', ), + 'ext_favicon' => 'Set automatically', // TODO + 'favicon_changed_by_ext' => 'The icon has been set by the <b>%s</b> extension.', // TODO 'filteractions' => array( '_' => '过滤动作', 'help' => '每行写一条过滤规则,过滤规则可见 <a href="https://freshrss.github.io/FreshRSS/en/users/10_filter.html#with-the-search-field" target="_blank">文档</a>。', ), 'http_headers' => 'HTTP Headers', // TODO 'http_headers_help' => 'Headers are separated by a newline, and the name and value of a header are separated by a colon (e.g: <kbd><code>Accept: application/atom+xml<br />Authorization: Bearer some-token</code></kbd>).', // TODO + 'icon' => 'Icon', // TODO 'information' => '信息', 'keep_min' => '至少保存的文章数', 'kind' => array( @@ -212,6 +216,7 @@ return array( ), 'proxy' => '获取订阅源时的代理', 'proxy_help' => '选择协议(例:SOCKS5)和代理地址(例:<kbd>127.0.0.1:1080</kbd> 或者 <kbd>username:password@127.0.0.1:1080</kbd>)', + 'reset_favicon' => 'Reset to default', // TODO 'selector_preview' => array( 'show_raw' => '显示源码', 'show_rendered' => '显示内容', diff --git a/app/i18n/zh-tw/feedback.php b/app/i18n/zh-tw/feedback.php index d43e6efbd..92c3a0f05 100644 --- a/app/i18n/zh-tw/feedback.php +++ b/app/i18n/zh-tw/feedback.php @@ -95,6 +95,10 @@ return array( 'cache_cleared' => '<em>%s</em> 緩存已清理', 'deleted' => '已刪除訂閱源', 'error' => '訂閱源更新失敗', + 'favicon' => array( + 'too_large' => 'Uploaded icon is too large. The maximum file size is <em>%s</em>.', // TODO + 'unsupported_format' => 'Unsupported image file format!', // TODO + ), 'internal_problem' => '訂閱源添加失敗。<a href="%s">檢查 FreshRSS 日誌</a> 查看詳情。你可以在地址連結後附加 <code>#force_feed</code> 從而嘗試強制添加。', 'invalid_url' => '地址鏈接 <em>%s</em> 無效', 'n_actualized' => '已更新 %d 個訂閱源', diff --git a/app/i18n/zh-tw/sub.php b/app/i18n/zh-tw/sub.php index d0a8c91a1..d0ff30f94 100644 --- a/app/i18n/zh-tw/sub.php +++ b/app/i18n/zh-tw/sub.php @@ -50,6 +50,7 @@ return array( 'password' => 'HTTP 密碼', 'username' => 'HTTP 用戶名', ), + 'change_favicon' => 'Change…', // TODO 'clear_cache' => '總是清除暫存', 'content_action' => array( '_' => '獲取原文後的操作', @@ -74,12 +75,15 @@ return array( 'help' => 'XML file (data subset. <a href="https://freshrss.github.io/FreshRSS/en/developers/OPML.html" target="_blank">See documentation</a>)', // TODO 'label' => '匯出為OPML', ), + 'ext_favicon' => 'Set automatically', // TODO + 'favicon_changed_by_ext' => 'The icon has been set by the <b>%s</b> extension.', // TODO 'filteractions' => array( '_' => '過濾動作', 'help' => '每行寫一條過濾搜尋 Operators <a href="https://freshrss.github.io/FreshRSS/en/users/10_filter.html#with-the-search-field" target="_blank">see documentation</a>.', // DIRTY ), 'http_headers' => 'HTTP Headers', // TODO 'http_headers_help' => 'Headers are separated by a newline, and the name and value of a header are separated by a colon (e.g: <kbd><code>Accept: application/atom+xml<br />Authorization: Bearer some-token</code></kbd>).', // TODO + 'icon' => 'Icon', // TODO 'information' => '信息', 'keep_min' => '至少保存的文章數', 'kind' => array( @@ -212,6 +216,7 @@ return array( ), 'proxy' => '獲取訂閱源時的代理', 'proxy_help' => '選擇協議(例:SOCKS5)和代理地址(例:<kbd>127.0.0.1:1080</kbd> or <kbd>username:password@127.0.0.1:1080</kbd>)', // DIRTY + 'reset_favicon' => 'Reset to default', // TODO 'selector_preview' => array( 'show_raw' => '顯示源碼', 'show_rendered' => '顯示內容', diff --git a/app/views/helpers/feed/update.phtml b/app/views/helpers/feed/update.phtml index 6a04edd07..f6c88d372 100644 --- a/app/views/helpers/feed/update.phtml +++ b/app/views/helpers/feed/update.phtml @@ -5,7 +5,7 @@ return; } ?> -<div class="post" id="feed_update"> +<div class="post" id="feed_update" data-feed-id="<?= $this->feed->id() ?>"> <h1><?= $this->feed->name() ?></h1> <div> @@ -35,11 +35,39 @@ } } ?> - <form method="post" action="<?= $url ?>" autocomplete="off"> + <form method="post" action="<?= $url ?>" autocomplete="off" enctype="multipart/form-data"> <input type="hidden" name="_csrf" value="<?= FreshRSS_Auth::csrfToken() ?>" /> <fieldset> <legend><?= _t('sub.feed.information') ?></legend> <div class="form-group"> + <?php + $currentIconUrl = $this->feed->favicon(); + $originalIconUrl = ''; + if ($this->feed->customFavicon()) { + $this->feed->_attribute('customFavicon', false); + $this->feed->resetFaviconHash(); + } + $originalIconUrl = $this->feed->favicon(); + $this->feed->_attribute('customFavicon', $currentIconUrl !== $originalIconUrl); + $this->feed->resetFaviconHash(); + $ext_url = Minz_ExtensionManager::callHook('custom_favicon_btn_url', $this->feed); + ?> + <label class="group-name"><?= _t('sub.feed.icon') ?></label> + <div class="group-controls"> + <img class="favicon upload" src="<?= $currentIconUrl ?>" data-initial-src="<?= $currentIconUrl ?>" data-original-icon="<?= $originalIconUrl ?>" alt="✇" loading="lazy" /> + <div class="favicon-controls"> + <input id="favicon-upload" name="newFavicon" type="file" accept="image/*" /> + <label for="favicon-upload" class="btn"><?= _t('sub.feed.change_favicon') ?></label> + <button id="reset-favicon" class="btn"<?= $this->feed->customFavicon() ? '' : ' disabled="disabled"'?>><?= _t('sub.feed.reset_favicon') ?></button> + <?php if (is_string($ext_url)) { ?> + <button id="favicon-ext-btn" class="btn" data-extension-url="<?= htmlspecialchars(html_entity_decode($ext_url), ENT_COMPAT, 'UTF-8') ?>"><?= _t('sub.feed.ext_favicon') ?></button> + <?php } ?> + </div> + <p id="favicon-ext" class="<?= $this->feed->customFaviconExt() !== null ? '' : 'hidden' ?>"><?= _t('sub.feed.favicon_changed_by_ext', htmlspecialchars($this->feed->customFaviconExt() ?? '', ENT_NOQUOTES, 'UTF-8')) ?></p> + <p id="favicon-error" class="error"></p> + </div> + </div> + <div class="form-group"> <label class="group-name" for="name"><?= _t('sub.feed.title') ?></label> <div class="group-controls"> <input type="text" name="name" id="name" class="w100" value="<?= $this->feed->name(true) ?>" required="required" /> diff --git a/app/views/helpers/javascript_vars.phtml b/app/views/helpers/javascript_vars.phtml index 159d7ba9b..65846b001 100644 --- a/app/views/helpers/javascript_vars.phtml +++ b/app/views/helpers/javascript_vars.phtml @@ -4,7 +4,7 @@ declare(strict_types=1); $mark = FreshRSS_Context::userConf()->mark_when; $s = FreshRSS_Context::userConf()->shortcuts; $extData = Minz_ExtensionManager::callHook('js_vars', []); -echo htmlspecialchars(json_encode([ +echo json_encode([ 'context' => [ 'anonymous' => !FreshRSS_Auth::hasAccess(), 'auto_remove_article' => !!FreshRSS_Context::isAutoRemoveAvailable(), @@ -30,6 +30,7 @@ echo htmlspecialchars(json_encode([ 'extra.js' => @filemtime(PUBLIC_PATH . '/scripts/extra.js'), 'feed.js' => @filemtime(PUBLIC_PATH . '/scripts/feed.js'), ], + 'max_favicon_upload_size' => FreshRSS_Context::systemConf()->limits['max_favicon_upload_size'], 'version' => FRESHRSS_VERSION, ], 'shortcuts' => [ @@ -73,6 +74,7 @@ echo htmlspecialchars(json_encode([ 'notif_request_failed' => _t('gen.js.feedback.request_failed'), 'category_empty' => _t('gen.js.category_empty'), 'labels_empty' => _t('gen.js.labels_empty'), + 'favicon_size_exceeded' => _t('feedback.sub.feed.favicon.too_large', format_bytes(FreshRSS_Context::systemConf()->limits['max_favicon_upload_size'])), 'language' => FreshRSS_Context::userConf()->language, ], 'icons' => [ @@ -81,4 +83,4 @@ echo htmlspecialchars(json_encode([ 'spinner' => '../themes/icons/spinner.svg', ], 'extensions' => $extData, -], JSON_UNESCAPED_UNICODE) ?: '', ENT_NOQUOTES, 'UTF-8'); +], JSON_UNESCAPED_UNICODE | JSON_HEX_TAG | JSON_HEX_AMP); |
