mirror of
https://github.com/Grasscutters/Cultivation.git
synced 2025-12-12 23:24:35 +01:00
translation system
This commit is contained in:
8
lang/en.json
Normal file
8
lang/en.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"lang_name": "English",
|
||||
"main": {
|
||||
"title": "Cultivation",
|
||||
"launch_button": "Launch",
|
||||
"gc_enable": "Connect via Grasscutter"
|
||||
}
|
||||
}
|
||||
28
src-tauri/src/lang.rs
Normal file
28
src-tauri/src/lang.rs
Normal file
@@ -0,0 +1,28 @@
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn get_lang(window: tauri::Window, lang: String) -> String {
|
||||
let lang = lang.to_lowercase();
|
||||
|
||||
// Send contents of language file back
|
||||
let contents = match std::fs::read_to_string(format!("../lang/{}.json", lang)) {
|
||||
Ok(x) => x,
|
||||
Err(e) => {
|
||||
emit_lang_err(window, format!("Failed to read language file: {}", e));
|
||||
return "".to_string();
|
||||
}
|
||||
};
|
||||
|
||||
return contents;
|
||||
}
|
||||
|
||||
|
||||
pub fn emit_lang_err(window: tauri::Window, msg: std::string::String) {
|
||||
let mut res_hash = std::collections::HashMap::new();
|
||||
|
||||
res_hash.insert(
|
||||
"error".to_string(),
|
||||
msg.to_string()
|
||||
);
|
||||
|
||||
window.emit("lang_error", &res_hash).unwrap();
|
||||
}
|
||||
@@ -6,6 +6,7 @@ windows_subsystem = "windows"
|
||||
use opener;
|
||||
|
||||
mod downloader;
|
||||
mod lang;
|
||||
mod proxy;
|
||||
|
||||
fn main() {
|
||||
@@ -14,7 +15,8 @@ fn main() {
|
||||
connect,
|
||||
disconnect,
|
||||
run_program,
|
||||
downloader::download_file
|
||||
downloader::download_file,
|
||||
lang::get_lang
|
||||
])
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import React from 'react'
|
||||
import { listen } from '@tauri-apps/api/event'
|
||||
import './App.css'
|
||||
import './custom.css'
|
||||
|
||||
@@ -47,6 +48,10 @@ class App extends React.Component<IProps, IState> {
|
||||
optionsOpen: false,
|
||||
miniDownloadsOpen: false,
|
||||
}
|
||||
|
||||
listen('lang_error', (payload) => {
|
||||
console.log(payload)
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
@@ -6,7 +6,10 @@ import minIcon from '../../resources/icons/min.svg'
|
||||
import cogBtn from '../../resources/icons/cog.svg'
|
||||
import downBtn from '../../resources/icons/download.svg'
|
||||
|
||||
import Tr, { translate } from '../../utils/language'
|
||||
|
||||
import './TopBar.css'
|
||||
import { listen } from '@tauri-apps/api/event'
|
||||
|
||||
interface IProps {
|
||||
optFunc: () => void;
|
||||
@@ -37,7 +40,9 @@ export default class TopBar extends React.Component<IProps, IState> {
|
||||
return (
|
||||
<div className="TopBar" data-tauri-drag-region >
|
||||
<div id="title">
|
||||
<span data-tauri-drag-region>Cultivation</span>
|
||||
<span data-tauri-drag-region>
|
||||
<Tr text="main.title" />
|
||||
</span>
|
||||
<span data-tauri-drag-region id="version">{this.state?.version}</span>
|
||||
</div>
|
||||
<div className="TopBtns">
|
||||
|
||||
88
src/utils/language.ts
Normal file
88
src/utils/language.ts
Normal file
@@ -0,0 +1,88 @@
|
||||
import { invoke } from '@tauri-apps/api'
|
||||
import React from 'react'
|
||||
import { getConfigOption } from './configuration'
|
||||
|
||||
interface IProps {
|
||||
text: string;
|
||||
}
|
||||
|
||||
interface IState {
|
||||
language: string;
|
||||
translated_text: string;
|
||||
}
|
||||
|
||||
export default class Tr extends React.Component<IProps, IState> {
|
||||
constructor(props: IProps) {
|
||||
super(props)
|
||||
|
||||
this.state = {
|
||||
language: 'en',
|
||||
translated_text: '',
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const { text } = this.props
|
||||
getConfigOption('language').then((language: string) => {
|
||||
// Get translation file
|
||||
if (!language) language = 'en'
|
||||
|
||||
invoke('get_lang', { lang: language }).then((response) => {
|
||||
const translation_obj = JSON.parse(response as string || '{}')
|
||||
|
||||
console.log(translation_obj)
|
||||
|
||||
// Traversal
|
||||
if (text.includes('.')) {
|
||||
const keys = text.split('.')
|
||||
let translation: string | Record<string, string> = translation_obj
|
||||
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
if (!translation) {
|
||||
translation = ''
|
||||
} else {
|
||||
translation = typeof translation !== 'string' ? translation[keys[i]] : translation as string
|
||||
}
|
||||
}
|
||||
|
||||
console.log(translation)
|
||||
|
||||
this.setState({
|
||||
translated_text: translation as string,
|
||||
})
|
||||
} else {
|
||||
this.setState({
|
||||
translated_text: translation_obj[text] || ''
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
return this.state.translated_text
|
||||
}
|
||||
}
|
||||
|
||||
export async function translate(text: string) {
|
||||
const language = await getConfigOption('language') || 'en'
|
||||
const translation_json = JSON.parse(await invoke('get_lang', { lang: language }) || '{}')
|
||||
|
||||
// Traversal
|
||||
if (text.includes('.')) {
|
||||
const keys = text.split('.')
|
||||
let translation = ''
|
||||
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
if (!translation) {
|
||||
translation = ''
|
||||
} else {
|
||||
translation = translation_json[keys[i]] || ''
|
||||
}
|
||||
}
|
||||
|
||||
return translation
|
||||
} else {
|
||||
return translation_json[text] || ''
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user