Files
BeatSaber/Assets/Script/SongSelectManager.cs
T

137 lines
4.6 KiB
C#

using System.Collections.Generic;
using System.IO;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class SongSelectManager : MonoBehaviour
{
[Header("탭 버튼")]
[SerializeField] private Button tabAllBtn;
[SerializeField] private Button tabOwnedBtn;
[SerializeField] private Color tabActiveColor = Color.white;
[SerializeField] private Color tabInactiveColor = new Color(0.6f, 0.6f, 0.6f);
[Header("카드 목록")]
[SerializeField] private Transform cardContainer;
[SerializeField] private GameObject songCardPrefab;
[Header("연결")]
[SerializeField] private SongDetailPanel detailPanel;
[SerializeField] private DownloadManager downloadManager;
[Header("상태 오버레이")]
[SerializeField] private GameObject loadingOverlay;
[SerializeField] private GameObject errorOverlay;
[SerializeField] private TMP_Text errorText;
private static string CachePath =>
Path.Combine(Application.persistentDataPath, "songs_cache.json");
private List<SongInfo> allSongs = new List<SongInfo>();
private bool showingOwned = false;
// ── Unity ────────────────────────────────────────────────
private void Start()
{
tabAllBtn.onClick.AddListener(() => SwitchTab(false));
tabOwnedBtn.onClick.AddListener(() => SwitchTab(true));
detailPanel.gameObject.SetActive(false);
SetTabVisual(false);
FetchSongs();
}
// ── 탭 전환 ──────────────────────────────────────────────
private void SwitchTab(bool owned)
{
showingOwned = owned;
SetTabVisual(owned);
RefreshCards();
}
private void SetTabVisual(bool owned)
{
tabAllBtn.image.color = owned ? tabInactiveColor : tabActiveColor;
tabOwnedBtn.image.color = owned ? tabActiveColor : tabInactiveColor;
}
// ── 데이터 로드 ───────────────────────────────────────────
private void FetchSongs()
{
loadingOverlay.SetActive(true);
errorOverlay.SetActive(false);
downloadManager.FetchSongsList(
onSuccess: list =>
{
allSongs = list.songs;
SaveCache(list);
SongLibrary.Instance.ValidateWithFileSystem(downloadManager, list.songs);
loadingOverlay.SetActive(false);
RefreshCards();
},
onError: _ =>
{
SongsList cached = LoadCache();
loadingOverlay.SetActive(false);
if (cached != null)
{
allSongs = cached.songs;
RefreshCards();
}
else
{
errorOverlay.SetActive(true);
errorText.text = "서버 연결 실패\n인터넷 연결을 확인해주세요";
}
});
}
// ── 카드 갱신 ────────────────────────────────────────────
public void RefreshCards()
{
foreach (Transform child in cardContainer)
Destroy(child.gameObject);
List<SongInfo> songs = showingOwned
? allSongs.FindAll(s => SongLibrary.Instance.IsSongDownloaded(s.id))
: allSongs;
foreach (SongInfo song in songs)
{
bool downloaded = SongLibrary.Instance.IsSongDownloaded(song.id);
GameObject obj = Instantiate(songCardPrefab, cardContainer);
SongInfo captured = song;
obj.GetComponent<SongCard>().Setup(song, downloaded, () => OnCardClicked(captured));
}
}
private void OnCardClicked(SongInfo song)
{
detailPanel.gameObject.SetActive(true);
detailPanel.Show(song, downloadManager, this);
}
// ── 로컬 캐시 (오프라인 폴백) ─────────────────────────────
private static void SaveCache(SongsList list)
{
try { File.WriteAllText(CachePath, JsonUtility.ToJson(list, true)); }
catch { }
}
private static SongsList LoadCache()
{
if (!File.Exists(CachePath)) return null;
try { return JsonUtility.FromJson<SongsList>(File.ReadAllText(CachePath)); }
catch { return null; }
}
}