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 - }) => ( -
- setFieldValue('miiType', k)} - > - - - - - - - Mii Preview - - + }, + error: 'An error occured, please try again later.' + } + ) + setSubmitting(false) + }} + > + {({ + values, + errors, + touched, + handleChange, + handleBlur, + setFieldValue, + handleSubmit, + isSubmitting + }) => ( + + setFieldValue('miiType', k)} + > + + + + + + + Mii Preview + + - - - - - - Mii Preview - - + + + + + + Mii Preview + + - - - -
-
- -
- - )} -
-
-
+ + + +
+
+ +
+ + )} +
+
+
+ ) } + ) } 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 +