finish custom accent color feature
This commit is contained in:
parent
3b9b99a07e
commit
92e71ae2f4
@ -10,7 +10,7 @@ namespace SharedLibraryCore.Configuration
|
|||||||
{
|
{
|
||||||
|
|
||||||
[LocalizedDisplayName("SETUP_ENABLE_WEBFRONT")]
|
[LocalizedDisplayName("SETUP_ENABLE_WEBFRONT")]
|
||||||
[ConfigurationLinked("WebfrontBindUrl", "ManualWebfrontUrl", "WebfrontPrimaryColor", "WebfrontSecondaryColor")]
|
[ConfigurationLinked("WebfrontBindUrl", "ManualWebfrontUrl", "WebfrontPrimaryColor", "WebfrontSecondaryColor", "WebfrontCustomBranding")]
|
||||||
public bool EnableWebFront { get; set; }
|
public bool EnableWebFront { get; set; }
|
||||||
[LocalizedDisplayName("WEBFRONT_CONFIGURATION_BIND_URL")]
|
[LocalizedDisplayName("WEBFRONT_CONFIGURATION_BIND_URL")]
|
||||||
public string WebfrontBindUrl { get; set; }
|
public string WebfrontBindUrl { get; set; }
|
||||||
@ -18,9 +18,14 @@ namespace SharedLibraryCore.Configuration
|
|||||||
[LocalizedDisplayName("WEBFRONT_CONFIGURATION_MANUAL_URL")]
|
[LocalizedDisplayName("WEBFRONT_CONFIGURATION_MANUAL_URL")]
|
||||||
public string ManualWebfrontUrl { get; set; }
|
public string ManualWebfrontUrl { get; set; }
|
||||||
[ConfigurationOptional]
|
[ConfigurationOptional]
|
||||||
|
[LocalizedDisplayName("WEBFRONT_CONFIGURATION_PRIMARY_COLOR")]
|
||||||
public string WebfrontPrimaryColor { get; set; }
|
public string WebfrontPrimaryColor { get; set; }
|
||||||
[ConfigurationOptional]
|
[ConfigurationOptional]
|
||||||
|
[LocalizedDisplayName("WEBFRONT_CONFIGURATION_SECONDARY_COLOR")]
|
||||||
public string WebfrontSecondaryColor { get; set; }
|
public string WebfrontSecondaryColor { get; set; }
|
||||||
|
[ConfigurationOptional]
|
||||||
|
[LocalizedDisplayName("WEBFRONT_CONFIGURATION_CUSTOM_BRANDING")]
|
||||||
|
public string WebfrontCustomBranding { get; set; }
|
||||||
|
|
||||||
[LocalizedDisplayName("SETUP_ENABLE_MULTIOWN")]
|
[LocalizedDisplayName("SETUP_ENABLE_MULTIOWN")]
|
||||||
public bool EnableMultipleOwners { get; set; }
|
public bool EnableMultipleOwners { get; set; }
|
||||||
|
@ -672,6 +672,7 @@ namespace SharedLibraryCore
|
|||||||
cmdProcess.WaitForExit();
|
cmdProcess.WaitForExit();
|
||||||
|
|
||||||
string[] cmdLine = cmdProcess.StandardOutput.ReadToEnd().Split("\r\n", StringSplitOptions.RemoveEmptyEntries);
|
string[] cmdLine = cmdProcess.StandardOutput.ReadToEnd().Split("\r\n", StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
cmdProcess.Dispose();
|
||||||
|
|
||||||
return cmdLine.Length > 1 ? cmdLine[1] : cmdLine[0];
|
return cmdLine.Length > 1 ? cmdLine[1] : cmdLine[0];
|
||||||
}
|
}
|
||||||
|
@ -107,6 +107,7 @@ namespace WebfrontCore.Controllers
|
|||||||
ViewBag.SocialTitle = SocialTitle;
|
ViewBag.SocialTitle = SocialTitle;
|
||||||
ViewBag.Pages = Pages;
|
ViewBag.Pages = Pages;
|
||||||
ViewBag.Localization = Utilities.CurrentLocalization.LocalizationIndex;
|
ViewBag.Localization = Utilities.CurrentLocalization.LocalizationIndex;
|
||||||
|
ViewBag.CustomBranding = Manager.GetApplicationSettings().Configuration().WebfrontCustomBranding ?? "IW4MAdmin";
|
||||||
|
|
||||||
base.OnActionExecuting(context);
|
base.OnActionExecuting(context);
|
||||||
}
|
}
|
||||||
|
@ -10,76 +10,90 @@ namespace WebfrontCore.Middleware
|
|||||||
{
|
{
|
||||||
public class CustomCssAccentMiddlewareAction : IMiddlewareAction<string>
|
public class CustomCssAccentMiddlewareAction : IMiddlewareAction<string>
|
||||||
{
|
{
|
||||||
private readonly Color _primaryColor;
|
private readonly List<ColorMap> ColorReplacements = new List<ColorMap>();
|
||||||
private readonly Color _secondaryColor;
|
|
||||||
private readonly Color _originalPrimaryColor;
|
private class ColorMap
|
||||||
private readonly Color _originalSecondaryColor;
|
{
|
||||||
|
public Color Original { get; set; }
|
||||||
|
public Color Replacement { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
public CustomCssAccentMiddlewareAction(string originalPrimaryColor, string originalSecondaryColor, string primaryColor, string secondaryColor)
|
public CustomCssAccentMiddlewareAction(string originalPrimaryColor, string originalSecondaryColor, string primaryColor, string secondaryColor)
|
||||||
{
|
{
|
||||||
_originalPrimaryColor = Color.FromArgb(Convert.ToInt32(originalPrimaryColor.Substring(1).ToString(), 16));
|
primaryColor = string.IsNullOrWhiteSpace(primaryColor) ? originalPrimaryColor : primaryColor;
|
||||||
_originalSecondaryColor = Color.FromArgb(Convert.ToInt32(originalSecondaryColor.Substring(1).ToString(), 16));
|
secondaryColor = string.IsNullOrWhiteSpace(secondaryColor) ? originalSecondaryColor : secondaryColor;
|
||||||
_primaryColor = string.IsNullOrEmpty(primaryColor) ? _originalPrimaryColor : Color.FromArgb(Convert.ToInt32(primaryColor.Substring(1).ToString(), 16));
|
try
|
||||||
_secondaryColor = string.IsNullOrEmpty(secondaryColor) ? _originalSecondaryColor : Color.FromArgb(Convert.ToInt32(secondaryColor.Substring(1).ToString(), 16));
|
{
|
||||||
|
ColorReplacements.AddRange(new[]
|
||||||
|
{
|
||||||
|
new ColorMap()
|
||||||
|
{
|
||||||
|
Original = Color.FromArgb(Convert.ToInt32(originalPrimaryColor.Substring(1).ToString(), 16)),
|
||||||
|
Replacement = Color.FromArgb(Convert.ToInt32(primaryColor.Substring(1).ToString(), 16))
|
||||||
|
},
|
||||||
|
new ColorMap()
|
||||||
|
{
|
||||||
|
Original = Color.FromArgb(Convert.ToInt32(originalSecondaryColor.Substring(1).ToString(), 16)),
|
||||||
|
Replacement = Color.FromArgb(Convert.ToInt32(secondaryColor.Substring(1).ToString(), 16))
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (FormatException)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<string> Invoke(string original)
|
public async Task<string> Invoke(string original)
|
||||||
{
|
{
|
||||||
string originalPrimaryHex = ColorToHex(_originalPrimaryColor);
|
foreach (var color in ColorReplacements)
|
||||||
string originalPrimaryDec = ColorToDec(_originalPrimaryColor);
|
{
|
||||||
string originalSecondaryHex = ColorToHex(_originalSecondaryColor);
|
foreach (var shade in new[] { 0, -19, -25 })
|
||||||
string originalSecondaryDec = ColorToDec(_originalSecondaryColor);
|
{
|
||||||
|
original = original
|
||||||
string primaryHex = ColorToHex(_primaryColor);
|
.Replace(ColorToHex(LightenDarkenColor(color.Original, shade)), ColorToHex(LightenDarkenColor(color.Replacement, shade)), StringComparison.OrdinalIgnoreCase)
|
||||||
string primaryDec = ColorToDec(_primaryColor);
|
.Replace(ColorToDec(LightenDarkenColor(color.Original, shade)), ColorToDec(LightenDarkenColor(color.Replacement, shade)), StringComparison.OrdinalIgnoreCase);
|
||||||
string secondaryHex = ColorToHex(_secondaryColor);
|
}
|
||||||
string secondaryDec = ColorToDec(_secondaryColor);
|
|
||||||
|
|
||||||
string originalPrimaryDarkenHex = ColorToHex(LightenDarkenColor(_originalPrimaryColor, -10));
|
|
||||||
string originalPrimaryDarkenDec = ColorToDec(LightenDarkenColor(_originalPrimaryColor, -10));
|
|
||||||
string originalSecondaryDarkenHex = ColorToHex(LightenDarkenColor(_originalSecondaryColor, -10));
|
|
||||||
string originalSecondaryDarkenDec = ColorToDec(LightenDarkenColor(_originalSecondaryColor, -10));
|
|
||||||
|
|
||||||
string primaryDarkenHex = ColorToHex(LightenDarkenColor(_primaryColor, -10));
|
|
||||||
string primaryDarkenDec = ColorToDec(LightenDarkenColor(_primaryColor, -10));
|
|
||||||
string secondaryDarkenHex = ColorToHex(LightenDarkenColor(_secondaryColor, -10));
|
|
||||||
string secondaryDarkenDec = ColorToDec(LightenDarkenColor(_secondaryColor, -10));
|
|
||||||
|
|
||||||
return original
|
|
||||||
.Replace(originalPrimaryHex, primaryHex, StringComparison.OrdinalIgnoreCase)
|
|
||||||
.Replace(originalPrimaryDec, primaryDec, StringComparison.OrdinalIgnoreCase)
|
|
||||||
.Replace(originalSecondaryHex, secondaryHex, StringComparison.OrdinalIgnoreCase)
|
|
||||||
.Replace(originalSecondaryDec, secondaryDec, StringComparison.OrdinalIgnoreCase)
|
|
||||||
.Replace(originalPrimaryDarkenHex, primaryDarkenHex, StringComparison.OrdinalIgnoreCase)
|
|
||||||
.Replace(originalPrimaryDarkenDec, primaryDarkenDec, StringComparison.OrdinalIgnoreCase)
|
|
||||||
.Replace(originalSecondaryDarkenHex, secondaryDarkenHex, StringComparison.OrdinalIgnoreCase)
|
|
||||||
.Replace(originalSecondaryDarkenDec, secondaryDarkenDec, StringComparison.OrdinalIgnoreCase);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return original;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// converts color to the hex string representation
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="color"></param>
|
||||||
|
/// <returns></returns>
|
||||||
private string ColorToHex(Color color) => $"#{color.R.ToString("X2")}{color.G.ToString("X2")}{color.B.ToString("X2")}";
|
private string ColorToHex(Color color) => $"#{color.R.ToString("X2")}{color.G.ToString("X2")}{color.B.ToString("X2")}";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// converts color to the rgb tuples representation
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="color"></param>
|
||||||
|
/// <returns></returns>
|
||||||
private string ColorToDec(Color color) => $"{(int)color.R}, {(int)color.G}, {(int)color.B}";
|
private string ColorToDec(Color color) => $"{(int)color.R}, {(int)color.G}, {(int)color.B}";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adapted from https://css-tricks.com/snippets/javascript/lighten-darken-color/
|
/// lightens or darkens a color on the given amount
|
||||||
|
/// Based off SASS darken/lighten function
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="col"></param>
|
/// <param name="color"></param>
|
||||||
/// <param name="amt"></param>
|
/// <param name="amount"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private Color LightenDarkenColor(Color col, float amt)
|
private Color LightenDarkenColor(Color color, float amount)
|
||||||
{
|
{
|
||||||
var num = col.ToArgb();
|
int r = color.R + (int)((amount / 100.0f) * color.R);
|
||||||
|
|
||||||
int r = (num >> 16) + (int)(amt * (num >> 16));
|
|
||||||
|
|
||||||
if (r > 255) r = 255;
|
if (r > 255) r = 255;
|
||||||
else if (r < 0) r = 0;
|
else if (r < 0) r = 0;
|
||||||
|
|
||||||
int g = ((num >> 8) & 0x00FF) + (int)(amt * ((num >> 8) & 0x00FF));
|
int g = color.G + (int)((amount / 100.0f) * color.G);
|
||||||
|
|
||||||
if (g > 255) g = 255;
|
if (g > 255) g = 255;
|
||||||
else if (g < 0) g = 0;
|
else if (g < 0) g = 0;
|
||||||
|
|
||||||
int b = (num & 0x0000FF) + (int)(amt * (num & 0x0000FF));
|
int b = color.B + (int)((amount / 100.0f) * color.B);
|
||||||
|
|
||||||
if (b > 255) b = 255;
|
if (b > 255) b = 255;
|
||||||
else if (b < 0) b = 0;
|
else if (b < 0) b = 0;
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
|
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
|
||||||
@Html.ActionLink("IW4MAdmin", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
|
@Html.ActionLink((string)ViewBag.CustomBranding, "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
|
||||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">
|
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">
|
||||||
<span class="navbar-toggler-icon"></span>
|
<span class="navbar-toggler-icon"></span>
|
||||||
</button>
|
</button>
|
||||||
|
@ -60,6 +60,7 @@
|
|||||||
<None Include="wwwroot\js\global.min.js" CopyToPublishDirectory="Always" />
|
<None Include="wwwroot\js\global.min.js" CopyToPublishDirectory="Always" />
|
||||||
<None Include="wwwroot\images\icon.png" CopyToPublishDirectory="Always" />
|
<None Include="wwwroot\images\icon.png" CopyToPublishDirectory="Always" />
|
||||||
<None Include="wwwroot\images\icons\**\*.png" CopyToPublishDirectory="Always" />
|
<None Include="wwwroot\images\icons\**\*.png" CopyToPublishDirectory="Always" />
|
||||||
|
<_ContentIncludedByDefault Remove="wwwroot\css\main.min.css" />
|
||||||
<None Include="wwwroot\lib\open-iconic\font\fonts\open-iconic.ttf" CopyToPublishDirectory="Always" />
|
<None Include="wwwroot\lib\open-iconic\font\fonts\open-iconic.ttf" CopyToPublishDirectory="Always" />
|
||||||
<None Include="wwwroot\lib\open-iconic\font\fonts\open-iconic.woff" CopyToPublishDirectory="Always" />
|
<None Include="wwwroot\lib\open-iconic\font\fonts\open-iconic.woff" CopyToPublishDirectory="Always" />
|
||||||
<None Include="wwwroot\lib\open-iconic\font\fonts\open-iconic.otf" CopyToPublishDirectory="Always" />
|
<None Include="wwwroot\lib\open-iconic\font\fonts\open-iconic.otf" CopyToPublishDirectory="Always" />
|
||||||
|
@ -233,7 +233,7 @@ form *, select {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.nav-tabs .nav-link.active:hover {
|
.nav-tabs .nav-link.active:hover {
|
||||||
opacity: 0.75;
|
background-color: darken($primary, 10%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-tabs .nav-item {
|
.nav-tabs .nav-item {
|
||||||
|
@ -77,7 +77,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.level-bgcolor-owner, .level-bgcolor-6 {
|
.level-bgcolor-owner, .level-bgcolor-6 {
|
||||||
background-color: rgb(0, 122, 204);
|
background-color: $primary;
|
||||||
}
|
}
|
||||||
|
|
||||||
.level-color-8 {
|
.level-color-8 {
|
||||||
@ -140,10 +140,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
#profile_aliases_btn:hover {
|
#profile_aliases_btn:hover {
|
||||||
opacity: 0.75;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.oi:hover {
|
||||||
|
color: darken($primary, 10%) !important;
|
||||||
|
}
|
||||||
|
|
||||||
#profile_aliases {
|
#profile_aliases {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: none;
|
display: none;
|
||||||
|
@ -55,7 +55,7 @@ $('.server-history-row').each(function (index, element) {
|
|||||||
let clientHistory = $(this).data('clienthistory');
|
let clientHistory = $(this).data('clienthistory');
|
||||||
let serverId = $(this).data('serverid');
|
let serverId = $(this).data('serverid');
|
||||||
let maxClients = parseInt($('#server_header_' + serverId + ' .server-maxclients').text());
|
let maxClients = parseInt($('#server_header_' + serverId + ' .server-maxclients').text());
|
||||||
let primaryColor = document.documentElement.style.getPropertyValue('--primary');
|
let primaryColor = window.getComputedStyle(document.body).getPropertyValue('--primary').trim();
|
||||||
let color = $(this).data('online') === 'True' ? primaryColor.endsWith('80') ? primaryColor : primaryColor + '80' : '#ff6060';
|
let color = $(this).data('online') === 'True' ? primaryColor.endsWith('80') ? primaryColor : primaryColor + '80' : '#ff6060';
|
||||||
let width = $('.server-header').first().width();
|
let width = $('.server-header').first().width();
|
||||||
let historyChart = getPlayerHistoryChart(clientHistory, serverId, width, color, maxClients);
|
let historyChart = getPlayerHistoryChart(clientHistory, serverId, width, color, maxClients);
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
if (interval < 1)
|
if (interval < 1)
|
||||||
interval = 1;
|
interval = 1;
|
||||||
|
|
||||||
let primaryColor = document.documentElement.style.getPropertyValue('--primary');
|
let primaryColor = window.getComputedStyle(document.body).getPropertyValue('--primary').trim();
|
||||||
|
|
||||||
return new CanvasJS.Chart(id, {
|
return new CanvasJS.Chart(id, {
|
||||||
backgroundColor: 'transparent',
|
backgroundColor: 'transparent',
|
||||||
|
@ -3,6 +3,7 @@ Version 2.4:
|
|||||||
-added chat message to server on server list view
|
-added chat message to server on server list view
|
||||||
-added recently connected players dropdown option on webfront
|
-added recently connected players dropdown option on webfront
|
||||||
-added "dashboard" to home view with quick stats
|
-added "dashboard" to home view with quick stats
|
||||||
|
-added ability to customize accent color and branding on webfront
|
||||||
-hid flagged status of users on webfront unless logged in
|
-hid flagged status of users on webfront unless logged in
|
||||||
|
|
||||||
Version 2.3:
|
Version 2.3:
|
||||||
|
Loading…
Reference in New Issue
Block a user