tlc: canonicalize skin_name to resolved theme name

FileManager.skin_name now stores the canonical MC skin name (e.g. "julia256") rather than the user-config alias (e.g. "default-dark"). When by_name() resolves a legacy alias to a real .ini skin, the resulting theme.name is what gets persisted.

apply_skin_selection follows the same rule.

Skin dialog tests use real MC skin names (dark, nicedark) and verify the catalog contains no TLC hardcoded presets (no more "default-dark", "mc-classic", etc. in the list).
This commit is contained in:
2026-06-20 14:35:02 +03:00
parent 03b5f88bf6
commit 9c8583fd3a
3 changed files with 39 additions and 22 deletions
@@ -368,14 +368,16 @@ impl FileManager {
/// Apply a confirmed skin selection: switch the active theme,
/// persist the new name to the user config, post a status.
pub fn apply_skin_selection(&mut self, name: String) {
self.theme = Theme::by_name(&name);
self.skin_name = name.clone();
if let Err(e) = self.persist_skin_name(&name) {
let theme = Theme::by_name(&name);
let canonical = theme.name.to_string();
self.theme = theme;
self.skin_name = canonical.clone();
if let Err(e) = self.persist_skin_name(&canonical) {
self.status
.set_message(format!("skin: {e}"));
} else {
self.status
.set_message(format!("Skin: {name}"));
.set_message(format!("Skin: {canonical}"));
}
self.dialog = None;
}
@@ -368,7 +368,7 @@ impl FileManager {
let left = Panel::new(start, &cfg.filemanager)?;
let right = Panel::new(&parent, &cfg.filemanager)?;
let theme: Theme = Theme::by_name(&cfg.skin.name);
let skin_name = cfg.skin.name.clone();
let skin_name = theme.name.to_string();
Ok(Self {
left,
right,
@@ -1116,13 +1116,13 @@ mod tests {
let original = fm.theme.name;
fm.dispatch(Cmd::SkinSelect).unwrap();
if let Some(DialogState::Skin(d)) = fm.dialog.as_mut() {
d.set_selected("nord");
d.set_selected("dark");
}
let consumed = fm.handle_dialog_key(Key::ENTER);
assert!(consumed);
assert!(fm.dialog.is_none());
assert_eq!(fm.theme.name, "nord");
assert_eq!(fm.skin_name, "nord");
assert_eq!(fm.theme.name, "dark");
assert_eq!(fm.skin_name, "dark");
assert_ne!(fm.theme.name, original);
let _ = fs::remove_dir_all(&dir);
}
@@ -324,16 +324,17 @@ mod tests {
#[test]
fn new_finds_named_skin() {
let d = SkinDialog::new("nord");
assert_eq!(d.selected_name(), Some("nord"));
assert_eq!(d.current_skin(), "nord");
let d = SkinDialog::new("dark");
assert_eq!(d.selected_name(), Some("dark"));
assert_eq!(d.current_skin(), "dark");
}
#[test]
fn new_falls_back_to_default_for_unknown_skin() {
let d = SkinDialog::new("no-such-skin");
let d = SkinDialog::new("no-such-skin-xyz");
assert_eq!(d.selected_index(), 0);
assert_eq!(d.selected_name(), Some("default-dark"));
// First skin in the list (whatever the .ini sort order yields)
assert_eq!(d.selected_name(), d.skins().first().map(|s| s.name.as_str()));
}
#[test]
@@ -342,45 +343,59 @@ mod tests {
assert!(d.skins().len() >= 8);
let names: Vec<&str> = d.skins().iter().map(|s| s.name.as_str()).collect();
for required in [
"julia256",
"dark",
"nicedark",
"sand256",
"default",
] {
assert!(names.contains(&required), "missing {required} in {names:?}");
}
// TLC no longer maintains its own presets; only MC .ini skins.
for forbidden in [
"default-dark",
"default-light",
"mc-classic",
"mc-dark",
"high-contrast",
"solarized-dark",
"nord",
] {
assert!(names.contains(&required), "missing {required} in {names:?}");
assert!(
!names.contains(&forbidden),
"{forbidden} should not appear; got {names:?}"
);
}
}
#[test]
fn enter_returns_selected_name() {
let mut d = SkinDialog::new("default-dark");
d.set_selected("nord");
let mut d = SkinDialog::new("dark");
d.set_selected("nicedark");
let outcome = d.handle_key(Key::ENTER);
assert_eq!(
outcome,
Some(SkinDialogOutcome::Selected("nord".to_string()))
Some(SkinDialogOutcome::Selected("nicedark".to_string()))
);
}
#[test]
fn esc_cancels() {
let mut d = SkinDialog::new("default-dark");
let mut d = SkinDialog::new("dark");
let outcome = d.handle_key(Key::ESCAPE);
assert_eq!(outcome, Some(SkinDialogOutcome::Cancelled));
}
#[test]
fn q_cancels() {
let mut d = SkinDialog::new("default-dark");
let mut d = SkinDialog::new("dark");
let outcome = d.handle_key(Key::from_char('q'));
assert_eq!(outcome, Some(SkinDialogOutcome::Cancelled));
}
#[test]
fn down_advances_cursor() {
let mut d = SkinDialog::new("default-dark");
let mut d = SkinDialog::new("dark");
let initial = d.selected_index();
let outcome = d.handle_key(Key {
code: 0x2193,
@@ -392,7 +407,7 @@ mod tests {
#[test]
fn up_retreats_cursor() {
let mut d = SkinDialog::new("nord");
let mut d = SkinDialog::new("nicedark");
let initial = d.selected_index();
let outcome = d.handle_key(Key {
code: 0x2191,
@@ -405,7 +420,7 @@ mod tests {
#[test]
fn down_clamps_at_last() {
let mut d = SkinDialog::new("");
d.set_selected("nord");
d.set_selected("sand256");
for _ in 0..100 {
d.handle_key(Key {
code: 0x2193,