228 lines
8.6 KiB
C#
228 lines
8.6 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Text;
|
|
using FairyGUI;
|
|
using SGModule.Common.Base;
|
|
using SGModule.Common.Helper;
|
|
using UnityEngine;
|
|
using UnityEngine.Networking;
|
|
|
|
namespace SGModule.MarkdownKit {
|
|
public class MarkdownKit : SingletonMonoBehaviour<MarkdownKit> {
|
|
/// <summary>
|
|
/// 加载文本,直接去网络下载
|
|
/// </summary>
|
|
/// <param name="key">自己为Md相关数据起的名字,后续都是通过这个来操作</param>
|
|
/// <param name="textSize">文字默认大小</param>
|
|
/// <param name="url">md下载地址</param>
|
|
public void LoadText(string key, string url, int textSize = 40) {
|
|
var data = new MarkdownData { Url = url, BaseSize = textSize };
|
|
if (!MarkdownDataMgr.TryAdd(key, data)) {
|
|
Log.MarkdownKit.Warning($"{key} 已加载,请勿重复加载!!!");
|
|
return;
|
|
}
|
|
|
|
StartCoroutine(Download(data));
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取指定的文本数据
|
|
/// </summary>
|
|
/// <param name="key">自定义键名</param>
|
|
/// <param name="onComplete">获取回调</param>
|
|
/// <param name="textSize">文本大小</param>
|
|
public void GetText(string key, Action<bool, List<string>> onComplete, int textSize = 40) {
|
|
if (!MarkdownDataMgr.TryGetValue(key, out var data)) {
|
|
Log.MarkdownKit.Warning($"{key} 未初始化,请加载后重试");
|
|
return;
|
|
}
|
|
|
|
SetMarkdownTextSize(data, textSize);
|
|
|
|
switch (data.State) {
|
|
case MarkdownTextState.Complete:
|
|
onComplete?.Invoke(true, data.RichTextList);
|
|
return;
|
|
case MarkdownTextState.Downloading:
|
|
data.OnComplete += onComplete;
|
|
return;
|
|
case MarkdownTextState.Exception:
|
|
data.OnComplete += onComplete;
|
|
StartCoroutine(Download(data));
|
|
break;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 下载md
|
|
/// </summary>
|
|
/// <param name="data"></param>
|
|
/// <returns></returns>
|
|
private IEnumerator Download(MarkdownData data) {
|
|
data.State = MarkdownTextState.Downloading;
|
|
|
|
var unityWebRequest = new UnityWebRequest(data.Url) {
|
|
downloadHandler = new DownloadHandlerBuffer()
|
|
};
|
|
|
|
unityWebRequest.SetRequestHeader("Content-Type", "application/json;charset=utf-8");
|
|
|
|
yield return unityWebRequest.SendWebRequest(); //发送请求
|
|
|
|
if (unityWebRequest.result is not UnityWebRequest.Result.Success) {
|
|
data.State = MarkdownTextState.Exception;
|
|
data.OnComplete?.Invoke(false, null);
|
|
Log.MarkdownKit.Error($"失败 {unityWebRequest.result} {unityWebRequest.error}");
|
|
}
|
|
else {
|
|
var receiveContent = unityWebRequest.downloadHandler.text;
|
|
|
|
data.Text = receiveContent;
|
|
data.MarkdownTextList = SplitMarkdownByHeaders(receiveContent);
|
|
UpdateMarkdownTextList(data);
|
|
data.State = MarkdownTextState.Complete;
|
|
|
|
data.OnComplete?.Invoke(true, data.RichTextList);
|
|
}
|
|
|
|
data.OnComplete = null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 根据md标题切割md文本
|
|
/// </summary>
|
|
/// <param name="markdownText"></param>
|
|
/// <returns></returns>
|
|
private List<string> SplitMarkdownByHeaders(string markdownText) {
|
|
var sections = new List<string>();
|
|
var currentSection = new StringBuilder();
|
|
|
|
using (var reader = new StringReader(markdownText)) {
|
|
string line;
|
|
while ((line = reader.ReadLine()) != null) {
|
|
if (line.StartsWith("#")) // 如果是标题行
|
|
{
|
|
if (currentSection.Length > 0) {
|
|
sections.Add(currentSection.ToString());
|
|
currentSection.Clear();
|
|
}
|
|
}
|
|
|
|
currentSection.AppendLine(line);
|
|
}
|
|
|
|
if (currentSection.Length > 0) // 添加最后一段
|
|
{
|
|
sections.Add(currentSection.ToString());
|
|
}
|
|
}
|
|
|
|
return sections;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 设置富文本默认文字大小
|
|
/// </summary>
|
|
/// <param name="data"></param>
|
|
/// <param name="textSize"></param>
|
|
private void SetMarkdownTextSize(MarkdownData data, int textSize) {
|
|
if (textSize > 0 && data.BaseSize != textSize) {
|
|
data.BaseSize = textSize;
|
|
|
|
UpdateMarkdownTextList(data);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 更新富文本数据
|
|
/// </summary>
|
|
/// <param name="data"></param>
|
|
private void UpdateMarkdownTextList(MarkdownData data) {
|
|
if (data.MarkdownTextList == null) {
|
|
return;
|
|
}
|
|
|
|
var richTextList = new List<string>();
|
|
foreach (var section in data.MarkdownTextList) {
|
|
var richText = MarkdownConvert.ToUBB(section, data.BaseSize);
|
|
|
|
richTextList.Add(richText);
|
|
}
|
|
|
|
data.RichTextList = richTextList;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 添加富文本到指定节点下
|
|
/// </summary>
|
|
/// <param name="parent">指定节点</param>
|
|
/// <param name="key">数据键名</param>
|
|
/// <param name="color">颜色</param>
|
|
/// <param name="callback">回调,参数分是代表了结果与当前状态</param>
|
|
/// <param name="textSize">字体大小,如果与当前不一致将更新富文本数据</param>
|
|
public void ShowAsRichText(GComponent parent, string key, Color color, Action<bool, MarkdownTextState> callback, int textSize = -1) {
|
|
//处理对象为空或者相关对象已经被销毁的情况,如界面在等待过程中已经被关闭
|
|
if (parent == null || parent.isDisposed) {
|
|
Log.MarkdownKit.Warning("parent 是无效的");
|
|
return;
|
|
}
|
|
|
|
if (!MarkdownDataMgr.TryGetValue(key, out var data)) {
|
|
Log.MarkdownKit.Error($"未加载 {key}的数据");
|
|
callback?.Invoke(false, MarkdownTextState.None);
|
|
return;
|
|
}
|
|
|
|
Action<List<string>> show = list => {
|
|
//处理对象为空或者相关对象已经被销毁的情况,如界面在等待过程中已经被关闭
|
|
if (parent == null || parent.isDisposed) {
|
|
Log.MarkdownKit.Warning("parent 是无效的");
|
|
return;
|
|
}
|
|
|
|
SetMarkdownTextSize(data, textSize);
|
|
foreach (var richText in list) {
|
|
// 创建 GRichTextField
|
|
var aRichTextField = new GRichTextField();
|
|
|
|
aRichTextField.UBBEnabled = true;
|
|
aRichTextField.SetSize(parent.size.x, 0);
|
|
aRichTextField.color = color;
|
|
aRichTextField.textFormat.size = data.BaseSize;
|
|
aRichTextField.autoSize = AutoSizeType.Height;
|
|
aRichTextField.AddRelation(GRoot.inst, RelationType.Width);
|
|
aRichTextField.text = richText;
|
|
parent.AddChild(aRichTextField);
|
|
}
|
|
};
|
|
|
|
Action<bool, List<string>> downloadingCallback = (result, list) => {
|
|
callback?.Invoke(result, data.State);
|
|
if (result) {
|
|
show.Invoke(list);
|
|
}
|
|
};
|
|
|
|
switch (data.State) {
|
|
case MarkdownTextState.Downloading:
|
|
callback?.Invoke(true, data.State);
|
|
data.OnComplete += downloadingCallback;
|
|
break;
|
|
case MarkdownTextState.Complete:
|
|
callback?.Invoke(true, data.State);
|
|
show.Invoke(data.RichTextList);
|
|
break;
|
|
case MarkdownTextState.Exception:
|
|
callback?.Invoke(true, data.State);
|
|
data.OnComplete += downloadingCallback;
|
|
StartCoroutine(Download(data));
|
|
break;
|
|
default:
|
|
throw new ArgumentOutOfRangeException();
|
|
}
|
|
}
|
|
}
|
|
}
|