Skip to content

fix(custom-page): 修复自定义主页不能正常跳转的问题 - #3528

Open
Pigeon0v0 wants to merge 3 commits into
devfrom
fix/custom-page-link
Open

fix(custom-page): 修复自定义主页不能正常跳转的问题#3528
Pigeon0v0 wants to merge 3 commits into
devfrom
fix/custom-page-link

Conversation

@Pigeon0v0

@Pigeon0v0 Pigeon0v0 commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Close #3517

Partly generated by GPT-5.6 Sol Max

Summary by Sourcery

通过将 JSON/XAML 内容加载到专用的帮助详情页,添加从事件打开自定义帮助/主页的支持。

新特性:

  • 引入 HelpDetail 页面类型,用于显示从 JSON 和 XAML 文件加载的详细帮助内容。
  • 允许 EventType.OpenHelp 解析本地或远程帮助资源,并在启动器中导航到相应的详情页。

缺陷修复:

  • 修复自定义主页/帮助事件的导航问题,使调用 EventType.OpenHelp 时能够正确打开目标帮助详情内容,而不再总是重定向到默认文档。

增强功能:

  • 扩展自定义事件的路径解析逻辑,以处理绝对 URL,并在显示前下载关联的帮助定义文件。
  • 改进页面栈相等性和标题解析,以正确处理帮助详情页及其关联实例。
Original summary in English

Summary by Sourcery

Add support for opening custom help/home pages from events by loading JSON/XAML content into a dedicated help detail page.

New Features:

  • Introduce a HelpDetail page type for displaying detailed help content loaded from JSON and XAML files.
  • Allow EventType.OpenHelp to resolve local or remote help resources and navigate to a corresponding detail page within the launcher.

Bug Fixes:

  • Fix custom home/help event navigation so that invoking EventType.OpenHelp correctly opens the intended help detail content instead of always redirecting to the default documentation.

Enhancements:

  • Extend path resolution logic for custom events to handle absolute URLs by downloading associated help definition files before display.
  • Improve page stack equality and title resolution to account for help detail pages and their associated instances.

@pcl-ce-automation pcl-ce-automation Bot added 🛠️ 等待审查 Pull Request 已完善,等待维护者或负责人进行代码审查 size: L PR 大小评估:大型 labels Aug 11, 2026
@sourcery-ai

sourcery-ai Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

审阅者指南

实现了新的 HelpDetail 页面以及自定义事件帮助 URL 的路由支持,包括远程 JSON/XAML 帮助内容支持,并重构了 GetAbsoluteUrls,以在解析和下载在线帮助定义的同时,将其接入主页面导航栈。

自定义 EventType.OpenHelp 处理与 HelpDetail 导航的时序图

sequenceDiagram
    participant CustomEvent
    participant ModBase
    participant GetAbsoluteUrls
    participant PageHelpDetail
    participant FormMain

    CustomEvent->>CustomEvent: _OpenHelp(arg, type)
    CustomEvent->>CustomEvent: SplitArgs(arg)
    CustomEvent->>CustomEvent: Uri.TryCreate(args[0])
    alt invalid_or_non_http_https_uri
        CustomEvent->>ModBase: OpenWebsite(https://docs.pclc.cc/ce)
    else valid_http_https_uri
        CustomEvent->>ModBase: RunInThread(lambda)
        ModBase->>GetAbsoluteUrls: GetAbsoluteUrls(args[0], type)
        GetAbsoluteUrls-->>ModBase: [location, pclDir]
        ModBase->>PageHelpDetail: LoadContent(location)
        PageHelpDetail-->>ModBase: HelpContent
        ModBase->>ModBase: RunInUiWait(lambda)
        ModBase->>FormMain: PageChange(new PageStackData { page = PageType.HelpDetail, helpPage = new PageHelpDetail(content) })
    end
Loading

文件级变更

变更 详情 文件
引入专门的 HelpDetail 页面并将其集成到主页面导航栈中,使帮助内容可以作为具有独立标题和刷新行为的子页面进行渲染。
  • 新增 PageType.HelpDetail,并在 PageNameGet 中添加对应的标题解析逻辑
  • 为 PageStackData 扩展 helpPage 字段,并更新 Equals 以按引用处理 HelpDetail 实例
  • 在 PageChangeActual 中处理 PageType.HelpDetail,通过动画切换到传入的 PageHelpDetail 实例
  • 创建 PageHelpDetail.xaml 和 PageHelpDetail.xaml.cs,从 JSON/XAML 加载帮助内容,对 XAML 进行安全处理,动态构建 UI 内容,并支持带日志和用户提示的刷新功能
Plain Craft Launcher 2/FormMain.xaml.cs
Plain Craft Launcher 2/Pages/PageHelpDetail.xaml
Plain Craft Launcher 2/Pages/PageHelpDetail.xaml.cs
重构自定义事件帮助处理逻辑,以同时支持本地和远程帮助定义,包括下载远程 JSON/XAML 帮助文件并通过新的 HelpDetail 页面打开。
  • 将内联的 OpenHelp 处理器替换为独立的 _OpenHelp 方法,该方法会校验 URL、在必要时回退到默认文档站点、加载帮助内容,并带错误日志地异步导航到 HelpDetail
  • 扩展 GetAbsoluteUrls,以检测用于 EventType.OpenHelp 的 HTTP/HTTPS 绝对 URL,强制要求其指向带有同名兄弟 .xaml 文件的 .json 帮助文件,通过 ModNet.NetDownloadByClient 将两者下载到临时目录,并解析最终本地 JSON 路径
  • 使用 Path.DirectorySeparatorChar 进行路径规范化,使用 Path.IsPathFullyQualified 进行绝对路径检测,并为不同解析分支添加说明性注释
Plain Craft Launcher 2/Modules/Event/CustomEvent.cs

与关联 issue 的对照评估

Issue 目标 已处理 说明
#3517 更新 EventType.OpenHelp 处理逻辑,使自定义主页(以及其他依赖该事件的功能)能够正确导航到其对应的帮助/自定义页面,而不是总是打开通用 Docs 网站。

可能关联的 issues


技巧与指令

与 Sourcery 交互

  • 触发新评审: 在 pull request 中评论 @sourcery-ai review
  • 继续讨论: 直接回复 Sourcery 的评审评论。
  • 从评审评论生成 GitHub issue: 在评审评论下回复,要求 Sourcery 从该评论创建 issue。你也可以回复 @sourcery-ai issue,从该评论创建 issue。
  • 生成 pull request 标题: 在 pull request 标题中任意位置写上 @sourcery-ai 即可随时生成标题。你也可以在 pull request 中评论 @sourcery-ai title 以(重新)生成标题。
  • 生成 pull request 摘要: 在 pull request 正文任意位置写上 @sourcery-ai summary,即可在该位置生成 PR 摘要。你也可以在 pull request 中评论 @sourcery-ai summary 以(重新)生成摘要。
  • 生成审阅者指南: 在 pull request 中评论 @sourcery-ai guide,即可(重新)生成审阅者指南。
  • 解决所有 Sourcery 评论: 在 pull request 中评论 @sourcery-ai resolve,即可将所有 Sourcery 评论标记为已解决。如果你已经处理完所有评论且不想再看到它们,这会很有用。
  • 撤销所有 Sourcery 评审: 在 pull request 中评论 @sourcery-ai dismiss,即可撤销所有现有的 Sourcery 评审。若你希望从一个新的评审开始,这尤其有用——别忘了再评论 @sourcery-ai review 来触发新的评审!

自定义你的使用体验

访问你的 控制面板 可以:

  • 启用或禁用评审功能,例如 Sourcery 自动生成的 pull request 摘要、审阅者指南等。
  • 修改评审语言。
  • 添加、移除或编辑自定义评审指令。
  • 调整其他评审设置。

获取帮助

Original review guide in English

Reviewer's Guide

Implements a new HelpDetail page and routing for custom-event help URLs, including support for remote JSON/XAML-based help content, and refactors GetAbsoluteUrls to resolve and download online help definitions while wiring them into the main page navigation stack.

Sequence diagram for custom EventType.OpenHelp handling and HelpDetail navigation

sequenceDiagram
    participant CustomEvent
    participant ModBase
    participant GetAbsoluteUrls
    participant PageHelpDetail
    participant FormMain

    CustomEvent->>CustomEvent: _OpenHelp(arg, type)
    CustomEvent->>CustomEvent: SplitArgs(arg)
    CustomEvent->>CustomEvent: Uri.TryCreate(args[0])
    alt invalid_or_non_http_https_uri
        CustomEvent->>ModBase: OpenWebsite(https://docs.pclc.cc/ce)
    else valid_http_https_uri
        CustomEvent->>ModBase: RunInThread(lambda)
        ModBase->>GetAbsoluteUrls: GetAbsoluteUrls(args[0], type)
        GetAbsoluteUrls-->>ModBase: [location, pclDir]
        ModBase->>PageHelpDetail: LoadContent(location)
        PageHelpDetail-->>ModBase: HelpContent
        ModBase->>ModBase: RunInUiWait(lambda)
        ModBase->>FormMain: PageChange(new PageStackData { page = PageType.HelpDetail, helpPage = new PageHelpDetail(content) })
    end
Loading

File-Level Changes

Change Details Files
Introduce a dedicated HelpDetail page and integrate it into the main page navigation stack so help content can be rendered as a subpage with its own title and refresh behavior.
  • Add PageType.HelpDetail and associated title resolution in PageNameGet
  • Extend PageStackData with a helpPage field and update Equals to handle HelpDetail instances by reference
  • Handle PageType.HelpDetail in PageChangeActual by animating to the provided PageHelpDetail instance
  • Create PageHelpDetail.xaml and PageHelpDetail.xaml.cs to load help content from JSON/XAML, sanitize XAML, build UI content dynamically, and support refresh with logging and user hints
Plain Craft Launcher 2/FormMain.xaml.cs
Plain Craft Launcher 2/Pages/PageHelpDetail.xaml
Plain Craft Launcher 2/Pages/PageHelpDetail.xaml.cs
Refactor custom event help handling to support both local and remote help definitions, including downloading remote JSON/XAML help files and opening them via the new HelpDetail page.
  • Replace inline OpenHelp handler with a dedicated _OpenHelp method that validates URLs, falls back to the default docs site, loads help content, and navigates to HelpDetail asynchronously with error logging
  • Extend GetAbsoluteUrls to detect absolute HTTP/HTTPS URLs for EventType.OpenHelp, enforce that they point to a .json help file with a sibling .xaml, download both to a temp folder via ModNet.NetDownloadByClient, and resolve the final local JSON path
  • Normalize paths using Path.DirectorySeparatorChar, use Path.IsPathFullyQualified for absolute path detection, and add clarifying comments for different resolution branches
Plain Craft Launcher 2/Modules/Event/CustomEvent.cs

Assessment against linked issues

Issue Objective Addressed Explanation
#3517 Update the EventType.OpenHelp handling so that custom homepages (and other features relying on this event) can correctly navigate to their intended help/custom pages instead of always opening the generic Docs website.

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - 我在这里给出了一些整体性的反馈:

  • _OpenHelp 中,使用了 SplitArgs(arg),并且在未检查数组长度的情况下访问了 args[0],如果事件参数为空或格式错误,就可能抛出异常;建议在索引前先对 args 进行校验。
给 AI 代理的提示
Please address the comments from this code review:

## Overall Comments
- In `_OpenHelp`, `SplitArgs(arg)` is used and `args[0]` is accessed without checking the array length, which can throw if the event arg is empty or malformed; consider validating `args` before indexing.

Sourcery 对开源项目免费——如果你觉得我们的评审有帮助,欢迎分享 ✨
帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据你的反馈改进后续评审。
Original comment in English

Hey - I've left some high level feedback:

  • In _OpenHelp, SplitArgs(arg) is used and args[0] is accessed without checking the array length, which can throw if the event arg is empty or malformed; consider validating args before indexing.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `_OpenHelp`, `SplitArgs(arg)` is used and `args[0]` is accessed without checking the array length, which can throw if the event arg is empty or malformed; consider validating `args` before indexing.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d8f47f5c44

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +31 to +32
var json = ModMain.ArgumentReplace(File.ReadAllText(jsonPath), SecurityElement.Escape);
using var document = JsonDocument.Parse(json);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Escape replacement values as JSON, not XML

When the help JSON contains a launcher placeholder such as {path} or {version_path}, ArgumentReplace passes its Windows value through SecurityElement.Escape, which does not escape backslashes for JSON. The resulting value contains sequences such as C:\PCL/\P, so JsonDocument.Parse treats them as invalid JSON escapes and the custom help page never opens. Use JSON string escaping (or parse/replace the relevant JSON value) instead of XML escaping.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size: L PR 大小评估:大型 🛠️ 等待审查 Pull Request 已完善,等待维护者或负责人进行代码审查

Projects

None yet

Development

Successfully merging this pull request may close these issues.

自定义主页可能不能正常跳转到其他页面

1 participant