using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using ShiroginSDK.Runtime.Modules.Data.Scripts; using ShiroginSDK.Runtime.Modules.Events; using ShiroginSDK.Runtime.Services.Base; using ShiroginSDK.Runtime.Services.Interfaces; using TMPro; using UnityEngine; using UnityEngine.UI; namespace ShiroginSDK.Samples.RemoteConfigSample.Scripts { /// /// Visual demo for ShiroginSDK RemoteConfig system. /// Automatically lists all local + remote configuration values /// inside a RectTransform UI container at runtime. /// public class RemoteConfigSampleUI : MonoBehaviour { [Header("UI References")] [SerializeField] private Button fetchButton; [SerializeField] private Button clearCacheButton; [SerializeField] private Button reloadButton; [SerializeField] private RectTransform contentParent; [SerializeField] private TMP_Text templateText; [SerializeField] private TMP_Text logText; [SerializeField] private TMP_Text gameNameText; private readonly List _spawnedEntries = new(); private IDataService _dataService; private IEventService _eventService; private IRemoteConfigService _remoteConfigService; private void Awake() { _dataService = ServiceLocator.Get(); _eventService = ServiceLocator.Get(); _remoteConfigService = ServiceLocator.Get(); fetchButton?.onClick.AddListener(OnFetchRemoteConfig); clearCacheButton?.onClick.AddListener(OnClearCache); reloadButton?.onClick.AddListener(OnReload); if (templateText != null) templateText.gameObject.SetActive(false); Log("๐Ÿง  RemoteConfigSampleUI initialized."); } private void OnEnable() { _eventService.Subscribe(OnRemoteConfigUpdated); Log("๐Ÿ“ก Listening for RemoteConfigUpdatedEvent..."); RefreshUI(); } private void OnDisable() { _eventService.Unsubscribe(OnRemoteConfigUpdated); } private void UpdateGameName() { var data = _dataService.Get(); gameNameText.text = data != null ? data.GameName : "Unknown"; } // --------------------------------------------------------- // ๐Ÿ”„ FETCH FROM FIREBASE // --------------------------------------------------------- private void OnFetchRemoteConfig() { if (_remoteConfigService == null) { Log("โŒ RemoteConfigService not found."); return; } Log("๐Ÿ”„ Fetching Remote Config from Firebase..."); _remoteConfigService.ForceRefresh(); } // --------------------------------------------------------- // โœ… EVENT: NEW DATA ARRIVED // --------------------------------------------------------- private void OnRemoteConfigUpdated(ShiroginEvents.RemoteConfig.RemoteConfigUpdatedEvent e) { Log("โœ… Remote Config updated from Firebase. Reloading UI..."); RefreshUI(); } // --------------------------------------------------------- // ๐Ÿงน CLEAR CACHE // --------------------------------------------------------- private void OnClearCache() { var cache = _dataService.Get(); if (cache == null) { Log("โš ๏ธ RemoteConfigData not found."); return; } cache.CachedJson = "{}"; cache.LastFetchTicksUtc = 0; cache.Save(); Log("๐Ÿงน RemoteConfig local cache cleared."); RefreshUI(); } // --------------------------------------------------------- // ๐Ÿ” MANUAL RELOAD // --------------------------------------------------------- private void OnReload() { Log("๐Ÿ” Manual reload requested."); var data = _dataService.Get(); data?.Load(); RefreshUI(); } // --------------------------------------------------------- // ๐Ÿช„ REFRESH DISPLAY // --------------------------------------------------------- private void RefreshUI() { if (contentParent == null || templateText == null) { Log("โŒ Missing UI references (contentParent or templateText)."); return; } UpdateGameName(); foreach (var entry in _spawnedEntries) if (entry != null) Destroy(entry.gameObject); _spawnedEntries.Clear(); var data = _dataService.Get(); if (data == null) { Log("โš ๏ธ RemoteConfigData not found in DataService."); return; } var fields = typeof(RemoteConfigData).GetFields( BindingFlags.Public | BindingFlags.Instance); foreach (var field in fields) { var val = field.GetValue(data); var valueString = FormatValue(val); AddEntry(field.Name, valueString); } AddEntry("๐Ÿ•’ Last Fetch", data.GetLastFetchTimeString()); AddEntry("๐Ÿ’พ Cached JSON", string.IsNullOrEmpty(data.CachedJson) ? "{}" : data.CachedJson.Length > 120 ? data.CachedJson[..120] + "..." : data.CachedJson); Canvas.ForceUpdateCanvases(); LayoutRebuilder.ForceRebuildLayoutImmediate(contentParent); } // --------------------------------------------------------- // ๐Ÿ”ง HELPERS // --------------------------------------------------------- private string FormatValue(object val) { if (val == null) return "null"; if (val is Array arr) return string.Join(",", arr.Cast()); return val.ToString(); } private void AddEntry(string key, string val) { var entry = Instantiate(templateText, contentParent); entry.text = $"{key}: {val}"; entry.gameObject.SetActive(true); _spawnedEntries.Add(entry); } private void Log(string msg) { Debug.Log($"[RemoteConfigSampleUI] {msg}"); if (logText != null) logText.text = msg + "\n" + logText.text; } } }