feat(presenter): 多根发现(配置根 + 官方启动器标准位置),实例按自己的根解析存档/模组/启动(M274)
This commit is contained in:
1 parent
dfc0f4bcb3
commit
dc8323531b
20 files changed
+943
-121
No files matched your search
@@ -116,6 +116,10 @@ pub(super) fn section<'a>(
|
||||
body = body.push(note(ui, texts.saves_loading()));
|
||||
return frame::card(ui, body);
|
||||
}
|
||||
// 来源那一行(M274):多根之后「这个实例的存档到底在哪个目录」必须看得见。
|
||||
if saves.has_view && !saves.source.is_empty() {
|
||||
body = body.push(note(ui, &saves.source));
|
||||
}
|
||||
if let Some(error) = saves.error.as_deref() {
|
||||
body = body.push(frame::text_role(
|
||||
ui,
|
||||
|
||||
@@ -86,6 +86,13 @@ pub struct Saves {
|
||||
pub retryable: bool,
|
||||
/// 手里有没有一份**快照**(`false` = 只拿到了失败,"还没有世界"那几句不许画)。
|
||||
pub has_view: bool,
|
||||
/// 来源那一行(M274 多根):`存档目录:<绝对路径>`,**在这一层拼好**。
|
||||
///
|
||||
/// 便携目录与官方启动器是两个不同的根,两个根里都可能有一个叫 `A` 的实例、各有一批世界。
|
||||
/// 世界名分辨不出来源,所以把路径原样摆出来(也是排障时要问的第一件事)。
|
||||
/// 为什么不是页面里现拼:iced 的 `Element` 只借这一帧的数据,`view()` 返回的树借的是局部
|
||||
/// `String`,一出栈就 `E0515`(与 [`Saves::count`] 同一条理由)。
|
||||
pub source: String,
|
||||
/// 两个目录都不存在(新实例的常态:还没进过游戏)。
|
||||
pub missing: bool,
|
||||
/// 世界行。
|
||||
@@ -162,6 +169,7 @@ pub fn from_state(state: &SavesState, catalog: Catalog) -> Saves {
|
||||
};
|
||||
if let Some(view) = &state.view {
|
||||
out.has_view = true;
|
||||
out.source = texts.saves_source(&view.dir);
|
||||
out.missing = !view.exists && !view.screenshots_exists;
|
||||
// 计数直接问快照(`view.world_count()`),不从刚装好的 `out.worlds` 再数一遍——
|
||||
// M224 出图实测过"先算计数后装列表"画出 `0 启用 · 0 禁用` 的那种顺序错,这里从根上绕开。
|
||||
|
||||
@@ -253,5 +253,39 @@ fn millisecond_stamps_are_rendered_in_utc() {
|
||||
);
|
||||
}
|
||||
|
||||
/// **来源那一行**(M274 多根):必须是这一份快照读的那个目录,两种语言都说出来。
|
||||
///
|
||||
/// 为什么非要有这一行:便携目录与官方启动器是两个不同的根,两个根里都可能有一个叫 `A` 的实例。
|
||||
/// 世界名分辨不出来源,只有路径能分辨(也是排障时要问的第一件事)。
|
||||
///
|
||||
/// 抓得住:来源行拿了别的实例 / 别的根的路径(界面上一模一样的错),或切了根却没跟着变;
|
||||
/// 抓不住:页面真的把这一行画出来(`Element` 没有内省接口,见模块文档)。
|
||||
#[test]
|
||||
fn the_source_line_names_the_folder_that_was_read() {
|
||||
let mut state = bound_state("a");
|
||||
state.changed(view("a"));
|
||||
let zh = from_state(&state, Lang::ZhCn.catalog());
|
||||
let en = from_state(&state, Lang::En.catalog());
|
||||
assert!(
|
||||
zh.source.contains("C:/mc/saves"),
|
||||
"来源行没带目录:{:?}",
|
||||
zh.source
|
||||
);
|
||||
assert!(en.source.contains("C:/mc/saves"), "{:?}", en.source);
|
||||
assert_ne!(zh.source, en.source, "切换语言时这一行要变");
|
||||
|
||||
// 换一个根(另一个 `.minecraft`)⇒ 这一行跟着变(不许留在旧路径上)。
|
||||
let mut other = view("a");
|
||||
other.dir = "D:/official/.minecraft/saves".to_string();
|
||||
let mut state = bound_state("a");
|
||||
state.changed(other);
|
||||
let moved = from_state(&state, Lang::ZhCn.catalog());
|
||||
assert!(
|
||||
moved.source.contains("D:/official"),
|
||||
"换了根之后来源行没跟着变:{:?}",
|
||||
moved.source
|
||||
);
|
||||
}
|
||||
|
||||
mod preview;
|
||||
mod write;
|
||||
@@ -37,6 +37,10 @@ impl Texts {
|
||||
pub(in crate::pages::instances) fn saves_missing_dir(self) -> &'static str {
|
||||
self.text(Key::InstancesSavesMissingDir)
|
||||
}
|
||||
/// 「这一份列表读自哪个目录」(M274 多根:世界名分辨不出来源,绝对路径可以)。
|
||||
pub(in crate::pages::instances) fn saves_source(self, dir: &str) -> String {
|
||||
self.0.render(Key::InstancesSavesSource, &[("dir", dir)])
|
||||
}
|
||||
pub(in crate::pages::instances) fn saves_worlds(self) -> &'static str {
|
||||
self.text(Key::InstancesSavesWorlds)
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user