feat: Implement image caching for game covers, enhance frontend game list item layout, add Factorio to the game list, and ignore the cache directory.
This commit is contained in:
@@ -123,6 +123,26 @@ async fn get_game_thumbnail(
|
||||
title: &str,
|
||||
game_list: &rocket::State<Mutex<Vec<Game>>>,
|
||||
) -> Option<(rocket::http::ContentType, Vec<u8>)> {
|
||||
// 1. Sanitize title for filename
|
||||
let safe_title: String = title
|
||||
.chars()
|
||||
.map(|c| if c.is_alphanumeric() { c } else { '_' })
|
||||
.collect();
|
||||
|
||||
let cache_dir = "cache";
|
||||
let _ = std::fs::create_dir_all(cache_dir);
|
||||
let cache_path_bin = format!("{}/{}.bin", cache_dir, safe_title);
|
||||
let cache_path_type = format!("{}/{}.type", cache_dir, safe_title);
|
||||
|
||||
// 2. Check cache
|
||||
if let (Ok(bytes), Ok(type_str)) = (
|
||||
std::fs::read(&cache_path_bin),
|
||||
std::fs::read_to_string(&cache_path_type),
|
||||
) && let Some(ct) = rocket::http::ContentType::parse_flexible(&type_str)
|
||||
{
|
||||
return Some((ct, bytes));
|
||||
}
|
||||
|
||||
let games = game_list.lock().await;
|
||||
let game = games.iter().find(|g| g.title == title)?;
|
||||
|
||||
@@ -174,6 +194,11 @@ async fn get_game_thumbnail(
|
||||
.and_then(rocket::http::ContentType::parse_flexible)
|
||||
.unwrap_or(rocket::http::ContentType::Binary);
|
||||
let bytes = resp.bytes().await.ok()?.to_vec();
|
||||
|
||||
// 3. Write to cache
|
||||
let _ = std::fs::write(&cache_path_bin, &bytes);
|
||||
let _ = std::fs::write(&cache_path_type, content_type.to_string());
|
||||
|
||||
Some((content_type, bytes))
|
||||
}
|
||||
Err(_) => None,
|
||||
|
||||
Reference in New Issue
Block a user