PageDownloadMod.xaml.vb 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. Public Class PageDownloadMod
  2. Public Const PageSize = 40
  3. '加载器信息
  4. Public Shared Loader As New LoaderTask(Of CompProjectRequest, Integer)("CompProject Mod", AddressOf CompProjectsGet, AddressOf LoaderInput) With {.ReloadTimeout = 60 * 1000}
  5. Public Shared Storage As New CompProjectStorage
  6. Public Shared Page As Integer = 0
  7. Private Sub PageDownloadMod_Inited(sender As Object, e As EventArgs) Handles Me.Initialized
  8. PageLoaderInit(Load, PanLoad, PanContent, PanAlways, Loader, AddressOf Load_OnFinish, AddressOf LoaderInput)
  9. If McVersionHighest = -1 Then McVersionHighest = Math.Max(McVersionHighest, Integer.Parse(CType(TextSearchVersion.Items(1), MyComboBoxItem).Content.ToString.Split(".")(1)))
  10. End Sub
  11. Private Shared Function LoaderInput() As CompProjectRequest
  12. Dim Request As New CompProjectRequest(CompType.Mod, Storage, (Page + 1) * PageSize)
  13. If FrmDownloadMod IsNot Nothing Then
  14. Dim ModLoader As CompModLoaderType = Val(FrmDownloadMod.ComboSearchLoader.SelectedItem.Tag)
  15. Dim GameVersion As String = If(FrmDownloadMod.TextSearchVersion.Text = "全部 (也可自行输入)", Nothing,
  16. If(FrmDownloadMod.TextSearchVersion.Text.Contains(".") OrElse FrmDownloadMod.TextSearchVersion.Text.Contains("w"), FrmDownloadMod.TextSearchVersion.Text, Nothing))
  17. If GameVersion IsNot Nothing AndAlso GameVersion.Contains(".") AndAlso Val(GameVersion.Split(".")(1)) < 14 AndAlso '1.14-
  18. ModLoader = CompModLoaderType.Forge Then '选择了 Forge
  19. ModLoader = CompModLoaderType.Any '此时,视作没有筛选 Mod Loader(因为部分老 Mod 没有设置自己支持的加载器)
  20. End If
  21. With Request
  22. .SearchText = FrmDownloadMod.TextSearchName.Text
  23. .GameVersion = GameVersion
  24. .Tag = FrmDownloadMod.ComboSearchTag.SelectedItem.Tag
  25. .ModLoader = ModLoader
  26. .Source = CType(Val(FrmDownloadMod.ComboSearchSource.SelectedItem.Tag), CompSourceType)
  27. End With
  28. End If
  29. Return Request
  30. End Function
  31. '结果 UI 化
  32. Private Sub Load_OnFinish()
  33. Try
  34. Log($"[Comp] 开始可视化 Mod 列表,已储藏 {Storage.Results.Count} 个结果,当前在第 {Page + 1} 页")
  35. '列表项
  36. PanProjects.Children.Clear()
  37. For i = Math.Min(Page * PageSize, Storage.Results.Count - 1) To Math.Min((Page + 1) * PageSize - 1, Storage.Results.Count - 1)
  38. PanProjects.Children.Add(Storage.Results(i).ToCompItem(Loader.Input.GameVersion Is Nothing, Loader.Input.ModLoader = CompModLoaderType.Any))
  39. Next
  40. '页码
  41. CardPages.Visibility = If(Storage.Results.Count > 40 OrElse
  42. Storage.CurseForgeOffset < Storage.CurseForgeTotal OrElse Storage.ModrinthOffset < Storage.ModrinthTotal,
  43. Visibility.Visible, Visibility.Collapsed)
  44. LabPage.Text = Page + 1
  45. BtnPageFirst.IsEnabled = Page > 1
  46. BtnPageFirst.Opacity = If(Page > 1, 1, 0.2)
  47. BtnPageLeft.IsEnabled = Page > 0
  48. BtnPageLeft.Opacity = If(Page > 0, 1, 0.2)
  49. Dim IsRightEnabled As Boolean = '由于 WPF 的未知 bug,读取到的 IsEnabled 可能是错误的值(#3319)
  50. Storage.Results.Count > PageSize * (Page + 1) OrElse
  51. Storage.CurseForgeOffset < Storage.CurseForgeTotal OrElse Storage.ModrinthOffset < Storage.ModrinthTotal
  52. BtnPageRight.IsEnabled = IsRightEnabled
  53. BtnPageRight.Opacity = If(IsRightEnabled, 1, 0.2)
  54. '错误信息
  55. If Storage.ErrorMessage Is Nothing Then
  56. HintError.Visibility = Visibility.Collapsed
  57. Else
  58. HintError.Visibility = Visibility.Visible
  59. HintError.Text = Storage.ErrorMessage
  60. End If
  61. '强制返回顶部
  62. PanBack.ScrollToTop()
  63. Catch ex As Exception
  64. Log(ex, "可视化 Mod 列表出错", LogLevel.Feedback)
  65. End Try
  66. End Sub
  67. '自动重试
  68. Private Sub Load_State(sender As Object, state As MyLoading.MyLoadingState, oldState As MyLoading.MyLoadingState) Handles Load.StateChanged
  69. Select Case Loader.State
  70. Case LoadState.Failed
  71. Dim ErrorMessage As String = ""
  72. If Loader.Error IsNot Nothing Then ErrorMessage = Loader.Error.Message
  73. If ErrorMessage.Contains("不是有效的 json 文件") Then
  74. Log("[Download] 下载的 Mod 列表 json 文件损坏,已自动重试", LogLevel.Debug)
  75. PageLoaderRestart()
  76. End If
  77. End Select
  78. End Sub
  79. '切换页码
  80. Private Sub BtnPageFirst_Click(sender As Object, e As RoutedEventArgs) Handles BtnPageFirst.Click
  81. ChangePage(0)
  82. End Sub
  83. Private Sub BtnPageLeft_Click(sender As Object, e As RoutedEventArgs) Handles BtnPageLeft.Click
  84. ChangePage(Page - 1)
  85. End Sub
  86. Private Sub BtnPageRight_Click(sender As Object, e As RoutedEventArgs) Handles BtnPageRight.Click
  87. ChangePage(Page + 1)
  88. End Sub
  89. Private Sub ChangePage(NewPage As Integer)
  90. CardPages.IsEnabled = False
  91. Page = NewPage
  92. FrmMain.BackToTop()
  93. Log($"[Download] Mod 切换到第 {Page + 1} 页")
  94. RunInThread(
  95. Sub()
  96. Thread.Sleep(100) '等待向上滚的动画结束
  97. RunInUi(Sub() CardPages.IsEnabled = True)
  98. Loader.Start()
  99. End Sub)
  100. End Sub
  101. #Region "搜索"
  102. '搜索按钮
  103. Private Sub StartNewSearch() Handles BtnSearchRun.Click
  104. Page = 0
  105. If Loader.ShouldStart(LoaderInput()) Then Storage = New CompProjectStorage '避免连续搜索两次使得 CompProjectStorage 引用丢失(#1311)
  106. Loader.Start()
  107. End Sub
  108. Private Sub EnterTrigger(sender As Object, e As KeyEventArgs) Handles TextSearchName.KeyDown, TextSearchVersion.KeyDown
  109. If e.Key = Key.Enter Then StartNewSearch()
  110. End Sub
  111. '重置按钮
  112. Private Sub BtnSearchReset_Click(sender As Object, e As EventArgs) Handles BtnSearchReset.Click
  113. TextSearchName.Text = ""
  114. TextSearchVersion.Text = "全部 (也可自行输入)"
  115. TextSearchVersion.SelectedIndex = 0
  116. ComboSearchSource.SelectedIndex = 0
  117. ComboSearchTag.SelectedIndex = 0
  118. ComboSearchLoader.SelectedIndex = 0
  119. Loader.LastFinishedTime = 0 '要求强制重新开始
  120. End Sub
  121. '版本选择
  122. '#3067:当下拉菜单展开时,程序会被 WPF 挂起,因而无法更新 Grid 布局,所以必须延迟到下拉菜单收起后才能更新
  123. Private Sub TextSearchVersion_TextChanged() Handles TextSearchVersion.TextChanged
  124. If Not TextSearchVersion.IsDropDownOpen Then UpdateSearchLoaderVisibility()
  125. End Sub
  126. Private Sub UpdateSearchLoaderVisibility() Handles TextSearchVersion.DropDownClosed
  127. If TextSearchVersion.Text.Contains(".") OrElse TextSearchVersion.Text.Contains("w") Then
  128. ComboSearchLoader.Visibility = Visibility.Visible
  129. Grid.SetColumnSpan(TextSearchVersion, 1)
  130. Else
  131. ComboSearchLoader.Visibility = Visibility.Collapsed
  132. Grid.SetColumnSpan(TextSearchVersion, 2)
  133. ComboSearchLoader.SelectedIndex = 0
  134. End If
  135. End Sub
  136. #End Region
  137. End Class