From f9fa8cd9dd163809502b9f32f6628a0b2a7c6f9c Mon Sep 17 00:00:00 2001 From: Felix Hahn Date: Sun, 2 Feb 2025 23:55:27 +0100 Subject: [PATCH] rework color fallback strategy and code order --- models/AbstractColorSettings.php | 107 +++++++++++++++++++++---------- models/ColorSettings.php | 77 ++++++++++++---------- models/DarkColorSettings.php | 95 ++++++++++++++------------- 3 files changed, 167 insertions(+), 112 deletions(-) diff --git a/models/AbstractColorSettings.php b/models/AbstractColorSettings.php index 045f1bd..ef850f2 100644 --- a/models/AbstractColorSettings.php +++ b/models/AbstractColorSettings.php @@ -12,13 +12,30 @@ abstract class AbstractColorSettings extends \yii\base\Model * Prefix (needed for DarkMode) */ public const PREFIX = ''; + + /* + * colors that need a default value + */ + public const DEFAULT_COLORS = []; + /* + * wether to load settings on init + */ public bool $autoLoadSettings = true; + /* + * array of the names of the configurable colors + */ public $configurableColors = []; + + /* + * wether the model has warnings (after saving) + */ public $hasWarnings = false; - // Main Colors (configurable) + /* + * Main Colors (configurable) + */ public const MAIN_COLORS = ['default', 'primary', 'info', 'link', 'success', 'warning', 'danger']; public $default; public $primary; @@ -28,7 +45,9 @@ abstract class AbstractColorSettings extends \yii\base\Model public $warning; public $danger; - // Text Colors (configurable) + /* + * Text Colors (configurable) + */ public const TEXT_COLORS = ['text_color_main', 'text_color_secondary', 'text_color_highlight', 'text_color_soft', 'text_color_soft2', 'text_color_soft3', 'text_color_contrast']; public $text_color_main; public $text_color_secondary; @@ -38,23 +57,44 @@ abstract class AbstractColorSettings extends \yii\base\Model public $text_color_soft3; public $text_color_contrast; - // Background Colors (configurable) + /* + * Background Colors (configurable) + */ public const BACKGROUND_COLORS = ['background_color_main', 'background_color_secondary', 'background_color_page', 'background_color_highlight', 'background_color_highlight_soft', 'background3', 'background4']; public $background_color_main; public $background_color_secondary; public $background_color_page; - public $background_color_highlight = '#daf0f3'; - public $background_color_highlight_soft = '#f2f9fb'; + public $background_color_highlight; + public $background_color_highlight_soft; public $background3; public $background4; - // Special colors which were generated by Less functions lighten(), darken() or fade() + /* + * Special colors which were generated by Less functions lighten(), darken() or fade() + */ public const SPECIAL_COLORS = ['background4__fade__50','background4__lighten__10','background4__lighten__16','background_color_main__darken__10','background_color_page__darken__5','background_color_page__darken__8','background_color_page__lighten__10','background_color_page__lighten__20','background_color_page__lighten__3','background_color_page__lighten__30','background_color_secondary__darken__5','danger__darken__10','danger__darken__5','danger__lighten__20','danger__lighten__5','default__darken__2','default__darken__5','default__lighten__2','info__darken__10','info__darken__27','info__darken__5','info__lighten__25','info__lighten__30','info__lighten__40','info__lighten__45','info__lighten__5','info__lighten__50','info__lighten__8','link__darken__2','link__fade__60','link__lighten__5','primary__darken__10','primary__darken__5','primary__lighten__10','primary__lighten__20','primary__lighten__25','primary__lighten__5','primary__lighten__8','success__darken__10','success__darken__5','success__lighten__20','success__lighten__5','text_color_highlight__fade__15','text_color_highlight__fade__30','text_color_secondary__lighten__25','warning__darken__10','warning__darken__2','warning__darken__5','warning__lighten__10','warning__lighten__20','warning__lighten__40','warning__lighten__5',]; + /* + * abstract function to get all colors, configured, default or fallback + * mainly used to store them in the variables.less file, see saveVarsToFile() + */ abstract public function getColors(): array; + /* + * color fallback + * 1. default value + * 2. get from standard theme + */ abstract protected function getColorFallback(string $color): string; + + /* + * Additional color saving, used by light mode to save colors as theme var + */ + protected function additonalColorSaving(string $color, ?string $value): void + { + } + public function __construct($autoLoadSettings = true) { $this->autoLoadSettings = $autoLoadSettings; @@ -75,7 +115,7 @@ public function init() public function loadSettings() { $settings = static::getSettings(); - foreach($this->configurableColors as $color) { + foreach ($this->configurableColors as $color) { $this->$color = $settings->get(static::PREFIX . $color); } } @@ -83,8 +123,7 @@ public function loadSettings() public function rules(): array { return [ - [[ - 'default', 'primary', 'info', 'link', 'success', 'warning', 'danger', + [['default', 'primary', 'info', 'link', 'success', 'warning', 'danger', 'text_color_main', 'text_color_secondary', 'text_color_highlight', 'text_color_soft', 'text_color_soft2', 'text_color_soft3', 'text_color_contrast', 'background_color_main', 'background_color_secondary', 'background_color_page', 'background_color_highlight', 'background_color_highlight_soft', 'background3', 'background4' ], 'validateHexColor'] @@ -98,6 +137,13 @@ public function validateHexColor(string $attribute, $params, $validator) } } + /* + * Save colors to databse + * Save special colors (lightened etc.) to database + * save colors as CSS variables to variables file + * update theme.css + * eventually set hasWarnings to true (especially when file permission problems occur) + */ public function save(): bool { if(!$this->validate()) { @@ -122,7 +168,12 @@ public function save(): bool return true; } - + + /* + * Save colors to database + * as module setting + * in light mode also as theme variable + */ protected function saveColors(): void { $settings = static::getSettings(); @@ -138,14 +189,10 @@ protected function saveColors(): void $this->additonalColorSaving($color, $value); } } - + /* - * Additional color saving, used by light mode to save colors as theme var + * Calculate and save special colors to database (module settings) */ - protected function additonalColorSaving(string $color, ?string $value): void - { - } - protected function saveSpecialColors(): void { $settings = static::getSettings(); @@ -158,27 +205,13 @@ protected function saveSpecialColors(): void // Get value of base color $original_color = $this->$base_var; if (empty($original_color)) { - // Get Base Theme Fallback (only used by light mode) + // Get fallback for base color $original_color = $this->getColorFallback($base_var); } // Calculate color value with ColorHelper functions - if ($function == 'darken') { - - $value = ColorHelper::darken($original_color, $amount); - - } elseif ($function == 'lighten') { - - $value = ColorHelper::lighten($original_color, $amount); - - } elseif ($function == 'fade') { - - $value = ColorHelper::fade($original_color, $amount); - - } elseif ($function == 'fadeout') { - - $value = ColorHelper::fadeout($original_color, $amount); - + if (!empty($function)) { + $value = ColorHelper::$function($original_color, $amount); } else { $value = ''; } @@ -202,6 +235,14 @@ protected function saveVarsToFile(): bool return FileHelper::updateVarsFile($content, static::PREFIX); } + + protected function getDefaultValue(string $color): ?string + { + if (array_key_exists($color, static::EXTRA_COLORS)) { + return static::DEFAULT_COLORS[$color]; + } + return ''; + } protected function getSettings() { diff --git a/models/ColorSettings.php b/models/ColorSettings.php index e6d0cb7..3dd07e6 100644 --- a/models/ColorSettings.php +++ b/models/ColorSettings.php @@ -8,9 +8,21 @@ class ColorSettings extends AbstractColorSettings { - // Base Theme for fallback and default values + // Colors that are not hard coded in default theme + public const DEFAULT_COLORS = [ + 'background_color_highlight' => '#daf0f3', + 'background_color_highlight_soft' => '#f2f9fb', + ]; + + /* + * Base Theme for fallback values + */ public const BASE_THEME = 'HumHub'; + /* + * get all colors, configured, default or fallback to standard theme color + * mainly used to store them in the variables.less file, see saveVarsToFile() + */ public function getColors(): array { $settings = self::getSettings(); @@ -41,6 +53,35 @@ public function getColors(): array return $result; } + /* + * color fallback + * 1. default value + * 2. get from standard theme + */ + protected function getColorFallBack(string $color): string + { + $value = self::getDefaultValue($color); + + if (empty($value)) { + $theme_var = str_replace('_', '-', $color); + $value = ThemeHelper::getThemeByName(self::BASE_THEME)->variable(static::PREFIX . $theme_var); + } + return $value; + } + + /* + * Save color values as theme variables (take default theme's color if value is empty) + */ + protected function additonalColorSaving(string $color, ?string $value): void + { + $theme_var = str_replace('_', '-', $color); + if (empty($value)) { + $value = ThemeHelper::getThemeByName(self::BASE_THEME)->variable($theme_var); + } + $theme_key = 'theme.var.FlexTheme.' . static::PREFIX . $theme_var; + Yii::$app->settings->set($theme_key, $value); + } + public function attributeHints(): array { $hints = []; @@ -60,38 +101,4 @@ public function attributeHints(): array return $hints; } - - protected function additonalColorSaving(string $color, ?string $value): void - { - // Save color values as theme variables (take default theme's color if value is empty) - $theme_var = str_replace('_', '-', $color); - if (empty($value)) { - $value = ThemeHelper::getThemeByName(self::BASE_THEME)->variable($theme_var); - } - $theme_key = 'theme.var.FlexTheme.' . static::PREFIX . $theme_var; - Yii::$app->settings->set($theme_key, $value); - } - - protected function getColorFallBack(string $color): string - { - $value = self::getDefaultValue($color); - - if (empty($value)) { - $theme_var = str_replace('_', '-', $color); - $value = ThemeHelper::getThemeByName(self::BASE_THEME)->variable(static::PREFIX . $theme_var); - } - return $value; - } - - private function getDefaultValue(string $color): ?string - { - // compatiblity with PHP 7.4 will be removed in next version - if (version_compare(phpversion(), '8.0.0', '<')) { - $value = (new \ReflectionProperty($this, $color))->getDeclaringClass()->getDefaultProperties()[$color] ?? null; - } else { - // min PHP 8.0 - $value = (new \ReflectionClass($this))->getProperty($color)->getDefaultValue(); - } - return $value; - } } diff --git a/models/DarkColorSettings.php b/models/DarkColorSettings.php index 3aaea6c..1e21e3c 100644 --- a/models/DarkColorSettings.php +++ b/models/DarkColorSettings.php @@ -12,23 +12,37 @@ class DarkColorSettings extends AbstractColorSettings --background-color-success:#3e423b;--text-color-success:#84be5e;--border-color-success:#97d271;--background-color-warning:#4d443b;--text-color-warning:#e9b168;--border-color-warning:#fdd198;--background-color-danger:#372a2a;--text-color-danger:#ff8989;--border-color-danger:#ff8989;} */ - public $default = '#0d0d0d'; - - public $text_color_main = '#ddd'; - public $text_color_secondary = '#bbb'; - public $text_color_highlight = '#fff'; - public $text_color_soft = '#dddddd'; - public $text_color_soft2 = '#ccc'; - public $text_color_soft3 = '#7b7773'; - public $text_color_contrast = '#000'; - - public $background_color_main = '#222'; - public $background_color_secondary = '#333'; - public $background_color_page = '#000'; - public $background_color_highlight = '#2e393a'; - public $background_color_highlight_soft = '#171d1e'; - public $background3 = '#393939'; - public $background4 = '#5e5e5e'; + + /* + * As we can't fallback to the standard theme's colors, + * in dark mode all colors need a default color except from main colors (primary etc.) + * the main color default needs also a dark default color + */ + public const DEFAULT_COLORS = + [ + 'default' => '#0d0d0d', + + 'text_color_main' => '#ddd', + 'text_color_secondary' => '#bbb', + 'text_color_highlight' => '#fff', + 'text_color_soft' => '#dddddd', + 'text_color_soft2' => '#ccc', + 'text_color_soft3' => '#7b7773', + 'text_color_contrast' => '#000', + + 'background_color_main' => '#222', + 'background_color_secondary' => '#333', + 'background_color_page' => '#000', + 'background_color_highlight' => '#2e393a', + 'background_color_highlight_soft' => '#171d1e', + 'background3' => '#393939', + 'background4' => '#5e5e5e', + ]; + + /* + * caching light colors array + */ + private array $_lightColors; public function getColors(): array { @@ -74,7 +88,26 @@ public function getColors(): array return $result; } - + + /* + * color fallback + * 1. default value + * 2. get from light theme settings (should only happen to main colors like primary, link etc.) + */ + protected function getColorFallBack(string $color): string + { + $value = self::getDefaultValue($color); + + if (empty($value)) { + if (!isset($this->_lightColors)) { + $this->_lightColors = (new ColorSettings())->getColors(); + } + $color = str_replace('_', '-', $color);// getColors() returns the string-replaced color keys as array keys, so we need this here also + $value = $this->_lightColors[$color]; + } + return $value; + } + public function attributeHints(): array { $hints = []; @@ -100,33 +133,7 @@ public function attributeHints(): array $icon = Icon::get('circle', ['color' => $default_value]); $hints[$color] = Yii::t('FlexThemeModule.admin', 'Default') . ': ' . '' . $default_value . ' ' . $icon; } - // @todo check that it works for background_color_highlight and background_color_highlight_soft return $hints; } - - protected function getColorFallBack(string $color): string - { - $value = self::getDefaultValue($color); - - if (empty($value)) {// only main colors can be empty! - if (!isset($lightColors)) { - $lightColors = (new ColorSettings())->getColors(); - } - $value = $lightColors[$color]; - } - return $value; - } - - private function getDefaultValue(string $color): ?string - { - // compatiblity with PHP 7.4 will be removed in next version - if (version_compare(phpversion(), '8.0.0', '<')) { - $value = (new \ReflectionProperty($this, $color))->getDeclaringClass()->getDefaultProperties()[$color] ?? null; - } else { - // min PHP 8.0 - $value = (new \ReflectionClass($this))->getProperty($color)->getDefaultValue(); - } - return $value; - } }