using System.Collections.Generic; using TMPro; using UnityEngine; using UnityEngine.UI; using UnityEngine.Pool; using Cysharp.Threading.Tasks; using System.Threading.Tasks; using System.Linq; using System; using BestHTTP; using Unity.VisualScripting; public class SearchCtrl : SingletonMonoBehaviour { //¿É¼Ç ÆäÀÌÁö UI [SerializeField] GameObject opsion; [SerializeField] Image searchMenuButtonImage; [SerializeField] Sprite[] searchMenuButton; [SerializeField] TMP_Text searchMenuButtonText; [SerializeField] TMP_InputField name; [SerializeField] TMP_Dropdown suitStyle; [SerializeField] TMP_Dropdown suitType; [SerializeField] TMP_Dropdown region; [SerializeField] TMP_Dropdown animalTypes; [SerializeField] Toggle[] colors; [SerializeField] Sprite[] isOnSprite; // °Ë»ö °á°ú UI [SerializeField] ItemPrefab item; [SerializeField] Transform results; [SerializeField] GameObject listTop; [SerializeField] RectTransform content; [SerializeField] Animator searchUI; [SerializeField] GameObject loading; [SerializeField] Transform loadingImage; // ¸ð´Þ UI [SerializeField] ModalCtrl model; // °Ë»ö °á°ú µ¥ÀÌÅÍ private SearchRequest request = new SearchRequest(); [SerializeField] private List librarys; private bool hasMore; // °Ë»ö°á°ú UI ÇÁ¸®ÆÕ private List itemPrefabs; private ObjectPool itemPrefabPool; // ??? private bool isSearching = false; private bool isRefreshing = false; private Queue searchResults = new Queue(); bool isLoading = false; protected override void OnAwake() { name.onEndEdit.AddListener(INPUTFIELD); librarys = new List(); itemPrefabPool = new ObjectPool(itemPrefabs_OnCreate, itemPrefabs_OnGet, itemPrefabs_OnRelease, null, true, 100); itemPrefabs = new List(); } void INPUTFIELD(string input) { if (Input.GetKeyDown(KeyCode.Return) || Input.GetKeyDown(KeyCode.KeypadEnter)) { SearchButton(); } } #region ObjectPool private ItemPrefab itemPrefabs_OnCreate() { return Instantiate(item, results); } private void itemPrefabs_OnGet(ItemPrefab itemPrefab) { itemPrefabs.Add(itemPrefab); itemPrefab.gameObject.SetActive(true); } private void itemPrefabs_OnRelease(ItemPrefab itemPrefab) { itemPrefab.gameObject.SetActive(false); itemPrefabs.Remove(itemPrefab); } #endregion private void OnEnable() { hasMore = false; model.modelCanvas.SetActive(false); searchUI.SetTrigger("reset"); loading.SetActive(false); ResetButton(); ObjectClear(); } private void ObjectClear() { results.gameObject.SetActive(false); listTop.SetActive(false); librarys.Clear(); while (itemPrefabPool.CountActive > 0) { var item = itemPrefabs[itemPrefabs.Count - 1]; itemPrefabPool.Release(item); } } public void OpsionButton() { //¿É¼ÇâÀÌ ³ª¿ÀÁö ¾Ê¾ÒÀ»¶§ 250,100 //¿É¼ÇâÀÌ ³ª¿ÔÀ»¶§ 60 ,290 bool isSelf = !opsion.activeSelf; searchMenuButtonImage.sprite = searchMenuButton[(isSelf ? 1 : 0)]; searchMenuButtonImage.pixelsPerUnitMultiplier = (isSelf ? 3.5f : 1.75f); searchMenuButtonText.color = (isSelf ? Color.white : Color.black); searchUI.SetBool("isSelf", isSelf); ResetButton(); } public void SearchButton() { bool isBefore = true; if(request.fursuitName != name.text) { request.fursuitName = name.text; isBefore = false; } if (suitStyle.value != 0) { if (request.suitStyle != GameManager.Instance.suitStyle[suitStyle.value - 1].code_id) { request.suitStyle = GameManager.Instance.suitStyle[suitStyle.value - 1].code_id; isBefore = false; } } else if(request.suitStyle != "") { request.suitStyle = ""; isBefore = false; } if (suitType.value != 0) { if (request.suitType != GameManager.Instance.suitType[suitType.value - 1].code_id) { request.suitType = GameManager.Instance.suitType[suitType.value - 1].code_id; isBefore = false; } } else if (request.suitType != "") { request.suitType = ""; isBefore = false; } if (region.value != 0) { if (request.suitRegion != GameManager.Instance.region[region.value - 1].code_id) { request.suitRegion = GameManager.Instance.region[region.value - 1].code_id; isBefore = false; } } else if (request.suitRegion != "") { request.suitRegion = ""; isBefore = false; } if (animalTypes.value != 0) { if (request.suitAnimalType != GameManager.Instance.animalTypes[animalTypes.value - 1].code_id) { request.suitAnimalType = GameManager.Instance.animalTypes[animalTypes.value - 1].code_id; isBefore = false; } } else if (request.suitAnimalType != "") { request.suitAnimalType = ""; isBefore = false; } //ù °Ë»öÀ̰ųª ÀÌÀü°ú °Ë»ö°á°ú°¡ °°Áö ¾ÊÀ¸¸é °Ë»öÁøÇà if (!isBefore || !listTop.activeSelf) { request.offset = 0; request.page = 1; request.size = 10; ObjectClear(); results.gameObject.SetActive(true); listTop.SetActive(true); SearchSuiters().Forget(); } } private void Update() { if (isLoading) { loadingImage.rotation *= Quaternion.Euler(0, 0, 5); } } public async UniTask SearchSuiters() { if (isSearching) return; isSearching = true; var tcs = new TaskCompletionSource(); HTTPRequest searchRequest = NetworkManager.Instance.CreateRequest( "library/select/suiters", request, (data) => { for (int n = 0; n < data.data.Count; n++) { searchResults.Enqueue(data.data[n]); } hasMore = data.hasMore; tcs.SetResult(true); // ÀÀ´ä ¿Ï·á ½ÅÈ£ loading.SetActive(hasMore); } ); await searchRequest.Send(); await tcs.Task; // ÀÀ´äÀÌ ¿Ï·áµÉ ¶§±îÁö ´ë±â await RefreshScroll(); isSearching = false; } public async UniTask RefreshScroll() { if (isRefreshing) return; isRefreshing = true; if (searchResults.Count > 0) { while (searchResults.TryDequeue(out var result)) { librarys.Add(result); } } int n = 0; for (; n < itemPrefabs.Count; n++) { var item = itemPrefabs[n]; item.Set(librarys[n]); await UniTask.Yield(); } for (; n < librarys.Count; n++) { var item = itemPrefabPool.Get(); LayoutRebuilder.ForceRebuildLayoutImmediate(content); item.Set(librarys[n]); await UniTask.Yield(); } isLoading = false; loadingImage.rotation = Quaternion.identity; for (; n > librarys.Count; n--) { var item = itemPrefabs.Last(); itemPrefabPool.Release(item); await UniTask.Yield(); } await ApplayImages(); isRefreshing = false; } private async UniTask ApplayImages() { for (int i = 0; itemPrefabs.Count > i; i++) { await GetImage(itemPrefabs[i].library); itemPrefabs[i].ImageSet(); } } public async UniTask GetImage(Library library) { if (library._suit_image != null) { return library._suit_image; } var tcs = new TaskCompletionSource(); var request = NetworkManager.Instance.CreateImageRequest( library.imageBase64.Substring(1), new object(), (data) => { library._suit_image = data; tcs.SetResult(data); }, (fail) => { //Debug.LogError("GetImage Fail"); tcs.SetResult(null); }, BestHTTP.HTTPMethods.Get ); await request.Send(); await tcs.Task; return library._suit_image; } public void NextSearch() { if (isSearching == false) { hasMore = false; request.page++; SearchSuiters().Forget(); } } public void ResetButton() { suitStyle.value = 0; suitType.value = 0; region.value = 0; animalTypes.value = 0; for (int n = 0; n < colors.Length; n++) { colors[n].isOn = false; colors[n].image.sprite = isOnSprite[0]; } } public void OnToggle(int velue) { colors[velue].image.sprite = isOnSprite[(colors[velue].isOn ? 1 : 0)]; } public void ModelSet(Library library) { model.Set(library); } public void ScrollValue(RectTransform Content) { if (Content.anchoredPosition.y < 0.0f) { Content.anchoredPosition = Vector2.zero; } else if (hasMore && Content.sizeDelta.y != Screen.height && Content.sizeDelta.y - Screen.height < (Content.anchoredPosition.y + 25)) { isLoading = true; NextSearch(); } } } public class SearchRequest { public int xid; public string fursuitName = ""; /*¿À³Ê,½´Æ® À̸§*/ public string suitMaker; /*»ç¿ë¾ÈÇÔ*/ public string suitRegion = ""; /*Ȱµ¿ ±¹°¡*/ public string suitStyle = ""; /*½´Æ® ½ºÅ¸ÀÏ*/ public string suitAnimalType = ""; /*½´Æ® µ¿¹° Á¾*/ public string suitType = ""; /*½´Æ® ÇüÅÂ*/ public List colorList = new List(); /*½´Æ® »ö»ó*/ public int page = 1; public int size = 10; public int offset = 0; } public class SearchResponse { public List data; public bool hasMore; } public class ImageResponse { public byte[] imageBytes; } [Serializable] public class Library { public string imageBase64; public string suit_name; public string owner_id; public string owner_name; public string production_date; public Texture2D _suit_image = null; public string maker; public string region; public string animal_type; public string suit_style; public string suit_type; public List suit_color; }