diff --git a/locales/en.json b/locales/en.json
index 68ea126..2b64580 100644
--- a/locales/en.json
+++ b/locales/en.json
@@ -45,6 +45,7 @@
"images": "Images",
"home": "Home",
+ "leaderboard": "Leaderboard",
"profile": "Profile",
"account": "My Account",
"edit_mii": "Edit Mii",
diff --git a/locales/en_uk.json b/locales/en_uk.json
index cee5152..584bfc1 100644
--- a/locales/en_uk.json
+++ b/locales/en_uk.json
@@ -45,6 +45,7 @@
"images": "Images",
"home": "Home",
+ "leaderboard": "Leaderboard",
"profile": "Profile",
"account": "My Account",
"edit_mii": "Edit Mii",
diff --git a/locales/fr_fr.json b/locales/fr_fr.json
new file mode 100644
index 0000000..817e2ae
--- /dev/null
+++ b/locales/fr_fr.json
@@ -0,0 +1,65 @@
+{
+ "name": "Français (France)",
+
+ "welcome": "Bienvenue sur LinkTag !",
+ "join_others": "Rejoingnez {0} autres joueurs qui ont joués à des jeux {1} fois !",
+ "credits": "Crédits",
+ "discord": "Se connecter avec Discord",
+ "carasol_LinkTag": "Linktag de {1}",
+ "supported_platforms": "Plateformes supportées",
+ "banned_reason": "Ce compte a été banni. Raison : {0}",
+ "game_id": "Jeu / ID",
+ "play_time": "Temps de jeu",
+ "last_played": "Dernière session",
+ "play_count": "Nombre de sessions",
+ "user_info": "Information de l'utilisateur",
+ "banned": "Banni",
+ "hidden": "Caché",
+ "administrator": "Administrateur",
+ "moderator": "Modérateur",
+ "donor": "Donateur",
+ "play_log": "Historique de jeu",
+
+ "registered_on": "Inscrit le",
+ "overlay": "Disposition",
+ "background": "Arrière-plan",
+ "coin": "Pièce",
+ "font": "Police",
+ "flag": "Drapeau",
+ "cover_region": "Région de la jaquette",
+ "cover_type": "Type de la jaquette",
+
+ "edit_tag": "Modifier le tag",
+
+ "general": "Général",
+ "display_name": "Nom affiché",
+ "friend_code": "Code ami",
+
+ "cover_region_explanation": "LinkTag essaiera la région du jeu et se rabattra sur l'anglais\ns'il ne trouve pas de jaquette.",
+ "show_avatar": "Afficher l'avatar",
+
+ "select_overlay": "Sélectionner une disposition",
+ "select_background": "Sélectionner un arrière-plan",
+ "select_coin": "Sélectionner une pièce",
+ "select_font": "Sélectionner une police",
+
+ "images": "Images",
+ "donators": "Avantages donateurs",
+ "name_color": "Couleurs de noms",
+
+ "home": "Accueil",
+ "leaderboard": "Leaderboard",
+ "profile": "Profil",
+ "account": "Mon compte",
+ "edit_mii": "Modifier le Mii",
+ "logout": "Déconnexion",
+
+ "search": "Recherche",
+ "previous": "Précédent",
+ "next": "Suivant",
+
+ "playtimes_since": "Joué {0} fois depuis {1}",
+ "total_playtime": "Joué {0} au total",
+
+ "date_format": "DD/MM/YYYY"
+}
diff --git a/locales/hu.json b/locales/hu.json
new file mode 100644
index 0000000..e86583c
--- /dev/null
+++ b/locales/hu.json
@@ -0,0 +1,75 @@
+{
+ "name": "magyar",
+
+ "welcome": "Isten hozott a LinkTag-honlapon!",
+ "join_others": "Csatlakozz {0} másik felhasználóhoz, akik {1} alkalommal játszottak különböző játékokkal!",
+ "credits": "Stáblista",
+ "discord": "Bejelentkezés Discord-fiókkal",
+ "carasol_LinkTag": "{1} LinkTagje",
+ "supported_platforms": "Támogatott platformok",
+ "banned_reason": "Ez a fiók kitiltásra került. A kitiltás oka: {0}",
+ "game_id": "Cím / Azonosító",
+ "play_time": "Játékidő",
+ "last_played": "Legutóbb játszott",
+ "play_count": "Indítások száma",
+ "user_info": "Felhasználóinformáció",
+ "banned": "Kitiltva",
+ "hidden": "Elrejtve",
+ "administrator": "Rendszergazda",
+ "moderator": "Moderátor",
+ "donor": "Támogató",
+ "play_log": "Játéknapló",
+
+ "registered_on": "Regisztráció dátuma",
+ "overlay": "Átfedés",
+ "background": "Háttér",
+ "coin": "Érme",
+ "font": "Betűtípus",
+ "flag": "Zászló",
+ "cover_region": "Borítórégió",
+ "cover_type": "Borítótípus",
+
+ "edit_tag": "LinkTag szerkesztése",
+
+ "general": "Általános",
+ "display_name": "Megjelenített név",
+ "friend_code": "Barátkód",
+
+ "cover_region_explanation": "A LinkTag megpróbálja a megadott régió borítóját megjeleníteni.\nHa ez nem sikerül, akkor az angol borító lesz megjelenítve.",
+ "show_avatar": "Profilkép mutatása",
+
+ "select_overlay": "Módosítás",
+ "select_background": "Módosítás",
+ "select_coin": "Módosítás",
+ "select_font": "Módosítás",
+
+ "images": "Képek",
+ "donators": "Támogatói előnyök",
+ "name_color": "Névszínek",
+
+ "home": "Kezdőlap",
+ "leaderboard": "Ranglista",
+ "profile": "Profil",
+ "account": "Saját fiók",
+ "edit_mii": "Mii szerkesztése",
+ "logout": "Kijelentkezés",
+
+ "search": "Keresés",
+ "previous": "Előző",
+ "next": "Következő",
+
+ "playtimes_since": "{1} óta {0} alkalommal játszott",
+ "total_playtime": "Összesen {0} játszott",
+
+ "guest_mii": "Guest Mii",
+ "cmoc_channel": "Check Mii Out Channel",
+ "upload": "Upload",
+ "cmoc_entry": "Check Mii Out Channel Entry Number",
+ "cmoc_entry_error": "Entry Number must be exactly 12 numbers long (ignoring dashes).",
+ "cmoc_entry_subtext": "You can browse all Miis from the Check Mii Out Channel on mii.rc24.xyz. The entry number can be entered with or without dashes",
+ "save": "Save",
+ "upload_qr": "Upload your Mii binary file or QR code.",
+ "qr_code_subtext": "Some QR codes may not be supported. Known working codes are from 3DS, Wii U, Miitomo, Tomodachi Life and Miitopia (.jpg). Known working binary files are in Wii format (.mae).",
+
+ "date_format": "YYYY. MM. DD."
+}
diff --git a/locales/jp.json b/locales/jp.json
index eb3f74e..23fc974 100644
--- a/locales/jp.json
+++ b/locales/jp.json
@@ -2,7 +2,7 @@
"name": "日本語",
"welcome": "LinkTagへようこそ!",
- "join_others": "ゲームを{0}回プレイしたことがある他の{1}人のゲーマーに参加しよう!",
+ "join_others": "ゲームを{0}回プレイした他の{1}人のゲーマーに参加しよう!",
"discord": "Discordでログイン",
"carasol_LinkTag": "{1}のLinkTag",
"supported_platforms": "対応プラットホーム",
@@ -45,7 +45,6 @@
"home": "ホーム",
"leaderboard": "リーダーボード",
-
"profile": "プロファイル",
"account": "マイアカウント",
"edit_mii": "Miiを編集",
diff --git a/locales/ru.json b/locales/ru.json
new file mode 100644
index 0000000..1aa2144
--- /dev/null
+++ b/locales/ru.json
@@ -0,0 +1,54 @@
+{
+ "account" : "Моя учетная запись",
+ "administrator" : "Администратор",
+ "background" : "Фоновое изображение",
+ "banned" : "Пользователь заблокирован",
+ "banned_reason" : "Эта учетная запись заблокирована. Причина: {0}",
+ "carasol_LinkTag" : "LinkTag пользователя {1}",
+ "coin" : "Валюта",
+ "cover_region" : "Регион обложки",
+ "cover_region_explanation" : "LinkTag попытается найти регион игры и вернётся на английский язык, если приложение не сможет найти обложку игры.",
+ "cover_type" : "Тип обложки",
+ "credits" : "Титры",
+ "date_format" : "DD.MM.YYYY",
+ "discord" : "Войти с помощью Discord",
+ "display_name" : "Отображаемое имя",
+ "donators" : "Преимущества для донаторов",
+ "donor" : "Донаторы",
+ "edit_mii" : "Редактировать Mii",
+ "edit_tag" : "Изменить тег",
+ "flag" : "Флаг",
+ "font" : "Шрифт",
+ "friend_code" : "Код друга",
+ "game_id" : "Игра / ID игры",
+ "general" : "Основное",
+ "hidden" : "Скрытые пользователи",
+ "home" : "Главная",
+ "images" : "Изображения",
+ "join_others" : "Присоединяйтесь к {0} другим игрокам, которые сыграли в игры {1} раз!",
+ "last_played" : "Последняя активность",
+ "leaderboard" : "Таблица лидеров",
+ "logout" : "Выйти",
+ "moderator" : "Модератор",
+ "name" : "Русский",
+ "name_color" : "Имена цветов",
+ "next" : "Далее",
+ "overlay" : "Верхний слой",
+ "play_count" : "Количество запусков",
+ "play_log" : "Игровой журнал",
+ "play_time" : "Времени в игре",
+ "playtimes_since" : "Сыграно {0} раз с {1}",
+ "previous" : "Назад",
+ "profile" : "Профиль",
+ "registered_on" : "Зарегистрирован",
+ "search" : "Поиск",
+ "select_background" : "Выберите фон",
+ "select_coin" : "Выбрать валюту",
+ "select_font" : "Выбрать шрифт",
+ "select_overlay" : "Выбрать верхний слой",
+ "show_avatar" : "Показать аватар",
+ "supported_platforms" : "Поддерживаемые платформы",
+ "total_playtime" : "Всего сыграно {0} раз",
+ "user_info" : "Информация о пользователе",
+ "welcome" : "Добро пожаловать в LinkTag!"
+}
diff --git a/locales/ua.json b/locales/ua.json
new file mode 100644
index 0000000..650ad34
--- /dev/null
+++ b/locales/ua.json
@@ -0,0 +1,53 @@
+{
+ "account" : "Мій обліковий запис",
+ "administrator" : "Адміністратор",
+ "background" : "Фонове зображення",
+ "banned" : "Користувача заблоковано",
+ "banned_reason" : "Цей обліковий запис заблоковано. Причина: {0}",
+ "carasol_LinkTag" : "LinkTag користувача {1}",
+ "coin" : "Валюта",
+ "cover_region" : "Регіон обкладинки",
+ "cover_region_explanation" : "LinkTag спробує визначити регіон гри і повернеться до англійської мови, якщо не зможе знайти її обкладинку.",
+ "cover_type" : "Тип обкладинки",
+ "date_format" : "DD.MM.YYYY",
+ "discord" : "Увійти за допомогою Discord",
+ "display_name" : "Екранне ім' я",
+ "donators" : "Переваги донаторам",
+ "donor" : "Донатор",
+ "edit_mii" : "Редагувати Mii",
+ "edit_tag" : "Редагувати тег",
+ "flag" : "Прапор",
+ "font" : "Шрифт",
+ "friend_code" : "Код друга",
+ "game_id" : "Гра / Ідентифікатор гри",
+ "general" : "Загальне",
+ "hidden" : "Приховані користувачі",
+ "home" : "Головна",
+ "images" : "Зображення",
+ "join_others" : "Приєднуйтесь до {0} інших гравців, які грали в ігри {1} разів!",
+ "last_played" : "Остання активність",
+ "leaderboard" : "Таблиця лідерів",
+ "logout" : "Вийти",
+ "moderator" : "Модератор",
+ "name" : "Українська",
+ "name_color" : "Назви кольорів",
+ "next" : "Далі",
+ "overlay" : "Верхній шар",
+ "play_count" : "Кількість запусків",
+ "play_log" : "Ігровий журнал",
+ "play_time" : "Час у грі",
+ "playtimes_since" : "Зіграно {0} разів з {1}",
+ "previous" : "Назад",
+ "profile" : "Профіль",
+ "registered_on" : "Зареєстрован",
+ "search" : "Пошук",
+ "select_background" : "Виберіть фон",
+ "select_coin" : "Виберіть валюту",
+ "select_font" : "Обрати шрифт",
+ "select_overlay" : "Обрати поверхню",
+ "show_avatar" : "Показати аватар",
+ "supported_platforms" : "Підтримувані платформи",
+ "total_playtime" : "Всього зіграно {0} разів",
+ "user_info" : "Інформація про користувача",
+ "welcome" : "Вітаємо в LinkTag!"
+}
diff --git a/src/components/edit/SelectCoinModal.jsx b/src/components/edit/SelectCoinModal.jsx
index a0e5f96..5021c4f 100644
--- a/src/components/edit/SelectCoinModal.jsx
+++ b/src/components/edit/SelectCoinModal.jsx
@@ -1,6 +1,7 @@
import PropTypes from 'prop-types'
import { React, useState } from 'react'
import { Button, Card, Col, Modal, Row } from 'react-bootstrap'
+import LocalizedString from '@/components/shared/LocalizedString'
function SelectCoinModal ({ options, field, form }) {
const [show, setShow] = useState(false)
@@ -15,7 +16,7 @@ function SelectCoinModal ({ options, field, form }) {
return (
<>
diff --git a/src/components/edit/SelectFontModal.jsx b/src/components/edit/SelectFontModal.jsx
index 1342283..0bc8628 100644
--- a/src/components/edit/SelectFontModal.jsx
+++ b/src/components/edit/SelectFontModal.jsx
@@ -1,6 +1,7 @@
import PropTypes from 'prop-types'
import { React, useState } from 'react'
import { Button, Card, Col, Modal, Row } from 'react-bootstrap'
+import LocalizedString from '@/components/shared/LocalizedString'
function SelectFontModal ({ options, field, form }) {
const [show, setShow] = useState(false)
@@ -15,7 +16,7 @@ function SelectFontModal ({ options, field, form }) {
return (
<>
diff --git a/src/components/mii/EditYourMiiCard.jsx b/src/components/mii/EditYourMiiCard.jsx
index 3de4b9f..a017297 100644
--- a/src/components/mii/EditYourMiiCard.jsx
+++ b/src/components/mii/EditYourMiiCard.jsx
@@ -9,221 +9,226 @@ import { Formik } from 'formik'
import GuestMiiForm from './GuestMiiForm'
import CmocForm from './CmocForm'
import MiiUploadForm from './MiiUploadForm'
+import LanguageContext from '@/components/shared/LanguageContext'
function EditYourMiiCard ({ miiInfo }) {
const [miiPreviewCount, setMiiPreviewCount] = useState(0)
return (
-
- Edit your Mii
-
- {
- const errors = {}
+
+ {(lang) => (
+
+ Edit your Mii
+
+ {
+ const errors = {}
- if (
- values.miiType === MII_TYPE.CMOC &&
- values.cmocEntryNo.replaceAll('-', '').length !== 12
- ) {
- errors.cmocEntryNo =
- 'Entry Number must be exactly 12 numbers long (ignoring dashes).'
- }
-
- if (values.miiType === MII_TYPE.UPLOAD) {
- if (values.file === null) {
- errors.file = 'Please choose a file.'
- } else if (values.file.type !== 'image/jpeg') {
- if (
- !isBlank(values.file.type) ||
- !values.file.name.endsWith('.mae')
- ) {
- errors.file = 'This file is not supported.'
- } else if (values.file.size !== 74) {
- errors.file = 'File is too big.'
- }
+ if (
+ values.miiType === MII_TYPE.CMOC &&
+ values.cmocEntryNo.replaceAll('-', '').length !== 12
+ ) {
+ errors.cmocEntryNo =
+ 'Entry Number must be exactly 12 numbers long (ignoring dashes).'
}
- }
- return errors
- }}
- onSubmit={async (values, { setSubmitting, setFieldError }) => {
- const handleJsonForm = async () => {
- const body = {
- miiType: values.miiType
+ if (values.miiType === MII_TYPE.UPLOAD) {
+ if (values.file === null) {
+ errors.file = 'Please choose a file.'
+ } else if (values.file.type !== 'image/jpeg') {
+ if (
+ !isBlank(values.file.type) ||
+ !values.file.name.endsWith('.mae')
+ ) {
+ errors.file = 'This file is not supported.'
+ } else if (values.file.size !== 74) {
+ errors.file = 'File is too big.'
+ }
+ }
}
- switch (values.miiType) {
- case MII_TYPE.GUEST: {
- body.guestMii = values.guestMii
- break
- }
- case MII_TYPE.CMOC: {
- body.cmocEntryNo = values.cmocEntryNo
- break
+ return errors
+ }}
+ onSubmit={async (values, { setSubmitting, setFieldError }) => {
+ const handleJsonForm = async () => {
+ const body = {
+ miiType: values.miiType
}
- default: {
- break
+
+ switch (values.miiType) {
+ case MII_TYPE.GUEST: {
+ body.guestMii = values.guestMii
+ break
+ }
+ case MII_TYPE.CMOC: {
+ body.cmocEntryNo = values.cmocEntryNo
+ break
+ }
+ default: {
+ break
+ }
}
- }
- // Validate CMOC entry first
- if (values.miiType === MII_TYPE.CMOC) {
- const cmocResponse = await fetch(
- `/api/cmoc/${values.cmocEntryNo}`
- )
- if (cmocResponse.status !== 200) {
- setFieldError(
- 'cmocEntryNo',
- 'Mii not found in Check Mii Out Channel'
+ // Validate CMOC entry first
+ if (values.miiType === MII_TYPE.CMOC) {
+ const cmocResponse = await fetch(
+ `/api/cmoc/${values.cmocEntryNo}`
)
- setSubmitting(false)
- return null
+ if (cmocResponse.status !== 200) {
+ setFieldError(
+ 'cmocEntryNo',
+ 'Mii not found in Check Mii Out Channel'
+ )
+ setSubmitting(false)
+ return null
+ }
}
- }
- return fetch('/api/account/mii', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json'
- },
- body: JSON.stringify(body)
- })
- }
+ return fetch('/api/account/mii', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify(body)
+ })
+ }
- const handleMultiPartForm = async () => {
- const formData = new FormData()
- formData.append('file', values.file)
+ const handleMultiPartForm = async () => {
+ const formData = new FormData()
+ formData.append('file', values.file)
- return fetch('/api/account/mii-upload', {
- method: 'POST',
- body: formData
- })
- }
+ return fetch('/api/account/mii-upload', {
+ method: 'POST',
+ body: formData
+ })
+ }
- toast.promise(
- values.miiType === MII_TYPE.UPLOAD
- ? handleMultiPartForm()
- : handleJsonForm(),
- {
- pending: 'Updating Mii...',
- success: {
- render ({ data, toastProps }) {
- if (data.status !== 200) {
- toastProps.type = 'error'
- if (data.status === 413) {
- return 'This file is too big, sorry'
- }
- if (
- data.status === 400 &&
- values.miiType === MII_TYPE.UPLOAD
- ) {
- return 'This does not appear to be a supported Mii'
+ toast.promise(
+ values.miiType === MII_TYPE.UPLOAD
+ ? handleMultiPartForm()
+ : handleJsonForm(),
+ {
+ pending: 'Updating Mii...',
+ success: {
+ render ({ data, toastProps }) {
+ if (data.status !== 200) {
+ toastProps.type = 'error'
+ if (data.status === 413) {
+ return 'This file is too big, sorry'
+ }
+ if (
+ data.status === 400 &&
+ values.miiType === MII_TYPE.UPLOAD
+ ) {
+ return 'This does not appear to be a supported Mii'
+ }
+ return 'An error occured, please try again later'
}
- return 'An error occured, please try again later'
+ setMiiPreviewCount((previous) => previous + 1)
+ return 'Saved!'
}
- setMiiPreviewCount((previous) => previous + 1)
- return 'Saved!'
- }
- },
- error: 'An error occured, please try again later.'
- }
- )
- setSubmitting(false)
- }}
- >
- {({
- values,
- errors,
- touched,
- handleChange,
- handleBlur,
- setFieldValue,
- handleSubmit,
- isSubmitting
- }) => (
-
-
-
+
+
+
+
+
+
+
+
+ )}
+
+
+
+ ) }
+
)
}
diff --git a/src/components/shared/AppNavbar.jsx b/src/components/shared/AppNavbar.jsx
index 72ee9d5..f031f6f 100644
--- a/src/components/shared/AppNavbar.jsx
+++ b/src/components/shared/AppNavbar.jsx
@@ -9,7 +9,11 @@ import LocalizedString from './LocalizedString'
const flags = {
en: '/img/flag/us.png',
en_uk: '/img/flag/eu.png',
- jp: '/img/flag/jp.png'
+ jp: '/img/flag/jp.png',
+ hu: '/img/flag/hu.png',
+ fr_fr: '/img/flag/fr.png',
+ ru: '/img/flag/ru.png',
+ ua: '/img/flag/ua.png'
}
function AppNavbar () {
@@ -54,7 +58,7 @@ function AppNavbar () {
- Leaderboard
+