203 lines
No EOL
7.1 KiB
C#
203 lines
No EOL
7.1 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using DG.Tweening;
|
|
using ShiroginSDK.Runtime.Core.SDK;
|
|
using ShiroginSDK.Runtime.Core.Utils;
|
|
using ShiroginSDK.Runtime.Modules.Events;
|
|
using ShiroginSDK.Runtime.Modules.UI.Popup.Enums;
|
|
using ShiroginSDK.Runtime.Modules.UI.Popup.Scripts.SO;
|
|
using ShiroginSDK.Runtime.Modules.UI.Popup.Scripts.UI.Base;
|
|
using ShiroginSDK.Runtime.Services.Base;
|
|
using ShiroginSDK.Runtime.Services.Interfaces;
|
|
using ShiroginSDK.Runtime.Shared.Constants;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
namespace ShiroginSDK.Runtime.Services.Implementations.UI
|
|
{
|
|
/// <summary>
|
|
/// Manages all queued popups with background dimming and smooth animations.
|
|
/// Integrated with EventService to automatically respond to common SDK events.
|
|
/// </summary>
|
|
public class PopupService : ServiceBase, IPopupService
|
|
{
|
|
private readonly Queue<(PopupType, object)> _popupQueue = new();
|
|
private CanvasGroup _dimBackground;
|
|
private bool _isShowing;
|
|
private PopupRepository _repository;
|
|
private Canvas _rootCanvas;
|
|
|
|
// ----------------------------------------------------
|
|
// Initialization
|
|
// ----------------------------------------------------
|
|
public void Initialize(Canvas canvas, PopupRepository repository)
|
|
{
|
|
_rootCanvas = canvas;
|
|
_repository = repository;
|
|
InitializeDim();
|
|
}
|
|
|
|
// ----------------------------------------------------
|
|
// Public API
|
|
// ----------------------------------------------------
|
|
public void Show(PopupType type, object data = null)
|
|
{
|
|
Enqueue(type, data);
|
|
}
|
|
|
|
public void SetRepository(PopupRepository repo)
|
|
{
|
|
_repository = repo;
|
|
}
|
|
|
|
public void SetCanvas(Canvas canvas)
|
|
{
|
|
_rootCanvas = canvas;
|
|
}
|
|
|
|
// ----------------------------------------------------
|
|
// Lifecycle
|
|
// ----------------------------------------------------
|
|
protected override void OnInitialize()
|
|
{
|
|
// Load repository from SDKConfig
|
|
var config = ShiroginConfig.Load();
|
|
if (config == null)
|
|
{
|
|
Debug.LogError("[PopupService] ❌ SDKConfig not found! Cannot load PopupRepository.");
|
|
return;
|
|
}
|
|
|
|
_repository = config.popupRepository;
|
|
if (_repository == null) Debug.LogWarning("[PopupService] ⚠️ PopupRepository is null in SDKConfig.");
|
|
|
|
// Try to find root canvas automatically if none assigned
|
|
if (_rootCanvas == null)
|
|
_rootCanvas = Object.FindFirstObjectByType<Canvas>();
|
|
|
|
InitializeDim();
|
|
SubscribeToEvents();
|
|
|
|
Debug.Log("[PopupService] ✅ Initialized and bound to SDKConfig.");
|
|
}
|
|
|
|
protected override void OnDispose()
|
|
{
|
|
_popupQueue.Clear();
|
|
_isShowing = false;
|
|
}
|
|
|
|
// ----------------------------------------------------
|
|
// Event Wiring
|
|
// ----------------------------------------------------
|
|
private void SubscribeToEvents()
|
|
{
|
|
var eventService = ServiceLocator.Get<IEventService>();
|
|
if (eventService == null)
|
|
{
|
|
Debug.LogError("[PopupService] ❌ EventService not found.");
|
|
return;
|
|
}
|
|
|
|
eventService.Subscribe<ShiroginEvents.Rewards.RewardClaimedEvent>(e => Enqueue(PopupType.RewardClaimed, e));
|
|
eventService.Subscribe<ShiroginEvents.IAP.PurchaseCompletedEvent>(e => Enqueue(PopupType.PurchaseSuccess, e));
|
|
eventService.Subscribe<ShiroginEvents.Connection.NoConnectionEvent>(e => Enqueue(PopupType.NoConnection, e));
|
|
eventService.Subscribe<ShiroginEvents.IAP.PurchaseFailedEvent>(e => Enqueue(PopupType.PurchaseFailed, e));
|
|
eventService.Subscribe<ShiroginEvents.Ads.AdWatchedEvent>(e =>
|
|
{
|
|
if (!e.Success)
|
|
Enqueue(PopupType.NoAdsAvailable, e);
|
|
});
|
|
eventService.Subscribe<ShiroginEvents.Ads.RewardedAdUnavailableEvent>(e =>
|
|
{
|
|
Enqueue(PopupType.RewardedAdUnavailable, e);
|
|
});
|
|
|
|
eventService.Subscribe<ShiroginEvents.Shop.Shop_UIStoreItem_Rewarded>(e =>
|
|
Enqueue(PopupType.Shop_UIStoreItem_Rewarded, e));
|
|
}
|
|
|
|
private void InitializeDim()
|
|
{
|
|
if (_dimBackground != null) return;
|
|
|
|
var dimObj = new GameObject("PopupDimmer", typeof(RectTransform), typeof(CanvasGroup), typeof(Image));
|
|
dimObj.transform.SetParent(_rootCanvas ? _rootCanvas.transform : null, false);
|
|
|
|
var img = dimObj.GetComponent<Image>();
|
|
img.color = new Color(0, 0, 0, 0.6f);
|
|
|
|
_dimBackground = dimObj.GetComponent<CanvasGroup>();
|
|
_dimBackground.alpha = 0;
|
|
_dimBackground.blocksRaycasts = false;
|
|
dimObj.transform.SetAsFirstSibling();
|
|
}
|
|
|
|
private void Enqueue(PopupType type, object data)
|
|
{
|
|
_popupQueue.Enqueue((type, data));
|
|
|
|
if (!_isShowing)
|
|
CoroutineRunner.Start(ProcessQueue());
|
|
}
|
|
|
|
private IEnumerator ProcessQueue()
|
|
{
|
|
_isShowing = true;
|
|
|
|
while (_popupQueue.Count > 0)
|
|
{
|
|
var (type, data) = _popupQueue.Dequeue();
|
|
yield return ShowPopup(type, data);
|
|
}
|
|
|
|
_isShowing = false;
|
|
yield return FadeDim(false);
|
|
}
|
|
|
|
private IEnumerator ShowPopup(PopupType type, object data)
|
|
{
|
|
if (_repository == null)
|
|
{
|
|
Debug.LogError("[PopupService] ❌ PopupRepository not assigned or missing in SDKConfig!");
|
|
yield break;
|
|
}
|
|
|
|
var prefab = _repository.GetPrefab(type);
|
|
if (prefab == null)
|
|
{
|
|
Debug.LogWarning($"[PopupService] ⚠️ No popup prefab for type: {type}");
|
|
yield break;
|
|
}
|
|
|
|
yield return FadeDim(true);
|
|
|
|
var instance = Object.Instantiate(prefab.gameObject, _rootCanvas ? _rootCanvas.transform : null);
|
|
var popup = instance.GetComponent<PopupBase>();
|
|
popup.Initialize(data);
|
|
|
|
yield return popup.AnimateIn();
|
|
yield return new WaitUntil(() => popup.IsClosed);
|
|
yield return popup.AnimateOut();
|
|
|
|
Object.Destroy(instance);
|
|
}
|
|
|
|
// ----------------------------------------------------
|
|
// Dimmer Control
|
|
// ----------------------------------------------------
|
|
private IEnumerator FadeDim(bool fadeIn)
|
|
{
|
|
if (_dimBackground == null) yield break;
|
|
|
|
_dimBackground.blocksRaycasts = fadeIn;
|
|
|
|
DOTween.To(() => _dimBackground.alpha,
|
|
x => _dimBackground.alpha = x,
|
|
fadeIn ? 1f : 0f,
|
|
0.3f);
|
|
|
|
yield return new WaitForSeconds(UIConstants.FadeDuration);
|
|
}
|
|
}
|
|
} |