1
0
mirror of https://github.com/RaidMax/IW4M-Admin.git synced 2025-06-10 15:20:48 -05:00

huge commit for webfront facelift

This commit is contained in:
RaidMax
2022-04-19 18:43:58 -05:00
parent 7b78e0803a
commit d5b4c60e5a
105 changed files with 2981 additions and 2545 deletions

View File

@ -1,26 +1,28 @@
@model IEnumerable<WebfrontCore.ViewModels.ScoreboardInfo>
@using WebfrontCore.ViewModels
@model IEnumerable<WebfrontCore.ViewModels.ScoreboardInfo>
<ul class="nav nav-tabs border-top border-bottom nav-fill row" role="tablist" id="scoreboard_servers">
@{ var i = 0; }
@foreach (var server in Model)
{
<li class="nav-item">
<a class="nav-link" href="#server_@server.ServerId" role="tab" data-toggle="tab" id="server_@(server.ServerId)_nav" data-serverid="@server.ServerId">
<color-code value="@server.ServerName"></color-code>
</a>
</li>
i++;
}
</ul>
<div class="tab-content border-bottom row">
@{ i = 0; }
@foreach (var server in Model)
{
<div role="tabpanel" class="scoreboard-container tab-pane striped flex-fill" id="server_@server.ServerId" data-server-id="@server.ServerId">
@await Html.PartialAsync("_Scoreboard", server)
</div>
i++;
<div class="content mt-20 row">
<div class="col-12 col-lg-9 col-xl-10">
@if (Model is not null)
{
<div class=" scoreboard-container" data-server-id="@ViewBag.SelectedServerId">
@await Html.PartialAsync("_Scoreboard", Model.FirstOrDefault(server => server.ServerId == ViewBag.SelectedServerId) ?? Model.First())
</div>
}
</div>
@{
var menuItems = new SideContextMenuItems
{
MenuTitle = "Server", Items = Model.Select(server => new SideContextMenuItem
{
IsLink = true,
Reference = Url.Action("Scoreboard", "Server", new { serverId = server.ServerId }),
Title = server.ServerName.StripColors(),
IsActive = ViewBag.SelectedServerId == server.ServerId
}).ToList()
};
}
<partial name="_SideContextMenu" for="@menuItems"></partial>
</div>
@section scripts {

View File

@ -2,146 +2,81 @@
@{
Layout = null;
int half = Model.ClientCount == 0 || Model.Players.Count == 0 ? 0 : (int)Math.Ceiling(Model.ClientCount / 2.0);
}
<div class="col-12 col-md-7 d-none d-md-block">
@{
for (int i = 0; i < Model.ChatHistory.Count; i++)
var half = Model.ClientCount == 0 || Model.Players.Count == 0 ? 0 : (int)Math.Ceiling(Model.ClientCount / 2.0);
var groupedClients = Model.Players.Select((client, i) => new { index = i, client })
.OrderBy(client => client.client.Name)
.GroupBy(client => client.index >= half).Select((group, index) => new
{
if (Model.ChatHistory[i] == null ||
Model.ChatHistory[i].Message == null ||
Model.ChatHistory[i].Name == null)
{
continue;
}
group,
index
}).ToList();
string message = Model.ChatHistory[i].IsHidden && !ViewBag.Authorized ? Model.ChatHistory[i].HiddenMessage : Model.ChatHistory[i].Message;
if (Model.ChatHistory[i].Message == "CONNECTED")
{
<span class="text-light">
<span class="oi oi-account-login mr-2 text-success"> </span>
<color-code value="@Model.ChatHistory[i].Name"></color-code>
</span><br />
}
if (Model.ChatHistory[i].Message == "DISCONNECTED")
{
<span class="text-light">
<span class="oi oi-account-logout mr-2 text-danger"> </span>
<color-code value="@Model.ChatHistory[i].Name"></color-code>
</span><br />
}
if (Model.ChatHistory[i].Message != "CONNECTED" && Model.ChatHistory[i].Message != "DISCONNECTED")
{
<span class="text-light">
<color-code value="@Model.ChatHistory[i].Name"></color-code>
</span>
<span>
&mdash;
<color-code value="@message.CapClientName(48)"></color-code>
</span><br />
}
}
string GetIconForState(string messageState)
{
return messageState switch
{
"CONNECTED" => "oi-account-login text-success mr-5",
"DISCONNECTED" => "oi-account-logout text-danger mr-5",
_ => ""
};
}
</div>
<div class="col-md-5">
<div class="row" style="overflow-wrap: anywhere">
<div class="col-6 text-left text-md-right">
@{
for (int i = 0; i < half; i++)
{
if (i > Model.Players.Count - 1)
}
<div class="pt-15 pl-15 pr-15 d-flex flex-wrap flex-column flex-md-row justify-content-between w-full w-auto-lg">
@if (groupedClients.Count > 0)
{
<div class="flex-fill flex-lg-grow-0 w-half-md mr-md-10 mb-md-10">
@foreach (var chat in Model.ChatHistory)
{
var message = chat.IsHidden && !ViewBag.Authorized ? chat.HiddenMessage : chat.Message;
var stateIcon = GetIconForState(chat.Message);
<div>
<i class="oi @stateIcon"></i>
<span>
<color-code value="@chat.Name"></color-code>
</span>
@if (stateIcon == "")
{
continue;
<span class="text-truncate">
&mdash;
<span class="text-white-dm text-black-lm">
<color-code value="@message?.CapClientName(48)"></color-code>
</span>
</span>
}
string levelColorClass = !ViewBag.Authorized ? "" : $"level-color-{Model.Players[i].LevelInt}";
<div class="d-inline-flex">
@if (ViewBag.Authorized)
{
<div class="oi oi-circle-x ml-0 mr-1 profile-action action-kick-button d-inline d-md-none" data-action="kick" data-action-id="@Model.Players[i].ClientId" aria-hidden="true"></div>
}
<a asp-controller="Client" asp-action="ProfileAsync" asp-route-id="@Model.Players[i].ClientId" class="@levelColorClass">
<color-code value="@Model.Players[i].Name"></color-code>
</a>
@if (ViewBag.Authorized)
{
<div class="oi oi-circle-x ml-1 profile-action action-kick-button d-none d-md-inline" data-action="kick" data-action-id="@Model.Players[i].ClientId" aria-hidden="true"></div>
}
</div>
<br />
}
</div>
}
<hr class="d-block d-md-none"/>
</div>
<div class="col-6 text-right w-50">
@{
for (int i = half; i < Math.Min(Model.ClientCount, Model.Players.Count); i++)
}
<div class="d-flex flex-row flex-fill flex-lg-grow-0 w-half-md">
@foreach (var clientIndex in groupedClients)
{
<div class="@(clientIndex.index == 1 ? "pl-md-10 text-right" : "pr-md-10") flex-fill">
@foreach (var client in clientIndex.group)
{
if (i > Model.Players.Count - 1)
{
continue;
}
string levelColorClass = !ViewBag.Authorized ? "" : $"level-color-{Model.Players[i].LevelInt}";
<div>
<a asp-controller="Client" asp-action="ProfileAsync" asp-route-id="@Model.Players[i].ClientId" class="@levelColorClass">
<color-code value="@Model.Players[i].Name"></color-code>
var levelColorClass = !ViewBag.Authorized || client.client.LevelInt == 0 ? "text-light-dm text-dark-lm" : $"level-color-{client.client.LevelInt}";
<div class="d-flex @(clientIndex.index == 1 ? "flex-row-reverse" : "") w-xl-150">
<has-permission entity="AdminMenu" required-permission="Update">
<a href="#actionModal" class="profile-action" data-action="kick" data-action-id="@client.client.ClientId" aria-hidden="true">
<i class="oi oi-circle-x font-size-12 @levelColorClass"></i>
</a>
</has-permission>
<a asp-controller="Client" asp-action="Profile" asp-route-id="@client.client.ClientId" class="@(clientIndex.index == 1 ? "mr-5" : "ml-5") @levelColorClass no-decoration">
<color-code value="@client.client.Name"></color-code>
</a>
@if (ViewBag.Authorized)
{
<span class="oi oi-circle-x profile-action align-baseline action-kick-button flex-column mt-0" data-action="kick" data-action-id="@Model.Players[i].ClientId" aria-hidden="true"></span>
}
<br />
</div>
}
}
</div>
</div>
}
@if (groupedClients.Count > 0)
{
<br/>
}
</div>
</div>
@if (Model.ChatHistory.Count > 0)
{
<div class="w-100 border-bottom d-md-none d-block mt-1 mb-1"></div>
}
<div class="col-12 col-md-8 d-md-none d-block text-left">
@{
for (int i = 0; i < Model.ChatHistory.Count; i++)
{
if (Model.ChatHistory[i] == null ||
Model.ChatHistory[i].Message == null ||
Model.ChatHistory[i].Name == null)
{
continue;
}
string message = Model.ChatHistory[i].IsHidden && !ViewBag.Authorized ? Model.ChatHistory[i].HiddenMessage : Model.ChatHistory[i].Message;
if (Model.ChatHistory[i].Message == "CONNECTED")
{
<span class="text-light">
<span class="oi oi-account-login mr-2 text-success"> </span>
<color-code value="@Model.ChatHistory[i].Name"></color-code>
</span><br />
}
if (Model.ChatHistory[i].Message == "DISCONNECTED")
{
<span class="text-light">
<span class="oi oi-account-logout mr-2 text-danger"> </span>
<color-code value="@Model.ChatHistory[i].Name"></color-code>
</span><br />
}
if (Model.ChatHistory[i].Message != "CONNECTED" && Model.ChatHistory[i].Message != "DISCONNECTED")
{
<span class="text-light">
<color-code value="@Model.ChatHistory[i].Name"></color-code>
</span>
<span>
&mdash;
<color-code value="@message.CapClientName(48)"></color-code>
</span><br />
}
}
}
</div>

View File

@ -1,5 +1,6 @@
@using WebfrontCore.ViewModels
@using System.Globalization
@using SharedLibraryCore.Database.Models
@model WebfrontCore.ViewModels.ScoreboardInfo
@{
Layout = null;
@ -16,17 +17,29 @@
{
if (propertyName == (Model.OrderByKey ?? nameof(ClientScoreboardInfo.Score)))
{
return Model.ShouldOrderDescending ? "<span class=\"ml-2\">▼</span>" : "<span class=\"ml-2\">▲</span>";
return Model.ShouldOrderDescending ? "<span class=\"ml-5 font-size-12\">▼</span>" : "<span class=\"ml-5 font-size-12\">▲</span>";
}
return null;
}
string GetTeamBackgroundColorClass(ClientScoreboardInfo client)
{
return $"team-{client.Team.ToString().ToLower()}-bg {(client.Team == EFClient.TeamType.Unknown ? "bg-dark-dm bg-light-lm" : "")}";
}
}
<table class="table thead-light bg-dark mb-0 table-responsive-md table-sort"
<h4 class="content-title mb-0">
Scoreboard
</h4>
<span class="text-muted">
<color-code value="@Model.ServerName"></color-code>
</span>
<table class="table table-sort mt-15"
data-sort-column="@(Model.OrderByKey ?? nameof(ClientScoreboardInfo.Score))"
data-sort-down="@Model.ShouldOrderDescending.ToString().ToLower()">
<tr class="bg-dark border-bottom">
<tr class="bg-dark-dm bg-white-lm d-none d-lg-table-row">
<th class="table-sort-column" data-column-name="@nameof(ClientScoreboardInfo.ClientName)">@ViewBag.Localization["WEBFRONT_SCOREBOARD_TABLE_PLAYER"]@Html.Raw(GetColumnSortDisplay(nameof(ClientScoreboardInfo.ClientName)))</th>
<th class="table-sort-column" data-column-name="@nameof(ClientScoreboardInfo.Score)">@ViewBag.Localization["WEBFRONT_ADV_STATS_SCORE"]@Html.Raw(GetColumnSortDisplay(nameof(ClientScoreboardInfo.Score)))</th>
<th class="table-sort-column" data-column-name="@nameof(ClientScoreboardInfo.Kills)">@ViewBag.Localization["WEBFRONT_ADV_STATS_KILLS"]@Html.Raw(GetColumnSortDisplay(nameof(ClientScoreboardInfo.Kills)))</th>
@ -38,9 +51,10 @@
</tr>
@foreach (var client in Model.ShouldOrderDescending ? Model.ClientInfo.OrderByDescending(OrderByFunc) : Model.ClientInfo.OrderBy(OrderByFunc))
{
<tr class="team-@client.Team.ToString().ToLower()-bg">
<!-- desktop -->
<tr class="@GetTeamBackgroundColorClass(client) d-none d-lg-table-row">
<td>
<a asp-controller="Client" asp-action="ProfileAsync" asp-route-id="@client.ClientId">
<a asp-controller="Client" asp-action="Profile" asp-route-id="@client.ClientId" class="no-decoration text-light-dm text-dark-lm">
<color-code value="@client.ClientName"></color-code>
</a>
</td>
@ -52,5 +66,31 @@
<td>@(client.ZScore is null or 0 ? "--" : Math.Round(client.ZScore.Value, 2).ToString(CultureInfo.CurrentCulture))</td>
<td class="text-right">@client.Ping</td>
</tr>
<tr class="d-table-row d-lg-none d-flex">
<td class="text-right bg-primary text-light flex-grow-0">
<div>@ViewBag.Localization["WEBFRONT_SCOREBOARD_TABLE_PLAYER"]</div>
<div>@ViewBag.Localization["WEBFRONT_ADV_STATS_SCORE"]</div>
<div>@ViewBag.Localization["WEBFRONT_ADV_STATS_KILLS"]</div>
<div>@ViewBag.Localization["WEBFRONT_SCOREBOARD_TABLE_DEATHS"]</div>
<div>@ViewBag.Localization["WEBFRONT_SCOREBOARD_TABLE_RATIO"]</div>
<div>@ViewBag.Localization["WEBFRONT_SCOREBOARD_TABLE_SPM"]</div>
<div>@ViewBag.Localization["WEBFRONT_ADV_STATS_ZSCORE"]</div>
<div>@ViewBag.Localization["WEBFRONT_SCOREBOARD_TABLE_PING"]</div>
</td>
<td class="@GetTeamBackgroundColorClass(client) flex-fill">
<a asp-controller="Client" asp-action="Profile" asp-route-id="@client.ClientId" class="no-decoration text-light-dm text-dark-lm">
<color-code value="@client.ClientName"></color-code>
</a>
<div>@client.Score</div>
<div>@(client.Kills ?? 0)</div>
<div>@(client.Deaths ?? 0)</div>
<div>@Math.Round(client.Kdr ?? 0, 2)</div>
<div>@Math.Round(client.ScorePerMinute ?? 0)</div>
<div>@(client.ZScore is null or 0 ? "--" : Math.Round(client.ZScore.Value, 2).ToString(CultureInfo.CurrentCulture))</div>
<div>@client.Ping</div>
</td>
</tr>
}
</table>

View File

@ -18,65 +18,70 @@
}
}
<div class="row server-header pt-1 pb-1 bg-primary " id="server_header_@Model.ID">
<div class="col-md-4 text-center text-md-left d-inline-flex justify-content-center justify-content-md-start">
<color-code value="@Model.Name"></color-code>
<a href="@Model.ConnectProtocolUrl" class="ml-2 mr-2 align-self-center d-none d-md-flex server-join-button" title="@Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_HOME_JOIN_DESC"]">
<span class="oi oi-play-circle mr-1 align-self-center"></span>
<span class="server-header-ip-address" style="display:none;">@Model.IPAddress</span>
</a>
@if (ViewBag.Authorized)
{
<span class="oi oi-chat align-self-center profile-action d-none d-md-flex mr-2" data-action="chat" data-action-id="@Model.ID"></span>
}
<a asp-controller="Server" asp-action="Scoreboard" asp-fragment="server_@Model.ID" title="@ViewBag.Localization["WEBFRONT_TITLE_SCOREBOARD"]"
class="align-self-center d-none d-md-flex">
<span class="oi oi-spreadsheet ml-1"></span>
</a>
</div>
<div class="text-center col-md-4 align-self-center">
<span>@Model.Map</span>
@if (!string.IsNullOrEmpty(Model.GameType) && Model.GameType.Length > 1)
{
<span>&ndash;</span>
<span>@Model.GameType</span>
}
</div>
<div class="text-center text-md-right col-md-4 d-flex align-self-center justify-content-center justify-content-md-end flex-column-reverse flex-sm-row">
@if (Model.LobbyZScore != null)
{
<div title="@ViewBag.Localization["WEBFRONT_HOME_RATING_DESC"]" class="cursor-help d-flex flex-row-reverse flex-md-row justify-content-center">
<span>@(Model.LobbyZScore ?? 0)</span>
<span class="oi oi-bolt align-self-center mr-1 ml-1"></span>
<div class="card mt-20 mb-20 ml-0 mr-0 p-0">
<div class="p-5 pl-10 pr-10 bg-primary rounded-top d-flex flex-column flex-md-row flex-wrap justify-content-between text-light" id="server_header_@Model.ID">
<div class="d-flex align-self-center flex-column-reverse flex-md-row">
<div class="ml-5 mr-5 text-center">
<color-code value="@Model.Name"></color-code>
</div>
<div class="d-flex justify-content-center">
<!-- connect button -->
<a href="@Model.ConnectProtocolUrl" class="text-light align-self-center" title="@Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_HOME_JOIN_DESC"]">
<i class="oi oi-play-circle ml-5 mr-5"></i>
<span class="server-header-ip-address" style="display:none;">@(Model.ExternalIPAddress):@(Model.Port)</span>
</a>
<has-permission entity="AdminMenu" required-permission="Update">
<!-- send message button -->
<a href="#actionModal" class="profile-action text-light align-self-center" data-action="chat" data-action-id="@Model.ID">
<i class="oi oi-chat ml-5 mr-5"></i>
</a>
</has-permission>
<!-- scoreboard button -->
<a asp-controller="Server" asp-action="Scoreboard" asp-route-serverId="@Model.Endpoint" title="@ViewBag.Localization["WEBFRONT_TITLE_SCOREBOARD"]"
class="text-light align-self-center">
<i class="oi oi-spreadsheet ml-5 mr-5"></i>
</a>
</div>
</div>
<div class="align-self-center">
<span>@Model.Map</span>
@if (!string.IsNullOrEmpty(Model.GameType) && Model.GameType.Length > 1)
{
<span>&ndash;</span>
<span>@Model.GameType</span>
}
</div>
<div class="align-self-center d-flex flex-column flex-md-row">
@if (Model.LobbyZScore != null)
{
<div data-toggle="tooltip" data-title="@ViewBag.Localization["WEBFRONT_HOME_RATING_DESC"]" class="cursor-help d-flex flex-row-reverse flex-md-row justify-content-center">
<span>@(Model.LobbyZScore ?? 0)</span>
<span class="oi oi-bolt align-self-center" style="margin-right: 2px; margin-left: 2px"></span>
</div>
}
<div class="mr-5 ml-5 align-self-center">
<span class="server-clientcount">@Model.ClientCount</span>/<span class="server-maxclients">@Model.MaxClients</span>
</div>
}
<div>
<span class="server-clientcount">@Model.ClientCount</span>/<span class="server-maxclients">@Model.MaxClients</span>
</div>
</div>
@if (ViewBag.Authorized)
<div id="server_clientactivity_@Model.ID" class="bg-dark-dm bg-light-lm server-activity">
<partial name="../Server/_ClientActivity" for="@Model"/>
</div>
@if (Model.Players.Any())
{
<div class="p-1 d-flex d-md-none justify-content-center col-12">
<span class="oi oi-chat align-self-center profile-action d-flex d-md-none" data-action="chat" data-action-id="@Model.ID"></span>
<div class="ml-15 mr-15">
<hr/>
</div>
}
<a asp-controller="Server" asp-action="Scoreboard" title="@ViewBag.Localization["WEBFRONT_TITLE_SCOREBOARD"]"
class="p-1 d-flex d-md-none justify-content-center col-12">
<span class="oi oi-spreadsheet ml-1"></span>
</a>
</div>
<div id="server_clientactivity_@Model.ID" class="bg-dark row server-activity @(Model.ClientCount > 0 ? "pt-2 pb-2" : "")">
@await Html.PartialAsync("../Server/_ClientActivity", Model)
</div>
<div class="row server-history mb-4">
<div class="server-history-row m-auto" style="position:relative; width: 100%" id="server_history_@Model.ID" data-serverid="@Model.ID"
data-clienthistory='@Html.Raw(Json.Serialize(Model.ClientHistory))'
data-clienthistory-ex='@Html.Raw(Json.Serialize(Model.ClientHistory.ClientCounts))'
data-online="@Model.Online">
<canvas id="server_history_canvas_@Model.ID" height="100"></canvas>
<div class="server-history">
<div class="server-history-row m-auto bg-dark-dm bg-light-lm rounded-bottom" style="position:relative; width: 100%" id="server_history_@Model.ID" data-serverid="@Model.ID"
data-clienthistory='@Html.Raw(Json.Serialize(Model.ClientHistory))'
data-clienthistory-ex='@Html.Raw(Json.Serialize(Model.ClientHistory.ClientCounts))'
data-online="@Model.Online">
<canvas id="server_history_canvas_@Model.ID" class="rounded-bottom" height="100"></canvas>
</div>
</div>
</div>