update: 更新接口, 删除包引用
parent
a0532a5ced
commit
29f0d32c36
|
|
@ -12,8 +12,8 @@ namespace Guru
|
||||||
public class EventSetting
|
public class EventSetting
|
||||||
{
|
{
|
||||||
public bool EnableFirebaseAnalytics;
|
public bool EnableFirebaseAnalytics;
|
||||||
public bool EnableFacebookAnalytics;
|
|
||||||
public bool EnableAdjustAnalytics;
|
public bool EnableAdjustAnalytics;
|
||||||
|
public bool EnableFacebookAnalytics;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static EventSetting _defaultEventSetting;
|
private static EventSetting _defaultEventSetting;
|
||||||
|
|
@ -143,15 +143,15 @@ namespace Guru
|
||||||
FirebaseAnalytics.LogEvent(eventName);
|
FirebaseAnalytics.LogEvent(eventName);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (eventSetting.EnableFacebookAnalytics)
|
|
||||||
{
|
|
||||||
FB.LogAppEvent(eventName);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (eventSetting.EnableAdjustAnalytics)
|
if (eventSetting.EnableAdjustAnalytics)
|
||||||
{
|
{
|
||||||
Adjust.trackEvent(CreateAdjustEvent(eventName));
|
Adjust.trackEvent(CreateAdjustEvent(eventName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (eventSetting.EnableFacebookAnalytics)
|
||||||
|
{
|
||||||
|
FB.LogAppEvent(eventName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -191,11 +191,6 @@ namespace Guru
|
||||||
}
|
}
|
||||||
|
|
||||||
Dictionary<string, object> dict = new Dictionary<string, object>(extras);
|
Dictionary<string, object> dict = new Dictionary<string, object>(extras);
|
||||||
if (eventSetting.EnableFacebookAnalytics)
|
|
||||||
{
|
|
||||||
FB.LogAppEvent(eventName, null, dict);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (eventSetting.EnableAdjustAnalytics)
|
if (eventSetting.EnableAdjustAnalytics)
|
||||||
{
|
{
|
||||||
AdjustEvent adjustEvent = Analytics.CreateAdjustEvent(eventName);
|
AdjustEvent adjustEvent = Analytics.CreateAdjustEvent(eventName);
|
||||||
|
|
@ -208,6 +203,11 @@ namespace Guru
|
||||||
Adjust.trackEvent(adjustEvent);
|
Adjust.trackEvent(adjustEvent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (eventSetting.EnableFacebookAnalytics)
|
||||||
|
{
|
||||||
|
FB.LogAppEvent(eventName, null, dict);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ namespace Guru
|
||||||
[Header("产品包名")]
|
[Header("产品包名")]
|
||||||
public string GameIdentifier = "com.guru.default.product";
|
public string GameIdentifier = "com.guru.default.product";
|
||||||
[Header("产品反馈邮箱(评分反馈邮箱)")]
|
[Header("产品反馈邮箱(评分反馈邮箱)")]
|
||||||
public string SupportEmail = "xxxx@fungame.studio";
|
public string SupportEmail = "test@fungame.studio";
|
||||||
[Header("隐私协议URL")]
|
[Header("隐私协议URL")]
|
||||||
public string PriacyUrl = "";
|
public string PriacyUrl = "";
|
||||||
[Header("服务条款URL")]
|
[Header("服务条款URL")]
|
||||||
|
|
@ -52,6 +52,45 @@ namespace Guru
|
||||||
{
|
{
|
||||||
return Resources.Load<GuruSettings>("GuruSettings");
|
return Resources.Load<GuruSettings>("GuruSettings");
|
||||||
}
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 运行时更新Adjust 的 AppToken
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="androidToken"></param>
|
||||||
|
/// <param name="iosToken"></param>
|
||||||
|
public void UpdateAdjustTokens(string androidToken, string iosToken)
|
||||||
|
{
|
||||||
|
if(!string.IsNullOrEmpty(androidToken))
|
||||||
|
AdjustSetting.androidAppToken = androidToken;
|
||||||
|
if(!string.IsNullOrEmpty(iosToken))
|
||||||
|
AdjustSetting.iOSAppToken = iosToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 运行时更新 Adjust 的事件列表
|
||||||
|
/// </summary>
|
||||||
|
public void UpdateAdjustEvents(IList<string> events)
|
||||||
|
{
|
||||||
|
if (events != null && events.Count > 0)
|
||||||
|
{
|
||||||
|
List<AnalyticsSetting.AdjustEvent> evtList = new List<AnalyticsSetting.AdjustEvent>(events.Count);
|
||||||
|
string key, atk, itk;
|
||||||
|
string[] tmp;
|
||||||
|
for (int i = 0; i < events.Count; i++)
|
||||||
|
{
|
||||||
|
tmp = events[i].Split(',');
|
||||||
|
if (tmp != null && tmp.Length > 2)
|
||||||
|
{
|
||||||
|
evtList.Add(new AnalyticsSetting.AdjustEvent()
|
||||||
|
{
|
||||||
|
EventName = tmp[0],
|
||||||
|
AndroidToken = tmp[1],
|
||||||
|
IOSToken = tmp[2],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AnalyticsSetting.adjustEventList = evtList;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
|
|
@ -73,7 +112,7 @@ namespace Guru
|
||||||
[SerializeField] private bool enalbeFirebaseAnalytics = true;
|
[SerializeField] private bool enalbeFirebaseAnalytics = true;
|
||||||
[SerializeField] private bool enalbeFacebookAnalytics = true;
|
[SerializeField] private bool enalbeFacebookAnalytics = true;
|
||||||
[SerializeField] private bool enalbeAdjustAnalytics = true;
|
[SerializeField] private bool enalbeAdjustAnalytics = true;
|
||||||
[SerializeField] private List<AdjustEvent> adjustEventList;
|
[SerializeField] internal List<AdjustEvent> adjustEventList;
|
||||||
|
|
||||||
public int LevelEndSuccessNum => levelEndSuccessNum;
|
public int LevelEndSuccessNum => levelEndSuccessNum;
|
||||||
public bool EnalbeFirebaseAnalytics => enalbeFirebaseAnalytics;
|
public bool EnalbeFirebaseAnalytics => enalbeFirebaseAnalytics;
|
||||||
|
|
@ -132,8 +171,8 @@ namespace Guru
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class AdjustSetting
|
public class AdjustSetting
|
||||||
{
|
{
|
||||||
[SerializeField] private string androidAppToken;
|
[SerializeField] internal string androidAppToken;
|
||||||
[SerializeField] private string iOSAppToken;
|
[SerializeField] internal string iOSAppToken;
|
||||||
|
|
||||||
public string AndroidAppToken => androidAppToken;
|
public string AndroidAppToken => androidAppToken;
|
||||||
public string IOSAppToken => iOSAppToken;
|
public string IOSAppToken => iOSAppToken;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 53abb1f4e73b4b44907c0a3c0a406079
|
||||||
|
timeCreated: 1687327402
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
# Guru 评价管理器
|
||||||
|
|
||||||
|
Version 0.1.0
|
||||||
|
|
||||||
|
## 简介
|
||||||
|
|
||||||
|
Guru 评价管理器内置了多平台评价管理实现, 包括
|
||||||
|
- GooglePlay 平台的 InAppReview 接口
|
||||||
|
- AppStore 平台的评价接口
|
||||||
|
|
||||||
|
|
||||||
|
## 库依赖
|
||||||
|
|
||||||
|
### **Android**
|
||||||
|
|
||||||
|
- 依赖于 `com.google.play.review` 的插件, 可在插件的 Package 文件夹内直接安装
|
||||||
|
- 注意: 由于模板已集成 ExternalDependencyManager (`1.2.174`), 因此无需导入包内的EDM插件.
|
||||||
|
|
||||||
|
|
||||||
|
### **iOS**
|
||||||
|
|
||||||
|
- 直接使用 Unity 内部的 `iOS` 的 Review 接口
|
||||||
|
|
||||||
|
## 实现方式
|
||||||
|
|
||||||
|
### 显示评价
|
||||||
|
|
||||||
|
只需调用以下代码即可:
|
||||||
|
|
||||||
|
```C#
|
||||||
|
// 直接显示包内的评价界面
|
||||||
|
GuruRating.ShowRating();
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### 提交反馈
|
||||||
|
|
||||||
|
- 发送反馈时, 实际上是调用了系统的邮件App, 需要提供收件人的邮箱地址
|
||||||
|
- 邮件的标题主体可以自由定制, 传入参数即可
|
||||||
|
|
||||||
|
```C#
|
||||||
|
// 向 support@fungame.com 的邮箱发送反馈信息. 邮件的标题和信息可以定制
|
||||||
|
GuruRating.SetEmailFeedback("support@fungame.com", "Thank you for the feedback!");
|
||||||
|
```
|
||||||
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 6fd1be4cf92d4854b9fad97b1bd11b7b
|
||||||
|
timeCreated: 1687327432
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d608c1853fbb4c4e9538d1af2ee2c65e
|
||||||
|
timeCreated: 1687327422
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b3f63a18067c45da82d3521e18127a88
|
||||||
|
timeCreated: 1687328000
|
||||||
|
|
@ -0,0 +1,188 @@
|
||||||
|
namespace Guru
|
||||||
|
{
|
||||||
|
using System;
|
||||||
|
#if UNITY_ANDROID
|
||||||
|
using Google.Play.Review;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if UNITY_IOS
|
||||||
|
using UnityEngine.iOS;
|
||||||
|
#endif
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.Networking;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 评价管理器
|
||||||
|
/// </summary>
|
||||||
|
public class GuruRating: Singleton<GuruRating>
|
||||||
|
{
|
||||||
|
|
||||||
|
public static bool ShowLog { get; set; } = false;
|
||||||
|
|
||||||
|
#region 初始化
|
||||||
|
|
||||||
|
protected override void Init()
|
||||||
|
{
|
||||||
|
base.Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 评价显示
|
||||||
|
|
||||||
|
#if UNITY_ANDROID
|
||||||
|
|
||||||
|
private bool _isOnRating = false;
|
||||||
|
/// <summary>
|
||||||
|
/// 显示Google的评价
|
||||||
|
/// </summary>
|
||||||
|
private void ShowGoogleRating()
|
||||||
|
{
|
||||||
|
if (_isOnRating) return;
|
||||||
|
_isOnRating = true;
|
||||||
|
OnGoogleRating();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 启动Google评价流程
|
||||||
|
/// </summary>
|
||||||
|
private void OnGoogleRating()
|
||||||
|
{
|
||||||
|
ReviewManager rm = new ReviewManager();
|
||||||
|
rm.RequestReviewFlow().Completed += pao =>
|
||||||
|
{
|
||||||
|
// 请求 PlayReviewInfo 对象
|
||||||
|
if (pao.Error != ReviewErrorCode.NoError)
|
||||||
|
{
|
||||||
|
if(ShowLog) Debug.Log($"ReviewInfo Error: {pao.Error.ToString()}");
|
||||||
|
OnGoogleRatingResult(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 启动应用内评价流程, 调用后可以不用关心后继的结果. 游戏继续流程即可
|
||||||
|
rm.LaunchReviewFlow(pao.GetResult()).Completed += lao =>
|
||||||
|
{
|
||||||
|
bool result = true;
|
||||||
|
if (lao.Error != ReviewErrorCode.NoError)
|
||||||
|
{
|
||||||
|
if(ShowLog) Debug.Log($"LaunchReview Error: {lao.Error.ToString()}");
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
OnGoogleRatingResult(result);
|
||||||
|
rm = null;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnGoogleRatingResult(bool success)
|
||||||
|
{
|
||||||
|
// On getting review result
|
||||||
|
if(ShowLog) Debug.Log($"Google Review flow ends, result: {success}");
|
||||||
|
_isOnRating = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if UNITY_IOS
|
||||||
|
/// <summary>
|
||||||
|
/// 显示苹果的Rating
|
||||||
|
/// </summary>
|
||||||
|
private void ShowAppleRating() => Device.RequestStoreReview(); // 显示苹果的评价面板
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 发送邮件
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置邮件显示
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="email"></param>
|
||||||
|
/// <param name="body"></param>
|
||||||
|
private void SendEmail(string email, string subject = "", string body = null)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(subject)) subject = GetDefaultMailTitle();
|
||||||
|
if (string.IsNullOrEmpty(body)) body = GetDefaultMailBody();
|
||||||
|
|
||||||
|
string url = $"mailto:{email}&subject={EscapeUrl(subject)}&body={EscapeUrl(body)}";
|
||||||
|
Application.OpenURL(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取默认的邮件标题
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
private string GetDefaultMailTitle()
|
||||||
|
{
|
||||||
|
return $"Some suggestions for improving {GuruSettings.Instance.ProductName}";
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取默认的邮件内容模版
|
||||||
|
/// </summary>
|
||||||
|
private string GetDefaultMailBody()
|
||||||
|
{
|
||||||
|
string body = "Please Enter your message here\n\n\n\n" +
|
||||||
|
"________" +
|
||||||
|
"\n\nPlease Do Not Modify This\n\n" +
|
||||||
|
"Game: " + GuruSettings.Instance.ProductName + "\n\n" +
|
||||||
|
"Model: " + SystemInfo.deviceModel + "\n\n" +
|
||||||
|
"OS: " + SystemInfo.operatingSystem + "\n\n" +
|
||||||
|
"UserId: " + IPMConfig.IPM_UID + "\n\n" +
|
||||||
|
"Version: " + Application.version + "\n\n" +
|
||||||
|
"________";
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 工具接口
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 转换为URL编码
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="str"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string EscapeUrl(string str)
|
||||||
|
{
|
||||||
|
return UnityWebRequest.EscapeURL(str).Replace("+", "%20");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 公开接口
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 显示评价面板
|
||||||
|
/// </summary>
|
||||||
|
public static void ShowRating()
|
||||||
|
{
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
Console.WriteLine($"Editor is Calling ShowRating api...");
|
||||||
|
#elif UNITY_ANDROID
|
||||||
|
Instance.ShowGoogleRating();
|
||||||
|
#elif UNITY_IOS
|
||||||
|
Instance.ShowAppleRating();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置邮件反馈
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="email"></param>
|
||||||
|
/// <param name="body"></param>
|
||||||
|
public static void SetEmailFeedback(string email, string subject = "", string body = "")
|
||||||
|
{
|
||||||
|
Instance.SendEmail(email, subject, body);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8d36e44d41f0423f8f9f6c23600ec512
|
||||||
|
timeCreated: 1687328021
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
using Google;
|
|
||||||
|
|
||||||
namespace Guru
|
namespace Guru
|
||||||
{
|
{
|
||||||
using System;
|
using System;
|
||||||
|
|
@ -7,21 +5,10 @@ namespace Guru
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 运控配置接口类
|
/// 运控配置接口类
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IRemoteConfig
|
public interface IRemoteConfig<T> where T : IRemoteConfig<T>
|
||||||
{
|
{
|
||||||
bool enable { get; set; }
|
bool enable { get; set; }
|
||||||
string key { get; }
|
Action<T> OnValueChanged { get; set; }
|
||||||
string value { get; }
|
|
||||||
|
|
||||||
Action<IRemoteConfig> OnValueChanged { get; set; }
|
|
||||||
|
|
||||||
void Init();
|
|
||||||
string ToJson();
|
string ToJson();
|
||||||
string GetDefaultValue();
|
|
||||||
string GetRemoteValue();
|
|
||||||
|
|
||||||
void GetRemoteJsonAsync(Action<string> onValueLoaded);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,45 +1,20 @@
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Guru
|
namespace Guru
|
||||||
{
|
{
|
||||||
public abstract class RemoteConfigBase: IRemoteConfig
|
using System;
|
||||||
{
|
|
||||||
|
|
||||||
|
public abstract class RemoteConfigBase<T>: IRemoteConfig<T> where T : IRemoteConfig<T>
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 配置是否可用
|
/// 配置是否可用
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool enable { get; set; } = true;
|
public bool enable { get; set; } = true;
|
||||||
|
public Action<T> OnValueChanged { get; set; }
|
||||||
public virtual string key { get; } = "remote-config-base";
|
|
||||||
public virtual string value { get; } = "{ \"enable\": true }";
|
|
||||||
public Action<IRemoteConfig> OnValueChanged { get; set; }
|
|
||||||
|
|
||||||
|
|
||||||
public void Init()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 转为Json
|
/// 转为Json
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public virtual string ToJson()
|
public virtual string ToJson() => JsonParser.ToJson(this);
|
||||||
=> JsonParser.ToJson(this);
|
|
||||||
|
|
||||||
public string GetDefaultValue()
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public string GetRemoteValue()
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void GetRemoteJsonAsync(Action<string> onValueLoaded)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace Guru
|
namespace Guru
|
||||||
{
|
{
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using JetBrains.Annotations;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using Firebase.RemoteConfig;
|
using Firebase.RemoteConfig;
|
||||||
using Firebase.Extensions;
|
using Firebase.Extensions;
|
||||||
|
|
@ -13,31 +15,29 @@ namespace Guru
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class RemoteConfigManager
|
public class RemoteConfigManager
|
||||||
{
|
{
|
||||||
public const double DefaultUpdateHours = 12;
|
public const double DefaultUpdateHours = 2;
|
||||||
private const string Tag = "[Remote]";
|
public const double DefaultFetchTimeout = 15;
|
||||||
|
internal const string Tag = "[Remote]";
|
||||||
private static bool _initOnce = false;
|
private static bool _initOnce = false;
|
||||||
private static RemoteConfigManager _instance;
|
private static RemoteConfigManager _instance;
|
||||||
public static RemoteConfigManager Instance => _instance ??= new RemoteConfigManager();
|
public static RemoteConfigManager Instance => _instance ??= new RemoteConfigManager();
|
||||||
|
|
||||||
private FirebaseRemoteConfig _firebaseRemote;
|
private FirebaseRemoteConfig _firebaseRemote;
|
||||||
private static bool _isDebug = false;
|
private static bool _isDebug = false;
|
||||||
private static double _updateHours = DefaultUpdateHours;
|
private static double _fetchIntervalHours = DefaultUpdateHours;
|
||||||
|
|
||||||
private RemoteConfigModel _model;
|
private RemoteConfigModel _model;
|
||||||
|
internal RemoteConfigModel Model => _model ??= RemoteConfigModel.LoadOrCreate();
|
||||||
|
|
||||||
internal RemoteConfigModel Model
|
private static Dictionary<string, object> _defaultValues;
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if(_model == null) _model = RemoteConfigModel.LoadOrCreate();
|
|
||||||
return _model;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private Dictionary<string, object> _defaults;
|
|
||||||
|
|
||||||
public static event Action<bool> OnFetchCompleted;
|
public static event Action<bool> OnFetchCompleted;
|
||||||
|
|
||||||
public static void Init(Dictionary<string, object> defaults, double updateHours = DefaultUpdateHours, bool isDebug = false)
|
private Dictionary<string, Action<string,string>> _changeEvents;
|
||||||
|
|
||||||
|
private Dictionary<string, string> _staticValues;
|
||||||
|
|
||||||
|
public static void Init(Dictionary<string, object> defaults = null, double updateHours = DefaultUpdateHours, bool isDebug = false)
|
||||||
{
|
{
|
||||||
if (_initOnce) return;
|
if (_initOnce) return;
|
||||||
Instance.InitAssets(defaults, updateHours, isDebug);
|
Instance.InitAssets(defaults, updateHours, isDebug);
|
||||||
|
|
@ -45,19 +45,23 @@ namespace Guru
|
||||||
|
|
||||||
// 拉取所有的线上配置数据
|
// 拉取所有的线上配置数据
|
||||||
// onFetchComplete 传参 true: 拉取成功 false: 拉取失败
|
// onFetchComplete 传参 true: 拉取成功 false: 拉取失败
|
||||||
public static void FetchAll(Action<bool> onFetchComplete = null)
|
public static void FetchAll(bool immediately = false)
|
||||||
{
|
{
|
||||||
OnFetchCompleted += onFetchComplete;
|
if (!_initOnce) Init(null, _fetchIntervalHours, _isDebug);
|
||||||
if (!_initOnce) Init(null, _updateHours, _isDebug);
|
Instance.FetchAllConfigs(immediately);
|
||||||
Instance.FetchAllConfigs();
|
}
|
||||||
|
|
||||||
|
public static void AddDefaultValues(Dictionary<string, object> dict)
|
||||||
|
{
|
||||||
|
if (!_initOnce) return;
|
||||||
|
Instance.AppendDefaultValues(dict);
|
||||||
}
|
}
|
||||||
|
|
||||||
#region 初始化
|
#region 初始化
|
||||||
|
|
||||||
private void InitAssets(Dictionary<string, object> defaults, double updateHours = DefaultUpdateHours, bool isDebug = false)
|
private void InitAssets(Dictionary<string, object> defaults = null, double updateHours = DefaultUpdateHours, bool isDebug = false)
|
||||||
{
|
{
|
||||||
_defaults = defaults;
|
_fetchIntervalHours = updateHours;
|
||||||
_updateHours = updateHours;
|
|
||||||
_isDebug = isDebug;
|
_isDebug = isDebug;
|
||||||
_firebaseRemote = FirebaseRemoteConfig.DefaultInstance;
|
_firebaseRemote = FirebaseRemoteConfig.DefaultInstance;
|
||||||
if (_firebaseRemote == null)
|
if (_firebaseRemote == null)
|
||||||
|
|
@ -66,36 +70,45 @@ namespace Guru
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 设置默认配置
|
||||||
if (_defaults != null)
|
_firebaseRemote.SetConfigSettingsAsync(new ConfigSettings()
|
||||||
{
|
{
|
||||||
_firebaseRemote.SetDefaultsAsync(_defaults);
|
FetchTimeoutInMilliseconds = (ulong)(DefaultFetchTimeout * 1000),
|
||||||
}
|
MinimumFetchInternalInMilliseconds = (ulong)(_fetchIntervalHours * 60 * 60 * 1000)
|
||||||
|
});
|
||||||
|
|
||||||
|
// 设置默认值
|
||||||
|
AppendDefaultValues(defaults);
|
||||||
_initOnce = true;
|
_initOnce = true;
|
||||||
|
|
||||||
|
// 监听事件合集
|
||||||
|
_changeEvents = new Dictionary<string, Action<string,string>>(30);
|
||||||
|
|
||||||
FetchAllConfigs();
|
FetchAllConfigs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void AppendDefaultValues(Dictionary<string, object> defaults)
|
||||||
|
|
||||||
|
|
||||||
// private void OnConfigUpdateListener()
|
|
||||||
// {
|
|
||||||
// if (evt.Error == RemoteConfigError.None)
|
|
||||||
// {
|
|
||||||
// LogI($"------- Config Update -------");
|
|
||||||
// var list = evt.UpdatedKeys.ToArray();
|
|
||||||
// for (int i = 0; i < list.Length; i++)
|
|
||||||
// {
|
|
||||||
// LogI($"[{i}] : {list[i]}");
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
private void FetchAllConfigs()
|
|
||||||
{
|
{
|
||||||
var span = _isDebug? TimeSpan.Zero : TimeSpan.FromHours(_updateHours);
|
if (defaults != null)
|
||||||
|
{
|
||||||
|
if(_defaultValues == null) _defaultValues = new Dictionary<string, object>(20);
|
||||||
|
string key;
|
||||||
|
object value;
|
||||||
|
for(int i = 0; i < defaults.Keys.Count; i++)
|
||||||
|
{
|
||||||
|
key = defaults.Keys.ElementAt(i);
|
||||||
|
value = defaults.Values.ElementAt(i);
|
||||||
|
_defaultValues[key] = value;
|
||||||
|
}
|
||||||
|
_firebaseRemote?.SetDefaultsAsync(_defaultValues);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void FetchAllConfigs(bool immediately = false)
|
||||||
|
{
|
||||||
|
var span = TimeSpan.FromHours(_fetchIntervalHours);
|
||||||
|
if(_isDebug || immediately) span = TimeSpan.Zero;
|
||||||
_firebaseRemote.FetchAsync(span)
|
_firebaseRemote.FetchAsync(span)
|
||||||
.ContinueWithOnMainThread(task =>
|
.ContinueWithOnMainThread(task =>
|
||||||
{
|
{
|
||||||
|
|
@ -106,11 +119,67 @@ namespace Guru
|
||||||
LogE($" --- FetchAllConfigs fails: {res}");
|
LogE($" --- FetchAllConfigs fails: {res}");
|
||||||
success = false;
|
success = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (success) OnFetchDataCompleted();
|
||||||
|
|
||||||
OnFetchCompleted?.Invoke(success);
|
OnFetchCompleted?.Invoke(success);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Model
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 判断是否为 Config 参数
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="rawStr"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private bool IsRemoteConfigStr(string rawStr)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(rawStr)) return false;
|
||||||
|
|
||||||
|
if (rawStr.TrimStart().StartsWith("{")
|
||||||
|
&& rawStr.TrimEnd().EndsWith("}")
|
||||||
|
&& rawStr.Contains("\"enable\":"))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 拉取成功
|
||||||
|
/// </summary>
|
||||||
|
private void OnFetchDataCompleted()
|
||||||
|
{
|
||||||
|
var values = _firebaseRemote.AllValues;
|
||||||
|
var updates = new Dictionary<string, string>(values.Count);
|
||||||
|
var configs = new Dictionary<string, string>(values.Count);
|
||||||
|
ConfigValue value;
|
||||||
|
string key, str;
|
||||||
|
for (int i = 0; i < values.Keys.Count; i++)
|
||||||
|
{
|
||||||
|
key = values.Keys.ElementAt(i);
|
||||||
|
value = values.Values.ElementAt(i);
|
||||||
|
str = value.StringValue;
|
||||||
|
|
||||||
|
updates[key] = str;
|
||||||
|
if (IsRemoteConfigStr(str))
|
||||||
|
{
|
||||||
|
configs[key] = str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configs.Count > 0)
|
||||||
|
{
|
||||||
|
Model.UpdateConfigs(configs);
|
||||||
|
}
|
||||||
|
|
||||||
|
DispatchUpdateValues(updates);
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region 数据接口
|
#region 数据接口
|
||||||
|
|
@ -185,7 +254,7 @@ namespace Guru
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return _firebaseRemote.GetValue(key).BooleanValue;
|
return _firebaseRemote?.GetValue(key).BooleanValue ?? defaultValue;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|
@ -195,8 +264,34 @@ namespace Guru
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
/// <summary>
|
||||||
|
/// 获取全部值
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static Dictionary<string, ConfigValue> GetAllValues()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return (Dictionary<string, ConfigValue>)(Instance._firebaseRemote?.AllValues ?? null);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
LogException(e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
[CanBeNull]
|
||||||
|
public static string GetStaticValue(string key)
|
||||||
|
{
|
||||||
|
if (Instance._staticValues != null && Instance._staticValues.TryGetValue(key, out var value))
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region 云控值获取
|
#region 云控值获取
|
||||||
|
|
||||||
|
|
@ -232,15 +327,133 @@ namespace Guru
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
#region 云控配置获取
|
#region 云控配置获取
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 注册云控配置对象
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <param name="defaultJson"></param>
|
||||||
|
public static void RegisterConfig(string key, string defaultJson)
|
||||||
|
{
|
||||||
|
Instance.Model.SetDefaultConfig(key, defaultJson); // 配置默认值
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取云控配置
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static T GetConfig<T>(string key) where T : IRemoteConfig<T>
|
||||||
|
{
|
||||||
|
var config = Instance.Model.Get<T>(key);
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region 监听云控值变化
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 注册值变化事件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <param name="onValueChanged"></param>
|
||||||
|
public static void RegisterOnValueChanged(string key, Action<string,string> onValueChanged)
|
||||||
|
{
|
||||||
|
Instance.AddOnValueChangeListener(key, onValueChanged);
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 取消注册值变化事件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <param name="onValueChanged"></param>
|
||||||
|
public static void UnRegisterOnValueChanged(string key, Action<string,string> onValueChanged)
|
||||||
|
{
|
||||||
|
Instance.RemoveOnValueChangeListener(key, onValueChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void AddOnValueChangeListener(string key, Action<string,string> onValueChanged)
|
||||||
|
{
|
||||||
|
if (_changeEvents == null) _changeEvents = new Dictionary<string, Action<string,string>>(30);
|
||||||
|
|
||||||
|
if (HasOnValueChangeListener(key))
|
||||||
|
{
|
||||||
|
_changeEvents[key] += onValueChanged;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_changeEvents[key] = onValueChanged;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RemoveOnValueChangeListener(string key, Action<string,string> onValueChanged)
|
||||||
|
{
|
||||||
|
if (_changeEvents != null && HasOnValueChangeListener(key))
|
||||||
|
{
|
||||||
|
_changeEvents[key] -= onValueChanged;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool HasOnValueChangeListener(string key)
|
||||||
|
{
|
||||||
|
if (_changeEvents != null)
|
||||||
|
{
|
||||||
|
return _changeEvents.ContainsKey(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void DispatchUpdateValues(Dictionary<string, string> updates)
|
||||||
|
{
|
||||||
|
Dictionary<string, string> changes = new Dictionary<string, string>(updates.Count);
|
||||||
|
|
||||||
|
if (_staticValues == null) _staticValues = new Dictionary<string, string>();
|
||||||
|
|
||||||
|
string key, value;
|
||||||
|
for (int i = 0; i < updates.Keys.Count; i++)
|
||||||
|
{
|
||||||
|
key = updates.Keys.ElementAt(i);
|
||||||
|
value = updates.Values.ElementAt(i);
|
||||||
|
|
||||||
|
if (_staticValues.TryGetValue(key, out var oldValue))
|
||||||
|
{
|
||||||
|
if (oldValue != updates[key] && _changeEvents.ContainsKey(key))
|
||||||
|
{
|
||||||
|
changes[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
changes[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------- 发送值变化事件 ------------
|
||||||
|
for (int i = 0; i < changes.Keys.Count; i++)
|
||||||
|
{
|
||||||
|
key = updates.Keys.ElementAt(i);
|
||||||
|
value = updates.Values.ElementAt(i);
|
||||||
|
|
||||||
|
if (_changeEvents.TryGetValue(key, out var callback))
|
||||||
|
{
|
||||||
|
callback?.Invoke(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_staticValues = updates;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
#region Log
|
#region Log
|
||||||
|
|
||||||
private static void LogI(string msg, params object[] args)
|
private static void LogI(string msg, params object[] args)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Guru
|
namespace Guru
|
||||||
|
|
@ -12,7 +13,7 @@ namespace Guru
|
||||||
{
|
{
|
||||||
private static float SaveInterval = 2f;
|
private static float SaveInterval = 2f;
|
||||||
private const string SaveKey = "comr.guru.remote.model.save";
|
private const string SaveKey = "comr.guru.remote.model.save";
|
||||||
public Dictionary<string, string> Data;
|
public Dictionary<string, string> configs;
|
||||||
public long last_modified = 0;
|
public long last_modified = 0;
|
||||||
|
|
||||||
private float _lastSavedTime = 0;
|
private float _lastSavedTime = 0;
|
||||||
|
|
@ -37,7 +38,7 @@ namespace Guru
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 默认赋值数据
|
/// 默认赋值数据
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private Dictionary<string, string> _defaultData;
|
private Dictionary<string, string> _defConfigs;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 加载数据
|
/// 加载数据
|
||||||
|
|
@ -70,8 +71,8 @@ namespace Guru
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public RemoteConfigModel()
|
public RemoteConfigModel()
|
||||||
{
|
{
|
||||||
_defaultData = new Dictionary<string, string>(20);
|
_defConfigs = new Dictionary<string, string>(20);
|
||||||
Data = new Dictionary<string, string>(20);
|
configs = new Dictionary<string, string>(20);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -79,7 +80,7 @@ namespace Guru
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="key"></param>
|
/// <param name="key"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public bool HasKey(string key) => Data.ContainsKey(key);
|
public bool HasKey(string key) => configs.ContainsKey(key);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 保存数据
|
/// 保存数据
|
||||||
|
|
@ -100,13 +101,12 @@ namespace Guru
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="key"></param>
|
/// <param name="key"></param>
|
||||||
/// <param name="value"></param>
|
/// <param name="value"></param>
|
||||||
public void SetDefault(string key, string value)
|
public void SetDefaultConfig(string key, string value)
|
||||||
{
|
{
|
||||||
_defaultData[key] = value;
|
_defConfigs[key] = value;
|
||||||
if (!HasKey(key))
|
if (!HasKey(key))
|
||||||
{
|
{
|
||||||
Data[key] = value;
|
SetConfigValue(key, value);
|
||||||
Save();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -115,10 +115,10 @@ namespace Guru
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="key"></param>
|
/// <param name="key"></param>
|
||||||
/// <param name="config"></param>
|
/// <param name="config"></param>
|
||||||
public void SetDefault<T>(string key, T config) where T : IRemoteConfig
|
public void SetDefaultConfig<T>(string key, T config) where T : IRemoteConfig<T>
|
||||||
{
|
{
|
||||||
var json = config.ToJson();
|
var json = config.ToJson();
|
||||||
SetDefault(key, json);
|
SetDefaultConfig(key, json);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -127,15 +127,59 @@ namespace Guru
|
||||||
/// <param name="key"></param>
|
/// <param name="key"></param>
|
||||||
/// <typeparam name="T"></typeparam>
|
/// <typeparam name="T"></typeparam>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public T Get<T>(string key) where T : IRemoteConfig
|
public T Get<T>(string key) where T : IRemoteConfig<T>
|
||||||
{
|
{
|
||||||
if(HasKey(key)) return JsonParser.ToObject<T>(Data[key]);
|
string json = "";
|
||||||
|
if (HasKey(key))
|
||||||
|
{
|
||||||
|
json = configs[json];
|
||||||
|
}
|
||||||
|
else if (_defConfigs.TryGetValue(key, out var defValue))
|
||||||
|
{
|
||||||
|
json = defValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(json))
|
||||||
|
{
|
||||||
|
return JsonParser.ToObject<T>(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.E(RemoteConfigManager.Tag, $" --- Remote Key {key} has never been registered.");
|
||||||
return default(T);
|
return default(T);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Set<T>(string key, T config) where T : IRemoteConfig
|
|
||||||
{
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置对象值
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
internal void SetConfigValue(string key, string value)
|
||||||
|
{
|
||||||
|
configs[key] = value;
|
||||||
|
Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新所有的配置
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="updates"></param>
|
||||||
|
public void UpdateConfigs(Dictionary<string, string> updates)
|
||||||
|
{
|
||||||
|
string key, value;
|
||||||
|
for (int i = 0; i < updates.Keys.Count; i++)
|
||||||
|
{
|
||||||
|
key = updates.Keys.ElementAt(i);
|
||||||
|
value = updates.Values.ElementAt(i);
|
||||||
|
|
||||||
|
if (!HasKey(key) || configs[key] != value)
|
||||||
|
{
|
||||||
|
// New Key or Value Changed
|
||||||
|
configs[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Save(true); // 直接保存
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,16 @@
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace Guru
|
namespace Guru
|
||||||
{
|
{
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Guru 内置浏览器
|
/// Guru 内置浏览器
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class GuruWebview
|
public class GuruWebview
|
||||||
{
|
{
|
||||||
public const string Version = "0.0.1";
|
public const string Version = "0.0.2";
|
||||||
|
public static float WindowFadeDuration = 0.35f;
|
||||||
|
|
||||||
private static UniWebView CreateWebView()
|
private static UniWebView CreateWebView()
|
||||||
{
|
{
|
||||||
|
|
@ -23,10 +23,14 @@ namespace Guru
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 打开链接
|
/// 打开页面
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="url"></param>
|
/// <param name="url">页面链接</param>
|
||||||
public static void OpenPage(string url, bool showToolbar = true)
|
/// <param name="showToolbar">显示工具条</param>
|
||||||
|
/// <param name="waitForReady">等待加载完成后再显示页面</param>
|
||||||
|
/// <param name="fadeIn">淡入显示效果</param>
|
||||||
|
public static void OpenPage(string url, bool showToolbar = true,
|
||||||
|
bool waitForReady = true, bool fadeIn = true)
|
||||||
{
|
{
|
||||||
Debug.Log($"---- Guru Open Url: {url}");
|
Debug.Log($"---- Guru Open Url: {url}");
|
||||||
var view = CreateWebView();
|
var view = CreateWebView();
|
||||||
|
|
@ -40,14 +44,19 @@ namespace Guru
|
||||||
}
|
}
|
||||||
|
|
||||||
view.Load(url);
|
view.Load(url);
|
||||||
view.OnPageFinished += (v, code, msg) =>
|
if (waitForReady)
|
||||||
{
|
{
|
||||||
// 加载完成后展示页面
|
view.OnPageFinished += (v, code, msg) =>
|
||||||
view.Show(true);
|
{
|
||||||
};
|
// 加载完成后展示页面
|
||||||
|
view.Show(fadeIn, duration:WindowFadeDuration);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
view.Show(fadeIn, duration:WindowFadeDuration); //直接加载页面
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
16
package.json
16
package.json
|
|
@ -12,21 +12,5 @@
|
||||||
"relatedPackages": {
|
"relatedPackages": {
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"com.unity.purchasing": "4.10.0",
|
|
||||||
"com.unity.mobile.android-logcat": "1.3.2",
|
|
||||||
"com.unity.editorcoroutines": "1.0.0",
|
|
||||||
"com.coffee.upm-git-extension": "https://github.com/mob-sakai/UpmGitExtension.git",
|
|
||||||
"com.google.external-dependency-manager": "https://github.com/GameWorkstore/com.google.external-dependency-manager.git",
|
|
||||||
"com.google.firebase.crashlytics": "https://github.com/GameWorkstore/com.google.firebase.crashlytics.git#10.1.1",
|
|
||||||
"com.google.firebase.analytics": "https://github.com/GameWorkstore/com.google.firebase.analytics.git#10.1.1",
|
|
||||||
"com.google.firebase.app": "https://github.com/GameWorkstore/com.google.firebase.app.git#10.1.1",
|
|
||||||
"com.google.firebase.auth": "https://github.com/GameWorkstore/com.google.firebase.auth.git#10.1.1",
|
|
||||||
"com.google.firebase.firestore": "https://github.com/GameWorkstore/com.google.firebase.firestore.git#10.1.1",
|
|
||||||
"com.google.firebase.messaging": "https://github.com/GameWorkstore/com.google.firebase.messaging.git#10.1.1",
|
|
||||||
"com.google.firebase.remote-config": "https://github.com/GameWorkstore/com.google.firebase.remote-config.git#10.1.1",
|
|
||||||
"com.google.firebase.dynamic-links": "https://github.com/GameWorkstore/com.google.firebase.dynamic-links.git#10.1.1",
|
|
||||||
|
|
||||||
"com.guru.unity.adjust": "git@git.chengdu.pundit.company:castbox/com.guru.unity.adjust.git",
|
|
||||||
"com.guru.unity.max": "git@git.chengdu.pundit.company:castbox/com.guru.unity.max.git"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue