178 lines
4.5 KiB
C#
178 lines
4.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using CSNetwork;
|
|
using UnityEngine;
|
|
using UnityEngine.Pool;
|
|
using UnityEngine.UI;
|
|
|
|
namespace BrewMonster.Scripts.ChatUI
|
|
{
|
|
public class ChatPanelUI : MonoBehaviour
|
|
{
|
|
[Header("UI")] public ScrollRect scrollRect;
|
|
public GameObject chatPanelUIGO;
|
|
public RectTransform content;
|
|
public ChatMessageView messagePrefab;
|
|
//public GameObject newMessageIndicator;
|
|
|
|
[Header("Config")] public int maxVisibleMessages = 30;
|
|
public int maxStoredMessages = 2000;
|
|
|
|
private List<string> _messages = new();
|
|
private List<ChatMessageView> _visibleViews = new();
|
|
|
|
private ObjectPool<ChatMessageView> _pool;
|
|
|
|
private bool _userAtBottom = true;
|
|
|
|
void Awake()
|
|
{
|
|
EventBus.Subscribe<GameSession.ChatMessageEvent>(OnChatMessageReceived);
|
|
_pool = new ObjectPool<ChatMessageView>(
|
|
CreateItem,
|
|
OnGetItem,
|
|
OnReleaseItem,
|
|
OnDestroyItem,
|
|
false,
|
|
10,
|
|
100
|
|
);
|
|
|
|
scrollRect.onValueChanged.AddListener(OnScrollChanged);
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
EventBus.Unsubscribe<GameSession.ChatMessageEvent>(OnChatMessageReceived);
|
|
}
|
|
|
|
private void OnChatMessageReceived(GameSession.ChatMessageEvent x)
|
|
{
|
|
ChatThreadDispatcher.Instance.Post(() =>
|
|
{
|
|
AddMessage(x.context);
|
|
});
|
|
}
|
|
|
|
ChatMessageView CreateItem()
|
|
{
|
|
var item = Instantiate(messagePrefab);
|
|
item.transform.SetParent(content, false);
|
|
return item;
|
|
}
|
|
|
|
void OnGetItem(ChatMessageView item)
|
|
{
|
|
item.gameObject.SetActive(true);
|
|
}
|
|
|
|
void OnReleaseItem(ChatMessageView item)
|
|
{
|
|
item.gameObject.SetActive(false);
|
|
}
|
|
|
|
void OnDestroyItem(ChatMessageView item)
|
|
{
|
|
Destroy(item.gameObject);
|
|
}
|
|
|
|
void OnScrollChanged(Vector2 pos)
|
|
{
|
|
_userAtBottom = scrollRect.verticalNormalizedPosition <= 0.001f;
|
|
|
|
if (_userAtBottom)
|
|
{
|
|
//newMessageIndicator.SetActive(false);
|
|
}
|
|
}
|
|
|
|
bool IsAtBottom()
|
|
{
|
|
return scrollRect.verticalNormalizedPosition <= 0.001f;
|
|
}
|
|
|
|
public void AddMessage(string msg)
|
|
{
|
|
_messages.Add(msg);
|
|
|
|
if (_messages.Count > maxStoredMessages)
|
|
_messages.RemoveAt(0);
|
|
|
|
if (!chatPanelUIGO.activeSelf)
|
|
return;
|
|
|
|
AddMessageView(msg);
|
|
|
|
if (_userAtBottom)
|
|
ScrollToBottom();
|
|
}
|
|
|
|
void AddMessageView(string msg)
|
|
{
|
|
var view = _pool.Get();
|
|
view.transform.SetParent(content, false);
|
|
view.transform.SetAsLastSibling();
|
|
view.Bind(msg);
|
|
|
|
_visibleViews.Add(view);
|
|
|
|
if (_visibleViews.Count > maxVisibleMessages)
|
|
{
|
|
var old = _visibleViews[0];
|
|
_visibleViews.RemoveAt(0);
|
|
_pool.Release(old);
|
|
}
|
|
|
|
Canvas.ForceUpdateCanvases();
|
|
}
|
|
|
|
void RefreshVisible()
|
|
{
|
|
foreach (var view in _visibleViews)
|
|
_pool.Release(view);
|
|
|
|
_visibleViews.Clear();
|
|
|
|
int start = Mathf.Max(0, _messages.Count - maxVisibleMessages);
|
|
|
|
for (int i = start; i < _messages.Count; i++)
|
|
{
|
|
var view = _pool.Get();
|
|
view.transform.SetParent(content, false);
|
|
view.transform.SetAsLastSibling();
|
|
view.Bind(_messages[i]);
|
|
|
|
_visibleViews.Add(view);
|
|
}
|
|
|
|
Canvas.ForceUpdateCanvases();
|
|
ScrollToBottom();
|
|
}
|
|
|
|
public void ScrollToBottom()
|
|
{
|
|
Canvas.ForceUpdateCanvases();
|
|
scrollRect.verticalNormalizedPosition = 0f;
|
|
//newMessageIndicator.SetActive(false);
|
|
}
|
|
|
|
public void ClearChat()
|
|
{
|
|
foreach (var view in _visibleViews)
|
|
_pool.Release(view);
|
|
|
|
_visibleViews.Clear();
|
|
_messages.Clear();
|
|
}
|
|
|
|
public void OnHandlerChatButton()
|
|
{
|
|
bool open = !chatPanelUIGO.activeSelf;
|
|
chatPanelUIGO.SetActive(open);
|
|
|
|
if (open)
|
|
RefreshVisible();
|
|
}
|
|
}
|
|
}
|