chore: cleanup for push to main
- Remove CLAUDE.md, TODO.md (dev-only task trackers) - Remove umutray.service (unused systemd unit) - Remove .vscode/settings.json (stale Makefile ref) - Add src/theme.rs (shared palette/styling module) - Update .gitignore: exclude .vscode/, packaging build artifacts - Fix README: add gui command, correct service description - Delete ~1.3GB packaging build artifacts from working tree Code changes from prior session (already committed locally): - Tray icon launches alongside GUI, close dialog with minimize-to-tray - Theme module extraction, button shadow fixes, UI polish - Game detection filtering, prettify_game_name, Battle.net fix
This commit is contained in:
+75
-5
@@ -191,16 +191,86 @@ fn scan_exe_dir(
|
||||
if !seen.insert(rel_lower) {
|
||||
continue;
|
||||
}
|
||||
let display = path
|
||||
.file_stem()
|
||||
.and_then(|s| s.to_str())
|
||||
.unwrap_or("Unknown")
|
||||
.to_string();
|
||||
let display = prettify_game_name(&path);
|
||||
out.push((display, rel_str));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Derive a human-readable game name from an exe path.
|
||||
///
|
||||
/// Strategy: use the parent directory name (e.g. "Call of Duty" from
|
||||
/// `Program Files/Call of Duty/game.exe`) unless it looks generic
|
||||
/// (like "Bin", "x64", "Binaries"), in which case walk up. Falls back
|
||||
/// to humanising the exe file stem by inserting spaces before capitals.
|
||||
fn prettify_game_name(path: &Path) -> String {
|
||||
// Generic directory names that don't make good game labels
|
||||
const GENERIC_DIRS: &[&str] = &[
|
||||
"bin", "binaries", "x64", "x86", "win64", "win32", "retail",
|
||||
"shipping", "game", "runtime", "_retail_", "_commonredist",
|
||||
"launcher", "engine", "client",
|
||||
];
|
||||
|
||||
// Try parent directories (closest first, up to 3 levels)
|
||||
let mut dir = path.parent();
|
||||
for _ in 0..3 {
|
||||
let Some(d) = dir else { break };
|
||||
let name = d.file_name().and_then(|n| n.to_str()).unwrap_or("");
|
||||
let lower = name.to_lowercase();
|
||||
if !name.is_empty()
|
||||
&& !GENERIC_DIRS.iter().any(|g| lower == *g)
|
||||
&& !lower.starts_with("program files")
|
||||
{
|
||||
return name.to_string();
|
||||
}
|
||||
dir = d.parent();
|
||||
}
|
||||
|
||||
// Fallback: humanise the exe stem ("BlackOps6" → "Black Ops 6")
|
||||
let stem = path
|
||||
.file_stem()
|
||||
.and_then(|s| s.to_str())
|
||||
.unwrap_or("Unknown");
|
||||
humanise_stem(stem)
|
||||
}
|
||||
|
||||
/// Insert spaces before uppercase runs and digit boundaries.
|
||||
/// "BlackOps6" → "Black Ops 6", "HITMAN3" → "HITMAN 3"
|
||||
fn humanise_stem(s: &str) -> String {
|
||||
let mut out = String::with_capacity(s.len() + 4);
|
||||
let chars: Vec<char> = s.chars().collect();
|
||||
for (i, &c) in chars.iter().enumerate() {
|
||||
if i > 0 {
|
||||
let prev = chars[i - 1];
|
||||
// Letter→digit or digit→letter boundary
|
||||
if (prev.is_alphabetic() && c.is_ascii_digit())
|
||||
|| (prev.is_ascii_digit() && c.is_alphabetic())
|
||||
{
|
||||
out.push(' ');
|
||||
}
|
||||
// lowercase→uppercase ("nO" in "BlackOps")
|
||||
else if prev.is_lowercase() && c.is_uppercase() {
|
||||
out.push(' ');
|
||||
}
|
||||
// UPPER run ending: "ABCdef" → "AB Cdef"
|
||||
else if i + 1 < chars.len()
|
||||
&& prev.is_uppercase()
|
||||
&& c.is_uppercase()
|
||||
&& chars[i + 1].is_lowercase()
|
||||
{
|
||||
out.push(' ');
|
||||
}
|
||||
}
|
||||
// Replace underscores / hyphens with spaces
|
||||
if c == '_' || c == '-' {
|
||||
out.push(' ');
|
||||
} else {
|
||||
out.push(c);
|
||||
}
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
const MAX_DEPTH: u32 = 3;
|
||||
|
||||
pub fn run(config: &Config, extra_dirs: &[PathBuf], apply: bool) -> Result<()> {
|
||||
|
||||
Reference in New Issue
Block a user