用户原话:「我们内置了那么多镜像源 甚至用户不能手动选择指定版本下载。」
「自动下载 jdk17 作为基准版本,后续在设置中提供多版本可供用户下载。」
- core:新增 `game::java::catalog`(8/11/17/21/25 五档 × 能承接的发行版 × 「该装哪档」),
数据全部来自 `JdkVendor::supports` 与 `vendor::order`,不复制第二份真相。
- progress:`SourceFailed` 补一个结构化的 `kind`(在这之前只有中文 `reason`,双语界面
要么放弃语言、要么放弃「哪个源为什么退避」这条用户可见信息)。
- app-iced:`downloads` 模块真下(后台线程 + `ProgressEmitter` + 快照),三态(选择列表 /
下载中 / 失败)都能说出「命中的源 / 退避原因 / 试过哪些源」;成功后重扫并(在
`java.auto_install` 开着且没有默认 JDK 时)把新装的那份设为默认。
- 三个设置键做成可改 UI:`java.installRoot` / `java.vendorPriority` / `java.auto_install`,
各自带「现在生效什么、从哪一层来」(数据目录模式 / 地区默认序),改完回读落盘值。
- `State::satisfied` 换成带方向的 `Fit`:1.12.2 + Java 21 不再被说成「低于要求」。
- i18n:删掉 `SettingsJavaEmptyBody` / `SettingsJavaAddHint` 的 markdown 反引号;
`SettingsJavaNeverScannedBody` 改成不与首屏自动扫矛盾的表述。
- 出图三张(选择列表 / 下载中 / 失败)在 DevDocs/artifacts/m197/。
顺带拆文件守 400 行:`golden/tail.rs` 的 M174 段搬到 `golden/tail_ai.rs`,
`pages/settings/java/{context,prefs,prefs_store,downloads,download_view}` 各自成模块。
43 lines
1.7 KiB
Rust
43 lines
1.7 KiB
Rust
//! 「现在该推荐哪一档」(M197):`java.auto_install` 的唯一消费者。
|
||
//!
|
||
//! 从 `downloads.rs` 拆出来(那个文件加了作业槽与事件映射之后越过 400 行硬线)。
|
||
//! 纯函数:只读「当前实例要求 + 已扫到的运行时 + 这个键」,不联网、不落盘。
|
||
|
||
use unlucky_core::game::java::catalog;
|
||
|
||
use crate::pages::settings::java::context::Requirement;
|
||
use crate::pages::settings::java::row::RuntimeRow;
|
||
|
||
/// 「现在该推荐哪一档」:`java.auto_install` 的真实消费者。
|
||
///
|
||
/// 语义(就是界面上那句 hint):**开着**时,只有当「扫到的 JDK 里没有一个满足当前实例的要求」
|
||
/// (没有实例时 = 一个 JDK 都没有)才推荐一档;推荐的是当前实例最低要求对齐到目录的那一档
|
||
/// ([`catalog::default_major`],没有实例时 = 基准 17)。**关掉**就一律不推荐,用户自己挑。
|
||
///
|
||
/// 为什么不直接自动开始下载:那是 180 MiB 起步、且用户可能只想手动指定 JAVA_HOME。
|
||
/// 「替你选好一档 + 一句话说明」把决定权留在用户手上,同时把「该装哪个」这件知识给出去。
|
||
#[must_use]
|
||
pub fn recommend(
|
||
required: Option<&Requirement>,
|
||
runtimes: &[RuntimeRow],
|
||
auto_install: bool,
|
||
) -> Option<u32> {
|
||
if !auto_install {
|
||
return None;
|
||
}
|
||
let satisfied = match required {
|
||
Some(required) => runtimes.iter().any(|runtime| {
|
||
runtime
|
||
.major
|
||
.is_some_and(|major| required.satisfied_by(major))
|
||
}),
|
||
None => !runtimes.is_empty(),
|
||
};
|
||
if satisfied {
|
||
return None;
|
||
}
|
||
Some(catalog::default_major(
|
||
required.map(|required| required.minimum),
|
||
))
|
||
}
|