Files
ft/Client/Assets/Scripts/UI/PartnerStatue/EventPartnerStatueInvitationPanel.cs
2026-06-29 21:18:33 +08:00

420 lines
16 KiB
C#

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<ScrollViewItemInfo> _scrollViewInfoList,
_requestList,
_recommendList,
_friendList,
_invitationList;
// private readonly FriendService _friendService = GContext.container.Resolve<FriendService>();
// private readonly IUserService _userService = GContext.container.Resolve<IUserService>();
// private Tables _tables;
private CompositeDisposable _disposables = new();
private EventPartnerGatherScrollViewAutoMatch _autoMatchView;
private class GroupSection
{
public string TitleKey;
public List<ScrollViewItemInfo> Items;
}
private List<GroupSection> _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<ScrollViewItemInfo>();
_recommendList = new List<ScrollViewItemInfo>();
_friendList = new List<ScrollViewItemInfo>();
_invitationList = new List<ScrollViewItemInfo>();
emptyGo.SetActive(false);
loadingGo.SetActive(false);
InitScrollView();
UpdateAutoMatchStatus();
GContext.OnEvent<EventPartnerGatherClickInvite>().Subscribe(OnInvite).AddTo(_disposables);
GContext.OnEvent<EventPartnerGatherClickAccept>().Subscribe(OnAccept).AddTo(_disposables);
GContext.OnEvent<EventPartnerGatherClickIgnore>().Subscribe(OnRefuse).AddTo(_disposables);
GContext.OnEvent<EventForAutoMatchChangeStage>().Subscribe(OnAutoMatchStateChange).AddTo(_disposables);
GContext.OnEvent<EventAutoMatchFailed>().Subscribe(OnAutoMatchFailed).AddTo(_disposables);
GContext.OnEvent<EventTryCloseAutoMatch>().Subscribe(OnTryCloseAutoMatch).AddTo(_disposables);
GContext.container.Resolve<GuideDataCenter>().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<ClubService>().OpenFishingSocialPanel(1);
}
private void InitScrollView()
{
loadingGo.SetActive(true);
var arc = GContext.container.Resolve<EventPartnerStatueArc>();
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<EventPartnerStatueArc>();
_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<GroupSection>
{
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<EventPartnerStatueArc>();
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<EventPartnerStatueArc>();
var invitationInfo = e.Info;
try
{
var partnerId = invitationInfo.PlayfabId;
if (RobotDataManager.IsRobot(partnerId))
arc.RobotData.PushToBuffer(partnerId);
else
{
// Debug.Log($"<color=#c191ff>[EventPartner]Inviting!</color>");
var resp = await arc.Requests.Invite(partnerId);
resp ??= new EventPartnerGatherOperationResp
{
State = EEventBuildState.Failed,
ErrorMessage = "Null response"
};
if (resp.State != EEventBuildState.Success)
{
Debug.Log($"<color=cyan>Fail to invite {partnerId} with code {resp.State}: {resp.ErrorMessage}</color>");
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<EventPartnerStatueArc>();
var info = e.Info;
try
{
if (arc.IsFull())
{
Debug.Log("<color=#c191ff>[EventPartner]Cannot accept. Fully matched.</color>");
ToastPanel.Show(LocalizationMgr.GetText(PlayerFullKey));
OnClickClose();
return;
}
// Debug.Log($"<color=#c191ff>[EventPartner]Accepting!</color>");
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($"<color=red>[EventPartner] Code: {response.State}</color>");
Debug.Log($"<color=red>[EventPartner] Event partner accept error from server: {response.Message}</color>");
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($"<color=#c191ff>[EventPartner]{ex}</color>");
ActiavteScrollerItemButtons();
}
}
private void OnRefuse(EventPartnerGatherClickIgnore e)
{
var arc = GContext.container.Resolve<EventPartnerStatueArc>();
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<EventPartnerGatherScrollViewItem>())
{
item.ActivateButton();
}
}
#region AutoMatch
private void UpdateAutoMatchUI(AutoMatchState state)
{
if (_autoMatchView)
_autoMatchView.SetupState(state);
}
private void UpdateAutoMatchStatus()
{
var arc = GContext.container.Resolve<EventPartnerStatueArc>();
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<EventPartnerStatueArc>();
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
}