NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Gameplay/UI/UI_NoticeController.cs

624 lines
18 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using TMPro;
using System;
using PhxhSDK;
using Gameplay;
using UnityEngine;
using UnityEngine.UI;
using System.Globalization;
using Cysharp.Threading.Tasks;
using System.Collections.Generic;
/// <summary>
/// 公告UI
/// </summary>
public class UI_NoticeController : UIWindow
{
/// <summary>
/// 打开公告界面
/// </summary>
public static async UniTask<UIWindow> Open(int id = -1, E_NoticeType type = E_NoticeType.Activity)
{
CommonUtils.CaptureScreenshot();
InputData inputData = new()
{
OpenType = type,
Idx = id,
};
return await UIManager.Instance.CreateAndOpenWindow(UINameConst.UI_Notice, inputData);
}
private struct InputData
{
public E_NoticeType OpenType;
public int Idx;
}
#region 类
/// <summary>
/// 公告类型
/// </summary>
private class NoticeTypeTab : UIGameObjectWrapper
{
#region UI
/// <summary>
/// 选中按钮
/// </summary>
private Button buttonChoose;
/// <summary>
/// 未选中按钮
/// </summary>
private Button buttonNormal;
/// <summary>
/// 公告类型
/// </summary>
private readonly E_NoticeType noticeType;
/// <summary>
/// 公告索引
/// </summary>
private readonly int index;
/// <summary>
/// 点击回调
/// </summary>
private readonly Action<E_NoticeType> clickAction;
/// <summary>
/// 选中红点
/// </summary>
private RedPointUIController redPointChoose;
/// <summary>
/// 未选中红点
/// </summary>
private RedPointUIController redPointNormal;
#endregion
/// <summary>
/// 是否选中
/// </summary>
public bool IsSelect
{
set
{
buttonChoose.gameObject.IsScaleShow(value);
buttonNormal.gameObject.IsScaleShow(!value);
}
}
public NoticeTypeTab(GameObject root, E_NoticeType noticeType, Action<E_NoticeType> click) : base(root, true)
{
this.noticeType = noticeType;
clickAction = click;
buttonChoose = GetComponent<Button>("ButtonChoose");
buttonNormal = GetComponent<Button>("ButtonNormal");
redPointChoose = GetComponent<RedPointUIController>("ButtonChoose/UI_RedPoint");
redPointNormal = GetComponent<RedPointUIController>("ButtonNormal/UI_RedPoint");
if (NoticeManager.Instance.RedPointNodeNoticeTypes.TryGetValue(noticeType, out var redPointNodeNotice) &&
redPointNodeNotice != null)
{
redPointChoose.SetNode(redPointNodeNotice.ID, redPointNodeNotice.MessageCount);
redPointNormal.SetNode(redPointNodeNotice.ID, redPointNodeNotice.MessageCount);
}
IsSelect = false;
CommonUtils.BindButton(buttonChoose, OnClick);
CommonUtils.BindButton(buttonNormal, OnClick);
}
private void OnClick()
{
clickAction?.Invoke(noticeType);
AudioManager.Instance.PlayAudio(Framework.Constants.Sound.COMMON_CLICK);
}
}
/// <summary>
/// 公告页签
/// </summary>
private class NoticeTab : UIGameObjectWrapper
{
#region UI
/// <summary>
/// 选中状态按钮
/// </summary>
private Button buttonChoose;
/// <summary>
/// 非选中状态按钮
/// </summary>
private Button buttonNormal;
/// <summary>
/// 选中状态标题
/// </summary>
private TMP_Text textSelectTitle;
/// <summary>
/// 选中状态日
/// </summary>
private TMP_Text textSelectDay;
/// <summary>
/// 选中状态月
/// </summary>
private TMP_Text textSelectWeek;
/// <summary>
/// 选中状态星期
/// </summary>
private TMP_Text textSelectMonth;
/// <summary>
/// 未选中状态标题
/// </summary>
private TMP_Text textTitle;
/// <summary>
/// 未选中状态日
/// </summary>
private TMP_Text textDay;
/// <summary>
/// 未选中状态月
/// </summary>
private TMP_Text textWeek;
/// <summary>
/// 未选中状态星期
/// </summary>
private TMP_Text textMonth;
/// <summary>
/// 选中红点
/// </summary>
private RedPointUIController redPointChoose;
/// <summary>
/// 未选中红点
/// </summary>
private RedPointUIController redPointNormal;
#endregion
public int ID;
/// <summary>
/// 选中回调
/// </summary>
private readonly Action<NoticeTab> selectAction;
/// <summary>
/// 公告数据
/// </summary>
private NoticeDataForDisplay noticeInfo;
/// <summary>
/// 是否选中
/// </summary>
public bool IsSelect
{
set
{
buttonChoose.gameObject.IsScaleShow(value);
buttonNormal.gameObject.IsScaleShow(!value);
}
}
public NoticeDataForDisplay NoticeInfo => noticeInfo;
public NoticeTab(GameObject root, Action<NoticeTab> select) : base(root)
{
selectAction = select;
buttonChoose = GetComponent<Button>("ButtonChoose");
buttonNormal = GetComponent<Button>("ButtonNormal");
textSelectTitle = GetComponent<TMP_Text>("ButtonChoose/TextTitle");
textSelectDay = GetComponent<TMP_Text>("ButtonChoose/TextDay");
textSelectWeek = GetComponent<TMP_Text>("ButtonChoose/TextWeek");
textSelectMonth = GetComponent<TMP_Text>("ButtonChoose/TextMonth");
textTitle = GetComponent<TMP_Text>("ButtonNormal/TextTitle");
textDay = GetComponent<TMP_Text>("ButtonNormal/TextDay");
textWeek = GetComponent<TMP_Text>("ButtonNormal/TextWeek");
textMonth = GetComponent<TMP_Text>("ButtonNormal/TextMonth");
redPointChoose = GetComponent<RedPointUIController>("ButtonChoose/UI_RedPoint");
redPointNormal = GetComponent<RedPointUIController>("ButtonNormal/UI_RedPoint");
IsSelect = false;
CommonUtils.BindButton(buttonChoose, OnClick);
CommonUtils.BindButton(buttonNormal, OnClick);
}
public void SetInfo(NoticeDataForDisplay notice)
{
if (notice == null)
{
IsScaleShow = false;
return;
}
noticeInfo = notice;
ID = notice.ID;
textSelectTitle.text = notice.Title;
textTitle.text = notice.Title;
ConvertTime();
if (notice.RedPointNodeNotice != null)
{
redPointChoose.SetNode(notice.RedPointNodeNotice.ID, notice.RedPointNodeNotice.MessageCount);
redPointNormal.SetNode(notice.RedPointNodeNotice.ID, notice.RedPointNodeNotice.MessageCount);
}
IsScaleShow = true;
}
private void OnClick()
{
selectAction?.Invoke(this);
AudioManager.Instance.PlayAudio(Framework.Constants.Sound.COMMON_CLICK);
}
private void ConvertTime()
{
try
{
// 解析时间字符串为 DateTime 对象
if (DateTime.TryParseExact(noticeInfo.UpdateTime, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture,
DateTimeStyles.None, out var dateTime))
{
var day = dateTime.Day.ToString(); // 日期1-31
var month = dateTime.Month.ToString();
var weekDayAbbreviation = dateTime.ToString("ddd", CultureInfo.InvariantCulture);
textSelectDay.text = day;
textDay.text = day;
textMonth.text = month + "/";
textSelectMonth.text = month + "/";
textWeek.text = weekDayAbbreviation;
textSelectWeek.text = weekDayAbbreviation;
/*// 输出结果
DebugUtil.LogError($"Day: {day}");
DebugUtil.LogError($"Month: {month}");
DebugUtil.LogError($"Weekday Abbreviation: {weekDayAbbreviation}");*/
}
else
{
DebugUtil.LogError("公告时间转换错误:{0}", noticeInfo.UpdateTime);
}
}
catch (Exception e)
{
DebugUtil.LogError("公告时间转换异常:{0}, Error:{1}", noticeInfo.UpdateTime, e);
}
}
}
/// <summary>
/// 公告内容
/// </summary>
private class NoticeContent : UIGameObjectWrapper
{
/// <summary>
/// 活动名
/// </summary>
private TMP_Text textActivityName;
/// <summary>
/// 横幅
/// </summary>
private Image imageBanner;
/// <summary>
/// 内置浏览器
/// </summary>
private UniWebView webView;
/// <summary>
/// 当前公告ID
/// </summary>
private int noticeID;
public NoticeContent(GameObject root) : base(root)
{
textActivityName = GetComponent<TMP_Text>("ImageTitle/TextActivityName");
imageBanner = GetComponent<Image>("ImageBanner");
webView = GetComponent<UniWebView>("TextContent");
}
public void SetInfo(NoticeDataForDisplay noticeInfo)
{
if (noticeInfo == null)
{
IsScaleShow = false;
return;
}
noticeID = noticeInfo.ID;
if (webView != null)
{
webView.LoadHTMLString(noticeInfo.Content, null, false);
webView.SetZoomEnabled(false); // 禁止缩放
webView.EmbeddedToolbar.Hide();
webView.Show();
webView.OnMessageReceived += HandleMessageReceived;
}
textActivityName.text = noticeInfo.Title;
IsScaleShow = true;
/*
if (noticeInfo.Bannersprite != null)
{
imageBanner.sprite = noticeInfo.ContentSprite;
}*/
}
protected override void Dispose(bool isDisposing)
{
if (webView != null)
webView.OnMessageReceived -= HandleMessageReceived;
base.Dispose(isDisposing);
}
private void HandleMessageReceived(UniWebView web, UniWebViewMessage message)
{
DebugUtil.Log("Message received: " + message.RawMessage);
if (!message.Path.Equals("open")) return;
var openUrl = message.Args["url"];
DebugUtil.Log($"公告跳转链接是: {openUrl}");
if (!string.IsNullOrEmpty(openUrl))
{
Application.OpenURL(openUrl);
NoticeManager.Instance.CloseRedNode(noticeID);
}
}
}
#endregion
#region UI
/// <summary>
/// 关闭按钮
/// </summary>
private Button buttonClose;
/// <summary>
/// 页签循环列表
/// </summary>
private RecycleView tabRecycleView;
/// <summary>
/// 高斯模糊遮罩
/// </summary>
private RawImage rawImageGaussianBlurMask;
#endregion
/// <summary>
/// 公告类型页签字典
/// </summary>
private readonly Dictionary<E_NoticeType, NoticeTypeTab> dicNoticeTypeTab = new();
/// <summary>
/// 页签字典
/// </summary>
private readonly Dictionary<int, NoticeTab> dicNoticeTap = new();
/// <summary>
/// 页签内容
/// </summary>
private NoticeContent noticeContent;
/// <summary>
/// 当前选中的公告类型
/// </summary>
private E_NoticeType curSelectNoticeType = E_NoticeType.None;
/// <summary>
/// 当前选择的页签
/// </summary>
private NoticeTab curSelectTab;
private ScrollRect contentScrollRect;
private InputData inputData;
public override void OnInit()
{
buttonClose = GetComponent<Button>("Image_NoticeBG/Button_Close");
tabRecycleView = GetComponent<RecycleView>("Image_NoticeBG/Tabs");
rawImageGaussianBlurMask = GetComponent<RawImage>("GaussianBlurMask");
dicNoticeTypeTab.Add(E_NoticeType.Activity,
new NoticeTypeTab(FindObj("Image_NoticeBG/Notices/ActivityNotice"), E_NoticeType.Activity,
OnNoticeTypeTab));
dicNoticeTypeTab.Add(E_NoticeType.System,
new NoticeTypeTab(FindObj("Image_NoticeBG/Notices/SystemNotice"), E_NoticeType.System, OnNoticeTypeTab));
noticeContent = new(FindObj("Image_NoticeBG/ContentRoot/Viewport/Content"));
contentScrollRect = GetComponent<ScrollRect>("Image_NoticeBG/ContentRoot");
rawImageGaussianBlurMask.texture = CommonUtils.GetScreenTexture2D();
tabRecycleView.Init(OnRefreshTab);
BindButton(buttonClose, OnClose);
}
protected override void OnShowWindow(object data)
{
if (data == null) return;
inputData = (InputData)data;
OnNoticeTypeTab(inputData.OpenType);
}
public override void OnRelease()
{
noticeContent.Dispose();
noticeContent = null;
base.OnRelease();
}
/// <summary>
/// 获取要显示的页签数量
/// </summary>
/// <returns></returns>
private int GetShowTabCount()
{
return curSelectNoticeType switch
{
E_NoticeType.Activity => NoticeManager.Instance.ActivityNoticeDataForDisplays.Count,
E_NoticeType.System => NoticeManager.Instance.SystemNoticeDataForDisplays.Count,
_ => 0,
};
}
#region 回调方法
/// <summary>
/// 刷新页签
/// </summary>
private void OnRefreshTab(GameObject cell, int index)
{
if (!dicNoticeTap.TryGetValue(cell.GetInstanceID(), out NoticeTab noticeTab))
{
noticeTab = new NoticeTab(cell, OnNoticeTab);
dicNoticeTap[cell.GetInstanceID()] = noticeTab;
}
switch (curSelectNoticeType)
{
case E_NoticeType.Activity:
{
if (NoticeManager.Instance.ActivityNoticeDataForDisplays.Count < 0 ||
index >= NoticeManager.Instance.ActivityNoticeDataForDisplays.Count)
{
DebugUtil.LogWarning("索引错误");
return;
}
if (!NoticeManager.Instance.ActivityNoticeDataForDisplays.TryGetValue(index, out var noticeInfo))
{
DebugUtil.LogError("没有索引为{0}的公告", index);
}
noticeTab.SetInfo(noticeInfo);
if ((inputData.Idx == -1 && curSelectTab == null) || inputData.Idx == noticeTab.ID)
{
curSelectTab = noticeTab;
OnNoticeTab(noticeTab);
}
else
{
noticeTab.IsSelect = false;
}
}
break;
case E_NoticeType.System:
{
if (NoticeManager.Instance.SystemNoticeDataForDisplays.Count < 0 ||
index >= NoticeManager.Instance.SystemNoticeDataForDisplays.Count)
{
DebugUtil.LogWarning("索引错误");
return;
}
if (!NoticeManager.Instance.SystemNoticeDataForDisplays.TryGetValue(index, out var noticeInfo))
{
DebugUtil.LogError("没有索引为{0}的系统公告", index);
}
noticeTab.SetInfo(noticeInfo);
if ((inputData.Idx == -1 && curSelectTab == null) || inputData.Idx == noticeTab.ID)
{
curSelectTab = noticeTab;
OnNoticeTab(noticeTab);
}
else
{
noticeTab.IsSelect = false;
}
}
break;
default:
{
noticeTab.IsSelect = false;
}
break;
}
}
/// <summary>
/// 关闭
/// </summary>
private void OnClose()
{
AudioManager.Instance.PlayAudio(Framework.Constants.Sound.COMMON_BACK);
CloseWindow();
}
/// <summary>
/// 公告类型切换
/// </summary>
private void OnNoticeTypeTab(E_NoticeType noticeType)
{
if (curSelectNoticeType == noticeType)
return;
if (dicNoticeTypeTab.TryGetValue(curSelectNoticeType, out NoticeTypeTab tab))
tab.IsSelect = false;
curSelectNoticeType = noticeType;
if (inputData.Idx != -1 && curSelectTab != null)
inputData.Idx = -1;
curSelectTab = null;
if (dicNoticeTypeTab.TryGetValue(curSelectNoticeType, out tab))
tab.IsSelect = true;
tabRecycleView.ShowList(GetShowTabCount());
}
/// <summary>
/// 公告页签
/// </summary>
private void OnNoticeTab(NoticeTab tab)
{
if (curSelectTab != null)
{
curSelectTab.IsSelect = false;
}
curSelectTab = tab;
curSelectTab.IsSelect = true;
contentScrollRect.verticalNormalizedPosition = 1f;
noticeContent.SetInfo(curSelectTab.NoticeInfo);
if (tab.NoticeInfo.LinkType != 2)
NoticeManager.Instance.CloseRedNode(tab.ID);
}
#endregion
}