~aleteoryx/pjsekai_emote_packs

ref: 4a81670f1b034fdd222ea7c22529874e1bc9d547 pjsekai_emote_packs/src/slug.rs -rw-r--r-- 4.0 KiB
4a81670fAleteoryx license 10 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
use std::collections::BTreeMap;
use std::fs::{File, self};
use std::path::{Path, PathBuf};

use eframe::egui;

#[derive(Default)]
pub struct SlugPrompter {
  id_to_stamp_map: BTreeMap<usize, crate::model::Stamp>,
  id_to_slug_map: BTreeMap<usize, Option<String>>,
  slug_to_id_map: BTreeMap<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::model::Stamp>) {
    let file_path = repo_dir.join(format!("slugs_{locale}.json"));
    let id_to_slug_map: BTreeMap<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: BTreeMap<usize, Option<String>>, stamps: Vec<crate::model::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());
      });
      let text_res = ui.text_edit_singleline(&mut self.current_slug);

      ui.label(format!("{}/{}", self.id_to_slug_map.len(), self.id_to_stamp_map.len()));

      if let Some(s) = self.current_err.as_ref() {
        ui.colored_label(egui::Color32::RED, s);
      }

      if ui.button("Confirm").clicked() || text_res.lost_focus() && ui.input(|i| i.key_pressed(egui::Key::Enter)) {
        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 {
          if self.current_slug == "" {
            self.id_to_slug_map.insert(self.current_id, None);
          } 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();
        }
      }
    });
  }
}