Imports System.Windows.Threading
Public Class PageLaunchRight
Implements IRefreshable, IDispatcherUnhandledException
Private Sub Init() Handles Me.Loaded
PanBack.ScrollToHome()
CommunismWelcome.Visibility = If(ThemeNow = DefaultTheme, Visibility.Visible, Visibility.Collapsed)
PanLog.Visibility = ModeDebug.ToVisibility
'快照版提示
PanHint.Visibility =
(BuildType <> BuildTypes.Release AndAlso VersionBranchMain = "Official" AndAlso
CurrentRank < DonationRank.Rank23 AndAlso Not Settings.Get(Of Boolean)("HintSnapshot")).ToVisibility
End Sub
Private Sub BtnRedDownload_Click(sender As Object, e As EventArgs) Handles BtnRedDownload.Click
FrmMain.PageChange(FormMain.PageType.Download)
End Sub
Private Sub BtnRedThemes_Click(sender As Object, e As EventArgs) Handles BtnRedThemes.Click
FrmMain.PageChange(FormMain.PageType.Setup, FormMain.PageSubType.SetupUI)
End Sub
#Region "主页"
'''
''' 刷新主页。
'''
Private Sub Refresh() Handles Me.Loaded
RunInThread(
Sub()
Try
SyncLock RefreshLock
RefreshReal()
End SyncLock
Catch ex As Exception
Logger.Error(ex, "加载 PCL 主页自定义信息失败", If(ModeDebug, LogBehavior.Alert, LogBehavior.Toast))
End Try
End Sub)
End Sub
Private Sub RefreshReal()
Dim Content As String = Nothing
If Settings.Get(Of Integer)("UiCustomType") = 1 Then
Content = FileUtils.TryReadAsString(Paths.Base & "PCL\Custom.xaml")
ElseIf Settings.Get(Of Integer)("UiCustomType") = 3 Then
Content = ""
End If
RunInUi(Sub() LoadContent(Content))
End Sub
Private RefreshLock As New Object
Public Sub ForceRefresh() Implements IRefreshable.Refresh
Logger.Info("要求强制刷新主页")
ClearCache()
'实际的刷新
If FrmMain.PageCurrent.Page = FormMain.PageType.Launch Then
PanBack.ScrollToHome()
Refresh()
Else
FrmMain.PageChange(FormMain.PageType.Launch)
End If
End Sub
'''
''' 清空主页缓存信息。
'''
Private Sub ClearCache()
LoadedContentHash = Nothing
Settings.Set("CacheSavedPageUrl", "")
Settings.Set("CacheSavedPageVersion", "")
Logger.Info("已清空主页缓存")
End Sub
'''
''' 从文本内容中加载主页。
''' 必须在 UI 线程调用。
'''
Private Sub LoadContent(Content As String)
Try
SyncLock LoadContentLock
'如果加载目标内容一致则不加载
Dim Hash = If(Content, "").GetStableHashCode()
If Hash = LoadedContentHash Then Return
LoadedContentHash = Hash
'实际加载内容
PanCustom.Children.Clear()
If String.IsNullOrWhiteSpace(Content) Then
Logger.Info($"实例化:清空主页 UI,来源为空")
Return
End If
Dim LoadStartTime As Date = Date.Now
'修改时应同时修改 PageOtherHelpDetail.Init
Content = ArgumentReplace(Content, AddressOf StringUtils.XmlEscape)
Do While Content.Contains("xmlns")
Content = Content.RegexReplace("xmlns[^""']*(""|')[^""']*(""|')", "").Replace("xmlns", "") '禁止声明命名空间
Loop
Content = "" & Content & ""
Logger.Info($"实例化:加载主页 UI 开始,最终内容长度:{Content.Count}")
PanCustom.Children.Add(GetObjectFromXML(Content))
'加载计时
Dim LoadCostTime = (Date.Now - LoadStartTime).Milliseconds
Logger.Info($"实例化:加载主页 UI 完成,耗时 {LoadCostTime}ms")
If LoadCostTime > 3000 Then Hint($"主页加载过于缓慢(花费了 {Math.Round(LoadCostTime / 1000, 1)} 秒),请向主页作者反馈此问题,或暂时停止使用该主页")
End SyncLock
Catch ex As Exception
Logger.Warn(ex, $"加载失败的主页内容:{vbCrLf}{Content}")
OnLoadContentFailed(ex)
End Try
End Sub
'''
''' 加载主页失败时调用。
'''
Private Sub OnLoadContentFailed(ex As Exception)
If ModeDebug OrElse Settings.Get(Of Integer)("UiCustomType") = 1 Then
Logger.Warn(ex, "加载主页失败")
If MyMsgBox(If(TypeOf ex Is UnauthorizedAccessException, ex.Message, $"主页内容编写有误,请根据下列错误信息进行检查:{vbCrLf}{ex.GetDisplay(False)}"),
"加载主页失败", "重试", "取消") = 1 Then ForceRefresh()
Else
Logger.Error(ex, "加载主页失败", LogBehavior.Toast)
End If
End Sub
'''
''' 捕获主页在 Measure 和 Arrange 阶段抛出的异常。
'''
Private Sub DispatcherUnhandledException(sender As Object, e As DispatcherUnhandledExceptionEventArgs) Implements IDispatcherUnhandledException.DispatcherUnhandledException
If TypeOf e.Exception IsNot Markup.XamlParseException Then Return
e.Handled = True
LoadContent(Nothing)
OnLoadContentFailed(e.Exception)
End Sub
Private LoadedContentHash As ULong? = Nothing
Private LoadContentLock As New Object
#End Region
End Class