Unity_Web/Assets/1_Script/SearchCtrl.cs

433 lines
12 KiB
C#

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 System.Runtime.CompilerServices;
public class SearchCtrl : SingletonMonoBehaviour<SearchCtrl>
{
//옵션 페이지 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<Library> librarys;
private bool hasMore;
// 검색결과 UI 프리팹
private List<ItemPrefab> itemPrefabs;
private ObjectPool<ItemPrefab> itemPrefabPool;
// ???
private bool isSearching = false;
private bool isRefreshing = false;
private Queue<Library> searchResults = new Queue<Library>();
bool isLoading = false;
protected override void OnAwake()
{
name.onEndEdit.AddListener(INPUTFIELD);
librarys = new List<Library>();
itemPrefabPool = new ObjectPool<ItemPrefab>(itemPrefabs_OnCreate, itemPrefabs_OnGet, itemPrefabs_OnRelease, null, true, 100);
itemPrefabs = new List<ItemPrefab>();
}
void INPUTFIELD(string input)
{
if (Input.GetKeyDown(KeyCode.Return) || Input.GetKeyDown(KeyCode.KeypadEnter))
{
SearchButton();
}
}
#region ObjectPool
private ItemPrefab itemPrefabs_OnCreate()
{
return Instantiate<ItemPrefab>(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;
}
List<string> selectColor = new List<string>();
for (int n = 0; n < colors.Length; n++) {
if (colors[n].isOn)
{
selectColor.Add((n + (int)GameManager.eColor.).ToString());
}
}
if(selectColor.Count != request.colorList.Count)
{
request.colorList = selectColor;
isBefore = false;
}
else
{
for(int n = 0; n < selectColor.Count; n++)
{
if (selectColor[n] != request.colorList[n])
{
request.colorList = selectColor;
isBefore = false;
break;
}
}
}
//첫 검색이거나 이전과 검색결과가 같지 않으면 검색진행
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<bool>();
HTTPRequest searchRequest = NetworkManager.Instance.CreateRequest<SearchResponse>("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<Texture2D> GetImage(Library library)
{
if (library._suit_image != null)
{
return library._suit_image;
}
var tcs = new TaskCompletionSource<Texture2D>();
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<string> colorList = new List<string>(); /*슈트 색상*/
public int page = 1;
public int size = 10;
public int offset = 0;
}
public class SearchResponse
{
public List<Library> data;
public bool hasMore;
}
public class ImageResponse
{
public byte[] imageBytes;
}
[Serializable]
public class Library
{
public string imageBase64;
public string suit_name;
public string user_info;
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<string> suit_color;
}