summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar maTh <1645099+math-GH@users.noreply.github.com> 2025-10-01 10:48:07 +0200
committerGravatar GitHub <noreply@github.com> 2025-10-01 10:48:07 +0200
commit2bcc090622c0e62dbff94e52bb6892a51b40ba2a (patch)
tree7d9d93c839e45e41c4a75db7dce04a9bb8bc6c2a
parent72884813e13596d211471482ffdc6d723ed678c9 (diff)
configurable notification timeout (#7942)
Ref #7931 Ref #5466 Ref #6409 added configuration in "Display" <img width="636" height="167" alt="grafik" src="https://github.com/user-attachments/assets/7bbc9f26-d91b-4dd2-b715-1d3f9b7a9ad3" /> * i18n: fr * Update app/i18n/pl/conf.php Co-authored-by: Inverle <inverle@proton.me> * make fix-all * max() * Minor whitespace (I am not a fan of excessive vertical indenting) --------- Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr> Co-authored-by: Inverle <inverle@proton.me>
-rw-r--r--app/Controllers/apiController.php6
-rw-r--r--app/Controllers/authController.php24
-rw-r--r--app/Controllers/categoryController.php30
-rw-r--r--app/Controllers/configureController.php69
-rw-r--r--app/Controllers/entryController.php18
-rw-r--r--app/Controllers/extensionController.php18
-rw-r--r--app/Controllers/feedController.php60
-rw-r--r--app/Controllers/importExportController.php5
-rw-r--r--app/Controllers/subscriptionController.php12
-rw-r--r--app/Controllers/tagController.php17
-rw-r--r--app/Controllers/updateController.php5
-rw-r--r--app/Controllers/userController.php39
-rw-r--r--app/Models/UserConfiguration.php2
-rw-r--r--app/i18n/cs/conf.php10
-rw-r--r--app/i18n/de/conf.php10
-rw-r--r--app/i18n/el/conf.php10
-rw-r--r--app/i18n/en-us/conf.php10
-rw-r--r--app/i18n/en/conf.php10
-rw-r--r--app/i18n/es/conf.php10
-rw-r--r--app/i18n/fa/conf.php10
-rw-r--r--app/i18n/fi/conf.php10
-rw-r--r--app/i18n/fr/conf.php10
-rw-r--r--app/i18n/he/conf.php10
-rw-r--r--app/i18n/hu/conf.php10
-rw-r--r--app/i18n/id/conf.php10
-rw-r--r--app/i18n/it/conf.php10
-rw-r--r--app/i18n/ja/conf.php10
-rw-r--r--app/i18n/ko/conf.php10
-rw-r--r--app/i18n/lv/conf.php10
-rw-r--r--app/i18n/nl/conf.php10
-rw-r--r--app/i18n/oc/conf.php10
-rw-r--r--app/i18n/pl/conf.php10
-rw-r--r--app/i18n/pt-br/conf.php10
-rw-r--r--app/i18n/pt-pt/conf.php10
-rw-r--r--app/i18n/ru/conf.php10
-rw-r--r--app/i18n/sk/conf.php10
-rw-r--r--app/i18n/tr/conf.php10
-rw-r--r--app/i18n/uk/conf.php10
-rw-r--r--app/i18n/zh-cn/conf.php10
-rw-r--r--app/i18n/zh-tw/conf.php10
-rw-r--r--app/views/configure/display.phtml18
-rw-r--r--app/views/helpers/javascript_vars.phtml5
-rw-r--r--config-user.default.php2
-rw-r--r--docs/en/developers/Minz/index.md2
-rw-r--r--docs/fr/developers/Minz/index.md2
-rw-r--r--docs/i18n/flags/gen/es.svg2
-rw-r--r--docs/i18n/flags/gen/fa.svg2
-rw-r--r--lib/Minz/Request.php6
-rw-r--r--p/scripts/main.js22
49 files changed, 561 insertions, 75 deletions
diff --git a/app/Controllers/apiController.php b/app/Controllers/apiController.php
index 585a7a9bb..139e2734e 100644
--- a/app/Controllers/apiController.php
+++ b/app/Controllers/apiController.php
@@ -58,7 +58,11 @@ class FreshRSS_api_Controller extends FreshRSS_ActionController {
if (is_string($error)) {
Minz_Request::bad($error, $return_url);
} else {
- Minz_Request::good(_t('feedback.api.password.updated'), $return_url);
+ Minz_Request::good(
+ _t('feedback.api.password.updated'),
+ $return_url,
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0
+ );
}
}
}
diff --git a/app/Controllers/authController.php b/app/Controllers/authController.php
index 1bdbc28b1..64526a884 100644
--- a/app/Controllers/authController.php
+++ b/app/Controllers/authController.php
@@ -56,7 +56,11 @@ class FreshRSS_auth_Controller extends FreshRSS_ActionController {
invalidateHttpCache();
if ($ok) {
- Minz_Request::good(_t('feedback.conf.updated'), [ 'c' => 'auth', 'a' => 'index' ]);
+ Minz_Request::good(
+ _t('feedback.conf.updated'),
+ [ 'c' => 'auth', 'a' => 'index' ],
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0
+ );
} else {
Minz_Request::bad(_t('feedback.conf.error'), [ 'c' => 'auth', 'a' => 'index' ]);
}
@@ -176,7 +180,11 @@ class FreshRSS_auth_Controller extends FreshRSS_ActionController {
if (empty($url)) {
$url = [ 'c' => 'index', 'a' => 'index' ];
}
- Minz_Request::good(_t('feedback.auth.login.success'), $url);
+ Minz_Request::good(
+ _t('feedback.auth.login.success'),
+ $url,
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0
+ );
} else {
Minz_Log::warning("Password mismatch for user={$username}, nonce={$nonce}, c={$challenge}");
header('HTTP/1.1 403 Forbidden');
@@ -214,7 +222,11 @@ class FreshRSS_auth_Controller extends FreshRSS_ActionController {
Minz_Translate::init(FreshRSS_Context::userConf()->language);
- Minz_Request::good(_t('feedback.auth.login.success'), ['c' => 'index', 'a' => 'index']);
+ Minz_Request::good(
+ _t('feedback.auth.login.success'),
+ ['c' => 'index', 'a' => 'index'],
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0
+ );
} else {
Minz_Log::warning('Unsafe password mismatch for user ' . $username);
Minz_Request::bad(
@@ -263,7 +275,11 @@ class FreshRSS_auth_Controller extends FreshRSS_ActionController {
invalidateHttpCache();
FreshRSS_Auth::removeAccess();
Minz_Session::regenerateID('FreshRSS');
- Minz_Request::good(_t('feedback.auth.logout.success'), [ 'c' => 'index', 'a' => 'index' ]);
+ Minz_Request::good(
+ _t('feedback.auth.logout.success'),
+ [ 'c' => 'index', 'a' => 'index' ],
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0
+ );
} else {
Minz_Error::error(403);
}
diff --git a/app/Controllers/categoryController.php b/app/Controllers/categoryController.php
index 316136b11..5ad83e977 100644
--- a/app/Controllers/categoryController.php
+++ b/app/Controllers/categoryController.php
@@ -70,7 +70,11 @@ class FreshRSS_category_Controller extends FreshRSS_ActionController {
if ($catDAO->addCategoryObject($cat)) {
$url_redirect['a'] = 'index';
- Minz_Request::good(_t('feedback.sub.category.created', $cat->name()), $url_redirect);
+ Minz_Request::good(
+ _t('feedback.sub.category.created', $cat->name()),
+ $url_redirect,
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0
+ );
} else {
Minz_Request::bad(_t('feedback.sub.category.error'), $url_redirect);
}
@@ -156,7 +160,11 @@ class FreshRSS_category_Controller extends FreshRSS_ActionController {
$url_redirect = ['c' => 'subscription', 'params' => ['id' => $id, 'type' => 'category']];
if (false !== $categoryDAO->updateCategory($id, $values)) {
- Minz_Request::good(_t('feedback.sub.category.updated'), $url_redirect);
+ Minz_Request::good(
+ _t('feedback.sub.category.updated'),
+ $url_redirect,
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0
+ );
} else {
Minz_Request::bad(_t('feedback.sub.category.error'), $url_redirect);
}
@@ -201,7 +209,11 @@ class FreshRSS_category_Controller extends FreshRSS_ActionController {
FreshRSS_Context::userConf()->queries = $queries;
FreshRSS_Context::userConf()->save();
- Minz_Request::good(_t('feedback.sub.category.deleted'), $url_redirect);
+ Minz_Request::good(
+ _t('feedback.sub.category.deleted'),
+ $url_redirect,
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0
+ );
}
Minz_Request::forward($url_redirect, true);
@@ -243,7 +255,11 @@ class FreshRSS_category_Controller extends FreshRSS_ActionController {
}
FreshRSS_Context::userConf()->save();
- Minz_Request::good(_t('feedback.sub.category.emptied'), $url_redirect);
+ Minz_Request::good(
+ _t('feedback.sub.category.emptied'),
+ $url_redirect,
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0
+ );
} else {
Minz_Request::bad(_t('feedback.sub.category.error'), $url_redirect);
}
@@ -284,7 +300,11 @@ class FreshRSS_category_Controller extends FreshRSS_ActionController {
$this->view->_layout(null);
} else {
if ($ok) {
- Minz_Request::good(_t('feedback.sub.category.updated'), $url_redirect);
+ Minz_Request::good(
+ _t('feedback.sub.category.updated'),
+ $url_redirect,
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0
+ );
} else {
Minz_Request::bad(_t('feedback.sub.category.error'), $url_redirect);
}
diff --git a/app/Controllers/configureController.php b/app/Controllers/configureController.php
index 50edbbff7..bcda947ff 100644
--- a/app/Controllers/configureController.php
+++ b/app/Controllers/configureController.php
@@ -74,14 +74,20 @@ class FreshRSS_configure_Controller extends FreshRSS_ActionController {
FreshRSS_Context::userConf()->bottomline_date = Minz_Request::paramBoolean('bottomline_date');
FreshRSS_Context::userConf()->bottomline_link = Minz_Request::paramBoolean('bottomline_link');
FreshRSS_Context::userConf()->show_nav_buttons = Minz_Request::paramBoolean('show_nav_buttons');
- FreshRSS_Context::userConf()->html5_notif_timeout = Minz_Request::paramInt('html5_notif_timeout');
+ FreshRSS_Context::userConf()->html5_notif_timeout = max(0, Minz_Request::paramInt('html5_notif_timeout'));
+ FreshRSS_Context::userConf()->good_notification_timeout = max(0, Minz_Request::paramInt('good_notification_timeout'));
+ FreshRSS_Context::userConf()->bad_notification_timeout = max(1, Minz_Request::paramInt('bad_notification_timeout'));
FreshRSS_Context::userConf()->save();
Minz_Session::_param('language', FreshRSS_Context::userConf()->language);
Minz_Translate::reset(FreshRSS_Context::userConf()->language);
invalidateHttpCache();
- Minz_Request::good(_t('feedback.conf.updated'), [ 'c' => 'configure', 'a' => 'display' ], 'displayAction');
+ Minz_Request::good(
+ _t('feedback.conf.updated'),
+ [ 'c' => 'configure', 'a' => 'display' ],
+ notificationName: 'displayAction',
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0);
}
$this->view->themes = FreshRSS_Themes::get();
@@ -163,7 +169,11 @@ class FreshRSS_configure_Controller extends FreshRSS_ActionController {
FreshRSS_Context::userConf()->save();
invalidateHttpCache();
- Minz_Request::good(_t('feedback.conf.updated'), [ 'c' => 'configure', 'a' => 'reading' ]);
+ Minz_Request::good(
+ _t('feedback.conf.updated'),
+ [ 'c' => 'configure', 'a' => 'reading' ],
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0
+ );
}
$this->view->viewModes = FreshRSS_ViewMode::getAllModes();
@@ -197,7 +207,11 @@ class FreshRSS_configure_Controller extends FreshRSS_ActionController {
invalidateHttpCache();
}
- Minz_Request::good(_t('feedback.conf.updated'), [ 'c' => 'configure', 'a' => 'integration' ]);
+ Minz_Request::good(
+ _t('feedback.conf.updated'),
+ [ 'c' => 'configure', 'a' => 'integration' ],
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0
+ );
}
FreshRSS_View::prependTitle(_t('conf.sharing.title') . ' · ');
@@ -229,7 +243,11 @@ class FreshRSS_configure_Controller extends FreshRSS_ActionController {
FreshRSS_Context::userConf()->save();
invalidateHttpCache();
- Minz_Request::good(_t('feedback.conf.shortcuts_updated'), ['c' => 'configure', 'a' => 'shortcut']);
+ Minz_Request::good(
+ _t('feedback.conf.shortcuts_updated'),
+ ['c' => 'configure', 'a' => 'shortcut'],
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0
+ );
}
FreshRSS_View::prependTitle(_t('conf.shortcut.title') . ' · ');
@@ -277,7 +295,11 @@ class FreshRSS_configure_Controller extends FreshRSS_ActionController {
FreshRSS_Context::userConf()->save();
invalidateHttpCache();
- Minz_Request::good(_t('feedback.conf.updated'), [ 'c' => 'configure', 'a' => 'archiving' ]);
+ Minz_Request::good(
+ _t('feedback.conf.updated'),
+ [ 'c' => 'configure', 'a' => 'archiving' ],
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0
+ );
}
$volatile = [
@@ -341,7 +363,11 @@ class FreshRSS_configure_Controller extends FreshRSS_ActionController {
FreshRSS_Context::userConf()->queries = $queries;
FreshRSS_Context::userConf()->save();
- Minz_Request::good(_t('feedback.conf.updated'), [ 'c' => 'configure', 'a' => 'queries' ]);
+ Minz_Request::good(
+ _t('feedback.conf.updated'),
+ [ 'c' => 'configure', 'a' => 'queries' ],
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0
+ );
} else {
$this->view->queries = [];
foreach (FreshRSS_Context::userConf()->queries as $key => $query) {
@@ -433,7 +459,10 @@ class FreshRSS_configure_Controller extends FreshRSS_ActionController {
FreshRSS_Context::userConf()->queries = $queries;
FreshRSS_Context::userConf()->save();
- Minz_Request::good(_t('feedback.conf.updated'), [ 'c' => 'configure', 'a' => 'queries', 'params' => ['id' => (string)$id] ]);
+ Minz_Request::good(
+ _t('feedback.conf.updated'),
+ [ 'c' => 'configure', 'a' => 'queries', 'params' => ['id' => (string)$id] ],
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0);
}
FreshRSS_View::prependTitle($query->getName() . ' · ' . _t('conf.query.title') . ' · ');
@@ -458,7 +487,11 @@ class FreshRSS_configure_Controller extends FreshRSS_ActionController {
FreshRSS_Context::userConf()->queries = $queries;
FreshRSS_Context::userConf()->save();
- Minz_Request::good(_t('feedback.conf.updated'), [ 'c' => 'configure', 'a' => 'queries' ]);
+ Minz_Request::good(
+ _t('feedback.conf.updated'),
+ [ 'c' => 'configure', 'a' => 'queries' ],
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0
+ );
}
/**
@@ -488,7 +521,11 @@ class FreshRSS_configure_Controller extends FreshRSS_ActionController {
FreshRSS_Context::userConf()->queries = $queries;
FreshRSS_Context::userConf()->save();
- Minz_Request::good(_t('feedback.conf.query_created', $params['name']), [ 'c' => 'configure', 'a' => 'queries' ]);
+ Minz_Request::good(
+ _t('feedback.conf.query_created', $params['name']),
+ [ 'c' => 'configure', 'a' => 'queries' ],
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0
+ );
}
/**
@@ -525,7 +562,11 @@ class FreshRSS_configure_Controller extends FreshRSS_ActionController {
invalidateHttpCache();
- Minz_Request::good(_t('feedback.conf.updated'), [ 'c' => 'configure', 'a' => 'system' ]);
+ Minz_Request::good(
+ _t('feedback.conf.updated'),
+ [ 'c' => 'configure', 'a' => 'system' ],
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0
+ );
}
}
@@ -535,7 +576,11 @@ class FreshRSS_configure_Controller extends FreshRSS_ActionController {
FreshRSS_Context::userConf()->save();
invalidateHttpCache();
- Minz_Request::good(_t('feedback.conf.updated'), ['c' => 'configure', 'a' => 'privacy']);
+ Minz_Request::good(
+ _t('feedback.conf.updated'),
+ ['c' => 'configure', 'a' => 'privacy'],
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0
+ );
}
FreshRSS_View::prependTitle(_t('conf.privacy') . ' · ');
diff --git a/app/Controllers/entryController.php b/app/Controllers/entryController.php
index 0e8a4a1b9..1d4792267 100644
--- a/app/Controllers/entryController.php
+++ b/app/Controllers/entryController.php
@@ -196,7 +196,8 @@ class FreshRSS_entry_Controller extends FreshRSS_ActionController {
'a' => 'index',
'params' => $params,
],
- 'readAction'
+ notificationName: 'readAction ',
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0
);
}
}
@@ -254,7 +255,11 @@ class FreshRSS_entry_Controller extends FreshRSS_ActionController {
$feedDAO->updateCachedValues();
invalidateHttpCache();
- Minz_Request::good(_t('feedback.admin.optimization_complete'), $url_redirect);
+ Minz_Request::good(
+ _t('feedback.admin.optimization_complete'),
+ $url_redirect,
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0
+ );
}
/**
@@ -290,9 +295,10 @@ class FreshRSS_entry_Controller extends FreshRSS_ActionController {
$databaseDAO->minorDbMaintenance();
invalidateHttpCache();
- Minz_Request::good(_t('feedback.sub.purge_completed', $nb_total), [
- 'c' => 'configure',
- 'a' => 'archiving',
- ]);
+ Minz_Request::good(
+ _t('feedback.sub.purge_completed', $nb_total),
+ ['c' => 'configure', 'a' => 'archiving'],
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0
+ );
}
}
diff --git a/app/Controllers/extensionController.php b/app/Controllers/extensionController.php
index 38f04a277..39b5e858a 100644
--- a/app/Controllers/extensionController.php
+++ b/app/Controllers/extensionController.php
@@ -191,7 +191,11 @@ class FreshRSS_extension_Controller extends FreshRSS_ActionController {
$conf->extensions_enabled = $ext_list;
$conf->save();
- Minz_Request::good(_t('feedback.extensions.enable.ok', $ext_name), $url_redirect);
+ Minz_Request::good(
+ _t('feedback.extensions.enable.ok', $ext_name),
+ $url_redirect,
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0
+ );
} else {
Minz_Log::warning('Cannot enable extension ' . $ext_name . ': ' . $res);
Minz_Request::bad(_t('feedback.extensions.enable.ko', $ext_name, _url('index', 'logs')), $url_redirect);
@@ -253,7 +257,11 @@ class FreshRSS_extension_Controller extends FreshRSS_ActionController {
$conf->extensions_enabled = $ext_list;
$conf->save();
- Minz_Request::good(_t('feedback.extensions.disable.ok', $ext_name), $url_redirect);
+ Minz_Request::good(
+ _t('feedback.extensions.disable.ok', $ext_name),
+ $url_redirect,
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0
+ );
} else {
Minz_Log::warning('Cannot disable extension ' . $ext_name . ': ' . $res);
Minz_Request::bad(_t('feedback.extensions.disable.ko', $ext_name, _url('index', 'logs')), $url_redirect);
@@ -290,7 +298,11 @@ class FreshRSS_extension_Controller extends FreshRSS_ActionController {
$res = recursive_unlink($ext->getPath());
if ($res) {
- Minz_Request::good(_t('feedback.extensions.removed', $ext_name), $url_redirect);
+ Minz_Request::good(
+ _t('feedback.extensions.removed', $ext_name),
+ $url_redirect,
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0
+ );
} else {
Minz_Request::bad(_t('feedback.extensions.cannot_remove', $ext_name), $url_redirect);
}
diff --git a/app/Controllers/feedController.php b/app/Controllers/feedController.php
index fe190dc77..678388cbb 100644
--- a/app/Controllers/feedController.php
+++ b/app/Controllers/feedController.php
@@ -344,7 +344,11 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController {
// Entries are in DB, we redirect to feed configuration page.
$url_redirect['a'] = 'feed';
$url_redirect['params']['id'] = '' . $feed->id();
- Minz_Request::good(_t('feedback.sub.feed.added', $feed->name()), $url_redirect);
+ Minz_Request::good(
+ _t('feedback.sub.feed.added', $feed->name()),
+ $url_redirect,
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0
+ );
} else {
// GET request: we must ask confirmation to user before adding feed.
FreshRSS_View::prependTitle(_t('sub.feed.title_add') . ' · ');
@@ -365,7 +369,11 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController {
// Already subscribe so we redirect to the feed configuration page.
$url_redirect['a'] = 'feed';
$url_redirect['params']['id'] = $feed->id();
- Minz_Request::good(_t('feedback.sub.feed.already_subscribed', $feed->name()), $url_redirect);
+ Minz_Request::good(
+ _t('feedback.sub.feed.already_subscribed', $feed->name()),
+ $url_redirect,
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0
+ );
}
}
}
@@ -400,7 +408,11 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController {
if ($n === false) {
Minz_Request::bad(_t('feedback.sub.feed.error'), $url_redirect);
} else {
- Minz_Request::good(_t('feedback.sub.feed.n_entries_deleted', $n), $url_redirect);
+ Minz_Request::good(
+ _t('feedback.sub.feed.n_entries_deleted', $n),
+ $url_redirect,
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0
+ );
}
}
@@ -952,13 +964,23 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController {
$this->view->_layout(null);
} elseif ($feed instanceof FreshRSS_Feed && $id > 0) {
// Redirect to the main page with correct notification.
- Minz_Request::good(_t('feedback.sub.feed.actualized', $feed->name()), [
- 'params' => ['get' => 'f_' . $id]
- ], 'actualizeAction');
+ Minz_Request::good(
+ _t('feedback.sub.feed.actualized', $feed->name()),
+ ['params' => ['get' => 'f_' . $id]],
+ notificationName: 'actualizeAction',
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0);
} elseif ($nbUpdatedFeeds >= 1) {
- Minz_Request::good(_t('feedback.sub.feed.n_actualized', $nbUpdatedFeeds), []);
+ Minz_Request::good(
+ _t('feedback.sub.feed.n_actualized', $nbUpdatedFeeds),
+ [],
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0
+ );
} else {
- Minz_Request::good(_t('feedback.sub.feed.no_refresh'), []);
+ Minz_Request::good(
+ _t('feedback.sub.feed.no_refresh'),
+ [],
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0
+ );
}
return $nbUpdatedFeeds;
}
@@ -1088,7 +1110,11 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController {
}
if (self::deleteFeed($id)) {
- Minz_Request::good(_t('feedback.sub.feed.deleted'), $redirect_url);
+ Minz_Request::good(
+ _t('feedback.sub.feed.deleted'),
+ $redirect_url,
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0
+ );
} else {
Minz_Request::bad(_t('feedback.sub.feed.error'), $redirect_url);
}
@@ -1117,9 +1143,11 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController {
$feed->clearCache();
- Minz_Request::good(_t('feedback.sub.feed.cache_cleared', $feed->name()), [
- 'params' => ['get' => 'f_' . $feed->id()],
- ]);
+ Minz_Request::good(
+ _t('feedback.sub.feed.cache_cleared', $feed->name()),
+ ['params' => ['get' => 'f_' . $feed->id()]],
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0
+ );
}
/**
@@ -1177,9 +1205,11 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController {
Minz_ModelPdo::$usesSharedPdo = true;
//Give feedback to user.
- Minz_Request::good(_t('feedback.sub.feed.reloaded', $feed->name()), [
- 'params' => ['get' => 'f_' . $feed->id()]
- ]);
+ Minz_Request::good(
+ _t('feedback.sub.feed.reloaded', $feed->name()),
+ ['params' => ['get' => 'f_' . $feed->id()]],
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0
+ );
}
/**
diff --git a/app/Controllers/importExportController.php b/app/Controllers/importExportController.php
index 8e03299f9..294f4de2c 100644
--- a/app/Controllers/importExportController.php
+++ b/app/Controllers/importExportController.php
@@ -200,7 +200,10 @@ class FreshRSS_importExport_Controller extends FreshRSS_ActionController {
// And finally, we get import status and redirect to the home page
$content_notif = $error === true ? _t('feedback.import_export.feeds_imported_with_errors') : _t('feedback.import_export.feeds_imported');
- Minz_Request::good($content_notif);
+ Minz_Request::good(
+ $content_notif,
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0
+ );
}
/**
diff --git a/app/Controllers/subscriptionController.php b/app/Controllers/subscriptionController.php
index 6573c0eb3..ccd421a41 100644
--- a/app/Controllers/subscriptionController.php
+++ b/app/Controllers/subscriptionController.php
@@ -383,7 +383,11 @@ class FreshRSS_subscription_Controller extends FreshRSS_ActionController {
Minz_Request::bad(_t('feedback.sub.feed.error'), $url_redirect);
return;
}
- Minz_Request::good(_t('feedback.sub.feed.updated'), $url_redirect);
+ Minz_Request::good(
+ _t('feedback.sub.feed.updated'),
+ $url_redirect,
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0
+ );
} elseif ($values['url'] != '' && $feedDAO->updateFeed($id, $values) !== false) {
$feed->_categoryId($values['category']);
// update url and website values for faviconPrepare
@@ -391,7 +395,11 @@ class FreshRSS_subscription_Controller extends FreshRSS_ActionController {
$feed->_website($values['website'], false);
$feed->faviconPrepare();
- Minz_Request::good(_t('feedback.sub.feed.updated'), $url_redirect);
+ Minz_Request::good(
+ _t('feedback.sub.feed.updated'),
+ $url_redirect,
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0
+ );
} else {
if ($values['url'] == '') {
Minz_Log::warning('Invalid feed URL!');
diff --git a/app/Controllers/tagController.php b/app/Controllers/tagController.php
index 47301bba0..aaeff7f75 100644
--- a/app/Controllers/tagController.php
+++ b/app/Controllers/tagController.php
@@ -126,7 +126,11 @@ class FreshRSS_tag_Controller extends FreshRSS_ActionController {
$url_redirect = ['c' => 'tag', 'a' => 'update', 'params' => ['id' => $id]];
if ($ok) {
- Minz_Request::good(_t('feedback.tag.updated'), $url_redirect);
+ Minz_Request::good(
+ _t('feedback.tag.updated'),
+ $url_redirect,
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0
+ );
} else {
Minz_Request::bad(_t('feedback.tag.error'), $url_redirect);
}
@@ -167,7 +171,11 @@ class FreshRSS_tag_Controller extends FreshRSS_ActionController {
}
$tagDAO->addTag(['name' => $name]);
- Minz_Request::good(_t('feedback.tag.created', $name), $url_redirect);
+ Minz_Request::good(
+ _t('feedback.tag.created', $name),
+ $url_redirect,
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0
+ );
}
/**
@@ -203,7 +211,10 @@ class FreshRSS_tag_Controller extends FreshRSS_ActionController {
$tagDAO->deleteTag($sourceId);
}
- Minz_Request::good(_t('feedback.tag.renamed', $sourceName, $targetName), ['c' => 'tag', 'a' => 'index']);
+ Minz_Request::good(
+ _t('feedback.tag.renamed', $sourceName, $targetName),
+ ['c' => 'tag', 'a' => 'index'],
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0);
}
public function indexAction(): void {
diff --git a/app/Controllers/updateController.php b/app/Controllers/updateController.php
index bd140b6d5..7c204de8c 100644
--- a/app/Controllers/updateController.php
+++ b/app/Controllers/updateController.php
@@ -289,7 +289,10 @@ class FreshRSS_update_Controller extends FreshRSS_ActionController {
@unlink(UPDATE_FILENAME);
@file_put_contents(join_path(DATA_PATH, self::LASTUPDATEFILE), '');
Minz_Log::notice(_t('feedback.update.finished'));
- Minz_Request::good(_t('feedback.update.finished'));
+ Minz_Request::good(
+ _t('feedback.update.finished'),
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0
+ );
} else {
Minz_Log::error(_t('feedback.update.error', is_string($res) ? $res : 'unknown'));
Minz_Request::bad(_t('feedback.update.error', is_string($res) ? $res : 'unknown'), [ 'c' => 'update', 'a' => 'index' ]);
diff --git a/app/Controllers/userController.php b/app/Controllers/userController.php
index f3db70c3a..f820ef882 100644
--- a/app/Controllers/userController.php
+++ b/app/Controllers/userController.php
@@ -86,9 +86,17 @@ class FreshRSS_user_Controller extends FreshRSS_ActionController {
if ($ok) {
$isSelfUpdate = Minz_User::name() === $username;
if ($newPasswordPlain == '' || !$isSelfUpdate) {
- Minz_Request::good(_t('feedback.user.updated', $username), ['c' => 'user', 'a' => 'manage']);
+ Minz_Request::good(
+ _t('feedback.user.updated', $username),
+ ['c' => 'user', 'a' => 'manage'],
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0
+ );
} else {
- Minz_Request::good(_t('feedback.profile.updated'), ['c' => 'index', 'a' => 'index']);
+ Minz_Request::good(
+ _t('feedback.profile.updated'),
+ ['c' => 'index', 'a' => 'index'],
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0
+ );
}
} else {
Minz_Request::bad(_t('feedback.user.updated.error', $username), ['c' => 'user', 'a' => 'manage']);
@@ -179,9 +187,17 @@ class FreshRSS_user_Controller extends FreshRSS_ActionController {
if ($ok) {
if (FreshRSS_Context::systemConf()->force_email_validation && $email !== $old_email) {
- Minz_Request::good(_t('feedback.profile.updated'), ['c' => 'user', 'a' => 'validateEmail']);
+ Minz_Request::good(
+ _t('feedback.profile.updated'),
+ ['c' => 'user', 'a' => 'validateEmail'],
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0
+ );
} else {
- Minz_Request::good(_t('feedback.profile.updated'), ['c' => 'user', 'a' => 'profile']);
+ Minz_Request::good(
+ _t('feedback.profile.updated'),
+ ['c' => 'user', 'a' => 'profile'],
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0
+ );
}
} else {
Minz_Request::bad(_t('feedback.profile.error'), ['c' => 'user', 'a' => 'profile']);
@@ -532,7 +548,8 @@ class FreshRSS_user_Controller extends FreshRSS_ActionController {
if ($user_config->email_validation_token === '') {
Minz_Request::good(
_t('user.email.validation.feedback.unnecessary'),
- ['c' => 'index', 'a' => 'index']
+ ['c' => 'index', 'a' => 'index'],
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0
);
}
@@ -548,7 +565,8 @@ class FreshRSS_user_Controller extends FreshRSS_ActionController {
if ($user_config->save()) {
Minz_Request::good(
_t('user.email.validation.feedback.ok'),
- ['c' => 'index', 'a' => 'index']
+ ['c' => 'index', 'a' => 'index'],
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0
);
} else {
Minz_Request::bad(
@@ -594,7 +612,8 @@ class FreshRSS_user_Controller extends FreshRSS_ActionController {
if ($ok) {
Minz_Request::good(
_t('user.email.validation.feedback.email_sent'),
- $redirect_url
+ $redirect_url,
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0
);
} else {
Minz_Request::bad(
@@ -709,7 +728,11 @@ class FreshRSS_user_Controller extends FreshRSS_ActionController {
FreshRSS_UserDAO::touch($username);
if ($ok) {
- Minz_Request::good(_t('feedback.user.updated', $username), ['c' => 'user', 'a' => 'manage']);
+ Minz_Request::good(
+ _t('feedback.user.updated', $username),
+ ['c' => 'user', 'a' => 'manage'],
+ showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0
+ );
} else {
Minz_Request::bad(
_t('feedback.user.updated.error', $username),
diff --git a/app/Models/UserConfiguration.php b/app/Models/UserConfiguration.php
index 919487bf0..2cb11bbe4 100644
--- a/app/Models/UserConfiguration.php
+++ b/app/Models/UserConfiguration.php
@@ -28,6 +28,8 @@ declare(strict_types=1);
* @property string $feverKey
* @property bool $hide_read_feeds
* @property int $html5_notif_timeout
+ * @property int $good_notification_timeout
+ * @property int $bad_notification_timeout
* @property-read bool $is_admin
* @property int|null $keep_history_default
* @property string $language
diff --git a/app/i18n/cs/conf.php b/app/i18n/cs/conf.php
index d84c13363..75412206a 100644
--- a/app/i18n/cs/conf.php
+++ b/app/i18n/cs/conf.php
@@ -105,6 +105,16 @@ return array(
'none' => 'None', // TODO
'small' => 'Small', // TODO
),
+ 'notification_timeout' => array(
+ 'bad' => array(
+ 'label' => 'Show warning banner', // TODO
+ 'seconds' => 'seconds (at least 1)', // TODO
+ ),
+ 'good' => array(
+ 'label' => 'Show acknowledgement banner', // TODO
+ 'seconds' => 'seconds (0 means not shown)', // TODO
+ ),
+ ),
'privacy' => array(
'_' => 'Privacy', // TODO
'retrieve_extension_list' => 'Retrieve extension list', // TODO
diff --git a/app/i18n/de/conf.php b/app/i18n/de/conf.php
index 5097dce38..7f6f4f5f9 100644
--- a/app/i18n/de/conf.php
+++ b/app/i18n/de/conf.php
@@ -105,6 +105,16 @@ return array(
'none' => 'Keine',
'small' => 'Klein',
),
+ 'notification_timeout' => array(
+ 'bad' => array(
+ 'label' => 'Show warning banner', // TODO
+ 'seconds' => 'seconds (at least 1)', // TODO
+ ),
+ 'good' => array(
+ 'label' => 'Show acknowledgement banner', // TODO
+ 'seconds' => 'seconds (0 means not shown)', // TODO
+ ),
+ ),
'privacy' => array(
'_' => 'Privatsphäre',
'retrieve_extension_list' => 'Erweiterungsliste abrufen',
diff --git a/app/i18n/el/conf.php b/app/i18n/el/conf.php
index b85d330f8..9936f18a7 100644
--- a/app/i18n/el/conf.php
+++ b/app/i18n/el/conf.php
@@ -105,6 +105,16 @@ return array(
'none' => 'None', // TODO
'small' => 'Small', // TODO
),
+ 'notification_timeout' => array(
+ 'bad' => array(
+ 'label' => 'Show warning banner', // TODO
+ 'seconds' => 'seconds (at least 1)', // TODO
+ ),
+ 'good' => array(
+ 'label' => 'Show acknowledgement banner', // TODO
+ 'seconds' => 'seconds (0 means not shown)', // TODO
+ ),
+ ),
'privacy' => array(
'_' => 'Privacy', // TODO
'retrieve_extension_list' => 'Retrieve extension list', // TODO
diff --git a/app/i18n/en-us/conf.php b/app/i18n/en-us/conf.php
index 9cf51423c..d64e93ca1 100644
--- a/app/i18n/en-us/conf.php
+++ b/app/i18n/en-us/conf.php
@@ -105,6 +105,16 @@ return array(
'none' => 'None', // IGNORE
'small' => 'Small', // IGNORE
),
+ 'notification_timeout' => array(
+ 'bad' => array(
+ 'label' => 'Show warning banner', // IGNORE
+ 'seconds' => 'seconds (at least 1)', // IGNORE
+ ),
+ 'good' => array(
+ 'label' => 'Show acknowledgment banner',
+ 'seconds' => 'seconds (0 means not shown)', // IGNORE
+ ),
+ ),
'privacy' => array(
'_' => 'Privacy', // IGNORE
'retrieve_extension_list' => 'Retrieve extension list', // IGNORE
diff --git a/app/i18n/en/conf.php b/app/i18n/en/conf.php
index 7d6ec17c7..025cb4f8f 100644
--- a/app/i18n/en/conf.php
+++ b/app/i18n/en/conf.php
@@ -105,6 +105,16 @@ return array(
'none' => 'None',
'small' => 'Small',
),
+ 'notification_timeout' => array(
+ 'bad' => array(
+ 'label' => 'Show warning banner', // TODO
+ 'seconds' => 'seconds (at least 1)', // TODO
+ ),
+ 'good' => array(
+ 'label' => 'Show acknowledgement banner', // TODO
+ 'seconds' => 'seconds (0 means not shown)', // TODO
+ ),
+ ),
'privacy' => array(
'_' => 'Privacy',
'retrieve_extension_list' => 'Retrieve extension list',
diff --git a/app/i18n/es/conf.php b/app/i18n/es/conf.php
index 067f82095..7548a0a38 100644
--- a/app/i18n/es/conf.php
+++ b/app/i18n/es/conf.php
@@ -105,6 +105,16 @@ return array(
'none' => 'None', // TODO
'small' => 'Small', // TODO
),
+ 'notification_timeout' => array(
+ 'bad' => array(
+ 'label' => 'Show warning banner', // TODO
+ 'seconds' => 'seconds (at least 1)', // TODO
+ ),
+ 'good' => array(
+ 'label' => 'Show acknowledgement banner', // TODO
+ 'seconds' => 'seconds (0 means not shown)', // TODO
+ ),
+ ),
'privacy' => array(
'_' => 'Privacy', // TODO
'retrieve_extension_list' => 'Retrieve extension list', // TODO
diff --git a/app/i18n/fa/conf.php b/app/i18n/fa/conf.php
index 41dc1edbb..96dae6faa 100644
--- a/app/i18n/fa/conf.php
+++ b/app/i18n/fa/conf.php
@@ -105,6 +105,16 @@ return array(
'none' => 'هیچ',
'small' => 'کوچک',
),
+ 'notification_timeout' => array(
+ 'bad' => array(
+ 'label' => 'Show warning banner', // TODO
+ 'seconds' => 'seconds (at least 1)', // TODO
+ ),
+ 'good' => array(
+ 'label' => 'Show acknowledgement banner', // TODO
+ 'seconds' => 'seconds (0 means not shown)', // TODO
+ ),
+ ),
'privacy' => array(
'_' => 'حریم خصوصی',
'retrieve_extension_list' => 'بازیابی لیست افزونه‌ها',
diff --git a/app/i18n/fi/conf.php b/app/i18n/fi/conf.php
index f9ed6b887..ac3929bc4 100644
--- a/app/i18n/fi/conf.php
+++ b/app/i18n/fi/conf.php
@@ -105,6 +105,16 @@ return array(
'none' => 'None', // TODO
'small' => 'Small', // TODO
),
+ 'notification_timeout' => array(
+ 'bad' => array(
+ 'label' => 'Show warning banner', // TODO
+ 'seconds' => 'seconds (at least 1)', // TODO
+ ),
+ 'good' => array(
+ 'label' => 'Show acknowledgement banner', // TODO
+ 'seconds' => 'seconds (0 means not shown)', // TODO
+ ),
+ ),
'privacy' => array(
'_' => 'Tietosuoja',
'retrieve_extension_list' => 'Nouda laajennusluettelo',
diff --git a/app/i18n/fr/conf.php b/app/i18n/fr/conf.php
index 9e9fcb938..432db40c3 100644
--- a/app/i18n/fr/conf.php
+++ b/app/i18n/fr/conf.php
@@ -105,6 +105,16 @@ return array(
'none' => 'Aucun',
'small' => 'Petit',
),
+ 'notification_timeout' => array(
+ 'bad' => array(
+ 'label' => 'Afficher la bannière d’avertissement',
+ 'seconds' => 'secondes (au moins 1)',
+ ),
+ 'good' => array(
+ 'label' => 'Afficher la bannière de confirmation',
+ 'seconds' => 'secondes (0 pour désactiver)',
+ ),
+ ),
'privacy' => array(
'_' => 'Vie privée',
'retrieve_extension_list' => 'Récupération de la liste des extensions',
diff --git a/app/i18n/he/conf.php b/app/i18n/he/conf.php
index 72b513943..c67888256 100644
--- a/app/i18n/he/conf.php
+++ b/app/i18n/he/conf.php
@@ -105,6 +105,16 @@ return array(
'none' => 'None', // TODO
'small' => 'Small', // TODO
),
+ 'notification_timeout' => array(
+ 'bad' => array(
+ 'label' => 'Show warning banner', // TODO
+ 'seconds' => 'seconds (at least 1)', // TODO
+ ),
+ 'good' => array(
+ 'label' => 'Show acknowledgement banner', // TODO
+ 'seconds' => 'seconds (0 means not shown)', // TODO
+ ),
+ ),
'privacy' => array(
'_' => 'Privacy', // TODO
'retrieve_extension_list' => 'Retrieve extension list', // TODO
diff --git a/app/i18n/hu/conf.php b/app/i18n/hu/conf.php
index 2f6bc5ae1..ee37e7c44 100644
--- a/app/i18n/hu/conf.php
+++ b/app/i18n/hu/conf.php
@@ -105,6 +105,16 @@ return array(
'none' => 'Egyik sem',
'small' => 'Kicsi',
),
+ 'notification_timeout' => array(
+ 'bad' => array(
+ 'label' => 'Show warning banner', // TODO
+ 'seconds' => 'seconds (at least 1)', // TODO
+ ),
+ 'good' => array(
+ 'label' => 'Show acknowledgement banner', // TODO
+ 'seconds' => 'seconds (0 means not shown)', // TODO
+ ),
+ ),
'privacy' => array(
'_' => 'Adatvédelem',
'retrieve_extension_list' => 'Kiterjesztés lista beszerzése',
diff --git a/app/i18n/id/conf.php b/app/i18n/id/conf.php
index e573fa913..64e1bc7c3 100644
--- a/app/i18n/id/conf.php
+++ b/app/i18n/id/conf.php
@@ -105,6 +105,16 @@ return array(
'none' => 'Tidak ditampilkan',
'small' => 'Kecil',
),
+ 'notification_timeout' => array(
+ 'bad' => array(
+ 'label' => 'Show warning banner', // TODO
+ 'seconds' => 'seconds (at least 1)', // TODO
+ ),
+ 'good' => array(
+ 'label' => 'Show acknowledgement banner', // TODO
+ 'seconds' => 'seconds (0 means not shown)', // TODO
+ ),
+ ),
'privacy' => array(
'_' => 'Privasi',
'retrieve_extension_list' => 'Ambil daftar ekstensi',
diff --git a/app/i18n/it/conf.php b/app/i18n/it/conf.php
index 06bebf33c..b3815a952 100644
--- a/app/i18n/it/conf.php
+++ b/app/i18n/it/conf.php
@@ -105,6 +105,16 @@ return array(
'none' => 'Nessuno',
'small' => 'Piccolo',
),
+ 'notification_timeout' => array(
+ 'bad' => array(
+ 'label' => 'Show warning banner', // TODO
+ 'seconds' => 'seconds (at least 1)', // TODO
+ ),
+ 'good' => array(
+ 'label' => 'Show acknowledgement banner', // TODO
+ 'seconds' => 'seconds (0 means not shown)', // TODO
+ ),
+ ),
'privacy' => array(
'_' => 'Privacy', // IGNORE
'retrieve_extension_list' => 'Recupero dell’elenco delle estensioni',
diff --git a/app/i18n/ja/conf.php b/app/i18n/ja/conf.php
index d55dc8ace..db04ea4f9 100644
--- a/app/i18n/ja/conf.php
+++ b/app/i18n/ja/conf.php
@@ -105,6 +105,16 @@ return array(
'none' => 'None', // TODO
'small' => 'Small', // TODO
),
+ 'notification_timeout' => array(
+ 'bad' => array(
+ 'label' => 'Show warning banner', // TODO
+ 'seconds' => 'seconds (at least 1)', // TODO
+ ),
+ 'good' => array(
+ 'label' => 'Show acknowledgement banner', // TODO
+ 'seconds' => 'seconds (0 means not shown)', // TODO
+ ),
+ ),
'privacy' => array(
'_' => 'プライバシー',
'retrieve_extension_list' => '拡張機能リストを取得する',
diff --git a/app/i18n/ko/conf.php b/app/i18n/ko/conf.php
index 72658941f..b659190d2 100644
--- a/app/i18n/ko/conf.php
+++ b/app/i18n/ko/conf.php
@@ -105,6 +105,16 @@ return array(
'none' => 'None', // TODO
'small' => 'Small', // TODO
),
+ 'notification_timeout' => array(
+ 'bad' => array(
+ 'label' => 'Show warning banner', // TODO
+ 'seconds' => 'seconds (at least 1)', // TODO
+ ),
+ 'good' => array(
+ 'label' => 'Show acknowledgement banner', // TODO
+ 'seconds' => 'seconds (0 means not shown)', // TODO
+ ),
+ ),
'privacy' => array(
'_' => 'Privacy', // TODO
'retrieve_extension_list' => 'Retrieve extension list', // TODO
diff --git a/app/i18n/lv/conf.php b/app/i18n/lv/conf.php
index 4c49de724..6375860e4 100644
--- a/app/i18n/lv/conf.php
+++ b/app/i18n/lv/conf.php
@@ -105,6 +105,16 @@ return array(
'none' => 'None', // TODO
'small' => 'Small', // TODO
),
+ 'notification_timeout' => array(
+ 'bad' => array(
+ 'label' => 'Show warning banner', // TODO
+ 'seconds' => 'seconds (at least 1)', // TODO
+ ),
+ 'good' => array(
+ 'label' => 'Show acknowledgement banner', // TODO
+ 'seconds' => 'seconds (0 means not shown)', // TODO
+ ),
+ ),
'privacy' => array(
'_' => 'Privacy', // TODO
'retrieve_extension_list' => 'Retrieve extension list', // TODO
diff --git a/app/i18n/nl/conf.php b/app/i18n/nl/conf.php
index ebf2dd079..d3cd21cd2 100644
--- a/app/i18n/nl/conf.php
+++ b/app/i18n/nl/conf.php
@@ -105,6 +105,16 @@ return array(
'none' => 'Geen',
'small' => 'Klein',
),
+ 'notification_timeout' => array(
+ 'bad' => array(
+ 'label' => 'Show warning banner', // TODO
+ 'seconds' => 'seconds (at least 1)', // TODO
+ ),
+ 'good' => array(
+ 'label' => 'Show acknowledgement banner', // TODO
+ 'seconds' => 'seconds (0 means not shown)', // TODO
+ ),
+ ),
'privacy' => array(
'_' => 'Privacy', // IGNORE
'retrieve_extension_list' => 'Extensielijst ophalen',
diff --git a/app/i18n/oc/conf.php b/app/i18n/oc/conf.php
index 49ac36d10..f8c5ecb44 100644
--- a/app/i18n/oc/conf.php
+++ b/app/i18n/oc/conf.php
@@ -105,6 +105,16 @@ return array(
'none' => 'None', // TODO
'small' => 'Small', // TODO
),
+ 'notification_timeout' => array(
+ 'bad' => array(
+ 'label' => 'Show warning banner', // TODO
+ 'seconds' => 'seconds (at least 1)', // TODO
+ ),
+ 'good' => array(
+ 'label' => 'Show acknowledgement banner', // TODO
+ 'seconds' => 'seconds (0 means not shown)', // TODO
+ ),
+ ),
'privacy' => array(
'_' => 'Privacy', // TODO
'retrieve_extension_list' => 'Retrieve extension list', // TODO
diff --git a/app/i18n/pl/conf.php b/app/i18n/pl/conf.php
index f65a64f1b..41a6e9808 100644
--- a/app/i18n/pl/conf.php
+++ b/app/i18n/pl/conf.php
@@ -105,6 +105,16 @@ return array(
'none' => 'Brak',
'small' => 'Mały',
),
+ 'notification_timeout' => array(
+ 'bad' => array(
+ 'label' => 'Pokaż baner ostrzeżenia',
+ 'seconds' => 'sekundy (przynajmniej 1)',
+ ),
+ 'good' => array(
+ 'label' => 'Pokaż baner potwierdzający',
+ 'seconds' => 'sekundy (0 oznacza nie pokazuj)',
+ ),
+ ),
'privacy' => array(
'_' => 'Prywatność',
'retrieve_extension_list' => 'Pobieraj listę rozszerzeń',
diff --git a/app/i18n/pt-br/conf.php b/app/i18n/pt-br/conf.php
index 69c7a40b3..9f2daba08 100644
--- a/app/i18n/pt-br/conf.php
+++ b/app/i18n/pt-br/conf.php
@@ -105,6 +105,16 @@ return array(
'none' => 'None', // TODO
'small' => 'Small', // TODO
),
+ 'notification_timeout' => array(
+ 'bad' => array(
+ 'label' => 'Show warning banner', // TODO
+ 'seconds' => 'seconds (at least 1)', // TODO
+ ),
+ 'good' => array(
+ 'label' => 'Show acknowledgement banner', // TODO
+ 'seconds' => 'seconds (0 means not shown)', // TODO
+ ),
+ ),
'privacy' => array(
'_' => 'Privacy', // TODO
'retrieve_extension_list' => 'Retrieve extension list', // TODO
diff --git a/app/i18n/pt-pt/conf.php b/app/i18n/pt-pt/conf.php
index 5d9d7e452..5977c0b97 100644
--- a/app/i18n/pt-pt/conf.php
+++ b/app/i18n/pt-pt/conf.php
@@ -105,6 +105,16 @@ return array(
'none' => 'None', // TODO
'small' => 'Small', // TODO
),
+ 'notification_timeout' => array(
+ 'bad' => array(
+ 'label' => 'Show warning banner', // TODO
+ 'seconds' => 'seconds (at least 1)', // TODO
+ ),
+ 'good' => array(
+ 'label' => 'Show acknowledgement banner', // TODO
+ 'seconds' => 'seconds (0 means not shown)', // TODO
+ ),
+ ),
'privacy' => array(
'_' => 'Privacy', // TODO
'retrieve_extension_list' => 'Retrieve extension list', // TODO
diff --git a/app/i18n/ru/conf.php b/app/i18n/ru/conf.php
index 8771be579..8f1eedc7f 100644
--- a/app/i18n/ru/conf.php
+++ b/app/i18n/ru/conf.php
@@ -105,6 +105,16 @@ return array(
'none' => 'None', // TODO
'small' => 'Small', // TODO
),
+ 'notification_timeout' => array(
+ 'bad' => array(
+ 'label' => 'Show warning banner', // TODO
+ 'seconds' => 'seconds (at least 1)', // TODO
+ ),
+ 'good' => array(
+ 'label' => 'Show acknowledgement banner', // TODO
+ 'seconds' => 'seconds (0 means not shown)', // TODO
+ ),
+ ),
'privacy' => array(
'_' => 'Privacy', // TODO
'retrieve_extension_list' => 'Retrieve extension list', // TODO
diff --git a/app/i18n/sk/conf.php b/app/i18n/sk/conf.php
index b7a1ebb94..604f2f9ad 100644
--- a/app/i18n/sk/conf.php
+++ b/app/i18n/sk/conf.php
@@ -105,6 +105,16 @@ return array(
'none' => 'None', // TODO
'small' => 'Small', // TODO
),
+ 'notification_timeout' => array(
+ 'bad' => array(
+ 'label' => 'Show warning banner', // TODO
+ 'seconds' => 'seconds (at least 1)', // TODO
+ ),
+ 'good' => array(
+ 'label' => 'Show acknowledgement banner', // TODO
+ 'seconds' => 'seconds (0 means not shown)', // TODO
+ ),
+ ),
'privacy' => array(
'_' => 'Privacy', // TODO
'retrieve_extension_list' => 'Retrieve extension list', // TODO
diff --git a/app/i18n/tr/conf.php b/app/i18n/tr/conf.php
index 92476e835..32c8060c5 100644
--- a/app/i18n/tr/conf.php
+++ b/app/i18n/tr/conf.php
@@ -105,6 +105,16 @@ return array(
'none' => 'Yok',
'small' => 'Küçük',
),
+ 'notification_timeout' => array(
+ 'bad' => array(
+ 'label' => 'Show warning banner', // TODO
+ 'seconds' => 'seconds (at least 1)', // TODO
+ ),
+ 'good' => array(
+ 'label' => 'Show acknowledgement banner', // TODO
+ 'seconds' => 'seconds (0 means not shown)', // TODO
+ ),
+ ),
'privacy' => array(
'_' => 'Gizlilik',
'retrieve_extension_list' => 'Eklenti listesini al',
diff --git a/app/i18n/uk/conf.php b/app/i18n/uk/conf.php
index bc08bb910..e3e9a8fae 100644
--- a/app/i18n/uk/conf.php
+++ b/app/i18n/uk/conf.php
@@ -105,6 +105,16 @@ return array(
'none' => 'Не показувати',
'small' => 'Мала',
),
+ 'notification_timeout' => array(
+ 'bad' => array(
+ 'label' => 'Show warning banner', // TODO
+ 'seconds' => 'seconds (at least 1)', // TODO
+ ),
+ 'good' => array(
+ 'label' => 'Show acknowledgement banner', // TODO
+ 'seconds' => 'seconds (0 means not shown)', // TODO
+ ),
+ ),
'privacy' => array(
'_' => 'Приватність',
'retrieve_extension_list' => 'Завантажувати список розширень',
diff --git a/app/i18n/zh-cn/conf.php b/app/i18n/zh-cn/conf.php
index 021574d64..1ee9bf404 100644
--- a/app/i18n/zh-cn/conf.php
+++ b/app/i18n/zh-cn/conf.php
@@ -105,6 +105,16 @@ return array(
'none' => '无',
'small' => '小',
),
+ 'notification_timeout' => array(
+ 'bad' => array(
+ 'label' => 'Show warning banner', // TODO
+ 'seconds' => 'seconds (at least 1)', // TODO
+ ),
+ 'good' => array(
+ 'label' => 'Show acknowledgement banner', // TODO
+ 'seconds' => 'seconds (0 means not shown)', // TODO
+ ),
+ ),
'privacy' => array(
'_' => 'Privacy', // TODO
'retrieve_extension_list' => '获取扩展列表',
diff --git a/app/i18n/zh-tw/conf.php b/app/i18n/zh-tw/conf.php
index 3fd65032d..ac83b7c1f 100644
--- a/app/i18n/zh-tw/conf.php
+++ b/app/i18n/zh-tw/conf.php
@@ -105,6 +105,16 @@ return array(
'none' => 'None', // TODO
'small' => 'Small', // TODO
),
+ 'notification_timeout' => array(
+ 'bad' => array(
+ 'label' => 'Show warning banner', // TODO
+ 'seconds' => 'seconds (at least 1)', // TODO
+ ),
+ 'good' => array(
+ 'label' => 'Show acknowledgement banner', // TODO
+ 'seconds' => 'seconds (0 means not shown)', // TODO
+ ),
+ ),
'privacy' => array(
'_' => 'Privacy', // TODO
'retrieve_extension_list' => 'Retrieve extension list', // TODO
diff --git a/app/views/configure/display.phtml b/app/views/configure/display.phtml
index 27231c2f0..8efc13266 100644
--- a/app/views/configure/display.phtml
+++ b/app/views/configure/display.phtml
@@ -242,12 +242,28 @@
<div class="form-group">
<label class="group-name" for="html5_notif_timeout"><?= _t('conf.display.notif_html5.timeout') ?></label>
<div class="group-controls">
- <input type="number" id="html5_notif_timeout" name="html5_notif_timeout" value="<?=
+ <input type="number" min="0" max="60" id="html5_notif_timeout" name="html5_notif_timeout" value="<?=
FreshRSS_Context::userConf()->html5_notif_timeout ?>" /> <?= _t('conf.display.notif_html5.seconds') ?>
</div>
</div>
<div class="form-group">
+ <label class="group-name" for="good_notification_timeout"><?= _t('conf.notification_timeout.good.label') ?></label>
+ <div class="group-controls">
+ <input type="number" min="0" max="60" id="good_notification_timeout" name="good_notification_timeout" value="<?=
+ FreshRSS_Context::userConf()->good_notification_timeout ?>" /> <?= _t('conf.notification_timeout.good.seconds') ?>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <label class="group-name" for="bad_notification_timeout"><?= _t('conf.notification_timeout.bad.label') ?></label>
+ <div class="group-controls">
+ <input type="number" min="1" max="60" id="bad_notification_timeout" name="bad_notification_timeout" value="<?=
+ FreshRSS_Context::userConf()->bad_notification_timeout ?>" /> <?= _t('conf.notification_timeout.bad.seconds') ?>
+ </div>
+ </div>
+
+ <div class="form-group">
<div class="group-controls">
<label class="checkbox" for="show_nav_buttons">
<input type="checkbox" name="show_nav_buttons" id="show_nav_buttons" value="1"<?=
diff --git a/app/views/helpers/javascript_vars.phtml b/app/views/helpers/javascript_vars.phtml
index 2cedc20c3..96275d51b 100644
--- a/app/views/helpers/javascript_vars.phtml
+++ b/app/views/helpers/javascript_vars.phtml
@@ -25,6 +25,11 @@ echo json_encode([
'sides_close_article' => !!FreshRSS_Context::userConf()->sides_close_article,
'sticky_post' => !!FreshRSS_Context::isStickyPostEnabled(),
'html5_notif_timeout' => FreshRSS_Context::userConf()->html5_notif_timeout,
+ 'closeNotification' => [
+ 'good' => FreshRSS_Context::userConf()->good_notification_timeout * 1000,
+ 'bad' => FreshRSS_Context::userConf()->bad_notification_timeout * 1000,
+ 'mouseLeave' => 3000,
+ ],
'auth_type' => FreshRSS_Context::systemConf()->auth_type,
'current_view' => Minz_Request::actionName(),
'csrf' => FreshRSS_Auth::csrfToken(),
diff --git a/config-user.default.php b/config-user.default.php
index 816b5a3a8..7f614d564 100644
--- a/config-user.default.php
+++ b/config-user.default.php
@@ -125,6 +125,8 @@ return array (
'queries' => array (
),
'html5_notif_timeout' => 0,
+ 'good_notification_timeout' => 3,
+ 'bad_notification_timeout' => 8,
'show_nav_buttons' => true,
# List of enabled FreshRSS extensions.
'extensions_enabled' => [],
diff --git a/docs/en/developers/Minz/index.md b/docs/en/developers/Minz/index.md
index 05fbfdaef..dadf38eed 100644
--- a/docs/en/developers/Minz/index.md
+++ b/docs/en/developers/Minz/index.md
@@ -173,7 +173,7 @@ $url_array = [
$feedback_good = 'All went well!';
$feedback_bad = 'Oops, something went wrong.';
-Minz_Request::good($feedback_good, $url_array);
+Minz_Request::good($feedback_good, $url_array, showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0);
// or
diff --git a/docs/fr/developers/Minz/index.md b/docs/fr/developers/Minz/index.md
index 3cdb692f3..f89686f1c 100644
--- a/docs/fr/developers/Minz/index.md
+++ b/docs/fr/developers/Minz/index.md
@@ -229,7 +229,7 @@ $url_array = [
$feedback_good = 'Tout s’est bien passé !';
$feedback_bad = 'Oups, quelque chose n’a pas marché.';
-Minz_Request::good($feedback_good, $url_array);
+Minz_Request::good($feedback_good, $url_array, showNotification: FreshRSS_Context::userConf()->good_notification_timeout > 0);
// ou
diff --git a/docs/i18n/flags/gen/es.svg b/docs/i18n/flags/gen/es.svg
index 6d976bfc8..e9ed3f3e7 100644
--- a/docs/i18n/flags/gen/es.svg
+++ b/docs/i18n/flags/gen/es.svg
@@ -2,6 +2,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="70" height="20">
<g fill="white" font-size="12" font-family="Verdana" text-anchor="middle">
<rect rx="3" width="70" height="20" fill="green" />
- <text x="34" y="14">🇪🇸 92%</text>
+ <text x="34" y="14">🇪🇸 91%</text>
</g>
</svg> \ No newline at end of file
diff --git a/docs/i18n/flags/gen/fa.svg b/docs/i18n/flags/gen/fa.svg
index 0870a09f7..f9a273509 100644
--- a/docs/i18n/flags/gen/fa.svg
+++ b/docs/i18n/flags/gen/fa.svg
@@ -2,6 +2,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="70" height="20">
<g fill="white" font-size="12" font-family="Verdana" text-anchor="middle">
<rect rx="3" width="70" height="20" fill="green" />
- <text x="34" y="14">🇮🇷 98%</text>
+ <text x="34" y="14">🇮🇷 97%</text>
</g>
</svg> \ No newline at end of file
diff --git a/lib/Minz/Request.php b/lib/Minz/Request.php
index a41ddb0a6..4bf6fa45c 100644
--- a/lib/Minz/Request.php
+++ b/lib/Minz/Request.php
@@ -461,8 +461,10 @@ class Minz_Request {
* @param string $msg notification content
* @param array{c?:string,a?:string,params?:array<string,mixed>} $url url array to where we should be forwarded
*/
- public static function good(string $msg, array $url = [], string $notificationName = ''): void {
- Minz_Request::setGoodNotification($msg, $notificationName);
+ public static function good(string $msg, array $url = [], string $notificationName = '', bool $showNotification = true): void {
+ if ($showNotification) {
+ Minz_Request::setGoodNotification($msg);
+ }
Minz_Request::forward($url, true);
}
diff --git a/p/scripts/main.js b/p/scripts/main.js
index 372a86050..8f85f7333 100644
--- a/p/scripts/main.js
+++ b/p/scripts/main.js
@@ -1814,14 +1814,22 @@ function openNotification(msg, status) {
}
notification_working = true;
notification.querySelector('.msg').innerHTML = msg;
- notification.className = 'notification';
- notification.classList.add(status);
+
if (status == 'good') {
- notification_interval = setTimeout(closeNotification, 4000);
+ if (context.closeNotification.good > 0) {
+ notification_interval = setTimeout(closeNotification, context.closeNotification.good);
+ } else {
+ notification.classList.add('closed');
+ notification_working = false;
+ }
} else {
// no status or f.e. status = 'bad', give some more time to read
- notification_interval = setTimeout(closeNotification, 8000);
+ if (context.closeNotification.good > 0) {
+ notification_interval = setTimeout(closeNotification, context.closeNotification.bad);
+ }
}
+ notification.className = 'notification';
+ notification.classList.add(status);
}
function closeNotification() {
@@ -1844,16 +1852,16 @@ function init_notifications() {
});
notification.addEventListener('mouseleave', function () {
- notification_interval = setTimeout(closeNotification, 3000);
+ notification_interval = setTimeout(closeNotification, context.closeNotification.mouseLeave);
});
if (notification.querySelector('.msg').innerHTML.length > 0) {
notification_working = true;
if (notification.classList.contains('good')) {
- notification_interval = setTimeout(closeNotification, 4000);
+ notification_interval = setTimeout(closeNotification, context.closeNotification.good);
} else {
// no status or f.e. status = 'bad', give some more time to read
- notification_interval = setTimeout(closeNotification, 8000);
+ notification_interval = setTimeout(closeNotification, context.closeNotification.bad);
}
}
}