| @@ -33,171 +33,171 @@ | ||
| 33 | 33 | use OCP\IURLGenerator; | 
| 34 | 34 | |
| 35 | 35 |  class DefaultTheme implements ITheme { | 
| 36 | - public Util $util; | |
| 37 | - public ThemingDefaults $themingDefaults; | |
| 38 | - public IURLGenerator $urlGenerator; | |
| 39 | - public ImageManager $imageManager; | |
| 40 | - public IConfig $config; | |
| 41 | - public IL10N $l; | |
| 42 | - | |
| 43 | - public string $primaryColor; | |
| 44 | - | |
| 45 | - public function __construct(Util $util, | |
| 46 | - ThemingDefaults $themingDefaults, | |
| 47 | - IURLGenerator $urlGenerator, | |
| 48 | - ImageManager $imageManager, | |
| 49 | - IConfig $config, | |
| 50 | -								IL10N $l) { | |
| 51 | - $this->util = $util; | |
| 52 | - $this->themingDefaults = $themingDefaults; | |
| 53 | - $this->urlGenerator = $urlGenerator; | |
| 54 | - $this->imageManager = $imageManager; | |
| 55 | - $this->config = $config; | |
| 56 | - $this->l = $l; | |
| 57 | - | |
| 58 | - $this->primaryColor = $this->themingDefaults->getColorPrimary(); | |
| 59 | - } | |
| 60 | - | |
| 61 | -	public function getId(): string { | |
| 62 | - return 'default'; | |
| 63 | - } | |
| 64 | - | |
| 65 | -	public function getType(): int { | |
| 66 | - return ITheme::TYPE_THEME; | |
| 67 | - } | |
| 68 | - | |
| 69 | -	public function getTitle(): string { | |
| 70 | -		return $this->l->t('System default theme'); | |
| 71 | - } | |
| 72 | - | |
| 73 | -	public function getEnableLabel(): string { | |
| 74 | -		return $this->l->t('Enable the system default'); | |
| 75 | - } | |
| 76 | - | |
| 77 | -	public function getDescription(): string { | |
| 78 | -		return $this->l->t('Using the default system appearance.'); | |
| 79 | - } | |
| 80 | - | |
| 81 | -	public function getMediaQuery(): string { | |
| 82 | - return ''; | |
| 83 | - } | |
| 84 | - | |
| 85 | -	public function getCSSVariables(): array { | |
| 86 | - $colorMainText = '#222222'; | |
| 87 | - $colorMainBackground = '#ffffff'; | |
| 88 | -		$colorMainBackgroundRGB = join(',', $this->util->hexToRGB($colorMainBackground)); | |
| 89 | - $colorBoxShadow = $this->util->darken($colorMainBackground, 70); | |
| 90 | -		$colorBoxShadowRGB = join(',', $this->util->hexToRGB($colorBoxShadow)); | |
| 91 | - | |
| 92 | - $variables = [ | |
| 93 | - '--color-main-background' => $colorMainBackground, | |
| 94 | - '--color-main-background-rgb' => $colorMainBackgroundRGB, | |
| 95 | - '--color-main-background-translucent' => 'rgba(var(--color-main-background-rgb), .97)', | |
| 96 | - | |
| 97 | -			// to use like this: background-image: linear-gradient(0, var('--gradient-main-background)); | |
| 98 | - '--gradient-main-background' => 'var(--color-main-background) 0%, var(--color-main-background-translucent) 85%, transparent 100%', | |
| 99 | - | |
| 100 | - // used for different active/hover/focus/disabled states | |
| 101 | - '--color-background-hover' => $this->util->darken($colorMainBackground, 4), | |
| 102 | - '--color-background-dark' => $this->util->darken($colorMainBackground, 7), | |
| 103 | - '--color-background-darker' => $this->util->darken($colorMainBackground, 14), | |
| 104 | - | |
| 105 | - '--color-placeholder-light' => $this->util->darken($colorMainBackground, 10), | |
| 106 | - '--color-placeholder-dark' => $this->util->darken($colorMainBackground, 20), | |
| 107 | - | |
| 108 | - // primary related colours | |
| 109 | - '--color-primary' => $this->primaryColor, | |
| 110 | - '--color-primary-text' => $this->util->invertTextColor($this->primaryColor) ? '#000000' : '#ffffff', | |
| 111 | - '--color-primary-hover' => $this->util->mix($this->primaryColor, $colorMainBackground, 60), | |
| 112 | - '--color-primary-light' => $this->util->mix($this->primaryColor, $colorMainBackground, -80), | |
| 113 | - '--color-primary-light-text' => $this->primaryColor, | |
| 114 | - '--color-primary-light-hover' => $this->util->mix($this->primaryColor, $colorMainText, -80), | |
| 115 | - '--color-primary-text-dark' => $this->util->darken($this->util->invertTextColor($this->primaryColor) ? '#000000' : '#ffffff', 7), | |
| 116 | - // used for buttons, inputs... | |
| 117 | - '--color-primary-element' => $this->util->elementColor($this->primaryColor), | |
| 118 | - '--color-primary-element-hover' => $this->util->mix($this->util->elementColor($this->primaryColor), $colorMainBackground, 80), | |
| 119 | - '--color-primary-element-light' => $this->util->lighten($this->util->elementColor($this->primaryColor), 15), | |
| 120 | - '--color-primary-element-lighter' => $this->util->mix($this->util->elementColor($this->primaryColor), $colorMainBackground, -70), | |
| 121 | - | |
| 122 | - // max contrast for WCAG compliance | |
| 123 | - '--color-main-text' => $colorMainText, | |
| 124 | - '--color-text-maxcontrast' => $this->util->lighten($colorMainText, 33), | |
| 125 | - '--color-text-light' => $colorMainText, | |
| 126 | - '--color-text-lighter' => $this->util->lighten($colorMainText, 33), | |
| 127 | - | |
| 128 | - // info/warning/success feedback colours | |
| 129 | - '--color-error' => '#e9322d', | |
| 130 | -			'--color-error-hover' => $this->util->mix('#e9322d', $colorMainBackground, 60), | |
| 131 | - '--color-warning' => '#eca700', | |
| 132 | -			'--color-warning-hover' => $this->util->mix('#eca700', $colorMainBackground, 60), | |
| 133 | - '--color-success' => '#46ba61', | |
| 134 | -			'--color-success-hover' => $this->util->mix('#46ba61', $colorMainBackground, 60), | |
| 135 | - | |
| 136 | - // used for the icon loading animation | |
| 137 | - '--color-loading-light' => '#cccccc', | |
| 138 | - '--color-loading-dark' => '#444444', | |
| 139 | - | |
| 140 | - '--color-box-shadow-rgb' => $colorBoxShadowRGB, | |
| 141 | - '--color-box-shadow' => "rgba(var(--color-box-shadow-rgb), 0.5)", | |
| 142 | - | |
| 143 | - '--color-border' => $this->util->darken($colorMainBackground, 7), | |
| 144 | - '--color-border-dark' => $this->util->darken($colorMainBackground, 14), | |
| 145 | - | |
| 146 | - '--font-face' => "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Cantarell, Ubuntu, 'Helvetica Neue', Arial, sans-serif, 'Noto Color Emoji', 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'", | |
| 147 | - '--default-font-size' => '15px', | |
| 148 | - | |
| 149 | - // TODO: support "(prefers-reduced-motion)" | |
| 150 | - '--animation-quick' => '100ms', | |
| 151 | - '--animation-slow' => '300ms', | |
| 152 | - | |
| 153 | - // Default variables -------------------------------------------- | |
| 154 | - '--border-radius' => '3px', | |
| 155 | - '--border-radius-large' => '10px', | |
| 156 | - // pill-style button, value is large so big buttons also have correct roundness | |
| 157 | - '--border-radius-pill' => '100px', | |
| 158 | - | |
| 159 | - '--default-line-height' => '24px', | |
| 160 | - | |
| 161 | - // various structure data | |
| 162 | - '--header-height' => '50px', | |
| 163 | - '--navigation-width' => '300px', | |
| 164 | - '--sidebar-min-width' => '300px', | |
| 165 | - '--sidebar-max-width' => '500px', | |
| 166 | - '--list-min-width' => '200px', | |
| 167 | - '--list-max-width' => '300px', | |
| 168 | - '--header-menu-item-height' => '44px', | |
| 169 | - '--header-menu-profile-item-height' => '66px', | |
| 170 | - | |
| 171 | - // mobile. Keep in sync with core/js/js.js | |
| 172 | - '--breakpoint-mobile' => '1024px', | |
| 173 | - | |
| 174 | - // invert filter if primary is too bright | |
| 175 | - // to be used for legacy reasons only. Use inline | |
| 176 | - // svg with proper css variable instead or material | |
| 177 | - // design icons. | |
| 178 | - '--primary-invert-if-bright' => $this->util->invertTextColor($this->primaryColor) ? 'invert(100%)' : 'unset', | |
| 179 | - '--background-invert-if-dark' => 'unset', | |
| 180 | - ]; | |
| 181 | - | |
| 182 | - // Register image variables only if custom-defined | |
| 183 | -		$backgroundDeleted = $this->config->getAppValue('theming', 'backgroundMime', '') === 'backgroundColor'; | |
| 184 | -		foreach(['logo', 'logoheader', 'favicon', 'background'] as $image) { | |
| 185 | -			if ($this->imageManager->hasImage($image)) { | |
| 186 | - // If primary as background has been request, let's not define the background image | |
| 187 | -				if ($image === 'background' && $backgroundDeleted) { | |
| 188 | - $variables["--image-background-plain"] = true; | |
| 189 | - continue; | |
| 190 | -				} else if ($image === 'background') { | |
| 191 | - $variables['--image-background-size'] = 'cover'; | |
| 192 | - } | |
| 193 | -				$variables["--image-$image"] = "url('".$this->imageManager->getImageUrl($image)."')"; | |
| 194 | - } | |
| 195 | - } | |
| 196 | - | |
| 197 | - return $variables; | |
| 198 | - } | |
| 199 | - | |
| 200 | -	public function getCustomCss(): string { | |
| 201 | - return ''; | |
| 202 | - } | |
| 36 | + public Util $util; | |
| 37 | + public ThemingDefaults $themingDefaults; | |
| 38 | + public IURLGenerator $urlGenerator; | |
| 39 | + public ImageManager $imageManager; | |
| 40 | + public IConfig $config; | |
| 41 | + public IL10N $l; | |
| 42 | + | |
| 43 | + public string $primaryColor; | |
| 44 | + | |
| 45 | + public function __construct(Util $util, | |
| 46 | + ThemingDefaults $themingDefaults, | |
| 47 | + IURLGenerator $urlGenerator, | |
| 48 | + ImageManager $imageManager, | |
| 49 | + IConfig $config, | |
| 50 | +                                IL10N $l) { | |
| 51 | + $this->util = $util; | |
| 52 | + $this->themingDefaults = $themingDefaults; | |
| 53 | + $this->urlGenerator = $urlGenerator; | |
| 54 | + $this->imageManager = $imageManager; | |
| 55 | + $this->config = $config; | |
| 56 | + $this->l = $l; | |
| 57 | + | |
| 58 | + $this->primaryColor = $this->themingDefaults->getColorPrimary(); | |
| 59 | + } | |
| 60 | + | |
| 61 | +    public function getId(): string { | |
| 62 | + return 'default'; | |
| 63 | + } | |
| 64 | + | |
| 65 | +    public function getType(): int { | |
| 66 | + return ITheme::TYPE_THEME; | |
| 67 | + } | |
| 68 | + | |
| 69 | +    public function getTitle(): string { | |
| 70 | +        return $this->l->t('System default theme'); | |
| 71 | + } | |
| 72 | + | |
| 73 | +    public function getEnableLabel(): string { | |
| 74 | +        return $this->l->t('Enable the system default'); | |
| 75 | + } | |
| 76 | + | |
| 77 | +    public function getDescription(): string { | |
| 78 | +        return $this->l->t('Using the default system appearance.'); | |
| 79 | + } | |
| 80 | + | |
| 81 | +    public function getMediaQuery(): string { | |
| 82 | + return ''; | |
| 83 | + } | |
| 84 | + | |
| 85 | +    public function getCSSVariables(): array { | |
| 86 | + $colorMainText = '#222222'; | |
| 87 | + $colorMainBackground = '#ffffff'; | |
| 88 | +        $colorMainBackgroundRGB = join(',', $this->util->hexToRGB($colorMainBackground)); | |
| 89 | + $colorBoxShadow = $this->util->darken($colorMainBackground, 70); | |
| 90 | +        $colorBoxShadowRGB = join(',', $this->util->hexToRGB($colorBoxShadow)); | |
| 91 | + | |
| 92 | + $variables = [ | |
| 93 | + '--color-main-background' => $colorMainBackground, | |
| 94 | + '--color-main-background-rgb' => $colorMainBackgroundRGB, | |
| 95 | + '--color-main-background-translucent' => 'rgba(var(--color-main-background-rgb), .97)', | |
| 96 | + | |
| 97 | +            // to use like this: background-image: linear-gradient(0, var('--gradient-main-background)); | |
| 98 | + '--gradient-main-background' => 'var(--color-main-background) 0%, var(--color-main-background-translucent) 85%, transparent 100%', | |
| 99 | + | |
| 100 | + // used for different active/hover/focus/disabled states | |
| 101 | + '--color-background-hover' => $this->util->darken($colorMainBackground, 4), | |
| 102 | + '--color-background-dark' => $this->util->darken($colorMainBackground, 7), | |
| 103 | + '--color-background-darker' => $this->util->darken($colorMainBackground, 14), | |
| 104 | + | |
| 105 | + '--color-placeholder-light' => $this->util->darken($colorMainBackground, 10), | |
| 106 | + '--color-placeholder-dark' => $this->util->darken($colorMainBackground, 20), | |
| 107 | + | |
| 108 | + // primary related colours | |
| 109 | + '--color-primary' => $this->primaryColor, | |
| 110 | + '--color-primary-text' => $this->util->invertTextColor($this->primaryColor) ? '#000000' : '#ffffff', | |
| 111 | + '--color-primary-hover' => $this->util->mix($this->primaryColor, $colorMainBackground, 60), | |
| 112 | + '--color-primary-light' => $this->util->mix($this->primaryColor, $colorMainBackground, -80), | |
| 113 | + '--color-primary-light-text' => $this->primaryColor, | |
| 114 | + '--color-primary-light-hover' => $this->util->mix($this->primaryColor, $colorMainText, -80), | |
| 115 | + '--color-primary-text-dark' => $this->util->darken($this->util->invertTextColor($this->primaryColor) ? '#000000' : '#ffffff', 7), | |
| 116 | + // used for buttons, inputs... | |
| 117 | + '--color-primary-element' => $this->util->elementColor($this->primaryColor), | |
| 118 | + '--color-primary-element-hover' => $this->util->mix($this->util->elementColor($this->primaryColor), $colorMainBackground, 80), | |
| 119 | + '--color-primary-element-light' => $this->util->lighten($this->util->elementColor($this->primaryColor), 15), | |
| 120 | + '--color-primary-element-lighter' => $this->util->mix($this->util->elementColor($this->primaryColor), $colorMainBackground, -70), | |
| 121 | + | |
| 122 | + // max contrast for WCAG compliance | |
| 123 | + '--color-main-text' => $colorMainText, | |
| 124 | + '--color-text-maxcontrast' => $this->util->lighten($colorMainText, 33), | |
| 125 | + '--color-text-light' => $colorMainText, | |
| 126 | + '--color-text-lighter' => $this->util->lighten($colorMainText, 33), | |
| 127 | + | |
| 128 | + // info/warning/success feedback colours | |
| 129 | + '--color-error' => '#e9322d', | |
| 130 | +            '--color-error-hover' => $this->util->mix('#e9322d', $colorMainBackground, 60), | |
| 131 | + '--color-warning' => '#eca700', | |
| 132 | +            '--color-warning-hover' => $this->util->mix('#eca700', $colorMainBackground, 60), | |
| 133 | + '--color-success' => '#46ba61', | |
| 134 | +            '--color-success-hover' => $this->util->mix('#46ba61', $colorMainBackground, 60), | |
| 135 | + | |
| 136 | + // used for the icon loading animation | |
| 137 | + '--color-loading-light' => '#cccccc', | |
| 138 | + '--color-loading-dark' => '#444444', | |
| 139 | + | |
| 140 | + '--color-box-shadow-rgb' => $colorBoxShadowRGB, | |
| 141 | + '--color-box-shadow' => "rgba(var(--color-box-shadow-rgb), 0.5)", | |
| 142 | + | |
| 143 | + '--color-border' => $this->util->darken($colorMainBackground, 7), | |
| 144 | + '--color-border-dark' => $this->util->darken($colorMainBackground, 14), | |
| 145 | + | |
| 146 | + '--font-face' => "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Cantarell, Ubuntu, 'Helvetica Neue', Arial, sans-serif, 'Noto Color Emoji', 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'", | |
| 147 | + '--default-font-size' => '15px', | |
| 148 | + | |
| 149 | + // TODO: support "(prefers-reduced-motion)" | |
| 150 | + '--animation-quick' => '100ms', | |
| 151 | + '--animation-slow' => '300ms', | |
| 152 | + | |
| 153 | + // Default variables -------------------------------------------- | |
| 154 | + '--border-radius' => '3px', | |
| 155 | + '--border-radius-large' => '10px', | |
| 156 | + // pill-style button, value is large so big buttons also have correct roundness | |
| 157 | + '--border-radius-pill' => '100px', | |
| 158 | + | |
| 159 | + '--default-line-height' => '24px', | |
| 160 | + | |
| 161 | + // various structure data | |
| 162 | + '--header-height' => '50px', | |
| 163 | + '--navigation-width' => '300px', | |
| 164 | + '--sidebar-min-width' => '300px', | |
| 165 | + '--sidebar-max-width' => '500px', | |
| 166 | + '--list-min-width' => '200px', | |
| 167 | + '--list-max-width' => '300px', | |
| 168 | + '--header-menu-item-height' => '44px', | |
| 169 | + '--header-menu-profile-item-height' => '66px', | |
| 170 | + | |
| 171 | + // mobile. Keep in sync with core/js/js.js | |
| 172 | + '--breakpoint-mobile' => '1024px', | |
| 173 | + | |
| 174 | + // invert filter if primary is too bright | |
| 175 | + // to be used for legacy reasons only. Use inline | |
| 176 | + // svg with proper css variable instead or material | |
| 177 | + // design icons. | |
| 178 | + '--primary-invert-if-bright' => $this->util->invertTextColor($this->primaryColor) ? 'invert(100%)' : 'unset', | |
| 179 | + '--background-invert-if-dark' => 'unset', | |
| 180 | + ]; | |
| 181 | + | |
| 182 | + // Register image variables only if custom-defined | |
| 183 | +        $backgroundDeleted = $this->config->getAppValue('theming', 'backgroundMime', '') === 'backgroundColor'; | |
| 184 | +        foreach(['logo', 'logoheader', 'favicon', 'background'] as $image) { | |
| 185 | +            if ($this->imageManager->hasImage($image)) { | |
| 186 | + // If primary as background has been request, let's not define the background image | |
| 187 | +                if ($image === 'background' && $backgroundDeleted) { | |
| 188 | + $variables["--image-background-plain"] = true; | |
| 189 | + continue; | |
| 190 | +                } else if ($image === 'background') { | |
| 191 | + $variables['--image-background-size'] = 'cover'; | |
| 192 | + } | |
| 193 | +                $variables["--image-$image"] = "url('".$this->imageManager->getImageUrl($image)."')"; | |
| 194 | + } | |
| 195 | + } | |
| 196 | + | |
| 197 | + return $variables; | |
| 198 | + } | |
| 199 | + | |
| 200 | +    public function getCustomCss(): string { | |
| 201 | + return ''; | |
| 202 | + } | |
| 203 | 203 | } | 
| @@ -35,27 +35,27 @@ | ||
| 35 | 35 | |
| 36 | 36 |  class LightTheme extends DefaultTheme implements ITheme { | 
| 37 | 37 | |
| 38 | -	public function getId(): string { | |
| 39 | - return 'light'; | |
| 40 | - } | |
| 38 | +    public function getId(): string { | |
| 39 | + return 'light'; | |
| 40 | + } | |
| 41 | 41 | |
| 42 | -	public function getType(): int { | |
| 43 | - return ITheme::TYPE_THEME; | |
| 44 | - } | |
| 42 | +    public function getType(): int { | |
| 43 | + return ITheme::TYPE_THEME; | |
| 44 | + } | |
| 45 | 45 | |
| 46 | -	public function getTitle(): string { | |
| 47 | -		return $this->l->t('Light theme'); | |
| 48 | - } | |
| 46 | +    public function getTitle(): string { | |
| 47 | +        return $this->l->t('Light theme'); | |
| 48 | + } | |
| 49 | 49 | |
| 50 | -	public function getEnableLabel(): string { | |
| 51 | -		return $this->l->t('Enable the default light theme'); | |
| 52 | - } | |
| 50 | +    public function getEnableLabel(): string { | |
| 51 | +        return $this->l->t('Enable the default light theme'); | |
| 52 | + } | |
| 53 | 53 | |
| 54 | -	public function getDescription(): string { | |
| 55 | -		return $this->l->t('The default light appearance.'); | |
| 56 | - } | |
| 54 | +    public function getDescription(): string { | |
| 55 | +        return $this->l->t('The default light appearance.'); | |
| 56 | + } | |
| 57 | 57 | |
| 58 | -	public function getMediaQuery(): string { | |
| 59 | - return '(prefers-color-scheme: light)'; | |
| 60 | - } | |
| 58 | +    public function getMediaQuery(): string { | |
| 59 | + return '(prefers-color-scheme: light)'; | |
| 60 | + } | |
| 61 | 61 | } | 
| @@ -35,141 +35,141 @@ | ||
| 35 | 35 | use OCP\IUserSession; | 
| 36 | 36 | |
| 37 | 37 |  class ThemesService { | 
| 38 | - private IUserSession $userSession; | |
| 39 | - private IConfig $config; | |
| 40 | - | |
| 41 | - /** @var ITheme[] */ | |
| 42 | - private array $themesProviders; | |
| 43 | - | |
| 44 | - public function __construct(IUserSession $userSession, | |
| 45 | - IConfig $config, | |
| 46 | - DefaultTheme $defaultTheme, | |
| 47 | - LightTheme $lightTheme, | |
| 48 | - DarkTheme $darkTheme, | |
| 49 | - HighContrastTheme $highContrastTheme, | |
| 50 | - DarkHighContrastTheme $darkHighContrastTheme, | |
| 51 | -								DyslexiaFont $dyslexiaFont) { | |
| 52 | - $this->userSession = $userSession; | |
| 53 | - $this->config = $config; | |
| 54 | - | |
| 55 | - // Register themes | |
| 56 | - $this->themesProviders = [ | |
| 57 | - $defaultTheme->getId() => $defaultTheme, | |
| 58 | - $lightTheme->getId() => $lightTheme, | |
| 59 | - $darkTheme->getId() => $darkTheme, | |
| 60 | - $highContrastTheme->getId() => $highContrastTheme, | |
| 61 | - $darkHighContrastTheme->getId() => $darkHighContrastTheme, | |
| 62 | - $dyslexiaFont->getId() => $dyslexiaFont, | |
| 63 | - ]; | |
| 64 | - } | |
| 65 | - | |
| 66 | - /** | |
| 67 | - * Get the list of all registered themes | |
| 68 | - * | |
| 69 | - * @return ITheme[] | |
| 70 | - */ | |
| 71 | -	public function getThemes(): array { | |
| 72 | - return $this->themesProviders; | |
| 73 | - } | |
| 74 | - | |
| 75 | - /** | |
| 76 | - * Enable a theme for the logged-in user | |
| 77 | - * | |
| 78 | - * @param ITheme $theme the theme to enable | |
| 79 | - * @return string[] the enabled themes | |
| 80 | - */ | |
| 81 | -	public function enableTheme(ITheme $theme): array { | |
| 82 | - $themesIds = $this->getEnabledThemes(); | |
| 83 | - | |
| 84 | - // If already enabled, ignore | |
| 85 | -		if (in_array($theme->getId(), $themesIds)) { | |
| 86 | - return $themesIds; | |
| 87 | - } | |
| 88 | - | |
| 89 | - /** @var ITheme[] */ | |
| 90 | -		$themes = array_map(function($themeId) { | |
| 91 | - return $this->getThemes()[$themeId]; | |
| 92 | - }, $themesIds); | |
| 93 | - | |
| 94 | - // Filtering all themes with the same type | |
| 95 | -		$filteredThemes = array_filter($themes, function(ITheme $t) use ($theme) { | |
| 96 | - return $theme->getType() === $t->getType(); | |
| 97 | - }); | |
| 98 | - | |
| 99 | - // Retrieve IDs only | |
| 100 | - /** @var string[] */ | |
| 101 | -		$filteredThemesIds = array_map(function(ITheme $t) { | |
| 102 | - return $t->getId(); | |
| 103 | - }, array_values($filteredThemes)); | |
| 104 | - | |
| 105 | - $enabledThemes = array_merge(array_diff($themesIds, $filteredThemesIds), [$theme->getId()]); | |
| 106 | - $this->setEnabledThemes($enabledThemes); | |
| 107 | - | |
| 108 | - return $enabledThemes; | |
| 109 | - } | |
| 110 | - | |
| 111 | - /** | |
| 112 | - * Disable a theme for the logged-in user | |
| 113 | - * | |
| 114 | - * @param ITheme $theme the theme to disable | |
| 115 | - * @return string[] the enabled themes | |
| 116 | - */ | |
| 117 | -	public function disableTheme(ITheme $theme): array { | |
| 118 | - $themesIds = $this->getEnabledThemes(); | |
| 119 | - | |
| 120 | - // If enabled, removing it | |
| 121 | -		if (in_array($theme->getId(), $themesIds)) { | |
| 122 | - $enabledThemes = array_diff($themesIds, [$theme->getId()]); | |
| 123 | - $this->setEnabledThemes($enabledThemes); | |
| 124 | - return $enabledThemes; | |
| 125 | - } | |
| 38 | + private IUserSession $userSession; | |
| 39 | + private IConfig $config; | |
| 40 | + | |
| 41 | + /** @var ITheme[] */ | |
| 42 | + private array $themesProviders; | |
| 43 | + | |
| 44 | + public function __construct(IUserSession $userSession, | |
| 45 | + IConfig $config, | |
| 46 | + DefaultTheme $defaultTheme, | |
| 47 | + LightTheme $lightTheme, | |
| 48 | + DarkTheme $darkTheme, | |
| 49 | + HighContrastTheme $highContrastTheme, | |
| 50 | + DarkHighContrastTheme $darkHighContrastTheme, | |
| 51 | +                                DyslexiaFont $dyslexiaFont) { | |
| 52 | + $this->userSession = $userSession; | |
| 53 | + $this->config = $config; | |
| 54 | + | |
| 55 | + // Register themes | |
| 56 | + $this->themesProviders = [ | |
| 57 | + $defaultTheme->getId() => $defaultTheme, | |
| 58 | + $lightTheme->getId() => $lightTheme, | |
| 59 | + $darkTheme->getId() => $darkTheme, | |
| 60 | + $highContrastTheme->getId() => $highContrastTheme, | |
| 61 | + $darkHighContrastTheme->getId() => $darkHighContrastTheme, | |
| 62 | + $dyslexiaFont->getId() => $dyslexiaFont, | |
| 63 | + ]; | |
| 64 | + } | |
| 65 | + | |
| 66 | + /** | |
| 67 | + * Get the list of all registered themes | |
| 68 | + * | |
| 69 | + * @return ITheme[] | |
| 70 | + */ | |
| 71 | +    public function getThemes(): array { | |
| 72 | + return $this->themesProviders; | |
| 73 | + } | |
| 74 | + | |
| 75 | + /** | |
| 76 | + * Enable a theme for the logged-in user | |
| 77 | + * | |
| 78 | + * @param ITheme $theme the theme to enable | |
| 79 | + * @return string[] the enabled themes | |
| 80 | + */ | |
| 81 | +    public function enableTheme(ITheme $theme): array { | |
| 82 | + $themesIds = $this->getEnabledThemes(); | |
| 83 | + | |
| 84 | + // If already enabled, ignore | |
| 85 | +        if (in_array($theme->getId(), $themesIds)) { | |
| 86 | + return $themesIds; | |
| 87 | + } | |
| 88 | + | |
| 89 | + /** @var ITheme[] */ | |
| 90 | +        $themes = array_map(function($themeId) { | |
| 91 | + return $this->getThemes()[$themeId]; | |
| 92 | + }, $themesIds); | |
| 93 | + | |
| 94 | + // Filtering all themes with the same type | |
| 95 | +        $filteredThemes = array_filter($themes, function(ITheme $t) use ($theme) { | |
| 96 | + return $theme->getType() === $t->getType(); | |
| 97 | + }); | |
| 98 | + | |
| 99 | + // Retrieve IDs only | |
| 100 | + /** @var string[] */ | |
| 101 | +        $filteredThemesIds = array_map(function(ITheme $t) { | |
| 102 | + return $t->getId(); | |
| 103 | + }, array_values($filteredThemes)); | |
| 104 | + | |
| 105 | + $enabledThemes = array_merge(array_diff($themesIds, $filteredThemesIds), [$theme->getId()]); | |
| 106 | + $this->setEnabledThemes($enabledThemes); | |
| 107 | + | |
| 108 | + return $enabledThemes; | |
| 109 | + } | |
| 110 | + | |
| 111 | + /** | |
| 112 | + * Disable a theme for the logged-in user | |
| 113 | + * | |
| 114 | + * @param ITheme $theme the theme to disable | |
| 115 | + * @return string[] the enabled themes | |
| 116 | + */ | |
| 117 | +    public function disableTheme(ITheme $theme): array { | |
| 118 | + $themesIds = $this->getEnabledThemes(); | |
| 119 | + | |
| 120 | + // If enabled, removing it | |
| 121 | +        if (in_array($theme->getId(), $themesIds)) { | |
| 122 | + $enabledThemes = array_diff($themesIds, [$theme->getId()]); | |
| 123 | + $this->setEnabledThemes($enabledThemes); | |
| 124 | + return $enabledThemes; | |
| 125 | + } | |
| 126 | 126 | |
| 127 | - return $themesIds; | |
| 128 | - } | |
| 129 | - | |
| 130 | - /** | |
| 131 | - * Check whether a theme is enabled or not | |
| 132 | - * for the logged-in user | |
| 133 | - * | |
| 134 | - * @return bool | |
| 135 | - */ | |
| 136 | -	public function isEnabled(ITheme $theme): bool { | |
| 137 | - $user = $this->userSession->getUser(); | |
| 138 | -		if ($user instanceof IUser) { | |
| 139 | - // Using keys as it's faster | |
| 140 | - $themes = $this->getEnabledThemes(); | |
| 141 | - return in_array($theme->getId(), $themes); | |
| 142 | - } | |
| 143 | - return false; | |
| 144 | - } | |
| 145 | - | |
| 146 | - /** | |
| 147 | - * Get the list of all enabled themes IDs | |
| 148 | - * for the logged-in user | |
| 149 | - * | |
| 150 | - * @return string[] | |
| 151 | - */ | |
| 152 | -	public function getEnabledThemes(): array { | |
| 153 | - $user = $this->userSession->getUser(); | |
| 154 | -		if ($user === null) { | |
| 155 | - return []; | |
| 156 | - } | |
| 157 | - | |
| 158 | -		try { | |
| 159 | - return json_decode($this->config->getUserValue($user->getUID(), Application::APP_ID, 'enabled-themes', '[]')); | |
| 160 | -		} catch (\Exception $e) { | |
| 161 | - return []; | |
| 162 | - } | |
| 163 | - } | |
| 164 | - | |
| 165 | - /** | |
| 166 | - * Set the list of enabled themes | |
| 167 | - * for the logged-in user | |
| 168 | - * | |
| 169 | - * @param string[] $themes the list of enabled themes IDs | |
| 170 | - */ | |
| 171 | -	private function setEnabledThemes(array $themes): void { | |
| 172 | - $user = $this->userSession->getUser(); | |
| 173 | - $this->config->setUserValue($user->getUID(), Application::APP_ID, 'enabled-themes', json_encode(array_unique(array_values($themes)))); | |
| 174 | - } | |
| 127 | + return $themesIds; | |
| 128 | + } | |
| 129 | + | |
| 130 | + /** | |
| 131 | + * Check whether a theme is enabled or not | |
| 132 | + * for the logged-in user | |
| 133 | + * | |
| 134 | + * @return bool | |
| 135 | + */ | |
| 136 | +    public function isEnabled(ITheme $theme): bool { | |
| 137 | + $user = $this->userSession->getUser(); | |
| 138 | +        if ($user instanceof IUser) { | |
| 139 | + // Using keys as it's faster | |
| 140 | + $themes = $this->getEnabledThemes(); | |
| 141 | + return in_array($theme->getId(), $themes); | |
| 142 | + } | |
| 143 | + return false; | |
| 144 | + } | |
| 145 | + | |
| 146 | + /** | |
| 147 | + * Get the list of all enabled themes IDs | |
| 148 | + * for the logged-in user | |
| 149 | + * | |
| 150 | + * @return string[] | |
| 151 | + */ | |
| 152 | +    public function getEnabledThemes(): array { | |
| 153 | + $user = $this->userSession->getUser(); | |
| 154 | +        if ($user === null) { | |
| 155 | + return []; | |
| 156 | + } | |
| 157 | + | |
| 158 | +        try { | |
| 159 | + return json_decode($this->config->getUserValue($user->getUID(), Application::APP_ID, 'enabled-themes', '[]')); | |
| 160 | +        } catch (\Exception $e) { | |
| 161 | + return []; | |
| 162 | + } | |
| 163 | + } | |
| 164 | + | |
| 165 | + /** | |
| 166 | + * Set the list of enabled themes | |
| 167 | + * for the logged-in user | |
| 168 | + * | |
| 169 | + * @param string[] $themes the list of enabled themes IDs | |
| 170 | + */ | |
| 171 | +    private function setEnabledThemes(array $themes): void { | |
| 172 | + $user = $this->userSession->getUser(); | |
| 173 | + $this->config->setUserValue($user->getUID(), Application::APP_ID, 'enabled-themes', json_encode(array_unique(array_values($themes)))); | |
| 174 | + } | |
| 175 | 175 | } |