Skip to content

Commit

Permalink
Merge pull request #24 from Warthunder-Open-Source-Foundation/nightly
Browse files Browse the repository at this point in the history
Version 1.2.0
  • Loading branch information
FlareFlo authored Apr 3, 2022
2 parents 121d186 + ebf2bd3 commit 3e385b8
Show file tree
Hide file tree
Showing 13 changed files with 745 additions and 74 deletions.
497 changes: 495 additions & 2 deletions Cargo.lock

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "wt_custom_lang"
description = "A tool to create custom language files for the game War Thunder"
version = "1.1.0"
version = "1.2.0"
edition = "2021"
rust-version = "1.58"
license = "Apache-2.0"
Expand Down Expand Up @@ -37,6 +37,9 @@ duckstore = "^2.1.0"
lazy_static = "^1.4.0"
fs_extra = "^1.2.0"
notify-rust = "^4.5.5"
wt_csv = "0.10.0"
levenshtein = "^1.0.5"
reqwest = { version = "^0.11.10", features = ["blocking"] }

#[target.'cfg(windows)'.build-dependencies]
#winres = "0.1.12"
2 changes: 1 addition & 1 deletion docker/start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ mv ./target/x86_64-pc-windows-gnu/release/wt_custom_lang.exe ./wt_custom_lang_wi
mv ./target/x86_64-unknown-linux-gnu/release/wt_custom_lang ./wt_custom_lang_linux_x86_64

echo "Creating release"
gh release create v1.0.1 --generate-notes ./wt_custom_lang_windows_x86_64.exe ./wt_custom_lang_linux_x86_64 ./LICENSE ./NOTICE
gh release create v1.2.0 --generate-notes ./wt_custom_lang_windows_x86_64.exe ./wt_custom_lang_linux_x86_64 ./LICENSE ./NOTICE
12 changes: 10 additions & 2 deletions src/app/basic_prompts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ impl CustomLang {
}
});
}
pub(crate) fn prompt_for_wt_path(&mut self, ctx: &CtxRef) {
pub fn prompt_for_wt_path(&mut self, ctx: &CtxRef) {
Window::new("First time setup").anchor(Align2::CENTER_CENTER, Vec2::new(0.0,0.0)).show(ctx, |ui| {
ui.add(Label::new("Select WarThunder installation folder"));
let select_button = ui.add(Button::new(RichText::new("Choose path").text_style(TextStyle::Body)));
Expand Down Expand Up @@ -82,7 +82,7 @@ impl CustomLang {
}
}
Err(err) => {
self.prompt_error.err_value = Some(err.to_string());
self.prompt_error.err_value = Some(format!("{:?} {}:{} {}", err, line!(), column!(), file!()));
return;
}
}
Expand Down Expand Up @@ -112,6 +112,14 @@ impl CustomLang {

ui.add_space(20.0);


if let Some(path) = self.config.wt_path.as_ref() {
if fs::read_dir(format!("{}/lang", path)).is_ok() {
self.config.lang_folder_created = true;
return;
}
}

if ui.add(Button::new(RichText::new("Verify folder").text_style(TextStyle::Heading))).clicked() {
if let Some(path) = self.config.wt_path.as_ref() {
if fs::read_dir(format!("{}/lang", path)).is_ok() {
Expand Down
22 changes: 14 additions & 8 deletions src/app/custom_lang.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@ use crate::{CONFIG_NAME, REPO_URL};
use crate::app::prompts::prompt_error::AppError;
use crate::app::prompts::prompt_for_backup::PromptForBackup;
use crate::app::update::update;
use crate::cache::cache::Cache;

pub struct CustomLang {
pub config: Configuration,
pub status_menu: bool,
pub prompt_for_backup: PromptForBackup,
pub prompt_for_entry: PromptForEntry,
pub prompt_error: AppError,
pub cache: Cache,
}

pub const STORE_CONF: fn(config: &Configuration) = |config| {
Expand Down Expand Up @@ -92,8 +94,9 @@ impl CustomLang {
config,
status_menu: false,
prompt_for_backup: PromptForBackup { active: false, backup_name: "".to_owned() },
prompt_for_entry: PromptForEntry { show: false, before_after_entry: EMPTY_BEFORE_AFTER(), toggle_dropdown: LangType::default() },
prompt_error: AppError { err_value: None },
prompt_for_entry: PromptForEntry { show: false, before_after_entry: EMPTY_BEFORE_AFTER(), toggle_dropdown: LangType::default(), searchbar: None },
prompt_error: AppError { err_value: None, already_wrote_err: false },
cache: Cache::new(),
}
}
pub fn render_header_bar(&mut self, ctx: &CtxRef, frame: &Frame) {
Expand All @@ -105,12 +108,7 @@ impl CustomLang {
});
ui.with_layout(Layout::right_to_left(), |ui| {
if ui.add(Button::new(RichText::new("🔄 Reset configuration").text_style(TextStyle::Body))).clicked() {
if let Err(err) = confy::store(CONFIG_NAME, Configuration::default()) {
self.prompt_error.err_value = Some(err.to_string());
return;
} else {
frame.quit();
}
self.reset_applet_config(frame);
}

if ui.add(Button::new(RichText::new("Status").text_style(TextStyle::Body))).clicked() {
Expand All @@ -126,6 +124,14 @@ impl CustomLang {
ui.add_space(10.);
});
}
pub fn reset_applet_config(&mut self, frame: &Frame) {
if let Err(err) = confy::store(CONFIG_NAME, Configuration::default()) {
self.prompt_error.err_value = Some(format!("{:?} {}:{} {}", err, line!(), column!(), file!()));
return;
} else {
frame.quit();
}
}
}

pub fn render_footer(ctx: &CtxRef) {
Expand Down
16 changes: 11 additions & 5 deletions src/app/prompts/prompt_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,33 @@ use std::fs;
use std::process::exit;
use std::thread::sleep;
use std::time::Duration;
use eframe::egui::{CtxRef, Label, Window};
use eframe::egui::{Button, CtxRef, Label, Window};
use eframe::epi::Frame;
use notify_rust::Notification;
use crate::{CONFIG_NAME, CustomLang};

pub struct AppError {
pub err_value: Option<String>,
pub already_wrote_err: bool,
}

impl CustomLang {
pub fn prompt_error(&self, ctx: &CtxRef) {
pub fn prompt_error(&mut self, ctx: &CtxRef, frame: &Frame) {
Window::new("An error occurred").show(ctx, |ui|{
if let Some(error) = self.prompt_error.err_value.as_ref() {
println!("{}", error);
store_err(&error);
if !self.prompt_error.already_wrote_err {
store_err(&error);
self.prompt_error.already_wrote_err = true;
}
ui.add(Label::new(&**error));
sleep(Duration::from_secs(10));
exit(1);
} else {
// No but seriously, this function should only be called if err_value is some in the first place
panic!("{}", "This level of failure should be impossible to reach");
}
if ui.add(Button::new("Reset application data")).clicked() {
self.reset_applet_config(frame);
}
});
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/app/prompts/prompt_for_backup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ impl CustomLang {
match fs::create_dir_all(&path) {
Ok(_) => {
if let Err(err) = fs_extra::dir::copy(wt_folder, &path, &COPY_OPTIONS) {
self.prompt_error.err_value = Some(err.to_string());
self.prompt_error.err_value = Some(format!("{:?} {}:{} {}", err, line!(), column!(), file!()));
return;
} else {
backups.push(BackupEntry {
Expand Down
71 changes: 58 additions & 13 deletions src/app/prompts/prompt_for_entry.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
use std::{fs};

use eframe::egui::{Button, Color32, ComboBox, CtxRef, Hyperlink, RichText, TextEdit, TextStyle, Window};
use levenshtein::levenshtein;
use wt_csv::wtcsv::core::wtcsv::WTCSV;

use crate::{CustomLang};
use crate::lang_manipulation::primitive_lang::PrimitiveEntry;
use crate::local_storage::entries::{LANG_PATH, READ_PRIMITIVE, WRITE_PRIMITIVE};

pub const EMPTY_BEFORE_AFTER: fn() -> (String, String) = ||{
pub const EMPTY_BEFORE_AFTER: fn() -> (String, String) = || {
("".to_owned(), "".to_owned())
};

pub struct PromptForEntry {
pub show: bool,
pub before_after_entry: (String, String),
pub toggle_dropdown: LangType,
pub searchbar: Option<String>,
}

#[derive(Debug, Eq, PartialEq)]
Expand Down Expand Up @@ -54,15 +57,19 @@ impl CustomLang {
if let Some(wt_raw) = self.config.wt_path.as_ref() {
Window::new("Adding a new entry").show(ctx, |ui| {
let mut original = self.prompt_for_entry.before_after_entry.clone();
let path = format!("{}/lang/{}.csv", wt_raw, &self.prompt_for_entry.toggle_dropdown.to_file_name());

let mut color= Color32::from_rgb(255,255,255);

let mut contains = |file_path: &str|{
if fs::read_to_string(format!("{}/lang/{}.csv", wt_raw, file_path)).unwrap_or("".to_owned()).contains(&format!(r#""{}""#, &original.0)) {
color = Color32::from_rgb(0,255,0);
let mut color = Color32::from_rgb(255, 255, 255);

let incomplete = fs::read_to_string(&path).unwrap_or("".to_owned());
let mut contains = || {
if let Some(search) = &self.prompt_for_entry.searchbar {
original.0 = search.clone();
color = Color32::from_rgb(64, 64, 255);
} else if incomplete.contains(&format!(r#""{}""#, &original.0)) {
color = Color32::from_rgb(0, 255, 0);
} else {
color = Color32::from_rgb(255,255,255);
color = Color32::from_rgb(255, 255, 255);
}
};

Expand All @@ -77,9 +84,25 @@ impl CustomLang {
});


contains(self.prompt_for_entry.toggle_dropdown.to_file_name());
contains();

let search_icon = if self.prompt_for_entry.searchbar.is_some() {
Button::new("❌")
} else {
Button::new("🔍")
};


ui.add(TextEdit::singleline (&mut original.0).hint_text("Old name").text_color(color));
ui.horizontal(|ui| {
ui.add(TextEdit::singleline(&mut original.0).interactive(self.prompt_for_entry.searchbar.is_none()).hint_text("Old name").text_color(color));
if ui.add(search_icon).clicked() {
if self.prompt_for_entry.searchbar.is_none() {
self.prompt_for_entry.searchbar = closest_word(&original.0, fs::read_to_string(&path).unwrap());
} else {
self.prompt_for_entry.searchbar = None;
}
}
});
ui.add(TextEdit::singleline(&mut original.1).hint_text("New name"));

self.prompt_for_entry.before_after_entry = original;
Expand Down Expand Up @@ -128,7 +151,7 @@ impl CustomLang {
let lang_type = self.prompt_for_entry.toggle_dropdown.to_file_name();
let path: String = format!("{}/lang/{}.csv", wt_raw, lang_type);

match fs::read_to_string(&path) {
match fs::read_to_string(&path) {
Ok(mut file) => {
let entry = PrimitiveEntry {
file: primitive_entry.file.clone(),
Expand All @@ -142,7 +165,7 @@ impl CustomLang {
if fs::write(&path, file).is_ok() {
match fs::read(&LANG_PATH.constructed_path) {
Ok(entries) => {
match serde_json::from_slice::<Vec<PrimitiveEntry>>(&entries) {
match serde_json::from_slice::<Vec<PrimitiveEntry>>(&entries) {
Ok(mut old) => {
old.remove(i);

Expand All @@ -159,9 +182,8 @@ impl CustomLang {
return;
}
}

}
},
}
Err(error) => {
self.prompt_error.err_value = Some(format!("{:?} {}:{} {}", error, line!(), column!(), file!()));
return;
Expand All @@ -172,4 +194,27 @@ impl CustomLang {
return;
}
}
}


pub fn closest_word(known: &str, file: String) -> Option<String> {
let wtcsv = WTCSV::new_from_file(&file, "blank").unwrap();

let mut vec: Vec<(usize, String)> = Vec::new();

for record in wtcsv.records {
let item = record.items[1].to_owned();
if item.contains(known) {
vec.push((levenshtein(&item, known), item));
}
}

vec.sort_by_key(|x| x.0);

if let Some(val) = vec.first() {
if val.0 < known.len() {
return Some(val.1.to_owned());
}
}
None
}
Loading

0 comments on commit 3e385b8

Please sign in to comment.