using System; using System.Collections.Generic; using UnityEngine; using EnhancedUI.EnhancedScroller; using UnityEngine.UI; using UI.PartnerGather; using game; using asap.core; using UniRx; using GameCore; using System.Linq; using ScrollViewItemInfo = EventPartnerScrollViewItem.ScrollViewItemInfo; using EScrollViewType = EventPartnerScrollViewItem.EScrollViewType; using EventPartner; using EventPartnerGather; using EventPartnerGatherRequests; using System.Threading.Tasks; using UI.PartnerGather.ScrollItems; public class EventPartnerStatueInvitationPanel : MonoBehaviour, IEnhancedScrollerDelegate { [SerializeField] private EnhancedScroller scrollView; [SerializeField] private Button btnClose, btnAddFriends; [SerializeField] private EventPartnerGatherScrollViewItem scrollViewItemPrefab; [SerializeField] private EventPartnerScrollViewTitle scrollViewTitlePrefab; [SerializeField] private EventPartnerGatherScrollViewAutoMatch scrollViewItemAutoMatch; [SerializeField] private GameObject emptyGo, loadingGo; private const string RequestTitleKey = "UI_EventPartnerMiningPanel_7"; private const string RecommendTitleKey = "UI_EventPartnerFishbowlPanel_30"; private const string FriendTitleKey = "UI_EventPartnerFishbowlPanel_31"; private const string InvitationTitleKey = "UI_EventPartnerFishbowlPanel_36"; private readonly string PlayerFullKey = "UI_ToastPanel_80"; // private readonly string CommonErrorKey = "UI_EventPartnerMiningPanel_12"; // private readonly string AlreadyExistKey = "UI_EventPartnerMiningPanel_10"; private readonly string PartnerFullKey = "UI_EventPartnerMiningPanel_11"; private List _scrollViewInfoList, _requestList, _recommendList, _friendList, _invitationList; // private readonly FriendService _friendService = GContext.container.Resolve(); // private readonly IUserService _userService = GContext.container.Resolve(); // private Tables _tables; private CompositeDisposable _disposables = new(); private EventPartnerGatherScrollViewAutoMatch _autoMatchView; private class GroupSection { public string TitleKey; public List Items; } private List _sections; [SerializeField] private float jiandaTitleHeight = 72f, jiandaItemHeight = 150f; [SerializeField] private float sectionItemSpacing = 0f; [SerializeField] private float autoMatchHeight = 144f; private void Start() { btnClose.onClick.AddListener(OnClickClose); btnAddFriends.onClick.AddListener(OnClickAddFriends); scrollView.lookAheadBefore = 500f; scrollView.lookAheadAfter = 500f; _scrollViewInfoList = new List(); _recommendList = new List(); _friendList = new List(); _invitationList = new List(); emptyGo.SetActive(false); loadingGo.SetActive(false); InitScrollView(); UpdateAutoMatchStatus(); GContext.OnEvent().Subscribe(OnInvite).AddTo(_disposables); GContext.OnEvent().Subscribe(OnAccept).AddTo(_disposables); GContext.OnEvent().Subscribe(OnRefuse).AddTo(_disposables); GContext.OnEvent().Subscribe(OnAutoMatchStateChange).AddTo(_disposables); GContext.OnEvent().Subscribe(OnAutoMatchFailed).AddTo(_disposables); GContext.OnEvent().Subscribe(OnTryCloseAutoMatch).AddTo(_disposables); GContext.container.Resolve().InspectTriggerGuide("EventPartnerStatueInvitationPanel", curPanelName: gameObject.name); } private void OnDestroy() { _disposables.Dispose(); _disposables = null; btnClose.onClick.RemoveAllListeners(); btnAddFriends.onClick.RemoveAllListeners(); } private void OnClickClose() { UIManager.Instance.DestroyUI(gameObject.name); } private void OnClickAddFriends() { GContext.container.Resolve().OpenFishingSocialPanel(1); } private void InitScrollView() { loadingGo.SetActive(true); var arc = GContext.container.Resolve(); arc.InvitationData.FillInFriends();// in case of insufficient friend data at init arc.PlayerInfoPool.FillInFriends(); _requestList = arc.InvitationData.RequestPfIdSet .Select(id => arc.GetScrollViewItemInfo(id, EScrollViewType.Partner2Accept)) .ToList(); _recommendList = arc.InvitationData.RecommendPfIdSet .Select(id => arc.GetScrollViewItemInfo(id, EScrollViewType.Recommendation)) .ToList(); _friendList = arc.InvitationData.FriendPfIdSet .Select(id => arc.GetScrollViewItemInfo(id, EScrollViewType.Friend)) .ToList(); _invitationList = arc.InvitationData.InvitePfIdSet .Select(id => arc.GetScrollViewItemInfo(id, EScrollViewType.MyInvitation)) .ToList(); RebuildSections(); BuildScrollViewInfoList(); scrollView.Delegate = this; loadingGo.SetActive(false); ReloadScrollViewData(); } private void ReloadScrollView() { loadingGo.SetActive(true); var arc = GContext.container.Resolve(); _requestList = arc.InvitationData.RequestPfIdSet .Select(id => arc.GetScrollViewItemInfo(id, EScrollViewType.Partner2Accept)) .ToList(); _recommendList = arc.InvitationData.RecommendPfIdSet .Select(id => arc.GetScrollViewItemInfo(id, EScrollViewType.Recommendation)) .ToList(); _friendList = arc.InvitationData.FriendPfIdSet .Select(id => arc.GetScrollViewItemInfo(id, EScrollViewType.Friend)) .ToList(); _invitationList = arc.InvitationData.InvitePfIdSet .Select(id => arc.GetScrollViewItemInfo(id, EScrollViewType.MyInvitation)) .ToList(); RebuildSections(); BuildScrollViewInfoList(); loadingGo.SetActive(false); ReloadScrollViewData(); } private void RebuildSections() { _sections = new List { new() { TitleKey = RequestTitleKey, Items = _requestList }, new() { TitleKey = RecommendTitleKey, Items = _recommendList }, new() { TitleKey = FriendTitleKey, Items = _friendList }, new() { TitleKey = InvitationTitleKey, Items = _invitationList }, }; } private void ReloadScrollViewData() { scrollView.ReloadData(); Canvas.ForceUpdateCanvases(); var onlyAutoMatch = _scrollViewInfoList.Count <= 1; emptyGo.SetActive(onlyAutoMatch); } #region EnhancedScrollerDelegate public int GetNumberOfCells(EnhancedScroller scroller) { return _scrollViewInfoList.Count; } private float GetSectionCellHeight(int itemCount) { if (itemCount <= 0) return jiandaTitleHeight; return jiandaTitleHeight + itemCount * jiandaItemHeight + Mathf.Max(0, itemCount - 1) * sectionItemSpacing; } public float GetCellViewSize(EnhancedScroller scroller, int dataIndex) { var info = _scrollViewInfoList[dataIndex]; switch (info.Type) { case EScrollViewType.AutoMatch: return autoMatchHeight; case EScrollViewType.Section: return GetSectionCellHeight(info.SectionItems?.Count ?? 0); default: return jiandaItemHeight; } } public EnhancedScrollerCellView GetCellView(EnhancedScroller scroller, int dataIndex, int cellIndex) { var info = _scrollViewInfoList[dataIndex]; switch (info.Type) { case EScrollViewType.Section: if (scroller.GetCellView(scrollViewTitlePrefab) is not EventPartnerScrollViewTitle sectionCell) return null; sectionCell.Init(info, jiandaItemHeight, sectionItemSpacing); return sectionCell; case EScrollViewType.AutoMatch: if (scroller.GetCellView(scrollViewItemAutoMatch) is not EventPartnerGatherScrollViewAutoMatch cellViewAutoMatch) return null; _autoMatchView = cellViewAutoMatch; { var arc = GContext.container.Resolve(); var state = arc.IsAutoMatchEnabled ? AutoMatchState.AutoMatchOn : AutoMatchState.AutoMatchOff; _autoMatchView.ApplyHostBinding(state); } return cellViewAutoMatch; default: throw new ArgumentOutOfRangeException(nameof(info.Type), info.Type, null); } } #endregion private void BuildScrollViewInfoList() { _scrollViewInfoList.Clear(); _scrollViewInfoList.Add(new ScrollViewItemInfo { Type = EScrollViewType.AutoMatch }); foreach (var section in _sections) { if (section.Items is not { Count: > 0 }) continue; _scrollViewInfoList.Add(new ScrollViewItemInfo { Type = EScrollViewType.Section, Title = LocalizationMgr.GetText(section.TitleKey), SectionItems = section.Items, }); } } #region Operation Callback private async void OnInvite(EventPartnerGatherClickInvite e) { // Log($"OnInvite -> {invitationInfo.PlayfabId}"); var arc = GContext.container.Resolve(); var invitationInfo = e.Info; try { var partnerId = invitationInfo.PlayfabId; if (RobotDataManager.IsRobot(partnerId)) arc.RobotData.PushToBuffer(partnerId); else { // Debug.Log($"[EventPartner]Inviting!"); var resp = await arc.Requests.Invite(partnerId); resp ??= new EventPartnerGatherOperationResp { State = EEventBuildState.Failed, ErrorMessage = "Null response" }; if (resp.State != EEventBuildState.Success) { Debug.Log($"Fail to invite {partnerId} with code {resp.State}: {resp.ErrorMessage}"); if (resp.State == EEventBuildState.AlreadyExist || resp.State == EEventBuildState.Full || resp.State == EEventBuildState.NoActiveEvent) { arc.InvitationData.OnRefuse(e.Info.PlayfabId); ReloadScrollView(); if (_scrollViewInfoList.Count <= 1) OnClickClose(); } ActiavteScrollerItemButtons(); return; } } arc.InvitationData.OnInvite(partnerId); ReloadScrollView(); ActiavteScrollerItemButtons(); } catch (System.Exception ex) { Debug.LogError(ex); ActiavteScrollerItemButtons(); } } private async void OnAccept(EventPartnerGatherClickAccept e) { var arc = GContext.container.Resolve(); var info = e.Info; try { if (arc.IsFull()) { Debug.Log("[EventPartner]Cannot accept. Fully matched."); ToastPanel.Show(LocalizationMgr.GetText(PlayerFullKey)); OnClickClose(); return; } // Debug.Log($"[EventPartner]Accepting!"); var response = await arc.Requests.Accept(info.PlayfabId); response ??= new EventPartnerGatherAcceptResponse { State = EEventBuildState.Failed, Message = "Null response." }; switch (response.State) { case EEventBuildState.Failed: case EEventBuildState.Full: case EEventBuildState.AlreadyExist: Debug.Log($"[EventPartner] Code: {response.State}"); Debug.Log($"[EventPartner] Event partner accept error from server: {response.Message}"); arc.InvitationData.OnRefuse(info.PlayfabId); ReloadScrollView(); ToastPanel.Show(LocalizationMgr.GetText(PartnerFullKey)); break; case EEventBuildState.Success: arc.InvitationData.OnAccept(info.PlayfabId); var idx = arc.AddPartner(info.PlayfabId); arc.EventTrackingSystem.InvitePartnerId = RobotDataManager.IsRobot(info.PlayfabId) ? "Robot" : info.PlayfabId; arc.EventTrackingSystem.InviteSlotId = idx; arc.EventTrackingSystem.InviteId = 2; arc.EventTrackingSystem.ReportInvite(); OnClickClose(); break; default: break; } ActiavteScrollerItemButtons(); } catch (System.Exception ex) { Debug.Log($"[EventPartner]{ex}"); ActiavteScrollerItemButtons(); } } private void OnRefuse(EventPartnerGatherClickIgnore e) { var arc = GContext.container.Resolve(); if (e.Info.Type != EScrollViewType.Partner2Accept && e.Info.Type != EScrollViewType.Recommendation) { Debug.LogWarning($"[EventPartner] OnRefuse: Invalid type: {e.Info.Type}"); ActiavteScrollerItemButtons(); return; } arc.InvitationData.OnRefuse(e.Info.PlayfabId); ReloadScrollView(); if (_scrollViewInfoList.Count <= 1) OnClickClose(); ActiavteScrollerItemButtons(); } #endregion private void ActiavteScrollerItemButtons() { foreach (var item in scrollView.GetComponentsInChildren()) { item.ActivateButton(); } } #region AutoMatch private void UpdateAutoMatchUI(AutoMatchState state) { if (_autoMatchView) _autoMatchView.SetupState(state); } private void UpdateAutoMatchStatus() { var arc = GContext.container.Resolve(); var state = arc.IsAutoMatchEnabled ? AutoMatchState.AutoMatchOn : AutoMatchState.AutoMatchOff; UpdateAutoMatchUI(state); } private void OnAutoMatchStateChange(EventForAutoMatchChangeStage e) { UpdateAutoMatchUI(e.State); } private void OnAutoMatchFailed(EventAutoMatchFailed e) { Debug.LogError($"[EventPartnerStatueInvitationPanel] AutoMatchFailed reason={e.Reason}"); UpdateAutoMatchUI(AutoMatchState.AutoMatchOff); } private void OnTryCloseAutoMatch(EventTryCloseAutoMatch e) { var arc = GContext.container.Resolve(); if (!arc.CanStopAutoMatch(out var leftTimes)) { if (leftTimes > 0) { var text = LocalizationMgr.GetFormatTextValue("UI_EventPartnerMiningPanel_13", leftTimes); ToastPanel.Show(text); } GContext.Publish(new EventTryCloseAutoMatchResult { IsCanClose = false }); } else { GContext.Publish(new EventTryCloseAutoMatchResult { IsCanClose = true }); } } #endregion }