From 51dfef56161dfd66c26bf1e03d6fbf87ca591ab7 Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Mon, 16 May 2022 20:14:54 -0700 Subject: [PATCH] language select --- lang/en.json | 3 +- src-tauri/src/lang.rs | 26 ++++++++++++++++++ src-tauri/src/main.rs | 3 +- src/ui/App.css | 17 ++++++++++++ src/ui/components/menu/Options.tsx | 44 +++++++++++++++++++++++------- src/utils/configuration.ts | 2 +- src/utils/language.ts | 19 +++++++++++++ 7 files changed, 101 insertions(+), 13 deletions(-) diff --git a/lang/en.json b/lang/en.json index 0d588ae..35086db 100644 --- a/lang/en.json +++ b/lang/en.json @@ -13,7 +13,8 @@ "game_exec": "Set Game Executable", "grasscutter_jar": "Set Grasscutter Jar", "java_path": "Set Custom Java Path", - "grasscutter_with_game": "Automatically launch Grasscutter with game" + "grasscutter_with_game": "Automatically launch Grasscutter with game", + "language": "Select Language" }, "downloads": { "grasscutter_stable_data": "Download Grasscutter Stable Data", diff --git a/src-tauri/src/lang.rs b/src-tauri/src/lang.rs index 0d47e91..dba9315 100644 --- a/src-tauri/src/lang.rs +++ b/src-tauri/src/lang.rs @@ -14,6 +14,32 @@ pub async fn get_lang(window: tauri::Window, lang: String) -> String { return contents; } +#[tauri::command] +pub async fn get_languages() -> std::collections::HashMap { + // for each lang file, set the key as the filename and the value as the lang_name contained in the file + let mut languages = std::collections::HashMap::new(); + + let mut lang_files = std::fs::read_dir("../lang").unwrap(); + + while let Some(entry) = lang_files.next() { + let entry = entry.unwrap(); + let path = entry.path(); + let filename = path.file_name().unwrap().to_str().unwrap(); + + let content = match std::fs::read_to_string(path.to_str().unwrap()) { + Ok(x) => x, + Err(e) => { + println!("Failed to read language file: {}", e); + break; + } + }; + + languages.insert(filename.to_string(), content); + } + + return languages; +} + pub fn emit_lang_err(window: tauri::Window, msg: std::string::String) { let mut res_hash = std::collections::HashMap::new(); diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 3e42162..7c04dea 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -29,7 +29,8 @@ fn main() { get_bg_file, downloader::download_file, downloader::stop_download, - lang::get_lang + lang::get_lang, + lang::get_languages ]) .run(tauri::generate_context!()) .expect("error while running tauri application"); diff --git a/src/ui/App.css b/src/ui/App.css index ad23f5d..b07f737 100644 --- a/src/ui/App.css +++ b/src/ui/App.css @@ -5,6 +5,23 @@ body { overflow: hidden; } +select { + width: 217px; + border: none; + border-bottom: 2px solid #cecece; + + padding-right: 16px; + + text-decoration-color: #000; + + transition: border-bottom-color 0.1s ease-in-out; +} + +select:focus { + outline: none; + border-bottom-color: #ffd326; +} + #root, .App { height: 100%; } diff --git a/src/ui/components/menu/Options.tsx b/src/ui/components/menu/Options.tsx index 85640ab..a8255a2 100644 --- a/src/ui/components/menu/Options.tsx +++ b/src/ui/components/menu/Options.tsx @@ -1,11 +1,12 @@ import React from 'react' import DirInput from '../common/DirInput' import Menu from './Menu' -import Tr from '../../../utils/language' +import Tr, { getLanguages } from '../../../utils/language' import './Options.css' import { setConfigOption, getConfig, getConfigOption } from '../../../utils/configuration' import Checkbox from '../common/Checkbox' import Divider from './Divider' +import { invoke } from '@tauri-apps/api' interface IProps { closeFn: () => void; @@ -16,6 +17,7 @@ interface IState { grasscutter_path: string java_path: string grasscutter_with_game: boolean + language_options: { [key: string]: string }[] } export default class Options extends React.Component { @@ -26,18 +28,21 @@ export default class Options extends React.Component { game_install_path: '', grasscutter_path: '', java_path: '', - grasscutter_with_game: false + grasscutter_with_game: false, + language_options: [] } } - componentDidMount() { - getConfig().then(config => { - this.setState({ - game_install_path: config.game_install_path || '', - grasscutter_path: config.grasscutter_path || '', - java_path: config.java_path || '', - grasscutter_with_game: config.grasscutter_with_game || false - }) + async componentDidMount() { + const config = await getConfig() + const languages = await getLanguages() + + this.setState({ + game_install_path: config.game_install_path || '', + grasscutter_path: config.grasscutter_path || '', + java_path: config.java_path || '', + grasscutter_with_game: config.grasscutter_with_game || false, + language_options: languages }) this.forceUpdate() @@ -55,6 +60,10 @@ export default class Options extends React.Component { setConfigOption('java_path', value) } + setLanguage(value: string) { + setConfigOption('language', value) + } + async toggleGrasscutterWithGame() { setConfigOption('grasscutter_with_game', !(await getConfigOption('grasscutter_with_game'))) } @@ -100,6 +109,21 @@ export default class Options extends React.Component { + +
+
+ +
+
+ +
+
) } diff --git a/src/utils/configuration.ts b/src/utils/configuration.ts index c9922a4..93ac627 100644 --- a/src/utils/configuration.ts +++ b/src/utils/configuration.ts @@ -92,7 +92,7 @@ async function readConfigFile() { // Create config file const file: fs.FsTextFileOption = { path: configFilePath, - contents: '{}' + contents: JSON.stringify(defaultConfig) } await fs.writeFile(file) diff --git a/src/utils/language.ts b/src/utils/language.ts index 751674f..4ae0250 100644 --- a/src/utils/language.ts +++ b/src/utils/language.ts @@ -60,6 +60,25 @@ export default class Tr extends React.Component { } } +export async function getLanguages() { + const resp: { + [key: string]: string; + } = await invoke('get_languages') + const lang_list: { + [key: string]: string; + }[] = [] + + Object.keys(resp).forEach(k => { + const parsed = JSON.parse(resp[k]) + + if (parsed.lang_name) { + lang_list.push({ [k.split('.json')[0]]: parsed.lang_name }) + } + }) + + return lang_list +} + export async function translate(text: string) { const language = await getConfigOption('language') || 'en' const translation_json = JSON.parse(await invoke('get_lang', { lang: language }) || '{}')