From 75ce21597be2342e4ec908902b7f517331e31a82 Mon Sep 17 00:00:00 2001 From: RaidMax Date: Sat, 27 Jul 2019 08:18:49 -0500 Subject: [PATCH] start work to allow custom accent colors --- .gitignore | 2 + Application/ApplicationManager.cs | 1 + Application/Misc/MiddlewareActionHandler.cs | 50 ++++ .../Configuration/ApplicationConfiguration.cs | 6 +- SharedLibraryCore/Interfaces/IManager.cs | 1 + .../Interfaces/IMiddlewareAction.cs | 12 + .../Interfaces/IMiddlewareActionHandler.cs | 13 + .../Controllers/ConfigurationController.cs | 4 +- .../Controllers/DynamicFileController.cs | 37 +++ .../CustomCssAccentMiddlewareAction.cs | 90 ++++++ WebfrontCore/Program.cs | 3 + WebfrontCore/Views/Home/Index.cshtml | 2 +- WebfrontCore/Views/Shared/_Layout.cshtml | 5 +- WebfrontCore/bundleconfig.json | 5 +- WebfrontCore/compilerconfig.json | 4 + .../wwwroot/css/bootstrap-custom.scss | 274 +----------------- WebfrontCore/wwwroot/css/main.scss | 266 +++++++++++++++++ .../wwwroot/css/{profile.css => profile.scss} | 2 +- WebfrontCore/wwwroot/js/server.js | 3 +- WebfrontCore/wwwroot/js/stats.js | 4 +- 20 files changed, 499 insertions(+), 285 deletions(-) create mode 100644 Application/Misc/MiddlewareActionHandler.cs create mode 100644 SharedLibraryCore/Interfaces/IMiddlewareAction.cs create mode 100644 SharedLibraryCore/Interfaces/IMiddlewareActionHandler.cs create mode 100644 WebfrontCore/Controllers/DynamicFileController.cs create mode 100644 WebfrontCore/Middleware/CustomCssAccentMiddlewareAction.cs create mode 100644 WebfrontCore/wwwroot/css/main.scss rename WebfrontCore/wwwroot/css/{profile.css => profile.scss} (99%) diff --git a/.gitignore b/.gitignore index 07c28090..159ef61d 100644 --- a/.gitignore +++ b/.gitignore @@ -236,3 +236,5 @@ launchSettings.json /Plugins/ScriptPlugins/VpnDetectionPrivate.js **/Master/env_master /GameLogServer/log_env +/WebfrontCore/wwwroot/css/main.min.css +/WebfrontCore/wwwroot/css/main.css diff --git a/Application/ApplicationManager.cs b/Application/ApplicationManager.cs index f81ebf63..f5be0294 100644 --- a/Application/ApplicationManager.cs +++ b/Application/ApplicationManager.cs @@ -45,6 +45,7 @@ namespace IW4MAdmin.Application public CancellationToken CancellationToken => _tokenSource.Token; public string ExternalIPAddress { get; private set; } public bool IsRestartRequested { get; private set; } + public IMiddlewareActionHandler MiddlewareActionHandler { get; private set; } = new MiddlewareActionHandler(); static ApplicationManager Instance; private readonly List Commands; private readonly List MessageTokens; diff --git a/Application/Misc/MiddlewareActionHandler.cs b/Application/Misc/MiddlewareActionHandler.cs new file mode 100644 index 00000000..8b5a12ad --- /dev/null +++ b/Application/Misc/MiddlewareActionHandler.cs @@ -0,0 +1,50 @@ +using SharedLibraryCore.Interfaces; +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; + +namespace IW4MAdmin.Application.Misc +{ + class MiddlewareActionHandler : IMiddlewareActionHandler + { + private static readonly IDictionary> _actions = new Dictionary>(); + + public async Task Execute(T value, string name = null) + { + string key = string.IsNullOrEmpty(name) ? typeof(T).ToString() : name; + + if (_actions.ContainsKey(key)) + { + foreach (var action in _actions[key]) + { + try + { + value = await ((IMiddlewareAction)action).Invoke(value); + } + // todo: probably log this somewhere + catch { } + } + + return value; + } + + return value; + } + + public void Register(T actionType, IMiddlewareAction action, string name = null) + { + string key = string.IsNullOrEmpty(name) ? typeof(T).ToString() : name; + + if (_actions.ContainsKey(key)) + { + _actions[key].Add(action); + } + + else + { + _actions.Add(key, new[] { action }); + } + } + } +} diff --git a/SharedLibraryCore/Configuration/ApplicationConfiguration.cs b/SharedLibraryCore/Configuration/ApplicationConfiguration.cs index 09ca66c5..0d318b7f 100644 --- a/SharedLibraryCore/Configuration/ApplicationConfiguration.cs +++ b/SharedLibraryCore/Configuration/ApplicationConfiguration.cs @@ -10,13 +10,17 @@ namespace SharedLibraryCore.Configuration { [LocalizedDisplayName("SETUP_ENABLE_WEBFRONT")] - [ConfigurationLinked("WebfrontBindUrl", "ManualWebfrontUrl")] + [ConfigurationLinked("WebfrontBindUrl", "ManualWebfrontUrl", "WebfrontPrimaryColor", "WebfrontSecondaryColor")] public bool EnableWebFront { get; set; } [LocalizedDisplayName("WEBFRONT_CONFIGURATION_BIND_URL")] public string WebfrontBindUrl { get; set; } [ConfigurationOptional] [LocalizedDisplayName("WEBFRONT_CONFIGURATION_MANUAL_URL")] public string ManualWebfrontUrl { get; set; } + [ConfigurationOptional] + public string WebfrontPrimaryColor { get; set; } + [ConfigurationOptional] + public string WebfrontSecondaryColor { get; set; } [LocalizedDisplayName("SETUP_ENABLE_MULTIOWN")] public bool EnableMultipleOwners { get; set; } diff --git a/SharedLibraryCore/Interfaces/IManager.cs b/SharedLibraryCore/Interfaces/IManager.cs index 9014a88b..fd62a0a5 100644 --- a/SharedLibraryCore/Interfaces/IManager.cs +++ b/SharedLibraryCore/Interfaces/IManager.cs @@ -46,6 +46,7 @@ namespace SharedLibraryCore.Interfaces /// Task> ExecuteSharedDatabaseOperation(string operationName); void RegisterSharedDatabaseOperation(Task operation, string operationName); + IMiddlewareActionHandler MiddlewareActionHandler { get; } IRConParser GenerateDynamicRConParser(); IEventParser GenerateDynamicEventParser(); string Version { get;} diff --git a/SharedLibraryCore/Interfaces/IMiddlewareAction.cs b/SharedLibraryCore/Interfaces/IMiddlewareAction.cs new file mode 100644 index 00000000..329bb75f --- /dev/null +++ b/SharedLibraryCore/Interfaces/IMiddlewareAction.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; + +namespace SharedLibraryCore.Interfaces +{ + public interface IMiddlewareAction + { + Task Invoke(T original); + } +} diff --git a/SharedLibraryCore/Interfaces/IMiddlewareActionHandler.cs b/SharedLibraryCore/Interfaces/IMiddlewareActionHandler.cs new file mode 100644 index 00000000..88877466 --- /dev/null +++ b/SharedLibraryCore/Interfaces/IMiddlewareActionHandler.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; + +namespace SharedLibraryCore.Interfaces +{ + public interface IMiddlewareActionHandler + { + void Register(T actionType, IMiddlewareAction action, string name = null); + Task Execute(T value, string name = null); + } +} diff --git a/WebfrontCore/Controllers/ConfigurationController.cs b/WebfrontCore/Controllers/ConfigurationController.cs index 53883142..d0acc6f5 100644 --- a/WebfrontCore/Controllers/ConfigurationController.cs +++ b/WebfrontCore/Controllers/ConfigurationController.cs @@ -12,7 +12,7 @@ namespace WebfrontCore.Controllers { public IActionResult Edit() { - if (Client.Level != SharedLibraryCore.Database.Models.EFClient.Permission.Owner) + if (Client.Level < SharedLibraryCore.Database.Models.EFClient.Permission.Owner) { return Unauthorized(); } @@ -23,7 +23,7 @@ namespace WebfrontCore.Controllers [HttpPost] public async Task Edit(ApplicationConfiguration newConfiguration, bool addNewServer = false, bool shouldSave = false) { - if (Client.Level != SharedLibraryCore.Database.Models.EFClient.Permission.Owner) + if (Client.Level < SharedLibraryCore.Database.Models.EFClient.Permission.Owner) { return Unauthorized(); } diff --git a/WebfrontCore/Controllers/DynamicFileController.cs b/WebfrontCore/Controllers/DynamicFileController.cs new file mode 100644 index 00000000..c0425ef4 --- /dev/null +++ b/WebfrontCore/Controllers/DynamicFileController.cs @@ -0,0 +1,37 @@ +using Microsoft.AspNetCore.Mvc; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace WebfrontCore.Controllers +{ + [Route("dynamic")] + public class DynamicFileController : BaseController + { + private static readonly IDictionary _fileCache = new Dictionary(); + + [Route("css/{fileName}")] + public async Task Css(string fileName) + { + if (fileName.EndsWith(".css")) + { + if (!_fileCache.ContainsKey(fileName)) + { +#if DEBUG + string path = $"X:\\IW4MAdmin\\WebfrontCore\\wwwroot\\css\\{fileName}"; +#else + string path = $"wwwroot\\css\\{fileName}"; +#endif + string cssData = await System.IO.File.ReadAllTextAsync(path); + cssData = await Manager.MiddlewareActionHandler.Execute(cssData, "custom_css_accent"); + _fileCache.Add(fileName, cssData); + } + + return Content(_fileCache[fileName], "text/css"); + } + + return StatusCode(400); + } + } +} diff --git a/WebfrontCore/Middleware/CustomCssAccentMiddlewareAction.cs b/WebfrontCore/Middleware/CustomCssAccentMiddlewareAction.cs new file mode 100644 index 00000000..4f6e79da --- /dev/null +++ b/WebfrontCore/Middleware/CustomCssAccentMiddlewareAction.cs @@ -0,0 +1,90 @@ +using SharedLibraryCore.Interfaces; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Globalization; +using System.Linq; +using System.Threading.Tasks; + +namespace WebfrontCore.Middleware +{ + public class CustomCssAccentMiddlewareAction : IMiddlewareAction + { + private readonly Color _primaryColor; + private readonly Color _secondaryColor; + private readonly Color _originalPrimaryColor; + private readonly Color _originalSecondaryColor; + + public CustomCssAccentMiddlewareAction(string originalPrimaryColor, string originalSecondaryColor, string primaryColor, string secondaryColor) + { + _originalPrimaryColor = Color.FromArgb(Convert.ToInt32(originalPrimaryColor.Substring(1).ToString(), 16)); + _originalSecondaryColor = Color.FromArgb(Convert.ToInt32(originalSecondaryColor.Substring(1).ToString(), 16)); + _primaryColor = string.IsNullOrEmpty(primaryColor) ? _originalPrimaryColor : Color.FromArgb(Convert.ToInt32(primaryColor.Substring(1).ToString(), 16)); + _secondaryColor = string.IsNullOrEmpty(secondaryColor) ? _originalSecondaryColor : Color.FromArgb(Convert.ToInt32(secondaryColor.Substring(1).ToString(), 16)); + } + + public async Task Invoke(string original) + { + string originalPrimaryHex = ColorToHex(_originalPrimaryColor); + string originalPrimaryDec = ColorToDec(_originalPrimaryColor); + string originalSecondaryHex = ColorToHex(_originalSecondaryColor); + string originalSecondaryDec = ColorToDec(_originalSecondaryColor); + + string primaryHex = ColorToHex(_primaryColor); + string primaryDec = ColorToDec(_primaryColor); + 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); + } + + private string ColorToHex(Color color) => $"#{color.R.ToString("X2")}{color.G.ToString("X2")}{color.B.ToString("X2")}"; + private string ColorToDec(Color color) => $"{(int)color.R}, {(int)color.G}, {(int)color.B}"; + + /// + /// Adapted from https://css-tricks.com/snippets/javascript/lighten-darken-color/ + /// + /// + /// + /// + private Color LightenDarkenColor(Color col, float amt) + { + var num = col.ToArgb(); + + int r = (num >> 16) + (int)(amt * (num >> 16)); + + if (r > 255) r = 255; + else if (r < 0) r = 0; + + int g = ((num >> 8) & 0x00FF) + (int)(amt * ((num >> 8) & 0x00FF)); + + if (g > 255) g = 255; + else if (g < 0) g = 0; + + int b = (num & 0x0000FF) + (int)(amt * (num & 0x0000FF)); + + if (b > 255) b = 255; + else if (b < 0) b = 0; + + return Color.FromArgb(r, g, b); + } + } +} diff --git a/WebfrontCore/Program.cs b/WebfrontCore/Program.cs index 8b5fd970..c37c5f73 100644 --- a/WebfrontCore/Program.cs +++ b/WebfrontCore/Program.cs @@ -4,6 +4,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using SharedLibraryCore.Interfaces; +using WebfrontCore.Middleware; namespace WebfrontCore { @@ -19,6 +20,8 @@ namespace WebfrontCore public static Task Init(IManager mgr, CancellationToken cancellationToken) { Manager = mgr; + var config = Manager.GetApplicationSettings().Configuration(); + Manager.MiddlewareActionHandler.Register(null, new CustomCssAccentMiddlewareAction("#007ACC", "#fd7e14", config.WebfrontPrimaryColor, config.WebfrontSecondaryColor), "custom_css_accent"); return BuildWebHost().RunAsync(cancellationToken); } diff --git a/WebfrontCore/Views/Home/Index.cshtml b/WebfrontCore/Views/Home/Index.cshtml index e185c639..f523f6a3 100644 --- a/WebfrontCore/Views/Home/Index.cshtml +++ b/WebfrontCore/Views/Home/Index.cshtml @@ -4,7 +4,7 @@ string formatTranslation(string translationKey, params object[] values) { var split = loc[translationKey].Split("::"); - return $"{SharedLibraryCore.Utilities.FormatExt(split[0], values)}{split[1]}"; + return split.Count() == 2 ? $"{SharedLibraryCore.Utilities.FormatExt(split[0], values)}{split[1]}" : translationKey; } }
diff --git a/WebfrontCore/Views/Shared/_Layout.cshtml b/WebfrontCore/Views/Shared/_Layout.cshtml index f1e02afd..90617f18 100644 --- a/WebfrontCore/Views/Shared/_Layout.cshtml +++ b/WebfrontCore/Views/Shared/_Layout.cshtml @@ -18,12 +18,11 @@ - + - - + diff --git a/WebfrontCore/bundleconfig.json b/WebfrontCore/bundleconfig.json index dc76ee1e..996c2e9e 100644 --- a/WebfrontCore/bundleconfig.json +++ b/WebfrontCore/bundleconfig.json @@ -5,9 +5,8 @@ "outputFileName": "wwwroot/css/global.min.css", // An array of relative input file paths. Globbing patterns supported "inputFiles": [ - "wwwroot/css/bootstrap-custom.css", - "wwwroot/lib/open-iconic/font/css/open-iconic-bootstrap.css", - "wwwroot/css/profile.css" + "wwwroot/css/main.css", + "wwwroot/lib/open-iconic/font/css/open-iconic-bootstrap.css" ] }, { diff --git a/WebfrontCore/compilerconfig.json b/WebfrontCore/compilerconfig.json index 11f3df7f..f3489eac 100644 --- a/WebfrontCore/compilerconfig.json +++ b/WebfrontCore/compilerconfig.json @@ -6,5 +6,9 @@ { "outputFile": "wwwroot/js/server.es5.js", "inputFile": "wwwroot/js/server.js" + }, + { + "outputFile": "wwwroot/css/main.css", + "inputFile": "wwwroot/css/main.scss" } ] \ No newline at end of file diff --git a/WebfrontCore/wwwroot/css/bootstrap-custom.scss b/WebfrontCore/wwwroot/css/bootstrap-custom.scss index 4cf86c6f..2ce4d80d 100644 --- a/WebfrontCore/wwwroot/css/bootstrap-custom.scss +++ b/WebfrontCore/wwwroot/css/bootstrap-custom.scss @@ -7,7 +7,7 @@ $primary: $blue !default; $secondary: $orange !default; $light: rgb(204, 204, 204) !default; $dark: rgb(24, 24, 24) !default; -$body-bg: rgb(34,34,34) !default; +$body-bg: rgb(34, 34, 34) !default; $big-dark: #191919; $body-color: $white !default; $link-color: $white !default; @@ -26,274 +26,4 @@ $navbar-toggler-font-size: $h5-font-size !default; $navbar-dark-hover-color: $primary !default; -@import '../lib/bootstrap/scss/bootstrap.scss'; - - -/*custom variables*/ - - -/* bootstrap overrides */ - -.navbar-nav .nav-link:hover { - background-color: $body-bg; -} - -nav.navbar-dark { - border-bottom: 1px solid $secondary; -} - -a.nav-link { - padding: $spacer * 1.5; -} - -.server-history-row { - height: 100px; - padding: 0 !important; -} - -.canvasjs-chart-credit { - display: none; -} - -.table thead th, -.table th, -.table td { - border: none; -} - -.server-history, -.server-activity, -#mobile_seperator, -.border-bottom { - border-bottom: 1px solid $primary !important; -} - -.server-history { - background-color: $big-dark; -} - -.border-top { - border-top: 1px solid $primary !important; -} - -#client_search { - background-color: #222222 !important; - border-radius: 0; - border: 1px solid $orange; - color: $white; -} - -.server-join-button, .server-join-button:hover { - color: $white !important; -} - -a.link-inverse { - color: $primary; -} - -a.link-inverse:hover { - color: $white; -} - -@media (min-width: 768px) { - .d-md-table-header-group { - display: table-header-group !important; - } -} - -@media (min-width: 992px) { - .d-lg-table-header-group { - display: table-header-group !important; - } -} - -#console_command_response { - min-height: 20rem; -} - -#console_command_response hr { - border-color: #6c757d; -} - -#console .form-control, #console button { - border-radius: 0; - border-color: $primary; - border-left: 0; - border-right: 0; -} - -.close { - text-shadow: none !important; -} - -.modal-footer { - border-top-color: $orange; -} - -.modal-header { - border-bottom-color: $orange; -} - -form *, select { - border-radius: 0 !important; -} - -#penalty_filter_selection { - border-left: none !important; - border-right: none !important; - border-bottom: none !important; - border-top: 2px solid rgba(0, 122, 204, 0.5) !important; -} - -.oi-fix-navbar { - line-height: 1.5 !important; - top: 0 !important; - font-size: 1rem !important; -} - -@-webkit-keyframes rotation { - from { - -webkit-transform: rotate(359deg); - } - - to { - -webkit-transform: rotate(0deg); - } -} - -.layout-loading-icon { - position: fixed !important; - left: 50%; - top: 50% !important; - margin-left: -37px; - margin-top: -37px; - color: $primary; - z-index: 100; - font-size: 4rem; - -webkit-animation: rotation 1s infinite linear; - background-color: $black; - background-color: rgba(0, 0,0, 0.5); - border-radius: 40px; - padding: 5px; - visibility: hidden; -} - -.loader-load-more { - border-radius: 0; -} - -.input-border-transition { - -webkit-transition: border 500ms ease-out; - -moz-transition: border 500ms ease-out; - -o-transition: border 500ms ease-out; -} - -.input-text-danger { - border-color: $red !important; -} - -.form-control:focus { - box-shadow: none; - -webkit-box-shadow: none; -} - -.dropdown-item { - border-bottom: 1px solid $secondary; - margin-top: -3px; -} - -.striped > div:nth-child(even) { - background-color: rgba(0, 0, 0, 0.125); -} - -.striped > div:nth-child(odd) { - background-color: rgba(0, 0, 0, 0.2); -} - -.client-rating-graph { - min-height: 100px; -} - -.client-rating-icon { -} - -.client-rating-change-up, .client-rating-change-down { - font-size: 0.75rem; -} - -.client-rating-change-amount { - font-size: 1rem; -} - -.client-message, .automated-penalty-info-detailed, .oi { - cursor: pointer; -} - -#footer_text { - font-size: 0.85rem; -} - -.footer-mobile { - position: fixed; - bottom: 1em; - right: 1em; -} - -.nav-tabs, .nav-tabs .nav-link.active { - color: $white; - color: $white !important; - border: none; -} - -.nav-tabs .nav-link:hover { - color: $blue; - background-color: rgba(24, 24, 24, 0.75); - border: none; -} - -.nav-tabs .nav-link { - border-radius: 0; - padding: 1.5rem; - color: #6c757d; - border: none; - min-width: 20rem; - background-color: #181818; -} - -.nav-tabs .nav-link.active { - border: none; - background-color: $blue; -} - -.nav-tabs .nav-link.active:hover { - background-color: rgba(0, 122, 204, 0.75); -} - -.nav-tabs .nav-item { - margin-bottom: 0; -} - -.mt-n1 { - margin-top: -0.25rem !important; -} - -.mt-n2 { - margin-top: -0.5rem !important; -} - -/* Configuration */ -.configuration-form input[type='text'], .configuration-form input[type='number'], input.text-box { - border: 1px solid $orange; -} - -.hide { - display: none; -} - -.client-location-flag { - width: 3rem; - height: 1.5rem; - background-image: url('/images/radar/hud_weapons/hud_neutral.png'); - background-size: contain; - background-repeat: no-repeat -} +@import '../lib/bootstrap/scss/bootstrap.scss'; \ No newline at end of file diff --git a/WebfrontCore/wwwroot/css/main.scss b/WebfrontCore/wwwroot/css/main.scss new file mode 100644 index 00000000..6395731a --- /dev/null +++ b/WebfrontCore/wwwroot/css/main.scss @@ -0,0 +1,266 @@ +@import 'bootstrap-custom.scss'; +@import 'profile.scss'; + +.navbar-nav .nav-link:hover { + background-color: $body-bg; +} + +nav.navbar-dark { + border-bottom: 1px solid $secondary; +} + +a.nav-link { + padding: $spacer * 1.5; +} + +.server-history-row { + height: 100px; + padding: 0 !important; +} + +.canvasjs-chart-credit { + display: none; +} + +.table thead th, +.table th, +.table td { + border: none; +} + +.server-history, +.server-activity, +#mobile_seperator, +.border-bottom { + border-bottom: 1px solid $primary !important; +} + +.server-history { + background-color: $big-dark; +} + +.border-top { + border-top: 1px solid $primary !important; +} + +#client_search { + background-color: #222222 !important; + border-radius: 0; + border: 1px solid $orange; + color: $white; +} + +.server-join-button, .server-join-button:hover { + color: $white !important; +} + +a.link-inverse { + color: $primary; +} + +a.link-inverse:hover { + color: $white; +} + +@media (min-width: 768px) { + .d-md-table-header-group { + display: table-header-group !important; + } +} + +@media (min-width: 992px) { + .d-lg-table-header-group { + display: table-header-group !important; + } +} + +#console_command_response { + min-height: 20rem; +} + +#console_command_response hr { + border-color: #6c757d; +} + +#console .form-control, #console button { + border-radius: 0; + border-color: $primary; + border-left: 0; + border-right: 0; +} + +.close { + text-shadow: none !important; +} + +.modal-footer { + border-top-color: $orange; +} + +.modal-header { + border-bottom-color: $orange; +} + +form *, select { + border-radius: 0 !important; +} + +#penalty_filter_selection { + border-left: none !important; + border-right: none !important; + border-bottom: none !important; + border-top: 2px solid $blue !important; +} + +.oi-fix-navbar { + line-height: 1.5 !important; + top: 0 !important; + font-size: 1rem !important; +} + +@-webkit-keyframes rotation { + from { + -webkit-transform: rotate(359deg); + } + + to { + -webkit-transform: rotate(0deg); + } +} + +.layout-loading-icon { + position: fixed !important; + left: 50%; + top: 50% !important; + margin-left: -37px; + margin-top: -37px; + color: $primary; + z-index: 100; + font-size: 4rem; + -webkit-animation: rotation 1s infinite linear; + background-color: $black; + background-color: rgba(0, 0,0, 0.5); + border-radius: 40px; + padding: 5px; + visibility: hidden; +} + +.loader-load-more { + border-radius: 0; +} + +.input-border-transition { + -webkit-transition: border 500ms ease-out; + -moz-transition: border 500ms ease-out; + -o-transition: border 500ms ease-out; +} + +.input-text-danger { + border-color: $red !important; +} + +.form-control:focus { + box-shadow: none; + -webkit-box-shadow: none; +} + +.dropdown-item { + border-bottom: 1px solid $secondary; + margin-top: -3px; +} + +.striped > div:nth-child(even) { + background-color: rgba(0, 0, 0, 0.125); +} + +.striped > div:nth-child(odd) { + background-color: rgba(0, 0, 0, 0.2); +} + +.client-rating-graph { + min-height: 100px; +} + +.client-rating-icon { +} + +.client-rating-change-up, .client-rating-change-down { + font-size: 0.75rem; +} + +.client-rating-change-amount { + font-size: 1rem; +} + +.client-message, .automated-penalty-info-detailed, .oi { + cursor: pointer; +} + +#footer_text { + font-size: 0.85rem; +} + +.footer-mobile { + position: fixed; + bottom: 1em; + right: 1em; +} + +.nav-tabs, .nav-tabs .nav-link.active { + color: $white; + color: $white !important; + border: none; +} + +.nav-tabs .nav-link:hover { + color: $blue; + background-color: rgba(24, 24, 24, 0.75); + border: none; +} + +.nav-tabs .nav-link { + border-radius: 0; + padding: 1.5rem; + color: #6c757d; + border: none; + min-width: 20rem; + background-color: #181818; +} + +.nav-tabs .nav-link.active { + border: none; + background-color: $blue; +} + +.nav-tabs .nav-link.active:hover { + opacity: 0.75; +} + +.nav-tabs .nav-item { + margin-bottom: 0; +} + +.mt-n1 { + margin-top: -0.25rem !important; +} + +.mt-n2 { + margin-top: -0.5rem !important; +} + +/* Configuration */ +.configuration-form input[type='text'], .configuration-form input[type='number'], input.text-box { + border: 1px solid $orange; +} + +.hide { + display: none; +} + +.client-location-flag { + width: 3rem; + height: 1.5rem; + background-image: url('/images/radar/hud_weapons/hud_neutral.png'); + background-size: contain; + background-repeat: no-repeat +} diff --git a/WebfrontCore/wwwroot/css/profile.css b/WebfrontCore/wwwroot/css/profile.scss similarity index 99% rename from WebfrontCore/wwwroot/css/profile.css rename to WebfrontCore/wwwroot/css/profile.scss index 64127515..f4e50fc2 100644 --- a/WebfrontCore/wwwroot/css/profile.css +++ b/WebfrontCore/wwwroot/css/profile.scss @@ -135,7 +135,7 @@ } #profile_aliases_btn { - color: rgb(0, 122, 204); + color: $blue; cursor: pointer; } diff --git a/WebfrontCore/wwwroot/js/server.js b/WebfrontCore/wwwroot/js/server.js index 3599fd18..966dfc00 100644 --- a/WebfrontCore/wwwroot/js/server.js +++ b/WebfrontCore/wwwroot/js/server.js @@ -55,7 +55,8 @@ $('.server-history-row').each(function (index, element) { let clientHistory = $(this).data('clienthistory'); let serverId = $(this).data('serverid'); let maxClients = parseInt($('#server_header_' + serverId + ' .server-maxclients').text()); - let color = $(this).data('online') === 'True' ? 'rgba(0, 122, 204, 0.432)' : '#ff6060'; + let primaryColor = document.documentElement.style.getPropertyValue('--primary'); + let color = $(this).data('online') === 'True' ? primaryColor.endsWith('80') ? primaryColor : primaryColor + '80' : '#ff6060'; let width = $('.server-header').first().width(); let historyChart = getPlayerHistoryChart(clientHistory, serverId, width, color, maxClients); historyChart.render(); diff --git a/WebfrontCore/wwwroot/js/stats.js b/WebfrontCore/wwwroot/js/stats.js index d6a711a3..b3de7d3a 100644 --- a/WebfrontCore/wwwroot/js/stats.js +++ b/WebfrontCore/wwwroot/js/stats.js @@ -20,6 +20,8 @@ if (interval < 1) interval = 1; + let primaryColor = document.documentElement.style.getPropertyValue('--primary'); + return new CanvasJS.Chart(id, { backgroundColor: 'transparent', height: height, @@ -55,7 +57,7 @@ }, data: [{ type: 'splineArea', - color: 'rgba(0, 122, 204, 0.25)', + color: primaryColor.endsWith('80') ? primaryColor : primaryColor + '40', markerSize: 3.5, dataPoints: fixedData }]