Files
rudder-unity-sdk/Assets/LiveOpsExamples/Scripts/UI/ShopModalPanel.cs
T

116 lines
3.2 KiB
C#
Raw Normal View History

2026-08-12 14:03:44 +03:00
using System.Text;
using UnityEngine;
using UnityEngine.UIElements;
namespace LiveOpsExamples
{
public class ShopModalPanel : MonoBehaviour
{
[SerializeField] private PanelRenderer panelRenderer;
[SerializeField] private CozyCollectorController controller;
[SerializeField] private VisualTreeAsset shopOfferRowTemplate;
private VisualElement _root;
private Label _walletLabel;
private ScrollView _offersScroll;
private VisualElement _emptyNote;
private Button _closeButton;
private void OnEnable()
{
panelRenderer.RegisterUIReloadCallback(OnUIReload);
controller.ModalChanged += ApplyVisibility;
controller.ShopChanged += Rebuild;
controller.WalletsChanged += RefreshWallet;
}
private void OnDisable()
{
panelRenderer.UnregisterUIReloadCallback(OnUIReload);
controller.ModalChanged -= ApplyVisibility;
controller.ShopChanged -= Rebuild;
controller.WalletsChanged -= RefreshWallet;
}
private void OnUIReload(PanelRenderer renderer, VisualElement root)
{
_root = root.Q<VisualElement>("shop-modal");
_walletLabel = _root.Q<Label>("shop-wallet");
_offersScroll = _root.Q<ScrollView>("shop-offers-scroll");
_emptyNote = _root.Q<VisualElement>("shop-empty");
_closeButton = _root.Q<Button>("shop-close-button");
_closeButton.clicked -= HandleCloseClicked;
_closeButton.clicked += HandleCloseClicked;
ApplyVisibility();
RefreshWallet();
Rebuild();
}
private void ApplyVisibility()
{
_root.style.display = controller.ActiveModal == CozyModal.Shop ? DisplayStyle.Flex : DisplayStyle.None;
}
private void RefreshWallet()
{
var wallets = controller.Wallets;
if (wallets == null || wallets.Count == 0)
{
_walletLabel.text = "Wallet: —";
return;
}
var builder = new StringBuilder("Wallet: ");
foreach (var wallet in wallets)
{
if (builder.Length > "Wallet: ".Length)
{
builder.Append(" · ");
}
builder.Append($"{wallet.Balance:0.##} {wallet.Currency}".TrimEnd());
}
_walletLabel.text = builder.ToString();
}
private void Rebuild()
{
_offersScroll.contentContainer.Clear();
var offers = controller.ShopOffers;
_emptyNote.style.display = offers == null || offers.Count == 0 ? DisplayStyle.Flex : DisplayStyle.None;
if (offers == null)
{
return;
}
foreach (var offer in offers)
{
var rowRoot = shopOfferRowTemplate.CloneTree();
_offersScroll.contentContainer.Add(rowRoot);
var row = new ShopOfferRowView(rowRoot);
row.Set(string.IsNullOrEmpty(offer.Name) ? offer.OfferId : offer.Name, PriceLabel(offer.Price, offer.Currency));
string offerId = offer.OfferId;
row.BuyButton.clicked += () => controller.BuyShopOffer(offerId);
}
}
internal static string PriceLabel(double price, string currency)
{
if (price <= 0)
{
return "Free";
}
return $"{price:0.##} {currency}".TrimEnd();
}
private void HandleCloseClicked()
{
controller.CloseModal();
}
}
}