using System;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
using Vanguard.Api;
using Vanguard.App;
using Vanguard.Auth;
using Vanguard.State;
namespace Vanguard.UI
{
///
/// Главный экран после входа: профиль и балансы, вход в бой/колоды/магазин,
/// заглушки разделов без серверной части и гамбургер-меню.
///
public sealed class LobbyView : IDisposable
{
public const string RootName = "LobbyScreen";
private const float Margin = 24f;
private const float TopHeight = 96f;
private const float LeftWidth = 560f;
private const float RightWidth = 336f;
private const float Gutter = 16f;
private const float ContentTop = 112f;
private const float BottomMargin = 24f;
private const float BalanceHeight = 88f;
private static readonly Color PanelFill = new Color(0.024f, 0.058f, 0.15f, 0.92f);
private static readonly Color PanelFillSoft = new Color(0.035f, 0.08f, 0.19f, 0.55f);
private static readonly Color Border = new Color(0.18f, 0.49f, 1f, 0.55f);
private static readonly Color BorderStrong = new Color(0.34f, 0.72f, 1f, 0.9f);
private static readonly Color TextPrimary = new Color(0.88f, 0.93f, 1f);
private static readonly Color TextMuted = new Color(0.58f, 0.69f, 0.88f);
private static readonly Color TextDim = new Color(0.44f, 0.55f, 0.75f);
private static readonly Color Accent = new Color(0.37f, 0.69f, 1f);
private readonly AuthService _auth;
private readonly PlayerState _player;
private readonly Action _onLoggedOut;
private readonly Action _onStore;
private readonly HamburgerMenu _menu;
private readonly StatusTicker _ticker;
private readonly RectTransform _root;
private Text _avatar;
private Text _playerName;
private Text _mmr;
private Text _gold;
private Text _dust;
private Text _tokens;
private Text _status;
private bool _disposed;
private bool _refreshing;
public LobbyView(
Transform parent,
AppConfig config,
AuthService auth,
PlayerState player,
Action onLoggedOut,
Action onBattle,
Action onDecks,
Action onStore,
Action onHistory,
Action onRating,
Action onCommunity)
{
_auth = auth;
_player = player;
_onLoggedOut = onLoggedOut;
_onStore = onStore;
_root = UiKit.CreatePanel(parent, RootName, new Color(0f, 0f, 0f, 0f));
_root.GetComponent().raycastTarget = false;
var top = TopBar(out _avatar, out _playerName, out _mmr);
AddTopAction(top, "Rating", "Рейтинг", -312f, 180f, () => onRating(), LobbyIcon.Chart);
AddTopAction(top, "Community", "Сообщество", -96f, 200f, () => onCommunity(), LobbyIcon.Friends);
BuildActions(onBattle, onDecks, onStore);
BuildMissions(out _status);
BuildBalances(out _gold, out _dust, out _tokens);
BuildChat();
BuildFriends();
_menu = new HamburgerMenu(_root, config, onLoggedOut, onHistory);
_ticker = _root.gameObject.AddComponent();
_ticker.Hide = () => SetStatus(string.Empty);
_player.Changed += UpdateTexts;
Loc.LanguageChanged += UpdateTexts;
UpdateTexts();
_root.gameObject.SetActive(false);
}
public bool IsMenuOpen => _menu != null && _menu.IsOpen;
public void CloseMenu()
{
if (_menu != null)
_menu.Close();
}
public void Show()
{
UiKit.SetActive(_root, true);
UpdateTexts();
_ = RefreshAsync();
}
public void Hide() => UiKit.SetActive(_root, false);
public void Dispose()
{
if (_disposed)
return;
_disposed = true;
_player.Changed -= UpdateTexts;
Loc.LanguageChanged -= UpdateTexts;
}
// ------------------------------------------------------------ топбар
private RectTransform TopBar(out Text avatar, out Text playerName, out Text mmr)
{
var top = Surface(_root, "TopBar", new Color(0.012f, 0.03f, 0.08f, 0.94f), Border, 1, 0);
top.anchorMin = new Vector2(0f, 1f);
top.anchorMax = new Vector2(1f, 1f);
top.pivot = new Vector2(0.5f, 1f);
top.offsetMin = new Vector2(Margin, -TopHeight);
top.offsetMax = new Vector2(-Margin, 0f);
var avatarRect = Surface(
top,
"Avatar",
new Color(0.05f, 0.13f, 0.3f, 0.95f),
BorderStrong,
2,
14);
avatarRect.anchorMin = new Vector2(0f, 0.5f);
avatarRect.anchorMax = new Vector2(0f, 0.5f);
avatarRect.pivot = new Vector2(0f, 0.5f);
avatarRect.sizeDelta = new Vector2(64f, 64f);
avatarRect.anchoredPosition = new Vector2(20f, 0f);
avatar = UiKit.CreateText(avatarRect, "Initials", "?", 26, TextPrimary);
avatar.fontStyle = FontStyle.Bold;
UiKit.Stretch(avatar.rectTransform);
UiKit.MakeLiteral(avatar);
playerName = UiKit.CreateText(
top,
"PlayerName",
"…",
22,
TextPrimary,
TextAnchor.MiddleLeft);
playerName.fontStyle = FontStyle.Bold;
var nameRect = playerName.rectTransform;
nameRect.anchorMin = new Vector2(0f, 0.5f);
nameRect.anchorMax = new Vector2(0f, 0.5f);
nameRect.pivot = new Vector2(0f, 0.5f);
nameRect.sizeDelta = new Vector2(420f, 30f);
nameRect.anchoredPosition = new Vector2(104f, 14f);
UiKit.MakeLiteral(playerName);
mmr = UiKit.CreateText(
top,
"Mmr",
string.Empty,
14,
TextMuted,
TextAnchor.MiddleLeft);
var mmrRect = mmr.rectTransform;
mmrRect.anchorMin = new Vector2(0f, 0.5f);
mmrRect.anchorMax = new Vector2(0f, 0.5f);
mmrRect.pivot = new Vector2(0f, 0.5f);
mmrRect.sizeDelta = new Vector2(460f, 22f);
mmrRect.anchoredPosition = new Vector2(104f, -16f);
UiKit.MakeLiteral(mmr);
var season = UiKit.CreateText(
top,
"Season",
"Сезон — скоро",
14,
TextDim,
TextAnchor.MiddleCenter);
var seasonRect = season.rectTransform;
seasonRect.anchorMin = new Vector2(0.5f, 0.5f);
seasonRect.anchorMax = new Vector2(0.5f, 0.5f);
seasonRect.sizeDelta = new Vector2(280f, 30f);
seasonRect.anchoredPosition = Vector2.zero;
return top;
}
private void AddTopAction(
RectTransform parent,
string name,
string label,
float rightOffset,
float width,
Action onClick,
Action icon)
{
var buttonRect = Surface(
parent,
name,
new Color(0.035f, 0.09f, 0.21f, 0.85f),
Border,
1,
12);
buttonRect.anchorMin = new Vector2(1f, 0.5f);
buttonRect.anchorMax = new Vector2(1f, 0.5f);
buttonRect.pivot = new Vector2(1f, 0.5f);
buttonRect.sizeDelta = new Vector2(width, 52f);
buttonRect.anchoredPosition = new Vector2(rightOffset, 0f);
var image = buttonRect.GetComponent();
image.raycastTarget = true;
var button = buttonRect.gameObject.AddComponent