VanguardReMaster/client/Assets/Vanguard/Runtime/UI/HistoryView.cs

219 lines
7.8 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
using Vanguard.Api;
using Vanguard.Api.Contracts;
using Vanguard.Auth;
using Vanguard.Meta;
namespace Vanguard.UI
{
/// <summary>История матчей в Lobby и вход в реплей.</summary>
public sealed class HistoryView
{
private readonly MetaService _meta;
private readonly AuthService _auth;
private readonly Action _onBack;
private readonly RectTransform _root;
private readonly Text _status;
private readonly RectTransform _content;
private readonly ReplayView _replay;
private bool _loading;
public HistoryView(
Transform parent,
MetaService meta,
AuthService auth,
Action onBack)
{
_meta = meta;
_auth = auth;
_onBack = onBack;
_root = UiKit.CreatePanel(parent, "HistoryScreen", new Color(0.018f, 0.03f, 0.06f, 0.96f));
var top = UiKit.CreatePanel(_root, "TopBar", new Color(0.06f, 0.08f, 0.13f, 1f));
top.anchorMin = new Vector2(0f, 1f);
top.anchorMax = new Vector2(1f, 1f);
top.pivot = new Vector2(0.5f, 1f);
top.anchoredPosition = Vector2.zero;
top.sizeDelta = new Vector2(0f, 88f);
UiKit.AddHorizontalLayout(top, 22, 16);
var back = UiKit.CreateButton(top, "Back", "← В лобби", () => _onBack(), 18);
UiKit.SetPreferredHeight(back, 44f, 0f);
var title = UiKit.CreateText(top, "Title", "История матчей", 32, Color.white, TextAnchor.MiddleLeft);
title.fontStyle = FontStyle.Bold;
UiKit.SetPreferredHeight(title, 46f);
var hint = UiKit.CreateText(
top, "Hint", "Только ваши матчи · реплей доступен участникам", 16,
new Color(0.60f, 0.68f, 0.84f), TextAnchor.MiddleRight);
UiKit.SetPreferredHeight(hint, 36f);
var body = UiKit.CreatePanel(_root, "Body", new Color(0f, 0f, 0f, 0f));
body.anchorMin = Vector2.zero;
body.anchorMax = Vector2.one;
body.offsetMin = new Vector2(44f, 30f);
body.offsetMax = new Vector2(-44f, -110f);
UiKit.AddVerticalLayout(body, 8, 10);
var scroll = UiKit.CreateScrollView(body, "HistoryScroll", out _content, 8f);
var scrollElement = scroll.gameObject.AddComponent<LayoutElement>();
scrollElement.flexibleHeight = 1f;
scrollElement.minHeight = 200f;
_status = UiKit.CreateText(
body, "Status", string.Empty, 18,
new Color(0.62f, 0.68f, 0.82f), TextAnchor.MiddleLeft);
UiKit.SetPreferredHeight(_status, 34f);
_replay = new ReplayView(_root, _meta, HideReplay);
_root.gameObject.SetActive(false);
}
public void Show()
{
UiKit.SetActive(_root, true);
_replay.Hide();
_ = LoadAsync();
}
public void Hide()
{
_replay.Hide();
UiKit.SetActive(_root, false);
}
private async Task LoadAsync()
{
if (_loading)
return;
_loading = true;
SetStatus("Загружаем историю…", new Color(0.62f, 0.68f, 0.82f));
ClearChildren(_content);
try
{
await _auth.EnsureAccessAsync();
var history = await _meta.GetHistoryAsync();
if (_root == null || !_root.gameObject.activeSelf)
return;
Build(history.Items);
SetStatus(
history.Items == null || history.Items.Count == 0
? "Матчей пока нет."
: "Матчей: " + history.Items.Count + ".",
new Color(0.62f, 0.68f, 0.82f));
}
catch (ApiException exception)
{
SetStatus(exception.Message, new Color(1f, 0.55f, 0.45f));
}
catch (Exception exception)
{
Debug.LogException(exception);
SetStatus("Не удалось загрузить историю.", new Color(1f, 0.55f, 0.45f));
}
finally
{
_loading = false;
}
}
private void Build(IReadOnlyList<MatchHistoryDto> items)
{
ClearChildren(_content);
if (items == null || items.Count == 0)
return;
foreach (var item in items)
AddRow(item);
}
private void AddRow(MatchHistoryDto item)
{
var row = UiKit.CreatePanel(_content, "Match_" + item.MatchId, new Color(0.07f, 0.09f, 0.14f, 1f));
var rowElement = row.gameObject.AddComponent<LayoutElement>();
rowElement.preferredHeight = 96f;
UiKit.AddHorizontalLayout(row, 14, 14);
var info = UiKit.CreatePanel(row, "Info", new Color(0f, 0f, 0f, 0f));
var infoElement = info.gameObject.AddComponent<LayoutElement>();
infoElement.flexibleWidth = 1f;
infoElement.preferredHeight = 64f;
UiKit.AddVerticalLayout(info, 0, 2);
var opponent = UiKit.CreateText(
info,
"Opponent",
(item.Result == "win" ? "Победа" : item.Result == "loss" ? "Поражение" : "Ничья")
+ " против " + item.OpponentName,
21,
item.Result == "win" ? new Color(0.45f, 0.85f, 0.55f) : new Color(1f, 0.62f, 0.48f),
TextAnchor.MiddleLeft);
opponent.fontStyle = FontStyle.Bold;
UiKit.SetPreferredHeight(opponent, 28f);
var detail = UiKit.CreateText(
info,
"Detail",
item.Mode + " · " + item.FinishReason + " · "
+ item.PlayedAt.ToLocalTime().ToString("dd.MM.yyyy HH:mm"),
16,
new Color(0.60f, 0.68f, 0.84f),
TextAnchor.MiddleLeft);
UiKit.SetPreferredHeight(detail, 24f);
var rewards = UiKit.CreateText(
row,
"Rewards",
"Gold " + item.Gold + " · XP " + item.Xp
+ "\nMMR " + item.MmrBefore + " → " + item.MmrAfter,
16,
new Color(0.72f, 0.78f, 0.92f));
var rewardsElement = rewards.gameObject.AddComponent<LayoutElement>();
rewardsElement.preferredWidth = 210f;
rewardsElement.preferredHeight = 56f;
var replay = UiKit.CreateButton(
row,
"Replay",
item.ReplayAvailable ? "Реплей" : "Нет реплея",
() => _replay.Show(item.MatchId),
17);
replay.interactable = item.ReplayAvailable;
var replayElement = replay.gameObject.AddComponent<LayoutElement>();
replayElement.preferredWidth = 130f;
replayElement.preferredHeight = 46f;
replayElement.flexibleWidth = 0f;
}
private void HideReplay()
{
_replay.Hide();
}
private void SetStatus(string text, Color color)
{
if (_status == null)
return;
_status.text = text ?? string.Empty;
_status.color = color;
}
private static void ClearChildren(Transform parent)
{
for (var i = parent.childCount - 1; i >= 0; i--)
UnityEngine.Object.Destroy(parent.GetChild(i).gameObject);
}
}
}