From a0f9be93ee8dee585b39970564dad1e08d9880e7 Mon Sep 17 00:00:00 2001 From: Slouchwind <2241051890@qq.com> Date: Mon, 19 Jun 2023 21:48:04 +0800 Subject: [PATCH] i18n --- components/i18n.ts | 123 +++++++++++++++++++++++++ components/main.tsx | 4 +- components/students/studentsMethods.ts | 4 +- next.config.js | 4 + pages/chat.tsx | 75 +++++++++------ pages/info.tsx | 16 +++- 6 files changed, 186 insertions(+), 40 deletions(-) create mode 100644 components/i18n.ts diff --git a/components/i18n.ts b/components/i18n.ts new file mode 100644 index 0000000..a6f4b6f --- /dev/null +++ b/components/i18n.ts @@ -0,0 +1,123 @@ +export type i18nContents = { + [x: string]: { + 'zh-CN': string, + 'zh-TW': string, + [x: string]: string, + } +} + +export function fillBlank(i18n: string, ...fills: (string | undefined)[]): string { + let text = i18n; + fills.forEach((v, i) => text = text.replace(`$${i}`, v || '')); + return text; +} + +export const info: i18nContents = { + title: { + 'zh-CN': '学生信息', + 'zh-TW': '學生信息', + }, + student: { + 'zh-CN': '学生', + 'zh-TW': '學生', + }, + allStudents: { + 'zh-CN': '所有学生', + 'zh-TW': '所有學生', + }, + selectStudents: { + 'zh-CN': '请选择学生。', + 'zh-TW': '請選擇學生。', + }, +} + +export const chat: i18nContents = { + title: { + 'zh-CN': '聊天编辑', + 'zh-TW': '聊天編輯', + }, + student: { + 'zh-CN': '学生', + 'zh-TW': '學生', + }, + allStudents: { + 'zh-CN': '所有学生', + 'zh-TW': '所有學生', + }, + selectStudents: { + 'zh-CN': '请选择学生。', + 'zh-TW': '請選擇學生。', + }, + '+': { + 'zh-CN': '添加', + 'zh-TW': '添加', + }, + '-': { + 'zh-CN': '去除', + 'zh-TW': '去除', + }, + idPromptTitle: { + 'zh-CN': '输入Id', + 'zh-TW': '輸入Id', + }, + idPromptInfo: { + 'zh-CN': '请输入需要在列表$0的学生的Id', + 'zh-TW': '請輸入需要在列表$0的學生的Id', + }, + error: { + 'zh-CN': '错误', + 'zh-TW': '錯誤', + }, + sameStudent: { + 'zh-CN': '已有此学生', + 'zh-TW': '已有此學生', + }, + withoutStudent: { + 'zh-CN': '列表中无此学生', + 'zh-TW': '列表中無此學生', + }, + sendMsgStudent: { + 'zh-CN': '发送学生消息', + 'zh-TW': '發送學生消息', + }, + sendMsgSensei: { + 'zh-CN': '发送老师消息', + 'zh-TW': '發送老師消息', + }, + sendMsgInfo: { + 'zh-CN': '请输入需要发送$0$1的$2', + 'zh-TW': '請輸入需要發送$0$1的$2', + }, + sendMsgStudentInfo: { + 'zh-CN': '的', + 'zh-TW': '的', + }, + sendMsgSenseiInfo: { + 'zh-CN': '给', + 'zh-TW': '給', + }, + text: { + 'zh-CN': '消息', + 'zh-TW': '消息', + }, + img: { + 'zh-CN': '图片链接', + 'zh-TW': '圖片鏈接', + }, + undefinedStudent: { + 'zh-CN': '$0的学生Id不存在', + 'zh-TW': '$0的學生Id不存在', + }, + up: { + 'zh-CN': '上传', + 'zh-TW': '上傳', + }, + down: { + 'zh-CN': '下载', + 'zh-TW': '下載', + }, + jsonFile: { + 'zh-CN': 'JSON文件', + 'zh-TW': 'JSON文件', + }, +} \ No newline at end of file diff --git a/components/main.tsx b/components/main.tsx index 7e586a8..a3b5e0f 100644 --- a/components/main.tsx +++ b/components/main.tsx @@ -62,9 +62,7 @@ export default function MainNode({ children }: { children: React.ReactNode }) {

MomoTalk

-

{ - - }}>X

+

X

diff --git a/components/students/studentsMethods.ts b/components/students/studentsMethods.ts index 59f1d39..030a241 100644 --- a/components/students/studentsMethods.ts +++ b/components/students/studentsMethods.ts @@ -1,8 +1,8 @@ import { fileInfo, schaleInfo, studentsJson, studentInfo } from './students'; -export async function getStudentsJson(): Promise { +export async function getStudentsJson(locale:string): Promise { const fileJson: fileInfo[] = await fetch('../students.json').then(r => r.json()); - const schaleJson: schaleInfo[] = await fetch('https://schale.gg/data/cn/students.min.json').then(r => r.json()); + const schaleJson: schaleInfo[] = await fetch(`https://schale.gg/data/${locale.slice(3).toLowerCase()}/students.min.json`).then(r => r.json()); return { fileJson, schaleJson }; } diff --git a/next.config.js b/next.config.js index 57883a4..f00b7fc 100644 --- a/next.config.js +++ b/next.config.js @@ -5,6 +5,10 @@ const nextConfig = { sassOptions: { includePaths: [path.join(__dirname, 'styles')], }, + i18n: { + locales: ['zh-CN', 'zh-TW'], + defaultLocale: 'zh-CN' + } } module.exports = nextConfig; diff --git a/pages/chat.tsx b/pages/chat.tsx index 5b80fc2..334c7ba 100644 --- a/pages/chat.tsx +++ b/pages/chat.tsx @@ -1,7 +1,10 @@ //Components import { NextSeo } from 'next-seo'; +import { useRouter } from 'next/router'; import MainNode from '@/components/main'; import Student, { AllStudentsIcon } from '@/components/students/student'; +import Repeat from '@/components/repeat'; +import ImgCol from '@/components/imgCol'; //Styles import styles from '@/styles/Chat.module.scss'; @@ -12,10 +15,9 @@ import getTitle from '@/components/title'; import { studentsJson } from '@/components/students/students'; import { getStudentInfo, getStudentsJson, getStuSenText } from '@/components/students/studentsMethods'; import Window, { AllWindows, AllWindow, getWindowFun } from '@/components/window'; -import Repeat from '@/components/repeat'; import { setStateFun, getClassState } from '@/components/extraReact'; -import ImgCol from '@/components/imgCol'; import { downloadFile, uploadFile } from '@/components/loadFile'; +import { chat, fillBlank, i18nContents } from '@/components/i18n'; const StatesContext = createContext<{ allWindow: AllWindow; @@ -34,6 +36,8 @@ const SendMessageFunContext = createContext<( type?: MessageData['type'], ) => void>(() => { }); +const loContext = createContext('zh-CN'); + interface MsgProps { msg: MessageProps['msg']; type: MessageData['type']; @@ -128,11 +132,12 @@ interface SenderState { function Sender({ id }: SenderState) { const sendMessageFun = useContext(SendMessageFunContext); + const lo = useContext(loContext); return ( {`${id} sendMessageFun(id)} onContextMenu={e => { e.preventDefault(); @@ -148,14 +153,12 @@ interface LoaderState { function Loader({ type }: LoaderState) { const { chatState, setChatState } = useContext(StatesContext); + const lo = useContext(loContext); return ( {`${type}load { if (type === 'up') uploadFile(e => { const result = e.target?.result; @@ -183,8 +186,9 @@ function ChatEditorBar() { function Content() { const { listState } = useContext(StatesContext); + const lo = useContext(loContext); if (!listState.studentsJson) return null; - if (listState.student === 0) return (

请选择学生。

); + if (listState.student === 0) return (

{chat.selectStudents[lo]}

); return (
@@ -225,6 +229,8 @@ interface SendMessageArg { } export default function Info() { + const { locale, defaultLocale = 'zh-CN' } = useRouter(); + const lo = locale || defaultLocale; const [listState, setListState] = getClassState(useState({ student: 0, studentsList: [10000, 10002], @@ -252,10 +258,10 @@ export default function Info() { if (chat !== undefined) { setChatState({ studentsChat: JSON.parse(chat) }); } - }, []) + }, []); useEffect(() => { - getStudentsJson().then(r => setListState({ studentsJson: { data: r } })); + getStudentsJson(locale || defaultLocale).then(r => setListState({ studentsJson: { data: r } })); }, []); //Window @@ -278,19 +284,18 @@ export default function Info() { const SendMessage = new Window('SendMessage'); useEffect(() => { - const IdPromptTypeText = { '+': '添加', '-': '去除' }; addNewWindow(IdPrompt, (zIndex, id, display, { studentsList, type }, all) => ( closeWindow(all, id)} element={close => (<> -

请输入需要在列表{IdPromptTypeText[type || '+']}的学生的Id

+

{fillBlank(chat.idPromptInfo[lo], chat[type || '+'][lo])}

{ idPromptInputRef.current = Number(e.target.value); }} /> + >{chat[type || '+'][lo]} )} zIndex={zIndex} display={display} @@ -330,20 +335,28 @@ export default function Info() { display={display} /> )); - const MsgInfoText = { 'text': '消息', 'img': '图片链接' }; addNewWindow(SendMessage, (zIndex, winId, display, { studentsJson, selId, studentsChat, id, type }, all) => ( closeWindow(all, winId)} element={close => { sendMessageInputRef.current = ''; return (<> -

请输入需要发送{getStuSenText(id, '的', '给')}{ - getStudentInfo( - studentsJson?.data || {}, - selId || 10000 - ).schale?.Name - }的{MsgInfoText[type]}

+

+ {fillBlank( + chat.sendMsgInfo[lo], + getStuSenText( + id, + chat.sendMsgStudentInfo[lo], + chat.sendMsgSenseiInfo[lo] + ), + getStudentInfo( + studentsJson?.data || {}, + selId || 10000 + ).schale?.Name, + chat[type][lo] + )} +

{type === 'text' &&