While the primary color is intended to highlight elements, it can not always be used as the background color. So now primary is independent from background a user set, the background color is, if not set directly, calculated as the mean color of the background image. That color is then used as a fallback if the background image could not be loaded and for calculating the color of the text used on the app menu and dashboard (they render directly on the background). Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>pull/42977/head
@@ -86,5 +86,6 @@ | |||
--color-primary-element-light-text: #00293f; | |||
--gradient-primary-background: linear-gradient(40deg, var(--color-primary) 0%, var(--color-primary-hover) 100%); | |||
--image-background-default: url('/apps/theming/img/background/kamil-porembinski-clouds.jpg'); | |||
--color-background-plain: #00679e; | |||
--color-background-plain: #0082c9; | |||
--color-background-plain-text: #ffffff; | |||
} |
@@ -241,7 +241,8 @@ class UserThemeController extends OCSController { | |||
return new JSONResponse([ | |||
'backgroundImage' => $this->config->getUserValue($this->userId, Application::APP_ID, 'background_image', BackgroundService::BACKGROUND_DEFAULT), | |||
'backgroundColor' => $this->themingDefaults->getColorPrimary(), | |||
'backgroundColor' => $this->themingDefaults->getColorBackground(), | |||
'primaryColor' => $this->themingDefaults->getColorPrimary(), | |||
'version' => $currentVersion, | |||
]); | |||
} |
@@ -237,7 +237,7 @@ class BackgroundService { | |||
throw new InvalidArgumentException('The given file name is invalid'); | |||
} | |||
$this->config->setUserValue($this->userId, Application::APP_ID, 'background_image', $fileName); | |||
$this->setColorBackground(self::SHIPPED_BACKGROUNDS[$fileName]['primary_color']); | |||
$this->config->setUserValue($this->userId, Application::APP_ID, 'primary_color', self::SHIPPED_BACKGROUNDS[$fileName]['primary_color']); | |||
} | |||
/** |
@@ -130,49 +130,37 @@ trait CommonThemeTrait { | |||
if ($user !== null | |||
&& !$this->themingDefaults->isUserThemingDisabled() | |||
&& $this->appManager->isEnabledForUser(Application::APP_ID)) { | |||
$adminBackgroundDeleted = $this->config->getAppValue(Application::APP_ID, 'backgroundMime', '') === 'backgroundColor'; | |||
$backgroundImage = $this->config->getUserValue($user->getUID(), Application::APP_ID, 'background_image', BackgroundService::BACKGROUND_DEFAULT); | |||
$backgroundColor = $this->config->getUserValue($user->getUID(), Application::APP_ID, 'background_color', $this->themingDefaults->getColorPrimary()); | |||
$currentVersion = (int)$this->config->getUserValue($user->getUID(), Application::APP_ID, 'userCacheBuster', '0'); | |||
$isPrimaryBright = $this->util->invertTextColor($this->primaryColor); | |||
$isBackgroundBright = $this->util->invertTextColor($backgroundColor); | |||
$backgroundTextColor = $this->util->invertTextColor($backgroundColor) ? '#000000' : '#ffffff'; | |||
$variables = [ | |||
'--color-background-plain' => $backgroundColor, | |||
'--color-background-plain-text' => $backgroundTextColor, | |||
'--background-image-invert-if-bright' => $isBackgroundBright ? 'invert(100%)' : 'no', | |||
]; | |||
// The user removed the background | |||
if ($backgroundImage === BackgroundService::BACKGROUND_DISABLED) { | |||
return [ | |||
// Might be defined already by admin theming, needs to be overridden | |||
'--image-background' => 'none', | |||
'--color-background-plain' => $this->primaryColor, | |||
// If no background image is set, we need to check against the shown primary colour | |||
'--background-image-invert-if-bright' => $isPrimaryBright ? 'invert(100%)' : 'no', | |||
]; | |||
// Might be defined already by admin theming, needs to be overridden | |||
$variables['--image-background'] = 'none'; | |||
} | |||
// The user uploaded a custom background | |||
if ($backgroundImage === BackgroundService::BACKGROUND_CUSTOM) { | |||
$cacheBuster = substr(sha1($user->getUID() . '_' . $currentVersion), 0, 8); | |||
return [ | |||
'--image-background' => "url('" . $this->urlGenerator->linkToRouteAbsolute('theming.userTheme.getBackground') . "?v=$cacheBuster')", | |||
'--color-background-plain' => $this->themingDefaults->getColorPrimary(), | |||
'--background-image-invert-if-bright' => $isPrimaryBright ? 'invert(100%)' : 'no', | |||
]; | |||
} | |||
// The user is using the default background and admin removed the background image | |||
if ($backgroundImage === BackgroundService::BACKGROUND_DEFAULT && $adminBackgroundDeleted) { | |||
return [ | |||
// --image-background is not defined in this case | |||
'--color-background-plain' => $this->primaryColor, | |||
'--background-image-invert-if-bright' => $isPrimaryBright ? 'invert(100%)' : 'no', | |||
]; | |||
$variables['--image-background'] = "url('" . $this->urlGenerator->linkToRouteAbsolute('theming.userTheme.getBackground') . "?v=$cacheBuster')"; | |||
} | |||
// The user picked a shipped background | |||
if (isset(BackgroundService::SHIPPED_BACKGROUNDS[$backgroundImage])) { | |||
return [ | |||
'--image-background' => "url('" . $this->urlGenerator->linkTo(Application::APP_ID, "img/background/$backgroundImage") . "')", | |||
'--color-background-plain' => $this->primaryColor, | |||
'--background-image-invert-if-bright' => BackgroundService::SHIPPED_BACKGROUNDS[$backgroundImage]['theming'] ?? null === BackgroundService::THEMING_MODE_DARK ? 'invert(100%)' : 'no', | |||
]; | |||
$variables['--image-background'] = "url('" . $this->urlGenerator->linkTo(Application::APP_ID, "img/background/$backgroundImage") . "')"; | |||
} | |||
return $variables; | |||
} | |||
return []; |
@@ -224,7 +224,7 @@ class ThemingDefaults extends \OC_Defaults { | |||
} | |||
/** | |||
* Color that is used for the header as well as for mail headers | |||
* Color that is used for highlighting elements like important buttons | |||
*/ | |||
public function getColorPrimary(): string { | |||
$user = $this->userSession->getUser(); | |||
@@ -238,32 +238,66 @@ class ThemingDefaults extends \OC_Defaults { | |||
// user-defined primary color | |||
if (!empty($user)) { | |||
$themingBackgroundColor = $this->config->getUserValue($user->getUID(), Application::APP_ID, 'background_color', ''); | |||
// If the user selected a specific colour | |||
if (preg_match('/^\#([0-9a-f]{3}|[0-9a-f]{6})$/i', $themingBackgroundColor)) { | |||
return $themingBackgroundColor; | |||
// we need the background color as a fallback for backwards compatibility with Nextcloud 28 and older | |||
$userBackgroundColor = $this->config->getUserValue($user->getUID(), Application::APP_ID, 'background_color', ''); | |||
$userPrimaryColor = $this->config->getUserValue($user->getUID(), Application::APP_ID, 'primary_color', $userBackgroundColor); | |||
if (preg_match('/^\#([0-9a-f]{3}|[0-9a-f]{6})$/i', $userPrimaryColor)) { | |||
return $userPrimaryColor; | |||
} | |||
} | |||
// If the default color is not valid, return the default background one | |||
if (!preg_match('/^\#([0-9a-f]{3}|[0-9a-f]{6})$/i', $defaultColor)) { | |||
return BackgroundService::DEFAULT_COLOR; | |||
// Finally, return the system global primary color | |||
return $defaultColor; | |||
} | |||
/** | |||
* Color that is used for the page background (e.g. the header) | |||
*/ | |||
public function getColorBackground(): string { | |||
$user = $this->userSession->getUser(); | |||
// admin-defined background color | |||
$defaultColor = $this->getDefaultColorBackground(); | |||
if ($this->isUserThemingDisabled()) { | |||
return $defaultColor; | |||
} | |||
// Finally, return the system global primary color | |||
// user-defined background color | |||
if (!empty($user)) { | |||
$userPrimaryColor = $this->config->getUserValue($user->getUID(), Application::APP_ID, 'background_color', ''); | |||
if (preg_match('/^\#([0-9a-f]{3}|[0-9a-f]{6})$/i', $userPrimaryColor)) { | |||
return $userPrimaryColor; | |||
} | |||
} | |||
// Finally, return the system global background color | |||
return $defaultColor; | |||
} | |||
/** | |||
* Return the default color primary | |||
* Return the default primary color | |||
*/ | |||
public function getDefaultColorPrimary(): string { | |||
$color = $this->config->getAppValue(Application::APP_ID, 'color', ''); | |||
if (!preg_match('/^\#([0-9a-f]{3}|[0-9a-f]{6})$/i', $color)) { | |||
return BackgroundService::DEFAULT_COLOR; | |||
// try admin color | |||
$defaultColor = $this->config->getAppValue(Application::APP_ID, 'primary_color', ''); | |||
if (preg_match('/^\#([0-9a-f]{3}|[0-9a-f]{6})$/i', $defaultColor)) { | |||
return $defaultColor; | |||
} | |||
return $color; | |||
// Fall back to background color | |||
return $this->getDefaultColorBackground(); | |||
} | |||
/** | |||
* Default background color only taking admin setting into account | |||
*/ | |||
public function getDefaultColorBackground(): string { | |||
$defaultColor = $this->config->getAppValue(Application::APP_ID, 'background_color', ''); | |||
if (!preg_match('/^\#([0-9a-f]{3}|[0-9a-f]{6})$/i', $defaultColor)) { | |||
$defaultColor = BackgroundService::DEFAULT_COLOR; | |||
} | |||
return $defaultColor; | |||
} | |||
/** | |||
@@ -344,6 +378,7 @@ class ThemingDefaults extends \OC_Defaults { | |||
/** | |||
* @return array scss variables to overwrite | |||
* @deprecated since Nextcloud 22 - https://github.com/nextcloud/server/issues/9940 | |||
*/ | |||
public function getScssVariables() { | |||
$cacheBuster = $this->config->getAppValue('theming', 'cachebuster', '0'); | |||
@@ -366,7 +401,7 @@ class ThemingDefaults extends \OC_Defaults { | |||
$variables['image-login-background'] = "url('".$this->imageManager->getImageUrl('background')."')"; | |||
$variables['image-login-plain'] = 'false'; | |||
if ($this->config->getAppValue('theming', 'color', '') !== '') { | |||
if ($this->config->getAppValue('theming', 'primary_color', '') !== '') { | |||
$variables['color-primary'] = $this->getColorPrimary(); | |||
$variables['color-primary-text'] = $this->getTextColorPrimary(); | |||
$variables['color-primary-element'] = $this->util->elementColor($this->getColorPrimary()); | |||
@@ -501,7 +536,16 @@ class ThemingDefaults extends \OC_Defaults { | |||
} | |||
/** | |||
* Color of text in the header and primary buttons | |||
* Color of text in the header menu | |||
* | |||
* @return string | |||
*/ | |||
public function getTextColorBackground() { | |||
return $this->util->invertTextColor($this->getColorBackground()) ? '#000000' : '#ffffff'; | |||
} | |||
/** | |||
* Color of text on primary buttons and other elements | |||
* | |||
* @return string | |||
*/ |