diff --git a/apps/theming/REUSE.toml b/apps/theming/REUSE.toml index c05da08200291..f0d04e87a163b 100644 --- a/apps/theming/REUSE.toml +++ b/apps/theming/REUSE.toml @@ -16,7 +16,7 @@ SPDX-FileCopyrightText = "2012-2019 Abbie Gonzalez $baseDir . '/../lib/Themes/DyslexiaFont.php', 'OCA\\Theming\\Themes\\HighContrastTheme' => $baseDir . '/../lib/Themes/HighContrastTheme.php', 'OCA\\Theming\\Themes\\LightTheme' => $baseDir . '/../lib/Themes/LightTheme.php', + 'OCA\\Theming\\Themes\\ReducedMotion' => $baseDir . '/../lib/Themes/ReducedMotion.php', 'OCA\\Theming\\ThemingDefaults' => $baseDir . '/../lib/ThemingDefaults.php', 'OCA\\Theming\\Util' => $baseDir . '/../lib/Util.php', ); diff --git a/apps/theming/composer/composer/autoload_static.php b/apps/theming/composer/composer/autoload_static.php index 184d9ed07615b..e9504ba0bea3e 100644 --- a/apps/theming/composer/composer/autoload_static.php +++ b/apps/theming/composer/composer/autoload_static.php @@ -54,6 +54,7 @@ class ComposerStaticInitTheming 'OCA\\Theming\\Themes\\DyslexiaFont' => __DIR__ . '/..' . '/../lib/Themes/DyslexiaFont.php', 'OCA\\Theming\\Themes\\HighContrastTheme' => __DIR__ . '/..' . '/../lib/Themes/HighContrastTheme.php', 'OCA\\Theming\\Themes\\LightTheme' => __DIR__ . '/..' . '/../lib/Themes/LightTheme.php', + 'OCA\\Theming\\Themes\\ReducedMotion' => __DIR__ . '/..' . '/../lib/Themes/ReducedMotion.php', 'OCA\\Theming\\ThemingDefaults' => __DIR__ . '/..' . '/../lib/ThemingDefaults.php', 'OCA\\Theming\\Util' => __DIR__ . '/..' . '/../lib/Util.php', ); diff --git a/apps/theming/img/reduced-motion.jpg b/apps/theming/img/reduced-motion.jpg new file mode 100644 index 0000000000000..de08aecf24316 Binary files /dev/null and b/apps/theming/img/reduced-motion.jpg differ diff --git a/apps/theming/lib/ITheme.php b/apps/theming/lib/ITheme.php index 2e40e8e489b93..fc18503c298d7 100644 --- a/apps/theming/lib/ITheme.php +++ b/apps/theming/lib/ITheme.php @@ -17,6 +17,11 @@ interface ITheme { public const TYPE_THEME = 1; public const TYPE_FONT = 2; + /** + * A supplementary theme where multiple can be active at the same time. + * @since 33.0.0 + */ + public const TYPE_SUPPLEMENTARY = 3; /** * Unique theme id diff --git a/apps/theming/lib/Service/ThemesService.php b/apps/theming/lib/Service/ThemesService.php index f49524cb62caf..ab265eb276c6f 100644 --- a/apps/theming/lib/Service/ThemesService.php +++ b/apps/theming/lib/Service/ThemesService.php @@ -14,6 +14,7 @@ use OCA\Theming\Themes\DyslexiaFont; use OCA\Theming\Themes\HighContrastTheme; use OCA\Theming\Themes\LightTheme; +use OCA\Theming\Themes\ReducedMotion; use OCP\IConfig; use OCP\IUser; use OCP\IUserSession; @@ -33,6 +34,7 @@ public function __construct( HighContrastTheme $highContrastTheme, DarkHighContrastTheme $darkHighContrastTheme, DyslexiaFont $dyslexiaFont, + ReducedMotion $motionSickness, ) { // Register themes @@ -43,6 +45,7 @@ public function __construct( $highContrastTheme->getId() => $highContrastTheme, $darkHighContrastTheme->getId() => $darkHighContrastTheme, $dyslexiaFont->getId() => $dyslexiaFont, + $motionSickness->getId() => $motionSickness, ]; } @@ -84,33 +87,22 @@ public function getThemes(): array { * @return string[] the enabled themes */ public function enableTheme(ITheme $theme): array { - $themesIds = $this->getEnabledThemes(); + $enabledThemeIds = $this->getEnabledThemes(); // If already enabled, ignore - if (in_array($theme->getId(), $themesIds)) { - return $themesIds; + if (in_array($theme->getId(), $enabledThemeIds)) { + return $enabledThemeIds; } - /** @var ITheme[] */ - $themes = array_filter(array_map(function ($themeId) { - return $this->getThemes()[$themeId]; - }, $themesIds)); - - // Filtering all themes with the same type - $filteredThemes = array_filter($themes, function (ITheme $t) use ($theme) { - return $theme->getType() === $t->getType(); - }); - - // Retrieve IDs only - /** @var string[] */ - $filteredThemesIds = array_map(function (ITheme $t) { - return $t->getId(); - }, array_values($filteredThemes)); - - $enabledThemes = array_merge(array_diff($themesIds, $filteredThemesIds), [$theme->getId()]); - $this->setEnabledThemes($enabledThemes); + // for other types then supplementary themes we need to filter out themes with the same type + if ($theme->getType() !== ITheme::TYPE_SUPPLEMENTARY) { + $allThemes = $this->getThemes(); + $enabledThemeIds = array_filter($enabledThemeIds, fn (string $themeId) => $allThemes[$themeId]->gettype() !== $theme->gettype()); + } - return $enabledThemes; + $enabledThemeIds[] = $theme->getId(); + $this->setEnabledThemes($enabledThemeIds); + return array_values($enabledThemeIds); } /** @@ -124,7 +116,7 @@ public function disableTheme(ITheme $theme): array { // If enabled, removing it if (in_array($theme->getId(), $themesIds)) { - $enabledThemes = array_diff($themesIds, [$theme->getId()]); + $enabledThemes = array_values(array_diff($themesIds, [$theme->getId()])); $this->setEnabledThemes($enabledThemes); return $enabledThemes; } diff --git a/apps/theming/lib/Themes/ReducedMotion.php b/apps/theming/lib/Themes/ReducedMotion.php new file mode 100644 index 0000000000000..2af78f3f37866 --- /dev/null +++ b/apps/theming/lib/Themes/ReducedMotion.php @@ -0,0 +1,60 @@ +l->t('Reduced motion'); + } + + public function getEnableLabel(): string { + return $this->l->t('Motion sickness reduction'); + } + + public function getDescription(): string { + return $this->l->t('Prevents animations, such as scaling or panning large objects, that can trigger discomfort for those with vestibular motion disorders.'); + } + + public function getCSSVariables(): array { + $variables = [ + '--animation-quick' => '0', + '--animation-slow' => '0', + ]; + + return $variables; + } + + public function getMediaQuery(): string { + return '(prefers-reduced-motion: reduce)'; + } +} diff --git a/apps/theming/src/UserTheming.vue b/apps/theming/src/UserTheming.vue index ff5908149bbef..539a99eb37822 100644 --- a/apps/theming/src/UserTheming.vue +++ b/apps/theming/src/UserTheming.vue @@ -13,28 +13,21 @@

-

- -
- -
- -
+ + + + +

{{ t('theming', 'Misc accessibility options') }}

+ + + + + + diff --git a/apps/theming/src/components/ItemPreview.vue b/apps/theming/src/components/ThemeListItem.vue similarity index 66% rename from apps/theming/src/components/ItemPreview.vue rename to apps/theming/src/components/ThemeListItem.vue index 5226ddb160990..2fb76f7a2ad2d 100644 --- a/apps/theming/src/components/ItemPreview.vue +++ b/apps/theming/src/components/ThemeListItem.vue @@ -3,8 +3,12 @@ - SPDX-License-Identifier: AGPL-3.0-or-later -->