PageLaunchRight.xaml.vb 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. Imports System.Windows.Threading
  2. Public Class PageLaunchRight
  3. Implements IRefreshable, IDispatcherUnhandledException
  4. Private Sub Init() Handles Me.Loaded
  5. PanBack.ScrollToHome()
  6. CommunismWelcome.Visibility = If(ThemeNow = DefaultTheme, Visibility.Visible, Visibility.Collapsed)
  7. PanLog.Visibility = ModeDebug.ToVisibility
  8. '快照版提示
  9. PanHint.Visibility =
  10. (BuildType <> BuildTypes.Release AndAlso VersionBranchMain = "Official" AndAlso
  11. CurrentRank < DonationRank.Rank23 AndAlso Not Settings.Get(Of Boolean)("HintSnapshot")).ToVisibility
  12. End Sub
  13. Private Sub BtnRedDownload_Click(sender As Object, e As EventArgs) Handles BtnRedDownload.Click
  14. FrmMain.PageChange(FormMain.PageType.Download)
  15. End Sub
  16. Private Sub BtnRedThemes_Click(sender As Object, e As EventArgs) Handles BtnRedThemes.Click
  17. FrmMain.PageChange(FormMain.PageType.Setup, FormMain.PageSubType.SetupUI)
  18. End Sub
  19. #Region "主页"
  20. ''' <summary>
  21. ''' 刷新主页。
  22. ''' </summary>
  23. Private Sub Refresh() Handles Me.Loaded
  24. RunInThread(
  25. Sub()
  26. Try
  27. SyncLock RefreshLock
  28. RefreshReal()
  29. End SyncLock
  30. Catch ex As Exception
  31. Logger.Error(ex, "加载 PCL 主页自定义信息失败", If(ModeDebug, LogBehavior.Alert, LogBehavior.Toast))
  32. End Try
  33. End Sub)
  34. End Sub
  35. Private Sub RefreshReal()
  36. Dim Content As String = Nothing
  37. If Settings.Get(Of Integer)("UiCustomType") = 1 Then
  38. Content = FileUtils.TryReadAsString(Paths.Base & "PCL\Custom.xaml")
  39. ElseIf Settings.Get(Of Integer)("UiCustomType") = 3 Then
  40. Content = "<local:MyCard Title=""你知道吗?"" Margin=""0,0,0,15""><TextBlock Margin=""25,38,23,15"" Text=""{hint}"" TextWrapping=""Wrap"" /></local:MyCard>"
  41. End If
  42. RunInUi(Sub() LoadContent(Content))
  43. End Sub
  44. Private RefreshLock As New Object
  45. Public Sub ForceRefresh() Implements IRefreshable.Refresh
  46. Logger.Info("要求强制刷新主页")
  47. ClearCache()
  48. '实际的刷新
  49. If FrmMain.PageCurrent.Page = FormMain.PageType.Launch Then
  50. PanBack.ScrollToHome()
  51. Refresh()
  52. Else
  53. FrmMain.PageChange(FormMain.PageType.Launch)
  54. End If
  55. End Sub
  56. ''' <summary>
  57. ''' 清空主页缓存信息。
  58. ''' </summary>
  59. Private Sub ClearCache()
  60. LoadedContentHash = Nothing
  61. Settings.Set("CacheSavedPageUrl", "")
  62. Settings.Set("CacheSavedPageVersion", "")
  63. Logger.Info("已清空主页缓存")
  64. End Sub
  65. ''' <summary>
  66. ''' 从文本内容中加载主页。
  67. ''' 必须在 UI 线程调用。
  68. ''' </summary>
  69. Private Sub LoadContent(Content As String)
  70. Try
  71. SyncLock LoadContentLock
  72. '如果加载目标内容一致则不加载
  73. Dim Hash = If(Content, "").GetStableHashCode()
  74. If Hash = LoadedContentHash Then Return
  75. LoadedContentHash = Hash
  76. '实际加载内容
  77. PanCustom.Children.Clear()
  78. If String.IsNullOrWhiteSpace(Content) Then
  79. Logger.Info($"实例化:清空主页 UI,来源为空")
  80. Return
  81. End If
  82. Dim LoadStartTime As Date = Date.Now
  83. '修改时应同时修改 PageOtherHelpDetail.Init
  84. Content = ArgumentReplace(Content, AddressOf StringUtils.XmlEscape)
  85. Do While Content.Contains("xmlns")
  86. Content = Content.RegexReplace("xmlns[^""']*(""|')[^""']*(""|')", "").Replace("xmlns", "") '禁止声明命名空间
  87. Loop
  88. Content = "<StackPanel xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" xmlns:sys=""clr-namespace:System;assembly=mscorlib"" xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"" xmlns:local=""clr-namespace:PCL;assembly=Plain Craft Launcher 2"" xmlns:core=""clr-namespace:MeloongCore;assembly=MeloongCore"" xmlns:corewpf=""clr-namespace:MeloongCore.Wpf;assembly=MeloongCore.Wpf"">" & Content & "</StackPanel>"
  89. Logger.Info($"实例化:加载主页 UI 开始,最终内容长度:{Content.Count}")
  90. PanCustom.Children.Add(GetObjectFromXML(Content))
  91. '加载计时
  92. Dim LoadCostTime = (Date.Now - LoadStartTime).Milliseconds
  93. Logger.Info($"实例化:加载主页 UI 完成,耗时 {LoadCostTime}ms")
  94. If LoadCostTime > 3000 Then Hint($"主页加载过于缓慢(花费了 {Math.Round(LoadCostTime / 1000, 1)} 秒),请向主页作者反馈此问题,或暂时停止使用该主页")
  95. End SyncLock
  96. Catch ex As Exception
  97. Logger.Warn(ex, $"加载失败的主页内容:{vbCrLf}{Content}")
  98. OnLoadContentFailed(ex)
  99. End Try
  100. End Sub
  101. ''' <summary>
  102. ''' 加载主页失败时调用。
  103. ''' </summary>
  104. Private Sub OnLoadContentFailed(ex As Exception)
  105. If ModeDebug OrElse Settings.Get(Of Integer)("UiCustomType") = 1 Then
  106. Logger.Warn(ex, "加载主页失败")
  107. If MyMsgBox(If(TypeOf ex Is UnauthorizedAccessException, ex.Message, $"主页内容编写有误,请根据下列错误信息进行检查:{vbCrLf}{ex.GetDisplay(False)}"),
  108. "加载主页失败", "重试", "取消") = 1 Then ForceRefresh()
  109. Else
  110. Logger.Error(ex, "加载主页失败", LogBehavior.Toast)
  111. End If
  112. End Sub
  113. ''' <summary>
  114. ''' 捕获主页在 Measure 和 Arrange 阶段抛出的异常。
  115. ''' </summary>
  116. Private Sub DispatcherUnhandledException(sender As Object, e As DispatcherUnhandledExceptionEventArgs) Implements IDispatcherUnhandledException.DispatcherUnhandledException
  117. If TypeOf e.Exception IsNot Markup.XamlParseException Then Return
  118. e.Handled = True
  119. LoadContent(Nothing)
  120. OnLoadContentFailed(e.Exception)
  121. End Sub
  122. Private LoadedContentHash As ULong? = Nothing
  123. Private LoadContentLock As New Object
  124. #End Region
  125. End Class