From 8fb91d7ecb5f0fcc1e953fe318036c8e791d5f94 Mon Sep 17 00:00:00 2001 From: Artemy Date: Tue, 4 Apr 2023 15:15:15 +0300 Subject: [PATCH] feat: localisation --- src/App.jsx | 18 +++++++++++++- src/components/menu.jsx | 12 ++++++---- src/components/note.jsx | 2 +- src/components/utils.js | 6 ++++- src/localisation/en.js | 46 +++++++++++++++++++++++++++++++++++ src/localisation/main.js | 22 +++++++++++++++++ src/localisation/ru.js | 47 ++++++++++++++++++++++++++++++++++++ src/pages/create.jsx | 16 ++++++------- src/pages/note.jsx | 6 ++--- src/pages/notes.jsx | 6 ++--- src/pages/pubError.jsx | 10 ++++---- src/pages/pubNote.jsx | 2 +- src/pages/pubNoteSafe.jsx | 25 ++++++++------------ src/pages/publish.jsx | 4 ++-- src/pages/settings.jsx | 50 ++++++++++++++++++++++++--------------- 15 files changed, 208 insertions(+), 64 deletions(-) create mode 100644 src/localisation/en.js create mode 100644 src/localisation/main.js create mode 100644 src/localisation/ru.js diff --git a/src/App.jsx b/src/App.jsx index bd568eb..f1e7888 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -12,6 +12,8 @@ import PubNoteSafe from "./pages/pubNoteSafe"; import RenderMarkdown from "./components/markdown"; import socket from "./components/socket"; import Settings from "./pages/settings"; +import Locales from "./localisation/main"; +import { useState } from "react"; function App() { Storage.prototype.setObj = function (key, obj) { @@ -21,10 +23,24 @@ function App() { return JSON.parse(this.getItem(key)) || {}; }; + const [key, setKey] = useState(Math.random()); + window.settings = localStorage.getObj("settings") || {}; + window.locals = + Locales[window.settings.language] || + Locales[navigator.language] || + Locales[navigator.userLanguage] || + Locales.en; + + window.addEventListener("reRenderPage", () => { + setKey(Math.random()); + }); return ( -
+
diff --git a/src/components/menu.jsx b/src/components/menu.jsx index 7c2f555..0bcc63e 100644 --- a/src/components/menu.jsx +++ b/src/components/menu.jsx @@ -11,14 +11,18 @@ function Menu() {
- - + +
diff --git a/src/components/note.jsx b/src/components/note.jsx index f358fe7..519b010 100644 --- a/src/components/note.jsx +++ b/src/components/note.jsx @@ -1,5 +1,5 @@ import RenderMarkdown from "../components/markdown"; -import printDate from "./utils"; +import { printDate } from "./utils"; function Note({ note }) { return ( diff --git a/src/components/utils.js b/src/components/utils.js index 54da7e3..f5d170c 100644 --- a/src/components/utils.js +++ b/src/components/utils.js @@ -13,4 +13,8 @@ function printDate(time) { return dateStr; } -export default printDate; +function reRenderPage() { + window.dispatchEvent(new Event("reRenderPage")); +} + +export { printDate, reRenderPage }; diff --git a/src/localisation/en.js b/src/localisation/en.js new file mode 100644 index 0000000..bff5fc3 --- /dev/null +++ b/src/localisation/en.js @@ -0,0 +1,46 @@ +let en = { + Notes: "Notes", + Write: "Write", + Chat: "Chat", + Settings: "Settings", + About: "About", + Name: "Name", + UserName: "Username", + User: "User", + PhotoUrl: "Photo URL", + Url: "URL", + Status: "Status", + UserStatus: "User status", + EditPreview: "Editing in preview", + EditPreviewWarn: + "Can cause irreversible text changes, such as breaking code tags", + PublicNote: "Public note", + PublicNoteTitle: "If enabled, note will be visible to all users", + Interface: "Interface", + Language: "Language", + ThirdPartyApi: "Third party API", + OpenAiKey: "OpenAI API key", + Key: "Key", + Preview: "Preview", + NotePlaceholder: + "Your note starts here. You can use markdown, MathJax and GFM.", + NoteName: "Note name", + Publish: "Publish", + Save: "Save", + WriteNote: "Write note", + PubError: "Error in publishing note", + PubErrorMsg: "Note was not published due to an unknown error", + PubErrorMsgNoName: "Note was not published, because it does not have a name.", + PubErrorMsgNoText: "Note was not published, because it does not have a text.", + Back: "Back", + PubNoteNotExist: "This note does not exist", + NoteNotExist: "This note does not exist", + Idontexists: "I don't exist", + PubUrlPlaceholder: + "The link to send a public note. When you click this link, the note will disappear from the server and be saved locally.", + Delete: "Delete", + Open: "Open", + NoNotesYet: "No notes yet", +}; + +export default en; diff --git a/src/localisation/main.js b/src/localisation/main.js new file mode 100644 index 0000000..206d363 --- /dev/null +++ b/src/localisation/main.js @@ -0,0 +1,22 @@ +import ru from "./ru"; +import en from "./en"; + +let Locales = { + ru, + en, + "en-US": en, + "en-AU": en, + "en-BZ": en, + "en-CA": en, + "en-IE": en, + "en-JM": en, + "en-NZ": en, + "en-ZA": en, + "en-TT": en, + "en-GB": en, + "en-US": en, + + "ru-RU": ru, +}; + +export default Locales; diff --git a/src/localisation/ru.js b/src/localisation/ru.js new file mode 100644 index 0000000..25a024a --- /dev/null +++ b/src/localisation/ru.js @@ -0,0 +1,47 @@ +let ru = { + Notes: "Заметки", + Write: "Написать", + Chat: "Чат", + Settings: "Настройки", + About: "Подробнее", + Name: "Имя", + UserName: "Имя пользователя", + User: "Пользователь", + PhotoUrl: "Ссылка на фото", + Url: "Ссылка", + Status: "Статус", + UserStatus: "Статус пользователя", + EditPreview: "Редактирование в предпросмотре", + EditPreviewWarn: + "Может вызывать необратимые изменения текста, например ломает теги кода", + PublicNote: "Публичная заметка", + PublicNoteTitle: "Если включено, то заметка будет видна всем пользователям", + Interface: "Интерфейс", + Language: "Язык", + ThirdPartyApi: "Сторонний API", + OpenAiKey: "OpenAI API ключ", + Key: "Ключ", + Preview: "Предпросмотр", + NotePlaceholder: + "Ваша заметка начинается здесь. Вы можете использовать markdown, MathJax и GFM.", + NoteName: "Название заметки", + Publish: "Опубликовать", + Save: "Сохранить", + WriteNote: "Написать заметку", + PubError: "Ошибка в публикации заметки", + PubErrorMsg: "Заметка не была опубликована из-за неизвестной ошибки", + PubErrorMsgNoName: + "Заметка не была опубликована, так как отсутствует название.", + PubErrorMsgNoText: "Заметка не была опубликована, так как отсутствует текст.", + Back: "Назад", + PubNoteNotExist: "Такой публичной заметки не существует", + NoteNotExist: "Заметки не существует", + Idontexists: "Меня не существует", + PubUrlPlaceholder: + "Ссылка для отправки публичной заметки. При переходе на эту ссылку, заметка исчезнет с сервера и будет сохранена локально.", + Delete: "Удалить", + Open: "Открыть", + NoNotesYet: "Заметок пока нет", +}; + +export default ru; diff --git a/src/pages/create.jsx b/src/pages/create.jsx index 5fcd2c5..74e83a6 100644 --- a/src/pages/create.jsx +++ b/src/pages/create.jsx @@ -3,7 +3,7 @@ import { ChevronDoubleRightIcon } from "@heroicons/react/24/outline"; import { CheckBox } from "../components/checkbox"; import { useState } from "react"; import RenderMarkdown from "../components/markdown"; -import printDate from "../components/utils"; +import { printDate } from "../components/utils"; import rehypeRemark from "rehype-remark/lib"; import ContentEditable from "react-contenteditable"; import ReactDOMServer from "react-dom/server"; @@ -41,11 +41,11 @@ function CreateNote() {

- {`${preview ? "" : "Написать заметку"}`} + {`${preview ? "" : locals.WriteNote}`}

{ setText(localStorage.getItem("NoteText")); @@ -60,7 +60,7 @@ function CreateNote() { className={`mb-2 md:w-1/6 w-full ${inputStyle} ${ preview ? "hidden" : "" }`} - placeholder="Название заметки..." + placeholder={locals.NoteName} maxLength={64} value={localStorage.getItem("NoteName") || ""} onChange={(e) => { @@ -75,7 +75,7 @@ function CreateNote() { ${preview ? "hidden" : ""} `} rows="10" - placeholder="Ваша заметка начинается здесь. Можно использовать markdown..." + placeholder={locals.NotePlaceholder} maxLength={5000} onChange={(e) => { setText(e.target.value); @@ -108,8 +108,8 @@ function CreateNote() {
- {note ? :
Заметки не существует.
} + {note ? :
{locals.NoteNotExists}
} {note && (
{ let notesObj = localStorage.getObj("Notes"); diff --git a/src/pages/notes.jsx b/src/pages/notes.jsx index 2868d27..35b23c0 100644 --- a/src/pages/notes.jsx +++ b/src/pages/notes.jsx @@ -1,6 +1,6 @@ import { ButtonWithIcon } from "../components/button"; import { ChevronDoubleRightIcon } from "@heroicons/react/24/outline"; -import printDate from "../components/utils"; +import { printDate } from "../components/utils"; function Notes() { let notes = Object.entries(localStorage.getObj("Notes")) @@ -23,7 +23,7 @@ function Notes() { href={`/notes/${val[0]}`} reverse={true} icon={ChevronDoubleRightIcon} - text="Перейти" + text={locals.Open} />
@@ -34,7 +34,7 @@ function Notes() { if (notes.length === 0) return (
-

Заметок пока нет

+

{locals.NoNotesYet}

); return notes; diff --git a/src/pages/pubError.jsx b/src/pages/pubError.jsx index 89bed51..1f4e3c4 100644 --- a/src/pages/pubError.jsx +++ b/src/pages/pubError.jsx @@ -1,4 +1,4 @@ -import printDate from "../components/utils"; +import { printDate } from "../components/utils"; import { ChevronDoubleLeftIcon } from "@heroicons/react/24/outline"; import { ButtonWithIcon } from "../components/button"; import { useSearchParams } from "react-router-dom"; @@ -12,22 +12,20 @@ function PubError() {

- Ошибка в публикации заметки + {locals.PubError}

{printDate(Date.now())}
-
- {err ? err : "Заметка не была опубликована из-за неизвестной ошибки"} -
+
{err ? err : locals.PubErrorMsg}
); diff --git a/src/pages/pubNote.jsx b/src/pages/pubNote.jsx index 267ac3a..f42c2da 100644 --- a/src/pages/pubNote.jsx +++ b/src/pages/pubNote.jsx @@ -1,7 +1,7 @@ import RenderMarkdown from "../components/markdown"; import { useState } from "react"; import { Navigate, useParams } from "react-router-dom"; -import printDate from "../components/utils"; +import { printDate } from "../components/utils"; import { ChevronDoubleLeftIcon } from "@heroicons/react/24/outline"; import { ButtonWithIcon } from "../components/button"; diff --git a/src/pages/pubNoteSafe.jsx b/src/pages/pubNoteSafe.jsx index a4ca99f..fd11849 100644 --- a/src/pages/pubNoteSafe.jsx +++ b/src/pages/pubNoteSafe.jsx @@ -9,6 +9,12 @@ function PubNoteSafe() { let params = useParams(); let [note, setNote] = useState(false); + let nullNote = { + text: locals.PubNoteNotExist, + name: locals.Idontexists, + time: Date.now(), + code: 0, + }; if (note === false) fetch(`/get-note/safe/${params.id}`) @@ -20,21 +26,11 @@ function PubNoteSafe() { setNote(data); }) .catch(() => { - setNote({ - text: "Такой публичной заметки не сущуествует", - name: "Меня не существует", - time: Date.now(), - code: 0, - }); + setNote(nullNote); }); }) .catch(() => { - setNote({ - text: "Такой публичной заметки не сущуествует", - name: "Меня не существует", - time: Date.now(), - code: 0, - }); + setNote(nullNote); }); return ( @@ -42,7 +38,7 @@ function PubNoteSafe() { @@ -50,8 +46,7 @@ function PubNoteSafe() {

- Ссылка для отправки публичной заметки. При переходе на эту ссылку, - заметка исчезнет с сервера и будет сохранена локально. + {locals.PubUrlPlaceholder}

- Настройки + {locals.Settings}

- + - + - + { + window.locals = + Locales[window.settings.language] || + Locales[navigator.language] || + Locales[navigator.userLanguage] || + Locales.en; + + reRenderPage(); + }} /> - +