using System; using System.Collections; using System.Collections.Generic; using System.Text.RegularExpressions; using UnityEngine; using UnityEngine.UI; using EnhancedUI.EnhancedScroller; namespace vnxbqy.UI { public class ChatContentBehaviour : MonoBehaviour { [SerializeField] ScrollerController m_ChatContentControl; [SerializeField] RichText m_DestSysText; [SerializeField] RichText m_DestTipText; [SerializeField] RectTransform m_ContaienrNewInfo; [SerializeField] Text m_NewInfoText; [SerializeField] Button m_NewInfoBtn; [SerializeField] Button m_LockAreaBtn; [SerializeField] Image m_LockAreaCheck; [SerializeField] RectTransform m_ContainerDisplay; [SerializeField] RectTransform m_ContainerPrivateChatRemind; [SerializeField] RectTransform m_Scroller; [SerializeField, Header("锁定当前区域比例"), Range(0, 1)] float m_Percent = 0.3f; [SerializeField] ChatPlayerMineCell m_ChatMineCell; [SerializeField] ChatPlayerOtherCell m_ChatOtherCell; [SerializeField] ChatMineVoiceCell m_ChatMineVoiceCell; [SerializeField] ChatOtherVoiceCell m_ChatOtherVoiceCell; private ChatInfoType m_ChatType = ChatInfoType.System; public ChatInfoType chatType { get { return m_ChatType; } set { bool isChange = m_ChatType != value; ResetNewInfo(); m_ChatType = value; DisplayChatContent(); if (isChange) { DisplayChatRemind(); } } } public ScrollerController chatContentControl { get { return m_ChatContentControl; } } private int cacheChatCount = 0; private bool onCheckArea = false; ChatCenter m_ChatCenter; ChatCenter chatCenter { get { return m_ChatCenter ?? (m_ChatCenter = ModelCenter.Instance.GetModel()); } } FriendsModel friendModel { get { return ModelCenter.Instance.GetModel(); } } private void Awake() { m_ChatContentControl.OnGetDynamicSize += OnGetChatDynamicSize; m_NewInfoBtn.onClick.AddListener(OnNewInfo); m_LockAreaBtn.onClick.AddListener(OnLockAreaBtn); m_ChatContentControl.mScrollRect.onValueChanged.AddListener(OnScrollValChange); if (m_DestSysText.font == null) { m_DestSysText.font = FontUtility.preferred; } if (m_DestTipText.font == null) { m_DestTipText.font = FontUtility.preferred; } } private void OnEnable() { DisplayChatContent(); DisplayChatRemind(); ChatCtrl.OnRefreshChat += OnRefreshChat; ChatCtrl.OnRefreshPteChat += OnRefreshPteChat; ChatCtrl.OnRefreshSelf += OnRefreshSelf; ChatCtrl.Inst.OnPteChatChangeEvent += OnPteChatChangeEvent; chatCenter.UpdateChatContent += UpdateChatContent; PlayerDatas.Instance.playerDataRefreshEvent += PlayerDataRefreshInfoEvent; friendModel.RefreshFriendCntEvent += RefreshFriendCntEvent; friendModel.RefreshFriendModel += DisplayChatRemind; ResetNewInfo(); UpdateChatContent(); if (m_ChatType == ChatInfoType.Friend) { DisplayChatContent(); JumpPteChatBottom(); } } private void OnPteChatChangeEvent() { if (m_ChatType == ChatInfoType.Friend) { DisplayChatContent(); DisplayChatRemind(); JumpPteChatBottom(); } } private void OnRefreshSelf(ChatData data) { chatCenter.ChangeChatValue(string.Empty, false, false); ChatCtrl.Inst.itemPlaceList.Clear(); if (m_ChatType == ChatInfoType.Friend) { JumpPteChatBottom(); } else { ChatCtrl.Inst.lockUpdate = false; } UpdateChatContent(); } private void OnRefreshPteChat(ChatFriendData data) { if (data == null) { return; } if (data.toPlayer != ChatCtrl.Inst.PteChatID && data.player != ChatCtrl.Inst.PteChatID) { return; } DisplayChatContent(true); float _displaySize = 0; if (m_ChatContentControl.mScrollRect != null) { _displaySize = m_ChatContentControl.mScrollRect.content.sizeDelta.y; } if (data.player == PlayerDatas.Instance.baseData.PlayerID) { OnRefreshSelf(data); } else if (ChatCtrl.Inst.lockUpdate && _displaySize > m_ChatContentControl.m_Scorller.ScrollRectSize) { cacheChatCount++; cacheChatCount = Mathf.Min(cacheChatCount, 999); m_NewInfoText.text = Language.Get("ChatNewWord", cacheChatCount); m_ContaienrNewInfo.SetActive(true); } } private void OnScrollValChange(Vector2 _pos) { if (m_ChatContentControl.mScrollRect.verticalNormalizedPosition < 0.1f && m_ChatType == ChatInfoType.Friend) { ResetNewInfo(); } if (m_ChatContentControl.m_Scorller._ScrollSize <= 0 || m_ChatType == ChatInfoType.Friend) { return; } float _value = m_Percent / m_ChatContentControl.m_Scorller._ScrollSize * m_ChatContentControl.m_Scorller.ScrollRectSize; if (_pos.y <= _value) { if (ChatCtrl.Inst.lockUpdate && !onCheckArea) { ChatCtrl.Inst.lockUpdate = false; UpdateLockAreaState(); ResetNewInfo(); } onCheckArea = true; } else { if (!ChatCtrl.Inst.lockUpdate) { ChatCtrl.Inst.lockUpdate = true; UpdateChatContent(); } onCheckArea = false; } } private void OnLockAreaBtn() { ChatCtrl.Inst.lockUpdate = !ChatCtrl.Inst.lockUpdate; UpdateChatContent(); } private void OnRefreshChat(ChatInfoType _type) { if (_type == m_ChatType) { DisplayChatContent(true); float _displaySize = 0; if (m_ChatContentControl.mScrollRect != null) { _displaySize = m_ChatContentControl.mScrollRect.content.sizeDelta.y; } if (ChatCtrl.Inst.lockUpdate && _displaySize > m_ChatContentControl.m_Scorller.ScrollRectSize) { cacheChatCount++; cacheChatCount = Mathf.Min(cacheChatCount, 999); m_NewInfoText.text = Language.Get("ChatNewWord", cacheChatCount); m_ContaienrNewInfo.SetActive(true); } } } private void ResetNewInfo() { cacheChatCount = 0; if (m_ContaienrNewInfo.gameObject.activeSelf) { m_ContaienrNewInfo.SetActive(false); } } private void DisplayChatContent(bool _keep = false) { float _offset = KeepArea(); m_ChatContentControl.Refresh(); if (m_ChatType != ChatInfoType.Friend) { List _list = ChatCtrl.Inst.GetChatInfo(m_ChatType); if (_list != null) { for (int i = 0; i < _list.Count; i++) { switch (_list[i].type) { case ChatInfoType.World: case ChatInfoType.Area: case ChatInfoType.CrossServer: case ChatInfoType.Team: case ChatInfoType.Trumpet: case ChatInfoType.Fairy: case ChatInfoType.default1: case ChatInfoType.default2: ChatUeseData data = _list[i] as ChatUeseData; if (data.detailType == ChatInfoType.FairyQuestion || data.detailType == ChatInfoType.FairyTip || data.detailType == ChatInfoType.TeamTip || data.detailType == ChatInfoType.default2) { m_ChatContentControl.AddCell(ScrollerDataType.Extra1, i); } else { if (data.IsSound) { m_ChatContentControl.AddCell(data.player == PlayerDatas.Instance.PlayerId ? ScrollerDataType.Extra2 : ScrollerDataType.Extra3, i); break; } if (data.player == PlayerDatas.Instance.baseData.PlayerID) { m_ChatContentControl.AddCell(ScrollerDataType.Header, i); } else { m_ChatContentControl.AddCell(ScrollerDataType.Normal, i); } } break; case ChatInfoType.Invite: case ChatInfoType.System: { m_ChatContentControl.AddCell(ScrollerDataType.Tail, i); } break; } } } } else { List _list = ChatCtrl.Inst.GetChatInfo(ChatCtrl.Inst.PteChatID); if (_list != null) { for (int i = 0; i < _list.Count; i++) { if (_list[i].IsSound) { m_ChatContentControl.AddCell(_list[i].player == PlayerDatas.Instance.PlayerId ? ScrollerDataType.Extra2 : ScrollerDataType.Extra3, i); continue; } if (Regex.IsMatch(_list[i].content, ChatCtrl.KILL_IDENTIFY)) { m_ChatContentControl.AddCell(ScrollerDataType.Tail, i); continue; } if (_list[i].player == PlayerDatas.Instance.baseData.PlayerID) { m_ChatContentControl.AddCell(ScrollerDataType.Header, i); } else { m_ChatContentControl.AddCell(ScrollerDataType.Normal, i); } } } } m_ChatContentControl.Restart(); if (_keep && ChatCtrl.Inst.lockUpdate) { m_ChatContentControl.JumpIndex(-_offset, 0, EnhancedUI.EnhancedScroller.EnhancedScroller.TweenType.immediate); } m_LockAreaBtn.SetActive(m_ChatType != ChatInfoType.Friend); } private void DisplayChatRemind() { if (m_ContainerPrivateChatRemind != null) { bool requireRemind = false; var _dict = friendModel.GetFriendInfoDict((byte)GroupType.RecentContact); if (m_ChatType == ChatInfoType.Friend) { if (WindowCenter.Instance.IsOpen()) { if (((_dict != null && _dict.Count > 0) || friendModel.tempFriendData != null) && ChatCtrl.Inst.PteChatID > 0) { requireRemind = true; } } else { requireRemind = true; } } var displayAreaHeight = m_ContainerDisplay.rect.height; m_ContainerPrivateChatRemind.SetActive(requireRemind); if (requireRemind) { displayAreaHeight = m_ContainerDisplay.rect.height - m_ContainerPrivateChatRemind.rect.height; } m_Scroller.sizeDelta = m_Scroller.sizeDelta.SetY(displayAreaHeight); } } float KeepArea() { if (m_ChatContentControl.GetNumberOfCells(m_ChatContentControl.m_Scorller) == ChatCtrl.Inst.CHAT_INFO_CNT) { var count = 0; if (m_ChatType == ChatInfoType.Friend) { var list = ChatCtrl.Inst.GetChatInfo(ChatCtrl.Inst.PteChatID); count = list == null ? 0 : list.Count; } else { var list = ChatCtrl.Inst.GetChatInfo(m_ChatType); count = list == null ? 0 : list.Count; } if (count == ChatCtrl.Inst.CHAT_INFO_CNT) { var first_size = m_ChatContentControl.GetCellSize(0); return first_size; } } return 0; } private void SoundReceiveEvent(ChatInfoType _type, int _index) { if (m_ChatType != _type) { return; } m_ChatContentControl.RefreshSingleCellView(_index); } private bool OnGetChatDynamicSize(ScrollerDataType _type, int _index, out float _height) { _height = 0; ChatData chat = null; if (m_ChatType == ChatInfoType.Friend) { var _list = ChatCtrl.Inst.GetChatInfo(ChatCtrl.Inst.PteChatID); if (_list == null || _index >= _list.Count) { return false; } chat = _list[_index]; } else { List _list = ChatCtrl.Inst.GetChatInfo(m_ChatType); if (_list == null || _index >= _list.Count) { return false; } chat = _list[_index]; } if (chat == null) { return false; } switch (_type) { case ScrollerDataType.Header: _height = m_ChatMineCell.GetHeight(chat.content, chat.infoList); return true; case ScrollerDataType.Normal: _height = m_ChatOtherCell.GetHeight(chat.content, chat.infoList); return true; case ScrollerDataType.Extra1: case ScrollerDataType.Tail: _height = 30; break; case ScrollerDataType.Extra2: _height = m_ChatMineVoiceCell.GetHeight(chat.content, chat.infoList); return true; case ScrollerDataType.Extra3: _height = m_ChatOtherVoiceCell.GetHeight(chat.content, chat.infoList); return true; } OnGetChatDynamicHeight(chat.content, ref _height, _type, chat.infoList); return true; } private void OnGetChatDynamicHeight(string _content, ref float _height, ScrollerDataType _type, ArrayList _infoList) { float _textHeight = 0; if (_type == ScrollerDataType.Tail) { m_DestSysText.SetExtenalData(_infoList); m_DestSysText.text = _content; _textHeight = Mathf.Max(m_DestSysText.preferredHeight, m_DestSysText.fontSize); _height += Mathf.Max(0, _textHeight - 23); } else if (_type == ScrollerDataType.Extra1) { m_DestTipText.SetExtenalData(_infoList); m_DestTipText.text = _content; _textHeight = Mathf.Max(m_DestTipText.preferredHeight, m_DestTipText.fontSize); _height += Mathf.Max(0, _textHeight - 23); } } private void UpdateChatContent() { UpdateLockAreaState(); if (!ChatCtrl.Inst.lockUpdate) { chatContentControl.ResetScrollPos(); ResetNewInfo(); } } private void UpdateLockAreaState() { chatContentControl.lockType = ChatCtrl.Inst.lockUpdate ? EnhanceLockType.KeepVertical : EnhanceLockType.LockVerticalBottom; m_LockAreaCheck.SetActive(ChatCtrl.Inst.lockUpdate); } private void OnNewInfo() { if (m_ChatType != ChatInfoType.Friend) { ChatCtrl.Inst.lockUpdate = false; } else { JumpPteChatBottom(); } UpdateChatContent(); } private void JumpPteChatBottom() { ChatCtrl.Inst.lockUpdate = true; chatContentControl.lockType = EnhanceLockType.LockVerticalBottom; chatContentControl.ResetScrollPos(); ResetNewInfo(); chatContentControl.lockType = EnhanceLockType.KeepVertical; } private void OnDisable() { ChatCtrl.OnRefreshChat -= OnRefreshChat; ChatCtrl.OnRefreshPteChat -= OnRefreshPteChat; ChatCtrl.OnRefreshSelf -= OnRefreshSelf; chatCenter.UpdateChatContent -= UpdateChatContent; ChatCtrl.Inst.OnPteChatChangeEvent -= OnPteChatChangeEvent; PlayerDatas.Instance.playerDataRefreshEvent -= PlayerDataRefreshInfoEvent; friendModel.RefreshFriendCntEvent -= RefreshFriendCntEvent; friendModel.RefreshFriendModel -= DisplayChatRemind; } private void RefreshFriendCntEvent(GroupType type, bool arg2) { if (type == GroupType.RecentContact && m_ChatType == ChatInfoType.Friend) { DisplayChatRemind(); if (WindowCenter.Instance.IsOpen()) { var _dict = friendModel.GetFriendInfoDict((byte)GroupType.RecentContact); if (!_dict.ContainsKey((uint)ChatCtrl.Inst.PteChatID)) { ChatCtrl.Inst.PteChatID = 0; } } } } private void PlayerDataRefreshInfoEvent(PlayerDataType refreshType) { if (refreshType == PlayerDataType.ExAttr10) { m_ChatContentControl.m_Scorller.RefreshActiveCellViews(); } } } }