diff --git a/apps/theming/lib/Listener/BeforePreferenceListener.php b/apps/theming/lib/Listener/BeforePreferenceListener.php index d823df1ab33c2..78e2f3c447c58 100644 --- a/apps/theming/lib/Listener/BeforePreferenceListener.php +++ b/apps/theming/lib/Listener/BeforePreferenceListener.php @@ -22,7 +22,15 @@ class BeforePreferenceListener implements IEventListener { /** * @var string[] */ - private const ALLOWED_KEYS = ['force_enable_blur_filter', 'shortcuts_disabled', 'primary_color']; + private const ALLOWED_KEYS = ['force_enable_blur_filter', 'shortcuts_disabled', 'primary_color', 'toast_timeout']; + + /** + * Allowed toast timeout values in milliseconds. + * Default (7000) is represented by deleting the preference. + * + * @var string[] + */ + public const TOAST_TIMEOUT_VALUES = ['15000', '30000', '-1']; public function __construct( private IAppManager $appManager, @@ -62,6 +70,9 @@ private function handleThemingValues(BeforePreferenceSetEvent|BeforePreferenceDe case 'primary_color': $event->setValid(preg_match('/^\#([0-9a-f]{3}|[0-9a-f]{6})$/i', $event->getConfigValue()) === 1); break; + case 'toast_timeout': + $event->setValid(in_array($event->getConfigValue(), self::TOAST_TIMEOUT_VALUES, true)); + break; default: $event->setValid(false); } diff --git a/apps/theming/lib/Listener/BeforeTemplateRenderedListener.php b/apps/theming/lib/Listener/BeforeTemplateRenderedListener.php index 3a62d8ebdf32b..88a307067d434 100644 --- a/apps/theming/lib/Listener/BeforeTemplateRenderedListener.php +++ b/apps/theming/lib/Listener/BeforeTemplateRenderedListener.php @@ -51,6 +51,17 @@ public function handle(Event $event): void { } return false; }); + + $this->initialState->provideLazyInitialState('toastTimeout', function () { + if ($this->userSession->getUser()) { + $uid = $this->userSession->getUser()->getUID(); + $value = $this->config->getUserValue($uid, Application::APP_ID, 'toast_timeout', '7000'); + if (in_array($value, BeforePreferenceListener::TOAST_TIMEOUT_VALUES, true) || $value === '7000') { + return (int)$value; + } + } + return 7000; + }); } $this->themeInjectionService->injectHeaders(); diff --git a/apps/theming/src/components/UserSectionToastTimeout.vue b/apps/theming/src/components/UserSectionToastTimeout.vue new file mode 100644 index 0000000000000..5506cdab0f9c2 --- /dev/null +++ b/apps/theming/src/components/UserSectionToastTimeout.vue @@ -0,0 +1,112 @@ + + + + + + + diff --git a/apps/theming/src/theming.ts b/apps/theming/src/theming.ts index 4678efe37a319..4187da73a9e56 100644 --- a/apps/theming/src/theming.ts +++ b/apps/theming/src/theming.ts @@ -3,6 +3,12 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ +import { setToastTimeout, TOAST_DEFAULT_TIMEOUT } from '@nextcloud/dialogs' import { loadState } from '@nextcloud/initial-state' window.OCA.Theming = loadState('theming', 'data') + +const toastTimeout = loadState('theming', 'toastTimeout', TOAST_DEFAULT_TIMEOUT) +if (typeof toastTimeout === 'number') { + setToastTimeout(toastTimeout) +} diff --git a/apps/theming/src/views/UserTheming.vue b/apps/theming/src/views/UserTheming.vue index 6ecee83202e7a..7bb7128547e0d 100644 --- a/apps/theming/src/views/UserTheming.vue +++ b/apps/theming/src/views/UserTheming.vue @@ -49,6 +49,7 @@ + @@ -68,6 +69,7 @@ import UserSectionAppMenu from '../components/UserSectionAppMenu.vue' import UserSectionBackground from '../components/UserSectionBackground.vue' import UserSectionHotkeys from '../components/UserSectionHotkeys.vue' import UserSectionPrimaryColor from '../components/UserSectionPrimaryColor.vue' +import UserSectionToastTimeout from '../components/UserSectionToastTimeout.vue' import { refreshStyles } from '../utils/refreshStyles.js' const isUserThemingDisabled = loadState('theming', 'isUserThemingDisabled')