From 2f25f2feed0583cd1720aae4c6675ada829a991c Mon Sep 17 00:00:00 2001 From: Ferdinand Thiessen Date: Thu, 14 Dec 2023 17:57:45 +0100 Subject: [PATCH 1/2] fix(theming): Adjust status colors to be also accessible on blurry background Signed-off-by: Ferdinand Thiessen --- apps/theming/css/default.css | 18 ++++----- apps/theming/lib/Themes/DefaultTheme.php | 12 +++--- .../tests/Themes/AccessibleThemeTestCase.php | 37 ++++++++++++++++++- 3 files changed, 51 insertions(+), 16 deletions(-) diff --git a/apps/theming/css/default.css b/apps/theming/css/default.css index e9388e6ab60ec..19d874e5a8ee9 100644 --- a/apps/theming/css/default.css +++ b/apps/theming/css/default.css @@ -21,17 +21,17 @@ /** @deprecated use `--color-text-maxcontrast` instead */ --color-text-lighter: var(--color-text-maxcontrast); --color-scrollbar: rgba(34,34,34, .15); - --color-error: #d91812; - --color-error-rgb: 217,24,18; - --color-error-hover: #dd342f; - --color-error-text: #c61610; - --color-warning: #b88100; - --color-warning-rgb: 184,129,0; - --color-warning-hover: #c69a32; - --color-warning-text: #855d00; + --color-error: #C00505; + --color-error-rgb: 192,5,5; + --color-error-hover: #c72424; + --color-error-text: #C00505; + --color-warning: #A37200; + --color-warning-rgb: 163,114,0; + --color-warning-hover: #8a6000; + --color-warning-text: #7f5900; --color-success: #2d7b41; --color-success-rgb: 45,123,65; - --color-success-hover: #448955; + --color-success-hover: #428854; --color-success-text: #286c39; --color-info: #0071ad; --color-info-rgb: 0,113,173; diff --git a/apps/theming/lib/Themes/DefaultTheme.php b/apps/theming/lib/Themes/DefaultTheme.php index e215ade7b6dac..599c5ed58a90d 100644 --- a/apps/theming/lib/Themes/DefaultTheme.php +++ b/apps/theming/lib/Themes/DefaultTheme.php @@ -111,8 +111,8 @@ public function getCSSVariables(): array { $colorBoxShadow = $this->util->darken($colorMainBackground, 70); $colorBoxShadowRGB = join(',', $this->util->hexToRGB($colorBoxShadow)); - $colorError = '#d91812'; - $colorWarning = '#b88100'; + $colorError = '#C00505'; + $colorWarning = '#A37200'; $colorSuccess = '#2d7b41'; $colorInfo = '#0071ad'; @@ -148,14 +148,14 @@ public function getCSSVariables(): array { '--color-error' => $colorError, '--color-error-rgb' => join(',', $this->util->hexToRGB($colorError)), '--color-error-hover' => $this->util->mix($colorError, $colorMainBackground, 75), - '--color-error-text' => $this->util->darken($colorError, 4), + '--color-error-text' => $colorError, '--color-warning' => $colorWarning, '--color-warning-rgb' => join(',', $this->util->hexToRGB($colorWarning)), - '--color-warning-hover' => $this->util->mix($colorWarning, $colorMainBackground, 60), - '--color-warning-text' => $this->util->darken($colorWarning, 10), + '--color-warning-hover' => $this->util->darken($colorWarning, 5), + '--color-warning-text' => $this->util->darken($colorWarning, 7), '--color-success' => $colorSuccess, '--color-success-rgb' => join(',', $this->util->hexToRGB($colorSuccess)), - '--color-success-hover' => $this->util->mix($colorSuccess, $colorMainBackground, 78), + '--color-success-hover' => $this->util->mix($colorSuccess, $colorMainBackground, 80), '--color-success-text' => $this->util->darken($colorSuccess, 4), '--color-info' => $colorInfo, '--color-info-rgb' => join(',', $this->util->hexToRGB($colorInfo)), diff --git a/apps/theming/tests/Themes/AccessibleThemeTestCase.php b/apps/theming/tests/Themes/AccessibleThemeTestCase.php index 29ad8cfaff24f..fbd0722552d60 100644 --- a/apps/theming/tests/Themes/AccessibleThemeTestCase.php +++ b/apps/theming/tests/Themes/AccessibleThemeTestCase.php @@ -46,6 +46,26 @@ public function dataAccessibilityPairs() { ], 3.0, ], + 'status color elements on background' => [ + [ + '--color-error', + '--color-error-hover', + '--color-warning', + '--color-warning-hover', + '--color-info', + '--color-info-hover', + '--color-success', + '--color-success-hover', + ], + [ + '--color-main-background', + '--color-background-hover', + '--color-background-dark', + '--color-background-darker', + '--color-main-background-blur', + ], + 3.0, + ], 'primary-element-text' => [ [ '--color-primary-element-text', @@ -92,6 +112,21 @@ public function dataAccessibilityPairs() { ], 4.5, ], + 'status-text' => [ + [ + '--color-error-text', + '--color-warning-text', + '--color-success-text', + '--color-info-text', + ], + [ + '--color-main-background', + '--color-background-hover', + '--color-background-dark', + '--color-main-background-blur', + ], + 4.5, + ], ]; } @@ -108,7 +143,7 @@ public function testAccessibilityOfVariables($mainColors, $backgroundColors, $mi $variables = $this->theme->getCSSVariables(); // Blur effect does not work so we mockup the color - worst supported case is the default "clouds" background image (on dark themes the clouds with white color are bad on bright themes the primary color as sky is bad) - $variables['--color-main-background-blur'] = $this->util->mix($variables['--color-main-background'], $this->util->isBrightColor($variables['--color-main-background']) ? $variables['--color-primary'] : '#ffffff', 75); + $variables['--color-main-background-blur'] = $this->util->mix($variables['--color-main-background'], $this->util->isBrightColor($variables['--color-main-background']) ? '#000000' : '#ffffff', 75); foreach ($backgroundColors as $background) { $this->assertStringStartsWith('#', $variables[$background], 'Is not a plain color variable - consider to remove or fix this test'); From 87c48b424cd64d3e8f320f99a8d6af7ff70db116 Mon Sep 17 00:00:00 2001 From: Ferdinand Thiessen Date: Thu, 14 Dec 2023 17:58:13 +0100 Subject: [PATCH 2/2] fix(theming): Make dark theme accessible and add unit test Signed-off-by: Ferdinand Thiessen --- apps/theming/lib/Themes/DarkTheme.php | 25 ++-- apps/theming/tests/Themes/DarkThemeTest.php | 143 ++++++++++++++++++++ 2 files changed, 156 insertions(+), 12 deletions(-) create mode 100644 apps/theming/tests/Themes/DarkThemeTest.php diff --git a/apps/theming/lib/Themes/DarkTheme.php b/apps/theming/lib/Themes/DarkTheme.php index d33f13dc57909..0fed06e22257a 100644 --- a/apps/theming/lib/Themes/DarkTheme.php +++ b/apps/theming/lib/Themes/DarkTheme.php @@ -60,10 +60,10 @@ public function getCSSVariables(): array { $colorBoxShadow = $this->util->darken($colorMainBackground, 70); $colorBoxShadowRGB = join(',', $this->util->hexToRGB($colorBoxShadow)); - $colorError = '#ee312b'; - $colorWarning = '#c28900'; - $colorSuccess = '#36914e'; - $colorInfo = '#007bbd'; + $colorError = '#FF5252'; + $colorWarning = '#FFCC00'; + $colorSuccess = '#50BB50'; + $colorInfo = '#00AEFF'; return array_merge( $defaultVariables, @@ -72,6 +72,7 @@ public function getCSSVariables(): array { '--color-main-text' => $colorMainText, '--color-main-background' => $colorMainBackground, '--color-main-background-rgb' => $colorMainBackgroundRGB, + '--color-main-background-blur' => 'rgba(var(--color-main-background-rgb), .85)', '--color-scrollbar' => $this->util->lighten($colorMainBackground, 15), @@ -84,26 +85,26 @@ public function getCSSVariables(): array { '--color-text-maxcontrast' => $colorTextMaxcontrast, '--color-text-maxcontrast-default' => $colorTextMaxcontrast, - '--color-text-maxcontrast-background-blur' => $this->util->lighten($colorTextMaxcontrast, 2), + '--color-text-maxcontrast-background-blur' => $this->util->lighten($colorTextMaxcontrast, 6), '--color-text-light' => 'var(--color-main-text)', // deprecated '--color-text-lighter' => 'var(--color-text-maxcontrast)', // deprecated '--color-error' => $colorError, '--color-error-rgb' => join(',', $this->util->hexToRGB($colorError)), - '--color-error-hover' => $this->util->mix($colorError, $colorMainBackground, 85), - '--color-error-text' => $this->util->lighten($colorError, 12), + '--color-error-hover' => $this->util->lighten($colorError, 10), + '--color-error-text' => $this->util->lighten($colorError, 10), '--color-warning' => $colorWarning, '--color-warning-rgb' => join(',', $this->util->hexToRGB($colorWarning)), - '--color-warning-hover' => $this->util->mix($colorWarning, $colorMainBackground, 60), + '--color-warning-hover' => $this->util->lighten($colorWarning, 10), '--color-warning-text' => $colorWarning, '--color-success' => $colorSuccess, '--color-success-rgb' => join(',', $this->util->hexToRGB($colorSuccess)), - '--color-success-hover' => $this->util->mix($colorSuccess, $colorMainBackground, 85), - '--color-success-text' => $this->util->lighten($colorSuccess, 6), + '--color-success-hover' => $this->util->lighten($colorSuccess, 10), + '--color-success-text' => $colorSuccess, '--color-info' => $colorInfo, '--color-info-rgb' => join(',', $this->util->hexToRGB($colorInfo)), - '--color-info-hover' => $this->util->mix($colorInfo, $colorMainBackground, 85), - '--color-info-text' => $this->util->lighten($colorInfo, 9), + '--color-info-hover' => $this->util->lighten($colorInfo, 10), + '--color-info-text' => $colorInfo, // used for the icon loading animation '--color-loading-light' => '#777', diff --git a/apps/theming/tests/Themes/DarkThemeTest.php b/apps/theming/tests/Themes/DarkThemeTest.php new file mode 100644 index 0000000000000..1a50e08d0f5cd --- /dev/null +++ b/apps/theming/tests/Themes/DarkThemeTest.php @@ -0,0 +1,143 @@ + + * + * @author John Molakvoæ + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ +namespace OCA\Theming\Tests\Themes; + +use OCA\Theming\AppInfo\Application; +use OCA\Theming\ImageManager; +use OCA\Theming\ITheme; +use OCA\Theming\Service\BackgroundService; +use OCA\Theming\Themes\DarkTheme; +use OCA\Theming\ThemingDefaults; +use OCA\Theming\Util; +use OCP\App\IAppManager; +use OCP\Files\IAppData; +use OCP\IConfig; +use OCP\IL10N; +use OCP\IURLGenerator; +use OCP\IUserSession; +use PHPUnit\Framework\MockObject\MockObject; + +class DarkThemeTest extends AccessibleThemeTestCase { + /** @var ThemingDefaults|MockObject */ + private $themingDefaults; + /** @var IUserSession|MockObject */ + private $userSession; + /** @var IURLGenerator|MockObject */ + private $urlGenerator; + /** @var ImageManager|MockObject */ + private $imageManager; + /** @var IConfig|MockObject */ + private $config; + /** @var IL10N|MockObject */ + private $l10n; + /** @var IAppManager|MockObject */ + private $appManager; + + protected function setUp(): void { + $this->themingDefaults = $this->createMock(ThemingDefaults::class); + $this->userSession = $this->createMock(IUserSession::class); + $this->urlGenerator = $this->createMock(IURLGenerator::class); + $this->imageManager = $this->createMock(ImageManager::class); + $this->config = $this->createMock(IConfig::class); + $this->l10n = $this->createMock(IL10N::class); + $this->appManager = $this->createMock(IAppManager::class); + + $this->util = new Util( + $this->config, + $this->appManager, + $this->createMock(IAppData::class), + $this->imageManager + ); + + $this->themingDefaults + ->expects($this->any()) + ->method('getColorPrimary') + ->willReturn('#0082c9'); + + $this->themingDefaults + ->expects($this->any()) + ->method('getDefaultColorPrimary') + ->willReturn('#0082c9'); + + $this->themingDefaults + ->expects($this->any()) + ->method('getBackground') + ->willReturn('/apps/' . Application::APP_ID . '/img/background/' . BackgroundService::DEFAULT_BACKGROUND_IMAGE); + + $this->l10n + ->expects($this->any()) + ->method('t') + ->willReturnCallback(function ($text, $parameters = []) { + return vsprintf($text, $parameters); + }); + + $this->urlGenerator + ->expects($this->any()) + ->method('imagePath') + ->willReturnCallback(function ($app = 'core', $filename = '') { + return "/$app/img/$filename"; + }); + + $this->theme = new DarkTheme( + $this->util, + $this->themingDefaults, + $this->userSession, + $this->urlGenerator, + $this->imageManager, + $this->config, + $this->l10n, + $this->appManager, + ); + + parent::setUp(); + } + + + public function testGetId() { + $this->assertEquals('dark', $this->theme->getId()); + } + + public function testGetType() { + $this->assertEquals(ITheme::TYPE_THEME, $this->theme->getType()); + } + + public function testGetTitle() { + $this->assertEquals('Dark theme', $this->theme->getTitle()); + } + + public function testGetEnableLabel() { + $this->assertEquals('Enable dark theme', $this->theme->getEnableLabel()); + } + + public function testGetDescription() { + $this->assertEquals('A dark theme to ease your eyes by reducing the overall luminosity and brightness.', $this->theme->getDescription()); + } + + public function testGetMediaQuery() { + $this->assertEquals('(prefers-color-scheme: dark)', $this->theme->getMediaQuery()); + } + + public function testGetCustomCss() { + $this->assertEquals('', $this->theme->getCustomCss()); + } +}