用户令「下载页只负责下载整合包和Mod/光影」:新开一页做**内容发现与装入**,
检索走 Modrinth(优先,无需 key)/ CurseForge(`ULL_CF_API_KEY` 环境变量,日志只打
set/unset),装入走 core 的下载引擎真下到实例目录,进度/取消/失败复用下载页那块安装面板。
- **入口(B1)**:`Route::Content` 是新顶层路由,但 `Route::nav()` 复用 `NavSection::Download`
——导航轨仍五项,页头右上是「版本管理 | 内容库」一级切换(版本管理页也加了同一个切换,
否则内容库只有 `ULL_START_ROUTE` 能到)
- **页内四条一级侧栏**(`pages/content/layout.rs` 四档几何:992/856/648 三个门槛都是
「Σ栏宽 + 间距」算出来的):整合包 / Mod / 资源包 / 光影;标签栏 200(`Resource packs`
比 M107 的版本类型名长,140 会切字,已登记偏离)
- **筛选**:关键词(草稿 + 显式「搜索」按钮,不逐字打网络)、来源、游戏版本、加载器
(Fabric/Forge/NeoForge/Quilt)、排序;**分页**(「加载更多」)而不是无限滚动——快照只有一个槽、
翻页要看得见、状态要可截图复现
- **四态**:加载 / 空 / 失败 / 有数据 + 「没有更多了」;筛选条在任何状态下都在(加载中藏筛选条
等于把入口收走)
- **一键装入**:`Content::blockers()` 是纯函数——版本不匹配、加载器不匹配、没有目标实例、
整合包缺管线**四条原因逐条**给出,按钮点之前就禁用;判定与画法分开(model/tests 直接钉)
- **整合包今天不可装**:`ContentKind::Modpack.dir()` 是 `None`,UI 禁用 + 说明,host 侧再挡
一次(绕过 UI 也只会回一条 Failed)。真流程是 M111 的导入管线
- **零 UI 网络**:`presenter/host/addon.rs` + `addon/{sources,http,install}.rs`;无 header 的请求走
core 的 `download_bytes`(信号量限流 + 健康度 + 退避全现成),带 `X-API-KEY` 的只有 CF 一条,
自带 429/5xx 退避(优先吃 `Retry-After`,封顶 30s);密钥不进 DTO/日志/仓库
- 文案 41 条中英进 `crates/i18n`(新域接在装配链末尾 ⇒ `Key::ALL` 与金表只追加)
- 演示数据 `ContentHit → Hit::of` 与产品路径同源(格式化不会两套),`ULL_CONTENT_KIND` /
`ULL_CONTENT_STATE` 供出图矩阵选类型与状态
取证:`DevDocs/artifacts/m109/`(10 张:四类内容 × 浅/深 + 搜索无结果 + 加载器不兼容禁用)
门禁:fmt ✓ / clippy `-D warnings`(三 crate)✓ / app-iced 450+6、presenter 170、i18n 24 全绿;
`cargo tree` 两条零 UI 门禁仍空;全部改动文件 ≤400 行。
222 lines
17 KiB
Rust
222 lines
17 KiB
Rust
//! 拆分前的 `key -> (en, zh-CN)` **逐字快照**(金表)。
|
||
//!
|
||
//! ## 它是什么
|
||
//!
|
||
//! M99 把 `catalog.rs` 的单张条目表按域拆到 `catalog/<域>.rs` 之后,这 72 行就是「拆分前那一份」
|
||
//! 的原样导出:由拆分前的 `Catalog::of(En)` / `Catalog::of(ZhCn)` 逐条 `println!` 出来,
|
||
//! 再原封不动抄进来(生成方式见 `catalog/tests.rs` 里 `split_keeps_every_translation` 的注释)。
|
||
//! M108 在它上面改了 3 条(`NavDownload` / `DownloadTitle` / `DownloadSubtitle`)、追加了 1 条
|
||
//! (`NavDownloadExpanded`);M105/M106/M107 各自追加的条目也都在,整表现在是 138 条。
|
||
//!
|
||
//! ## 为什么不是「数条数」
|
||
//!
|
||
//! 条数相等抓不住任何一种真会发生的坏法:某条译文在搬移时被漏掉、另一条被复制两次,条数照旧。
|
||
//! 这张表比的是**全量、逐字节、按声明顺序**的三元组,于是下面四种坏法都会红:
|
||
//!
|
||
//! | 坏法 | 红在哪 |
|
||
//! |---|---|
|
||
//! | 某个 key 整条被搬丢 | 条数不等 / 该行 key 名对不上 |
|
||
//! | 两条 key 的译文互抄(同 key 被覆盖到别的译文) | 该行 en 或 zh 不等 |
|
||
//! | 某条译文改了一个字符 | 该行不等(`assert_eq!` 带原文) |
|
||
//! | 域的顺序被调换(`Key` 的 `Ord` 与导出表顺序都靠它) | 该行 key 名对不上 |
|
||
//!
|
||
//! **抓不住**:译文本身翻得对不对(金表是「拆分前」的快照,它只能证明「没变」)。
|
||
//!
|
||
//! ## M108 更新了三条、新增了一条(版本管理改名)
|
||
//!
|
||
//! 用户令(2026-11-04)把这页的显示名从「下载 / Downloads」改成「版本管理 / Version management」:
|
||
//! [`super::Key::NavDownload`] / [`super::Key::DownloadTitle`] / [`super::Key::DownloadSubtitle`]
|
||
//! 三条译文按令改掉,并**新增** [`super::Key::NavDownloadExpanded`](240 展开态的全标签,
|
||
//! 88 轨放不下 18 字符的英文,见 `catalog/nav.rs` 的「两条 key」一节)。
|
||
//!
|
||
//! 其余各行仍逐字节等于拆分前那份快照——也就是说这张表现在证明的是「除这几条按令改过的,
|
||
//! 其余一字未动」,不再是「整表一字未动」。
|
||
|
||
/// 拆分前 `Key::ALL` 的顺序 × (en, zh-CN)。第一列是变体名(`Key::name()` 的返回值)。
|
||
pub(super) const GOLDEN: &[(&str, &str, &str)] = &[
|
||
("NavInstances", "Instances", "实例"),
|
||
("NavDownload", "Versions", "版本管理"),
|
||
("NavDownloadExpanded", "Version management", "版本管理"),
|
||
("NavLogs", "Logs", "日志"),
|
||
("NavSettings", "Settings", "设置"),
|
||
("InstancesNew", "New instance", "新建实例"),
|
||
("InstancesImport", "Import", "导入"),
|
||
("InstancesBack", "Back to instances", "返回实例列表"),
|
||
("InstancesPlay", "Play", "启动"),
|
||
("InstancesLastPlayed", "Last played {when}", "上次游玩 {when}"),
|
||
("InstancesEmptyTitle", "No instance selected", "未选择实例"),
|
||
("InstancesEmptyBody", "Pick an instance to see its details.", "选择一个实例查看详情。"),
|
||
("LoaderVanilla", "Vanilla", "原版"),
|
||
("LaunchOutcomeNormal", "Finished normally", "正常结束"),
|
||
("LaunchOutcomeCrash", "The game crashed", "游戏崩溃"),
|
||
("LaunchOutcomeSilent", "Suspected silent failure: exit code 0, but the game never really started", "疑似静默失败:退出码 0,但游戏没真正跑起来"),
|
||
("LaunchFailedWithCode", "Launch failed (exit {code}): {reason}", "启动失败(退出码 {code}):{reason}"),
|
||
("FontCjkNeedsDownload", "No Chinese font found on this system. Download an open-source (OFL) Chinese font?", "系统里没找到中文字体。要下载一套开源(OFL)中文字体吗?"),
|
||
("FontCjkDownloading", "Downloading Chinese font… {percent}%", "正在下载中文字体… {percent}%"),
|
||
("FontCjkDownloadFailed", "Chinese font download failed; the interface stays in English.", "中文字体下载失败,界面暂时保持英文。"),
|
||
("FontCjkReady", "Chinese font ready: {family}", "中文字体已就绪:{family}"),
|
||
("SettingsLanguage", "Language", "界面语言"),
|
||
("SettingsLanguageHint", "Switches the interface language. Chinese text needs a Chinese font.", "切换界面语言。显示中文需要中文字体。"),
|
||
("CoreTextUntranslated", "[system text not translated]", "[未翻译的系统文案]"),
|
||
("DownloadTitle", "Version management", "版本管理"),
|
||
("DownloadSubtitle", "Manage versions and loaders: install, upgrade, repair", "管理版本与加载器:安装、升级、修复"),
|
||
("DownloadRefresh", "Refresh", "刷新"),
|
||
("DownloadInstall", "Install", "安装"),
|
||
("DownloadCancel", "Cancel install", "取消安装"),
|
||
("DownloadInstalled", "Installed", "已安装"),
|
||
("DownloadCount", "{count} versions", "{count} 个版本"),
|
||
("DownloadRowSupporting", "{kind} · released {date}", "{kind} · 发布于 {date}"),
|
||
("DownloadSelectHint", "Pick a version, then install", "选一个版本再安装"),
|
||
("DownloadLoading", "Loading versions…", "正在加载版本列表…"),
|
||
("DownloadLoadingHint", "If this stays here, press Refresh in the top right.", "如果一直停在这里,点右上角的刷新。"),
|
||
("DownloadEmptyTitle", "No versions to show", "没有可显示的版本"),
|
||
("DownloadEmptyBody", "Pick another category, or refresh the list.", "换一个分类,或刷新一次列表。"),
|
||
("DownloadCategoryAll", "All", "全部"),
|
||
("DownloadCategoryRelease", "Release", "正式版"),
|
||
("DownloadCategorySnapshot", "Snapshot", "预览版"),
|
||
("DownloadCategoryAncient", "Ancient", "远古版"),
|
||
("DownloadStagePlanning", "Planning", "解析版本"),
|
||
("DownloadStageDownloading", "Downloading files", "下载文件"),
|
||
("DownloadStageInstalling", "Building the version", "生成版本"),
|
||
("DownloadStageRegistering", "Registering the instance", "登记实例"),
|
||
("DownloadStageDone", "Done", "已完成"),
|
||
("DownloadStageFailed", "Install failed", "安装失败"),
|
||
("DownloadStageCancelled", "Install cancelled", "安装已取消"),
|
||
("DownloadProgress", "{done}/{total} files", "{done}/{total} 文件"),
|
||
("DownloadProgressUnknown", "Waiting for the first file…", "等第一个文件…"),
|
||
("DownloadRate", "{speed} · {eta}", "{speed},{eta}"),
|
||
("DownloadEtaSecs", "{secs}s left", "剩 {secs}s"),
|
||
("DownloadEtaMins", "{mins}m{secs}s left", "剩 {mins}m{secs}s"),
|
||
("DownloadFailedHint", "The Logs page has the full reason.", "完整原因在日志页。"),
|
||
("DownloadOpenLogs", "Open logs", "打开日志"),
|
||
("DownloadDismiss", "Dismiss", "关闭"),
|
||
("DownloadOptionsTitle", "Install options", "安装选项"),
|
||
("DownloadOptionsLoaderVersion", "Loader version", "加载器版本"),
|
||
("DownloadOptionsLoaderVersionsLoading", "Fetching loader versions…", "正在获取加载器版本…"),
|
||
("DownloadOptionsLoaderVersionsFailed", "Could not fetch loader versions: {reason}", "取不到加载器版本:{reason}"),
|
||
("DownloadOptionsLoaderVersionsEmpty", "No loader builds published for {version}", "官方没有为 {version} 发布加载器版本"),
|
||
("DownloadOptionsInstanceName", "Instance name", "实例名"),
|
||
("DownloadOptionsInstanceNameHint", "Empty = use the version id", "留空就用版本号"),
|
||
("DownloadOptionsIncompatible", "{loader} has no builds for {version}", "{loader} 没有适配 {version} 的构建"),
|
||
("DownloadOptionsNeedsAtLeast", "{loader} needs Minecraft {min} or newer", "{loader} 需要 Minecraft {min} 或更新"),
|
||
("DownloadCancelled", "Install cancelled — finished files are kept, the instance was not created", "安装已取消 —— 已下好的文件保留,实例未登记"),
|
||
("LogsSubtitleIdle", "Nothing is running right now", "当前没有运行中的实例"),
|
||
("LogsStatus", "{instance} · {when} · {outcome}", "{instance}|{when}|{outcome}"),
|
||
("LogsOpenFolder", "Open folder", "打开目录"),
|
||
("LogsClear", "Clear", "清空"),
|
||
("LogsOutputTitle", "OUTPUT", "输出"),
|
||
("LogsDiagnosisTitle", "DIAGNOSIS", "诊断"),
|
||
("LogsConfidenceHigh", "HIGH CONFIDENCE", "高置信度"),
|
||
("LogsConfidenceMedium", "MEDIUM CONFIDENCE", "中置信度"),
|
||
("LogsConfidenceLow", "LOW CONFIDENCE", "低置信度"),
|
||
("LogsSubtitleLive", "Running now — logs stream as they arrive", "正在运行 — 日志实时滚动"),
|
||
("LogsConfidence", "Confidence {percent}%", "置信度 {percent}%"),
|
||
("LogsSuggestedFix", "Suggested fix", "建议动作"),
|
||
("LogsSummaryLabel", "One-line summary", "一行摘要"),
|
||
("LogsCopySummary", "Copy summary", "复制摘要"),
|
||
("LogsEmptyTitle", "No output yet", "还没有输出"),
|
||
("LogsEmptyBody", "Logs stream here while the launcher or the game is running. Pick an instance and start it to see the first lines.", "启动器或游戏运行时,日志会实时出现在这里。选择一个实例并启动,就能看到第一批日志。"),
|
||
("LogsEmptyAction", "Choose an instance", "选择实例"),
|
||
("AgentTitle", "Assistant", "助手"),
|
||
("AgentSubtitle", "Conversation shell · no backend yet", "会话外壳 · 后端未接"),
|
||
("AgentCollapse", "Collapse", "收起"),
|
||
("AgentDetach", "Pop out", "拆出"),
|
||
("AgentDock", "Dock back", "收回"),
|
||
("AgentOpen", "Open assistant", "打开助手"),
|
||
("AgentStripLabel", "AI", "助手"),
|
||
("AgentSend", "Send", "发送"),
|
||
("AgentStop", "Stop", "中断"),
|
||
("AgentPlaceholder", "Message the assistant…", "给助手发消息…"),
|
||
("AgentEmptyTitle", "Nothing in this session yet", "这个会话还没有内容"),
|
||
("AgentEmptyBody", "Ask about instances, downloads or logs. No model is wired up yet.", "可以问实例、下载或日志。模型还没接上。"),
|
||
("AgentNotePending", "Placeholder shell: your message is kept here, nothing was sent to a model.", "占位外壳:消息留在这里,没有发给任何模型。"),
|
||
("AgentNoteStopped", "Stopped by you.", "你中断了这次回复。"),
|
||
("AgentUnread", "{count} unread", "{count} 条未读"),
|
||
("AgentResize", "Drag to resize the assistant rail", "拖动调整助手栏宽度"),
|
||
("AgentWidthLabel", "Width {width}", "宽度 {width}"),
|
||
("AgentRoleYou", "You", "你"),
|
||
("AgentRoleAssistant", "Assistant", "助手"),
|
||
("AgentRoleNotice", "Notice", "提示"),
|
||
// ── M106 `I18NFOLLOW`:General 分组真控件(语言选择器 + 其余三行)。**只追加在链尾**,
|
||
// 上一行到 `LogsEmptyAction` 的既有顺序一字未动(金表要证明的正是这件事)。
|
||
("SettingsLanguageFollowSystem", "Follow system", "跟随系统"),
|
||
("SettingsLanguageZhCn", "Chinese (Simplified)", "简体中文"),
|
||
("SettingsLanguageEn", "English", "英文"),
|
||
("SettingsLanguageEffective", "Interface right now: {language}", "界面当前使用:{language}"),
|
||
("SettingsTheme", "Theme", "主题"),
|
||
("SettingsThemeFollowSystem", "Follow system", "跟随系统"),
|
||
("SettingsStartupPage", "Startup page", "启动页"),
|
||
("SettingsStartupInstances", "Instances", "实例"),
|
||
("SettingsCloseButton", "Close button", "关闭按钮"),
|
||
("SettingsCloseToTray", "Exit to tray", "退出到托盘"),
|
||
("SettingsSubtitle", "Launcher behaviour, Java runtimes and download sources", "启动器行为、Java 运行时与下载源"),
|
||
("SettingsResetSection", "Reset section", "重置本组"),
|
||
("SettingsSave", "Save", "保存"),
|
||
("NavAi", "Assistant", "助手"),
|
||
("SettingsGroupGeneral", "General", "通用"),
|
||
("SettingsGroupAppearance", "Appearance", "外观"),
|
||
("SettingsGroupJava", "Java", "Java 运行时"),
|
||
("SettingsGroupDownloads", "Downloads", "下载"),
|
||
("SettingsOverridesEmptyTitle", "No per-instance overrides", "没有逐实例覆盖"),
|
||
("SettingsOverridesEmptyBody", "Overrides let one instance keep its own Java runtime, memory or JVM flags while the rest of the launcher keeps the defaults above.", "逐实例覆盖让某个实例保留自己的 Java 运行时、内存或 JVM 参数,其余实例沿用上面的默认值。"),
|
||
("SettingsOverridesAdd", "Add override", "新增覆盖"),
|
||
("AgentFallbackBody", "The assistant page is not built yet. Chat lives in the docked panel once the AI mission lands; this screen is the M68 skeleton fallback.", "助手页还没做。AI 接线落地后对话会出现在右侧停靠面板;这一屏是 M68 的骨架回退。"),
|
||
// --- M107 版本管理页(追加在链尾:`Key::ALL` 顺序 = 金表顺序) ---
|
||
("VersionRailTitle", "Version type", "版本类型"),
|
||
("VersionMajorTitle", "Major version", "主版本"),
|
||
("VersionMajorAll", "All versions", "全部版本"),
|
||
("VersionSearchPlaceholder", "Search version numbers", "搜版本号"),
|
||
("VersionSearchClear", "Clear search", "清空搜索"),
|
||
("VersionSearchHits", "{count} matches", "{count} 个匹配"),
|
||
("VersionSearchEmptyTitle", "No matching versions", "没有匹配的版本"),
|
||
("VersionSearchEmptyBody", "Try a shorter piece of the number — 1.21, 24w, a1.", "试试更短的片段 — 1.21、24w、a1。"),
|
||
("VersionSearchElsewhere", "{count} versions match, but they are in another type.", "有 {count} 个版本匹配,但它们在别的类型里。"),
|
||
("VersionSearchElsewhereAction", "Show all types", "看全部类型"),
|
||
// --- M107 r2(追加在末尾:`Key::ALL` 顺序 = 金表顺序) ---
|
||
("VersionSearchHitsOne", "1 match", "1 个匹配"),
|
||
("VersionSearchElsewhereTitle", "Found in another type", "在别的类型里找到了"),
|
||
("VersionSearchElsewhereOne", "1 version matches, but it is in another type.", "有 1 个版本匹配,但它在别的类型里。"),
|
||
// --- M109 内容库页(同样追加在链尾:`Key::ALL` 顺序 = 金表顺序) ---
|
||
("ContentTitle", "Content", "内容库"),
|
||
("ContentSubtitle", "Modpacks, mods, resource packs and shaders", "整合包、Mod、资源包与光影"),
|
||
("ContentSectionVersions", "Version management", "版本管理"),
|
||
("ContentSectionContent", "Content library", "内容库"),
|
||
("ContentKindModpack", "Modpacks", "整合包"),
|
||
("ContentKindMod", "Mods", "Mod"),
|
||
("ContentKindResourcepack", "Resource packs", "资源包"),
|
||
("ContentKindShader", "Shaders", "光影"),
|
||
("ContentSourceModrinth", "Modrinth", "Modrinth 源"),
|
||
("ContentSourceCurseforge", "CurseForge", "CurseForge 源"),
|
||
("ContentSortRelevance", "Relevance", "相关度"),
|
||
("ContentSortDownloads", "Downloads", "下载量"),
|
||
("ContentSortNewest", "Newest", "最新发布"),
|
||
("ContentSortUpdated", "Recently updated", "最近更新"),
|
||
("ContentSearchPlaceholder", "Search content…", "搜索内容…"),
|
||
("ContentSearch", "Search", "搜索"),
|
||
("ContentFilterVersion", "Game version", "游戏版本"),
|
||
("ContentFilterLoader", "Loader", "加载器"),
|
||
("ContentFilterAny", "Any", "不限"),
|
||
("ContentCount", "{count} results", "{count} 个结果"),
|
||
("ContentLoading", "Loading content…", "正在加载内容…"),
|
||
("ContentLoadingHint", "Results come from the network; nothing is cached offline yet.", "结果来自网络,暂时没有离线缓存。"),
|
||
("ContentEmptyTitle", "Nothing matched", "没有匹配的内容"),
|
||
("ContentEmptyBody", "Try another keyword, or clear a filter.", "换个关键词,或清掉一个筛选条件。"),
|
||
("ContentFailedTitle", "Could not load content", "内容加载失败"),
|
||
("ContentFailedBody", "Check the network, then retry.", "检查网络后重试。"),
|
||
("ContentRetry", "Retry", "重试"),
|
||
("ContentLoadMore", "Load more", "加载更多"),
|
||
("ContentNoMore", "No more results", "没有更多了"),
|
||
("ContentDetailEmpty", "Pick an item to see what it supports.", "选一个项目看它支持什么。"),
|
||
("ContentDetailDownloads", "{count} downloads", "下载量 {count}"),
|
||
("ContentDetailUpdated", "Updated {date}", "更新于 {date}"),
|
||
("ContentDetailLoaders", "Loaders: {list}", "加载器:{list}"),
|
||
("ContentDetailVersions", "Game versions: {list}", "游戏版本:{list}"),
|
||
("ContentInstall", "Install into instance", "装入实例"),
|
||
("ContentTargetInstance", "Target instance", "目标实例"),
|
||
("ContentNoInstances", "No instance to install into", "没有可装入的实例"),
|
||
("ContentIncompatibleVersion", "Needs {version}; this instance runs {actual}", "需要 {version},该实例运行的是 {actual}"),
|
||
("ContentIncompatibleLoader", "Not built for {loader}", "不支持 {loader}"),
|
||
("ContentModpackNotReady", "Modpack install comes with the M111 import pipeline", "整合包安装要等 M111 的导入管线"),
|
||
("ContentSourceUnavailable", "Set ULL_CF_API_KEY to search CurseForge", "要搜 CurseForge 请先设置 ULL_CF_API_KEY"),
|
||
];
|