use std::collections::HashMap;
use std::fs::{File, self};
use std::path::{Path, PathBuf};
use eframe::egui;
#[derive(Default)]
pub struct SlugPrompter {
id_to_stamp_map: HashMap<usize, crate::en::Stamp>,
id_to_slug_map: HashMap<usize, Option<String>>,
slug_to_id_map: HashMap<String, usize>,
current_id: usize,
current_slug: String,
current_err: Option<String>,
cache_dir: PathBuf,
file_path: PathBuf
}
impl SlugPrompter {
pub fn run(locale: String, repo_dir: &Path, stamps: Vec<crate::en::Stamp>) {
let file_path = repo_dir.join(format!("slugs_{locale}.json"));
let id_to_slug_map: HashMap<usize, Option<String>>;
if fs::exists(&file_path).unwrap() {
id_to_slug_map =
serde_json::from_reader(
File::open(&file_path)
.unwrap())
.unwrap();
} else {
id_to_slug_map = Default::default();
}
let native_options = eframe::NativeOptions::default();
eframe::run_native(
&format!("Check Slugs for {locale} locale"),
native_options,
Box::new(|cc| Ok(Box::new(SlugPrompter::new(cc, id_to_slug_map, stamps, repo_dir.join("stamps_cache").join(&locale), file_path)))));
}
fn new(_cc: &eframe::CreationContext<'_>, id_to_slug_map: HashMap<usize, Option<String>>, stamps: Vec<crate::en::Stamp>, cache_dir: PathBuf, file_path: PathBuf) -> Self {
let current_id = stamps[0].id;
let slug_to_id_map = id_to_slug_map.clone().into_iter().filter_map(|(a, b)| b.map(|b2| (b2, a))).collect();
let id_to_stamp_map = stamps.into_iter().map(|stamp| (stamp.id, stamp)).collect();
SlugPrompter { id_to_stamp_map, id_to_slug_map, slug_to_id_map, cache_dir, file_path, current_id, current_slug: String::new(), current_err: None }
}
fn write_file(&self) {
serde_json::to_writer_pretty(File::create(&self.file_path).unwrap(), &self.id_to_slug_map);
}
}
impl eframe::App for SlugPrompter {
fn update(&mut self, ctx: &egui::Context, frame: &mut eframe::Frame) {
if self.id_to_slug_map.contains_key(&self.current_id) {
let mut hit = false;
for id in self.id_to_stamp_map.keys() {
if !self.id_to_slug_map.contains_key(id) {
hit = true;
self.current_id = *id;
self.current_slug = String::new();
self.current_err = None;
break
}
}
if !hit {
ctx.send_viewport_cmd(egui::viewport::ViewportCommand::Close);
return
}
}
egui_extras::install_image_loaders(ctx);
egui::CentralPanel::default().show(ctx, |ui| {
let image_path =
format!("file://{}",
self
.cache_dir
.join(&self.id_to_stamp_map[&self.current_id].assetbundle_name)
.with_extension("png")
.display());
ui.add(
egui::Image::new(image_path)
.max_width(200.0)
);
ui.horizontal(|ui| {
ui.label("Builtin name:");
ui.strong(
self
.id_to_stamp_map[&self.current_id]
.name
.split("]").nth(1).unwrap()
.trim());
});
ui.text_edit_singleline(&mut self.current_slug);
if let Some(s) = self.current_err.as_ref() {
ui.colored_label(egui::Color32::RED, s);
}
if ui.button("Confirm").clicked() {
if self.slug_to_id_map.contains_key(&self.current_slug) {
self.current_err = Some(format!("Slug \"{}\" already taken by {}!", self.current_slug, self.slug_to_id_map[&self.current_slug]));
} else {
self.slug_to_id_map.insert(self.current_slug.clone(), self.current_id);
self.id_to_slug_map.insert(self.current_id, Some(self.current_slug.clone()));
self.write_file();
}
}
});
}
}