feature: full i18n support

This commit is contained in:
kkzzhizhou 2021-11-29 13:56:44 +08:00
parent 933c74804c
commit 6433c4c72a
10 changed files with 64 additions and 52 deletions

1
.gitignore vendored
View file

@ -8,6 +8,7 @@ package-lock.json
# yarn
yarn.lock
yarn-error.log
*.js.map

View file

@ -30,7 +30,6 @@
},
"dependencies": {
"@mui/icons-material": "^5.2.0",
"@react-navigation/native": "^6.0.6",
"i18next": "^21.5.2",
"i18next-browser-languagedetector": "^6.1.2",
"node": "^16.10.0",
@ -38,10 +37,8 @@
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-emoji-render": "^1.2.4",
"react-hook-form": "^7.20.2",
"react-i18next": "^11.14.2",
"react-markdown": "^7.1.0",
"react-navigation": "^4.4.4",
"react-tabs": "^3.2.2"
}
}

View file

@ -17,5 +17,17 @@
"API Error: Please check credentials": "API错误请检查凭据",
"Resyncing, please try again": "重新同步失败,请稍后再试",
"Add!": "已添加",
"Loading....": "加载中...."
"Loading....": "加载中....",
"Deleted!": "已删除!",
"Edit!": "已修改!",
"running cron": "正在运行定时任务",
"Checked!": "已完成",
"Un-Checked!": "取消完成状态",
"Plus!": "+1",
"Minus :(": "-1",
"Cost!": "消费成功",
"Add Daily Task": "添加每日任务",
"Add Todo": "添加待办事项",
"Add Habit": "添加习惯",
"Add Reward": "添加奖励"
}

View file

@ -33,7 +33,6 @@ export default class HabiticaSync extends Plugin {
}
});
this.activateView();
}
async loadSettings() {
this.settings = Object.assign(DEFAULT_SETTINGS, await this.loadData())
@ -52,12 +51,10 @@ export default class HabiticaSync extends Plugin {
}
async activateView() {
this.app.workspace.detachLeavesOfType(VIEW_TYPE);
await this.app.workspace.getRightLeaf(false).setViewState({
type: VIEW_TYPE,
active: true,
});
this.app.workspace.revealLeaf(
this.app.workspace.getLeavesOfType(VIEW_TYPE)[0]
);

View file

@ -3,7 +3,9 @@ import { Notice } from "obsidian";
import { getStats, scoreTask, makeCronReq, costReward, addTask, deleteTask, updateTask } from "./habiticaAPI"
import Statsview from "./Components/Statsview"
import Taskview from "./Components/Taskview"
import "../i18n"
import { Trans } from 'react-i18next';
import "src/i18n"
import i18next from "i18next";
class App extends React.Component<any, any> {
private _username = "";
@ -63,7 +65,7 @@ class App extends React.Component<any, any> {
};
}
async runCron() {
console.log("running cron");
console.log(i18next.t('running cron'));
try {
let response = await makeCronReq(this.username, this.credentials);
this.setState({
@ -71,7 +73,7 @@ class App extends React.Component<any, any> {
})
} catch (error) {
console.log(error);
new Notice("There was an error running the cron. Please try again later.");
new Notice(i18next.t("There was an error running the cron. Please try again later."));
}
this.reloadData();
}
@ -80,7 +82,7 @@ class App extends React.Component<any, any> {
let response = await getStats(this.username, this.credentials);
let result = await response.json();
if (result.success === false) {
new Notice('Login Failed, Please check credentials and try again!');
new Notice(i18next.t('Login Failed, Please check credentials and try again!'));
}
else {
this.setState({
@ -91,7 +93,7 @@ class App extends React.Component<any, any> {
}
} catch (e) {
console.log(e);
new Notice("API Error: Please check credentials")
new Notice(i18next.t('API Error: Please check credentials'))
}
}
componentDidMount() {
@ -106,12 +108,12 @@ class App extends React.Component<any, any> {
new Notice(message);
this.reloadData();
} else {
new Notice("Resyncing, please try again");
new Notice(i18next.t('Resyncing, please try again'));
this.reloadData();
}
} catch (e) {
console.log(e);
new Notice("API Error: Please check credentials")
new Notice(i18next.t('API Error: Please check credentials'))
}
}
@ -123,12 +125,12 @@ class App extends React.Component<any, any> {
new Notice(message);
this.reloadData();
} else {
new Notice("Resyncing, please try again");
new Notice(i18next.t('Resyncing, please try again'));
this.reloadData();
}
} catch (e) {
console.log(e);
new Notice("API Error: Please check credentials")
new Notice(i18next.t('API Error: Please check credentials'))
}
}
@ -140,12 +142,12 @@ class App extends React.Component<any, any> {
new Notice(message);
this.reloadData();
} else {
new Notice("Resyncing, please try again");
new Notice(i18next.t('Resyncing, please try again'));
this.reloadData();
}
} catch (e) {
console.log(e);
new Notice("API Error: Please check credentials")
new Notice(i18next.t('API Error: Please check credentials'))
}
}
@ -157,12 +159,12 @@ class App extends React.Component<any, any> {
new Notice(message);
this.reloadData();
} else {
new Notice("Resyncing, please try again");
new Notice(i18next.t('Resyncing, please try again'));
this.reloadData();
}
} catch (e) {
console.log(e);
new Notice("API Error: Please check credentials")
new Notice(i18next.t('API Error: Please check credentials'))
}
}
@ -174,12 +176,12 @@ class App extends React.Component<any, any> {
new Notice(message);
this.reloadData();
} else {
new Notice("Resyncing, please try again");
new Notice(i18next.t('Resyncing, please try again'));
this.reloadData();
}
} catch (e) {
console.log(e);
new Notice("API Error: Please check credentials")
new Notice(i18next.t('API Error: Please check credentials'))
}
// console.log(id, type,title,notes)
}
@ -187,20 +189,20 @@ class App extends React.Component<any, any> {
handleChangeTodos(event: any) {
if (event.target.id == "add-todo") {
const title = event.target.name
this.sendAddTask("todo", title, "Add!")
this.sendAddTask("todo", title, i18next.t('Add!'))
} else {
this.state.tasks.todos.forEach((element: any) => {
if (element.id == event.target.id) {
if (event.type == "click") {
console.log(event)
if (event.target.innerText == 'clear') {
this.sendDeleteTask(event.target.id, "Deleted!")
this.sendDeleteTask(event.target.id, i18next.t('Deleted!'))
}
} else {
if (!element.completed) {
this.sendScore(event.target.id, "up", "Checked!")
this.sendScore(event.target.id, "up", i18next.t('Checked!'))
} else {
this.sendScore(event.target.id, "down", "Un-Checked!")
this.sendScore(event.target.id, "down", i18next.t('Un-Checked!'))
}
}
}
@ -212,7 +214,7 @@ class App extends React.Component<any, any> {
handleChangeDailys(event: any) {
if (event.target.id == "add-daily") {
const title = event.target.name
this.sendAddTask("daily", title, "Add!")
this.sendAddTask("daily", title, i18next.t('Add!'))
} else {
this.state.tasks.dailys.forEach((element: any) => {
if (element.id == event.target.id) {
@ -222,11 +224,11 @@ class App extends React.Component<any, any> {
const task_notes = event.target.attributes['data-notes'].value ? event.target.attributes['data-notes'].value : element.notes
this.sendUpdateTask(event.target.id, 'daily', "Update!", task_title, task_notes)
} else if (event.target.attributes.title.value == 'delete') {
this.sendDeleteTask(event.target.id, "Deleted!")
this.sendDeleteTask(event.target.id, i18next.t('Deleted!'))
} else if (!element.completed) {
this.sendScore(event.target.id, "up", "Checked!")
this.sendScore(event.target.id, "up", i18next.t('Checked!'))
} else {
this.sendScore(event.target.id, "down", "Un-Checked!")
this.sendScore(event.target.id, "down", i18next.t('Un-Checked!'))
}
}
}
@ -237,23 +239,23 @@ class App extends React.Component<any, any> {
handleChangeHabits(event: any) {
if (event.target.id == "add-habit") {
const title = event.target.name
this.sendAddTask("habit", title, "Add!")
this.sendAddTask("habit", title, i18next.t('Add!'))
} else {
if (event.target.innerText == 'clear') {
this.sendDeleteTask(event.target.id, "Deleted!")
this.sendDeleteTask(event.target.id, i18next.t('Deleted!'))
} else {
const target_id = event.target.id.slice(4)
if (event.target.id.slice(0, 4) == "plus") {
this.state.tasks.habits.forEach((element: any) => {
if (element.id == target_id) {
this.sendScore(target_id, "up", "Plus!")
this.sendScore(target_id, "up", i18next.t('Plus!'))
}
})
}
else {
this.state.tasks.habits.forEach((element: any) => {
if (element.id == target_id) {
this.sendScore(target_id, "down", "Minus :(")
this.sendScore(target_id, "down", i18next.t("Minus :("))
}
})
}
@ -265,17 +267,17 @@ class App extends React.Component<any, any> {
console.log(event)
if (event.target.id == "add-reward") {
const title = event.target.name
this.sendAddTask("reward", title, "Add!")
this.sendAddTask("reward", title, i18next.t('Add!'))
} else {
const target_id = event.target.id
this.state.tasks.rewards.forEach((element: any) => {
if (element.id == target_id) {
if (event.target.innerText == 'clear') {
this.sendDeleteTask(event.target.id, "Deleted!")
this.sendDeleteTask(event.target.id, i18next.t('Deleted!'))
} else if (event.target.innerText == 'create') {
this.sendUpdateTask(event.target.id, 'reward', "Edit!", "1", "1")
this.sendUpdateTask(event.target.id, 'reward', i18next.t('Edit!'), "1", "1")
} else {
this.sendReward(target_id, "down", "Cost!")
this.sendReward(target_id, "down", i18next.t('Cost!'))
}
}
})
@ -284,9 +286,9 @@ class App extends React.Component<any, any> {
render() {
let content = this.CheckCron(this.state.user_data.lastCron);
if (this.state.error)
return (<div className="loading">Loading....</div>)
return (<div className="loading"><Trans>Loading....</Trans></div>)
else if (!this.state.isLoaded)
return <div className="loading">Loading....</div>
return <div className="loading"><Trans>Loading....</Trans></div>
else {
return (<div className="plugin-root">
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" />

View file

@ -1,14 +1,14 @@
import * as React from "react";
import DailyItem from "./DailyItem"
import { Tab, Tabs, TabList, TabPanel } from "react-tabs";
import { Trans } from 'react-i18next';
import { Trans, useTranslation } from 'react-i18next';
export default function Index(props: any) {
const [title, setTitle] = React.useState('')
let { t ,i18n} = useTranslation()
if (props.dailys == undefined) {
return <div id="classDisplay">
<input type="text" placeholder="添加每日任务" onChange={event => setTitle(event.target.value)} />
<input type="text" placeholder={t('Add Daily Task')} onChange={event => setTitle(event.target.value)} />
<button className="submit-button" id="add-daily" onClick={props.onChange} name={title}><Trans>submit</Trans></button>
<Trans>No Dailies Present</Trans>
</div>
@ -32,7 +32,7 @@ export default function Index(props: any) {
<Tab><Trans>Completed</Trans></Tab>
</TabList>
<TabPanel>
<input type="text" id="task-input-box" placeholder="添加每日任务" onChange={event => setTitle(event.target.value)} value={title} />
<input type="text" id="task-input-box" placeholder={t('Add Daily Task')} onChange={event => setTitle(event.target.value)} value={title} />
<button className="submit-button" id="add-daily" onClick={function (e) { setTitle(""); props.onChange(e) }} name={title}><Trans>submit</Trans></button>
<div className="task-panel">
<ul>{incompleteDailies}</ul>

View file

@ -4,9 +4,10 @@ import { useTranslation, Trans, Translation } from 'react-i18next'
export default function Index(props: any){
const [title, setTitle] = React.useState('')
let { t ,i18n} = useTranslation()
if(props.habits == undefined) {
return (<div id="classDisplay">
<input type="text" placeholder="添加习惯" onChange={event => setTitle(event.target.value)} />
<input type="text" placeholder={t('Add Habit')} onChange={event => setTitle(event.target.value)} />
<button className="submit-button" id="add-habit" onClick={props.onChange} name={title}><Trans>submit</Trans></button>
<Trans>No habits present.</Trans>
</div>)
@ -18,7 +19,7 @@ export default function Index(props: any){
const display = <div id="classDisplay">
<input type="text" placeholder="添加习惯" onChange={event => setTitle(event.target.value)} />
<input type="text" placeholder={t('Add Habit')} onChange={event => setTitle(event.target.value)} />
<button className="submit-button" id="add-habit" onClick={props.onChange} name={title}><Trans>submit</Trans></button>
<ul>{allHabits}</ul>
</div>

View file

@ -1,12 +1,13 @@
import * as React from "react";
import RewardItem from "./RewardItem"
import { Trans } from 'react-i18next'
import { Trans,useTranslation } from 'react-i18next'
export default function Index(props: any){
const [title, setTitle] = React.useState('')
let { t ,i18n} = useTranslation()
if(props.rewards == undefined) {
return (<div id="classDisplay">
<input type="text" placeholder="添加奖励" onChange={event => setTitle(event.target.value)} />
<input type="text" placeholder={t('Add Reward')} onChange={event => setTitle(event.target.value)} />
<button className="submit-button" id="add-reward" onClick={props.onChange} name={title}><Trans>submit</Trans></button>
<Trans>No Rewards present.</Trans>
</div>)
@ -16,7 +17,7 @@ export default function Index(props: any){
return <RewardItem key={reward.id} id={reward.id} reward_text={reward.text} reward_notes={reward.notes} reward_value={reward.value} onChange={props.onChange}/>
})
const display = <div id="classDisplay">
<input type="text" placeholder="添加奖励" onChange={event => setTitle(event.target.value)} />
<input type="text" placeholder={t('Add Reward')} onChange={event => setTitle(event.target.value)} />
<button className="submit-button" id="add-reward" onClick={props.onChange} name={title}><Trans>submit</Trans></button>
<ul>{allRewards}</ul>
</div>

View file

@ -1,13 +1,14 @@
import * as React from "react";
import TodoItem from "./TodoItem"
import { Tab, Tabs, TabList, TabPanel } from "react-tabs";
import { Trans } from 'react-i18next'
import { Trans,useTranslation } from 'react-i18next'
export default function Index(props: any){
const [title, setTitle] = React.useState('')
let { t ,i18n} = useTranslation()
if(props.todos == undefined) {
return <div id="classDisplay">
<input type="text" placeholder="添加待办事项" onChange={event => setTitle(event.target.value)} />
<input type="text" placeholder={t('Add Todo')} onChange={event => setTitle(event.target.value)} />
<button className="submit-button" id="add-todo" onClick={props.onChange} name={title}><Trans>submit</Trans></button>
No Todos present.
</div>
@ -28,7 +29,7 @@ export default function Index(props: any){
<Tab><Trans>Completed</Trans></Tab>
</TabList>
<TabPanel>
<input type="text" placeholder="添加待办事项" onChange={event => setTitle(event.target.value)} />
<input type="text" placeholder={t('Add Todo')} onChange={event => setTitle(event.target.value)} />
<button className="submit-button" id="add-todo" onClick={props.onChange} name={title}><Trans>submit</Trans></button>
<ul>{incompleteTodos}</ul>
</TabPanel>