chore: update i18n (#215)

This commit is contained in:
ChasLui 2022-09-15 06:53:51 +08:00 committed by GitHub
parent 54db6eda04
commit 7e8d1128f8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 109 additions and 43 deletions

View file

@ -20,6 +20,7 @@ const ArchivedMemo: React.FC<Props> = (props: Props) => {
archivedAtStr: utils.getDateTimeString(propsMemo.updatedTs ?? Date.now()),
};
const { t } = useI18n();
const [showConfirmDeleteBtn, toggleConfirmDeleteBtn] = useToggle(false);
const handleDeleteMemoClick = async () => {
@ -43,7 +44,7 @@ const ArchivedMemo: React.FC<Props> = (props: Props) => {
rowStatus: "NORMAL",
});
await memoService.fetchMemos();
toastHelper.info("Restored successfully");
toastHelper.info(t("common.restored-successfully"));
} catch (error: any) {
console.error(error);
toastHelper.error(error.response.data.message);
@ -59,7 +60,9 @@ const ArchivedMemo: React.FC<Props> = (props: Props) => {
return (
<div className={`memo-wrapper archived-memo ${"memos-" + memo.id}`} onMouseLeave={handleMouseLeaveMemoWrapper}>
<div className="memo-top-wrapper">
<span className="time-text">Archived at {memo.archivedAtStr}</span>
<span className="time-text">
{t("common.archived-at")} {memo.archivedAtStr}
</span>
<div className="btns-container">
<span className="btn restore-btn" onClick={handleRestoreMemoClick}>
{t("common.restore")}

View file

@ -23,7 +23,7 @@ const ChangeMemoCreatedTsDialog: React.FC<Props> = (props: Props) => {
const datetime = dayjs(memo.createdTs).format("YYYY-MM-DDTHH:mm");
setCreatedAt(datetime);
} else {
toastHelper.error("Memo not found.");
toastHelper.error(t("common.memo-not-found"));
destroy();
}
}, []);
@ -42,7 +42,7 @@ const ChangeMemoCreatedTsDialog: React.FC<Props> = (props: Props) => {
const createdTs = dayjs(createdAt).unix();
if (createdTs > nowTs) {
toastHelper.error("Invalid created datetime.");
toastHelper.error(t("common.invalid-created-datetime"));
return;
}
@ -51,7 +51,7 @@ const ChangeMemoCreatedTsDialog: React.FC<Props> = (props: Props) => {
id: memoId,
createdTs,
});
toastHelper.info("Memo created datetime changed.");
toastHelper.info(t("common.memo-updated-datetime"));
handleCloseBtnClick();
} catch (error: any) {
console.error(error);
@ -62,7 +62,7 @@ const ChangeMemoCreatedTsDialog: React.FC<Props> = (props: Props) => {
return (
<>
<div className="dialog-header-container">
<p className="title-text">Change memo created time</p>
<p className="title-text">{t("common.change-memo-created-time")}</p>
<button className="btn close-btn" onClick={handleCloseBtnClick}>
<Icon.X />
</button>

View file

@ -17,7 +17,7 @@ const validateConfig: ValidatorConfig = {
type Props = DialogProps;
const ChangePasswordDialog: React.FC<Props> = ({ destroy }: Props) => {
const { t } = useI18n();
const { t, locale } = useI18n();
const [newPassword, setNewPassword] = useState("");
const [newPasswordAgain, setNewPasswordAgain] = useState("");
@ -41,19 +41,19 @@ const ChangePasswordDialog: React.FC<Props> = ({ destroy }: Props) => {
const handleSaveBtnClick = async () => {
if (newPassword === "" || newPasswordAgain === "") {
toastHelper.error("Please fill in all fields.");
toastHelper.error(t("common.fill-all"));
return;
}
if (newPassword !== newPasswordAgain) {
toastHelper.error("New passwords do not match.");
toastHelper.error(t("common.new-password-not-match"));
setNewPasswordAgain("");
return;
}
const passwordValidResult = validate(newPassword, validateConfig);
if (!passwordValidResult.result) {
toastHelper.error("Password " + passwordValidResult.reason);
toastHelper.error(t("common.password") + locale === "zh" ? "" : " " + passwordValidResult.reason);
return;
}
@ -63,7 +63,7 @@ const ChangePasswordDialog: React.FC<Props> = ({ destroy }: Props) => {
id: user.id,
password: newPassword,
});
toastHelper.info("Password changed.");
toastHelper.info(t("common.password") + t("common.changed"));
handleCloseBtnClick();
} catch (error: any) {
console.error(error);
@ -74,17 +74,22 @@ const ChangePasswordDialog: React.FC<Props> = ({ destroy }: Props) => {
return (
<>
<div className="dialog-header-container">
<p className="title-text">Change Password</p>
<p className="title-text">{t("common.password" + " " + t("common.change"))}</p>
<button className="btn close-btn" onClick={handleCloseBtnClick}>
<Icon.X />
</button>
</div>
<div className="dialog-content-container">
<label className="form-label input-form-label">
<input type="password" placeholder="New passworld" value={newPassword} onChange={handleNewPasswordChanged} />
<input type="password" placeholder={t("common.new-password")} value={newPassword} onChange={handleNewPasswordChanged} />
</label>
<label className="form-label input-form-label">
<input type="password" placeholder="Repeat the new password" value={newPasswordAgain} onChange={handleNewPasswordAgainChanged} />
<input
type="password"
placeholder={t("common.repeat-new-password")}
value={newPasswordAgain}
onChange={handleNewPasswordAgainChanged}
/>
</label>
<div className="btns-container">
<span className="btn cancel-btn" onClick={handleCloseBtnClick}>

View file

@ -45,7 +45,7 @@ const CreateShortcutDialog: React.FC<Props> = (props: Props) => {
const handleSaveBtnClick = async () => {
if (!title) {
toastHelper.error("Title is required");
toastHelper.error(t("shortcut-list.title-required"));
return;
}
@ -73,7 +73,7 @@ const CreateShortcutDialog: React.FC<Props> = (props: Props) => {
if (filters.length > 0) {
const lastFilter = filters[filters.length - 1];
if (lastFilter.value.value === "") {
toastHelper.info("Please fill in previous filter value");
toastHelper.info(t("shortcut-list.fill-previous"));
return;
}
}
@ -110,7 +110,13 @@ const CreateShortcutDialog: React.FC<Props> = (props: Props) => {
<div className="dialog-content-container">
<div className="form-item-container input-form-container">
<span className="normal-text">{t("common.title")}</span>
<input className="title-input" type="text" placeholder="shortcut title" value={title} onChange={handleTitleInputChange} />
<input
className="title-input"
type="text"
placeholder={t("common.shortcut-title")}
value={title}
onChange={handleTitleInputChange}
/>
</div>
<div className="form-item-container filter-form-container">
<span className="normal-text">{t("common.filter")}</span>

View file

@ -105,7 +105,7 @@ const Memo: React.FC<Props> = (props: Props) => {
if (memoTemp) {
showMemoCardDialog(memoTemp);
} else {
toastHelper.error("Memo Not Found");
toastHelper.error(t("common.memo-not-found"));
targetEl.classList.remove("memo-link-text");
}
} else if (targetEl.className === "tag-span") {

View file

@ -12,6 +12,7 @@ import Selector from "./common/Selector";
import MemoContent from "./MemoContent";
import MemoResources from "./MemoResources";
import showChangeMemoCreatedTsDialog from "./ChangeMemoCreatedTsDialog";
import useI18n from "../hooks/useI18n";
import "../less/memo-card-dialog.less";
interface LinkedMemo extends Memo {
@ -30,6 +31,7 @@ const MemoCardDialog: React.FC<Props> = (props: Props) => {
});
const [linkMemos, setLinkMemos] = useState<LinkedMemo[]>([]);
const [linkedMemos, setLinkedMemos] = useState<LinkedMemo[]>([]);
const { t } = useI18n();
useEffect(() => {
const fetchLinkedMemos = async () => {
@ -95,7 +97,7 @@ const MemoCardDialog: React.FC<Props> = (props: Props) => {
setLinkedMemos([]);
setMemo(nextMemo);
} else {
toastHelper.error("Memo Not Found");
toastHelper.error(t("common.memo-not-found"));
targetEl.classList.remove("memo-link-text");
}
}

View file

@ -110,7 +110,7 @@ const MemoEditor = () => {
const { type } = file;
if (!type.startsWith("image")) {
toastHelper.error("Only image file supported.");
toastHelper.error(t("editor.only-image-supported"));
return;
}
@ -133,7 +133,7 @@ const MemoEditor = () => {
const handleSaveBtnClick = async (content: string) => {
if (content === "") {
toastHelper.error("Content can't be empty");
toastHelper.error(t("editor.cant-empty"));
return;
}

View file

@ -108,7 +108,7 @@ const MemoList = () => {
))}
<Only when={!isFetching}>
<div className="status-text-container">
<p className="status-text">{sortedMemos.length === 0 ? "no memos 🌃" : showMemoFilter ? "" : "all memos are ready 🎉"}</p>
<p className="status-text">{sortedMemos.length === 0 ? t("common.no-memos") : showMemoFilter ? "" : t("common.memos-ready")}</p>
</div>
</Only>
</div>

View file

@ -48,7 +48,7 @@ const PreferencesSection = () => {
const handleCreateUserBtnClick = async () => {
if (isEmpty(state.createUserEmail) || isEmpty(state.createUserPassword)) {
toastHelper.error("Please fill out this form");
toastHelper.error(t("common.fill-form"));
return;
}
@ -125,10 +125,10 @@ const PreferencesSection = () => {
<button onClick={handleCreateUserBtnClick}>{t("common.create")}</button>
</div>
</div>
<p className="title-text">Member list</p>
<p className="title-text">{t("setting.member-list")}</p>
<div className="member-container field-container">
<span className="field-text">ID</span>
<span className="field-text">EMAIL</span>
<span className="field-text">{t("common.email")}</span>
<span></span>
</div>
{userList.map((user) => (
@ -137,7 +137,7 @@ const PreferencesSection = () => {
<span className="field-text email-text">{user.email}</span>
<div className="buttons-container">
{currentUser?.id === user.id ? (
<span className="tip-text">Yourself</span>
<span className="tip-text">{t("common.yourself")}</span>
) : (
<Dropdown className="actions-dropdown">
{user.rowStatus === "NORMAL" ? (

View file

@ -16,7 +16,7 @@ const validateConfig: ValidatorConfig = {
};
const MyAccountSection = () => {
const { t } = useI18n();
const { t, locale } = useI18n();
const user = useAppSelector((state) => state.user.user as User);
const [username, setUsername] = useState<string>(user.name);
const openAPIRoute = `${window.location.origin}/api/memo?openId=${user.openId}`;
@ -33,7 +33,7 @@ const MyAccountSection = () => {
const usernameValidResult = validate(username, validateConfig);
if (!usernameValidResult.result) {
toastHelper.error("Username " + usernameValidResult.reason);
toastHelper.error(t("common.username") + locale === "zh" ? "" : " " + usernameValidResult.reason);
return;
}
@ -42,7 +42,7 @@ const MyAccountSection = () => {
id: user.id,
name: username,
});
toastHelper.info("Username changed");
toastHelper.info(t("common.username") + locale === "zh" ? "" : " " + t("common.changed"));
} catch (error: any) {
console.error(error);
toastHelper.error(error.response.data.message);

View file

@ -59,7 +59,7 @@ const ShareMemoImageDialog: React.FC<Props> = (props: Props) => {
const handleImageOnLoad = (event: React.SyntheticEvent<HTMLImageElement>) => {
if (event.type === "error") {
toastHelper.error("Image load failed");
toastHelper.error(t("common.image-load-failed"));
(event.target as HTMLImageElement).remove();
}
setImgAmount(imgAmount - 1);

View file

@ -3,6 +3,8 @@
"about": "About",
"email": "Email",
"password": "Password",
"new-password": "New passworld",
"repeat-new-password": "Repeat the new password",
"username": "Username",
"save": "Save",
"cancel": "Cancel",
@ -28,9 +30,27 @@
"back-to-home": "Back to Home",
"type": "Type",
"shortcuts": "Shortcuts",
"shortcut-title": "shortcut title",
"title": "Title",
"filter": "Filter",
"tags": "Tags"
"tags": "Tags",
"no-memos": "no memos 🌃",
"memos-ready": "all memos are ready 🎉",
"yourself": "Yourself",
"archived-at": "Archived at",
"restored-successfully": "Restored successfully",
"memo-updated-datetime":"Memo created datetime changed.",
"invalid-created-datetime": "Invalid created datetime.",
"change-memo-created-time": "Change memo created time",
"memo-not-found": "Memo not found.",
"fill-all": "Please fill in all fields.",
"new-password-not-match": "New passwords do not match.",
"changed": "changed",
"image-load-failed": "Image load failed",
"fill-form": "Please fill out this form",
"login-failed": "Login failed",
"signup-failed": "Signup failed",
"user-not-found": "User not found"
},
"slogan": "An open source, self-hosted knowledge base that works with a SQLite db file.",
"auth": {
@ -63,7 +83,9 @@
"editor": {
"editing": "Editing...",
"save": "Save",
"placeholder": "Any thoughts..."
"placeholder": "Any thoughts...",
"only-image-supported": "Only image file supported.",
"cant-empty": "Content can't be empty"
},
"memo": {
"view-story": "View Story"
@ -75,7 +97,9 @@
"create-shortcut": "Create Shortcut",
"edit-shortcut": "Edit Shortcut",
"new-filter": "New Filter",
"eligible-memo": "eligible memo"
"eligible-memo": "eligible memo",
"fill-previous": "Please fill in previous filter value",
"title-required": "Title is required"
},
"tag-list": {
"tip-text": "Enter `#tag ` to create"
@ -87,6 +111,7 @@
"my-account": "My Account",
"preference": "Preference",
"member": "Member",
"member-list": "Member list",
"account-section": {
"title": "Account Information"
},

View file

@ -3,6 +3,8 @@
"about": "关于",
"email": "邮箱",
"password": "密码",
"new-password": "新密码",
"repeat-new-password": "重复新密码",
"username": "用户名",
"save": "保存",
"cancel": "退出",
@ -28,9 +30,27 @@
"back-to-home": "回到主页",
"type": "类型",
"shortcuts": "捷径",
"shortcut-title": "捷径标题",
"title": "标题",
"filter": "过滤器",
"tags": "全部标签"
"tags": "全部标签",
"no-memos": "没有 memo 了 🌃",
"memos-ready": "所有 memo 已就绪 🎉",
"yourself": "你自己",
"archived-at": "归档于",
"restored-successfully": "恢复成功",
"memo-updated-datetime": "Memo创建日期时间已更改。",
"invalid-created-datetime": "创建的日期时间无效。",
"change-memo-created-time": "更改Memo创建时间",
"memo-not-found": "找不到Memo。",
"fill-all": "请填写所有字段。",
"new-password-not-match": "新密码不匹配。",
"changed": "已更改",
"image-load-failed": "图片加载失败",
"fill-form": "请填写此表单",
"login-failed": "登录失败",
"signup-failed": "注册失败",
"user-not-found": "未找到用户"
},
"slogan": "一个开源的、支持私有化部署的碎片化知识卡片管理工具。",
"auth": {
@ -63,7 +83,9 @@
"editor": {
"editing": "编辑中...",
"save": "记下",
"placeholder": "现在的想法是..."
"placeholder": "现在的想法是...",
"only-image-supported": "仅支持图片文件。",
"cant-empty": "Content can't be empty"
},
"memo": {
"view-story": "查看详情"
@ -75,7 +97,9 @@
"create-shortcut": "创建捷径",
"edit-shortcut": "编辑捷径",
"new-filter": "新建过滤器",
"eligible-memo": "符合条件的 memo"
"eligible-memo": "符合条件的 memo",
"fill-previous": "请填写之前的过滤值",
"title-required": "标题是必填项。"
},
"tag-list": {
"tip-text": "输入`#tag `来创建标签"
@ -87,6 +111,7 @@
"my-account": "我的账号",
"preference": "偏好设置",
"member": "成员",
"member-list": "成员列表",
"account-section": {
"title": "账号信息"
},

View file

@ -53,13 +53,13 @@ const Auth = () => {
const emailValidResult = validate(email, validateConfig);
if (!emailValidResult.result) {
toastHelper.error("Email: " + emailValidResult.reason);
toastHelper.error(t("common.email") + ": " + emailValidResult.reason);
return;
}
const passwordValidResult = validate(password, validateConfig);
if (!passwordValidResult.result) {
toastHelper.error("Password: " + passwordValidResult.reason);
toastHelper.error(t("common.password") + ": " + passwordValidResult.reason);
return;
}
@ -70,7 +70,7 @@ const Auth = () => {
if (user) {
locationService.replaceHistory("/");
} else {
toastHelper.error("Login failed");
toastHelper.error(t("common.login-failed"));
}
} catch (error: any) {
console.error(error);
@ -86,13 +86,13 @@ const Auth = () => {
const emailValidResult = validate(email, validateConfig);
if (!emailValidResult.result) {
toastHelper.error("Email: " + emailValidResult.reason);
toastHelper.error(t("common.email") + ": " + emailValidResult.reason);
return;
}
const passwordValidResult = validate(password, validateConfig);
if (!passwordValidResult.result) {
toastHelper.error("Password: " + passwordValidResult.reason);
toastHelper.error(t("common.password") + ": " + passwordValidResult.reason);
return;
}
@ -103,7 +103,7 @@ const Auth = () => {
if (user) {
locationService.replaceHistory("/");
} else {
toastHelper.error("Signup failed");
toastHelper.error(t("common.singup-failed"));
}
} catch (error: any) {
console.error(error);

View file

@ -31,7 +31,7 @@ function Home() {
if (userService.isVisitorMode()) {
if (!owner) {
toastHelper.error("User not found");
toastHelper.error(t("common.user-not-found"));
}
} else {
if (!user) {