mirror of
https://github.com/aljazceru/btcpayserver.git
synced 2025-12-17 05:54:26 +01:00
UI: Theme extensions (#4398)
* Theme extensions Adds the ability to choose the themeing strategy: Extend one of the existing themes (light or dark) or go fully custom. The latter was the only option up to now, which isn't ideal: - One had to provide a full-blown theme file overriding all variables - Tedious, error prone and hard to maintain, because one has to keep track of updates This PR makes it so that one can choose light or dark as base theme and do modifications on top. Benefit: You can specify a limited set of variables and might get away with 5-20 lines of CSS. * Ensure custom theme is present * Update checkout test
This commit is contained in:
@@ -982,7 +982,10 @@ namespace BTCPayServer.Controllers
|
||||
}
|
||||
|
||||
[HttpPost("server/theme")]
|
||||
public async Task<IActionResult> Theme(ThemeSettings model, [FromForm] bool RemoveLogoFile)
|
||||
public async Task<IActionResult> Theme(
|
||||
ThemeSettings model,
|
||||
[FromForm] bool RemoveLogoFile,
|
||||
[FromForm] bool RemoveCustomThemeFile)
|
||||
{
|
||||
var settingsChanged = false;
|
||||
var settings = await _SettingsRepository.GetSettingAsync<ThemeSettings>() ?? new ThemeSettings();
|
||||
@@ -991,6 +994,40 @@ namespace BTCPayServer.Controllers
|
||||
if (userId is null)
|
||||
return NotFound();
|
||||
|
||||
if (model.CustomThemeFile != null)
|
||||
{
|
||||
if (model.CustomThemeFile.ContentType.Equals("text/css", StringComparison.InvariantCulture))
|
||||
{
|
||||
// delete existing file
|
||||
if (!string.IsNullOrEmpty(settings.CustomThemeFileId))
|
||||
{
|
||||
await _fileService.RemoveFile(settings.CustomThemeFileId, userId);
|
||||
}
|
||||
|
||||
// add new file
|
||||
try
|
||||
{
|
||||
var storedFile = await _fileService.AddFile(model.CustomThemeFile, userId);
|
||||
settings.CustomThemeFileId = storedFile.Id;
|
||||
settingsChanged = true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ModelState.AddModelError(nameof(settings.CustomThemeFile), $"Could not save theme file: {e.Message}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ModelState.AddModelError(nameof(settings.CustomThemeFile), "The uploaded theme file needs to be a CSS file");
|
||||
}
|
||||
}
|
||||
else if (RemoveCustomThemeFile && !string.IsNullOrEmpty(settings.CustomThemeFileId))
|
||||
{
|
||||
await _fileService.RemoveFile(settings.CustomThemeFileId, userId);
|
||||
settings.CustomThemeFileId = null;
|
||||
settingsChanged = true;
|
||||
}
|
||||
|
||||
if (model.LogoFile != null)
|
||||
{
|
||||
if (model.LogoFile.ContentType.StartsWith("image/", StringComparison.InvariantCulture))
|
||||
@@ -1010,12 +1047,12 @@ namespace BTCPayServer.Controllers
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ModelState.AddModelError(nameof(model.LogoFile), $"Could not save logo: {e.Message}");
|
||||
ModelState.AddModelError(nameof(settings.LogoFile), $"Could not save logo: {e.Message}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ModelState.AddModelError(nameof(model.LogoFile), "The uploaded logo file needs to be an image");
|
||||
ModelState.AddModelError(nameof(settings.LogoFile), "The uploaded logo file needs to be an image");
|
||||
}
|
||||
}
|
||||
else if (RemoveLogoFile && !string.IsNullOrEmpty(settings.LogoFileId))
|
||||
@@ -1025,14 +1062,28 @@ namespace BTCPayServer.Controllers
|
||||
settingsChanged = true;
|
||||
}
|
||||
|
||||
if (model.CustomTheme && !Uri.IsWellFormedUriString(model.CssUri, UriKind.RelativeOrAbsolute))
|
||||
if (model.CustomTheme && !string.IsNullOrEmpty(model.CustomThemeCssUri) && !Uri.IsWellFormedUriString(model.CustomThemeCssUri, UriKind.RelativeOrAbsolute))
|
||||
{
|
||||
ModelState.AddModelError(nameof(model.CustomTheme), "Please provide a non-empty theme URI");
|
||||
ModelState.AddModelError(nameof(settings.CustomThemeCssUri), "Please provide a non-empty theme URI");
|
||||
}
|
||||
else if (settings.CustomTheme != model.CustomTheme)
|
||||
|
||||
if (settings.CustomThemeExtension != model.CustomThemeExtension)
|
||||
{
|
||||
// Require a custom theme to be defined in that case
|
||||
if (string.IsNullOrEmpty(model.CustomThemeCssUri) && string.IsNullOrEmpty(settings.CustomThemeFileId))
|
||||
{
|
||||
ModelState.AddModelError(nameof(settings.CustomThemeFile), "Please provide a custom theme");
|
||||
}
|
||||
else
|
||||
{
|
||||
settings.CustomThemeExtension = model.CustomThemeExtension;
|
||||
settingsChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (settings.CustomTheme != model.CustomTheme)
|
||||
{
|
||||
settings.CustomTheme = model.CustomTheme;
|
||||
settings.CustomThemeCssUri = model.CustomThemeCssUri;
|
||||
settingsChanged = true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user