Add language selector

This commit is contained in:
Karim 2022-09-07 10:53:52 +02:00
parent bb27412d38
commit 50219ad15b
18 changed files with 244 additions and 3 deletions

18
package-lock.json generated
View file

@ -8,6 +8,7 @@
"name": "ryujinx-website",
"version": "3.0.0",
"dependencies": {
"@headlessui/vue": "^1.7.0",
"@heroicons/vue": "^1.0.6",
"axios": "^0.27.2",
"dayjs": "^1.11.5",
@ -81,6 +82,17 @@
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
},
"node_modules/@headlessui/vue": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/@headlessui/vue/-/vue-1.7.0.tgz",
"integrity": "sha512-ClrXMThmo9lrFjHdzDQXsopjCgRA28v+u5s/J+gIAgvS5l3tTAI84GaVghFwxobijL9c6BsVgDQ7SrJ2dS1nLw==",
"engines": {
"node": ">=10"
},
"peerDependencies": {
"vue": "^3.2.0"
}
},
"node_modules/@heroicons/vue": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/@heroicons/vue/-/vue-1.0.6.tgz",
@ -3341,6 +3353,12 @@
"strip-json-comments": "^3.1.1"
}
},
"@headlessui/vue": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/@headlessui/vue/-/vue-1.7.0.tgz",
"integrity": "sha512-ClrXMThmo9lrFjHdzDQXsopjCgRA28v+u5s/J+gIAgvS5l3tTAI84GaVghFwxobijL9c6BsVgDQ7SrJ2dS1nLw==",
"requires": {}
},
"@heroicons/vue": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/@heroicons/vue/-/vue-1.0.6.tgz",

View file

@ -12,7 +12,8 @@
"vue-i18n": "^9.2.2",
"@heroicons/vue": "^1.0.6",
"axios": "^0.27.2",
"dayjs": "^1.11.5"
"dayjs": "^1.11.5",
"@headlessui/vue": "^1.7.0"
},
"devDependencies": {
"@vitejs/plugin-vue": "^3.0.2",

Binary file not shown.

After

Width:  |  Height:  |  Size: 285 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View file

@ -1,6 +1,7 @@
<script setup lang="ts">
import BaseNavigation from "@/common/components/navigations/BaseNavigation.vue";
import SocialIconList from "@/modules/SocialIconList.vue";
import LanguageSelector from "@/modules/LanguageSelector.vue";
import { navigations } from "@/common/constants/navigation";
</script>
@ -21,6 +22,8 @@ import { navigations } from "@/common/constants/navigation";
<div class="flex items-center justify-center space-x-3">
<SocialIconList />
<LanguageSelector />
</div>
</div>
</div>

View file

@ -3,6 +3,7 @@ import { useI18n } from "vue-i18n";
import BaseNavigation from "@/common/components/navigations/BaseNavigation.vue";
import SocialIconList from "@/modules/SocialIconList.vue";
import LanguageSelector from "@/modules/LanguageSelector.vue";
import { navigations } from "@/common/constants/navigation";
const { t } = useI18n();
@ -40,6 +41,8 @@ const { t } = useI18n();
<div class="flex items-center justify-center space-x-3">
<SocialIconList />
</div>
<LanguageSelector />
</div>
</div>
</header>

View file

@ -0,0 +1,16 @@
import { Language } from "@/types";
export const availableLanguages: Language[] = [
{
id: 0,
tag: "en",
name: "English",
image: "/assets/images/flags/uk.png",
},
{
id: 1,
tag: "fr",
name: "Français",
image: "/assets/images/flags/fr.png",
},
];

View file

@ -1,12 +1,35 @@
import { createI18n } from "vue-i18n";
import { en } from "@/i18n/locales/en";
import { fr } from "@/i18n/locales/fr";
import { availableLanguages } from "@/common/constants/languages";
let locale = "en";
try {
const storeValue = localStorage.getItem("lang");
if (storeValue !== null) {
const lang = JSON.parse(storeValue as string);
locale = lang.tag;
} else {
if (navigator.language.startsWith("fr")) {
locale = "fr";
localStorage.setItem("lang", JSON.stringify(availableLanguages[1]));
} else {
localStorage.setItem("lang", JSON.stringify(availableLanguages[0]));
}
}
} catch (e) {
console.error("Invalid lang:" + e);
}
export const i18n = createI18n({
legacy: false,
locale: "en",
locale: locale,
fallbackLocale: "en",
messages: {
en,
fr,
},
});

View file

@ -0,0 +1,4 @@
{
"getStarted": "Démarrer",
"contribute": "Contribuer"
}

View file

@ -0,0 +1,8 @@
{
"title1": "Un émulateur simple et expérimental pour {0}",
"title2": "Nintendo Switch",
"description": "Ryujinx est un émulateur open source Nintendo Switch créé par {0} et écrit en C#. Il a pour but d'être précis et performant tout en ayant une interface conviviale et des versions régulières.",
"author": "gdkchan",
"getStarted": "Démarrer",
"contribute": "Contribuer"
}

View file

@ -0,0 +1,17 @@
import navigations from "./navigations.json";
import footer from "./footer.json";
import header from "./header.json";
import homepage from "./views/homepage.json";
import download from "./views/download.json";
import contribute from "./views/contribute.json";
export const fr = {
navigations: navigations,
header: header,
footer: footer,
views: {
homepage: homepage,
download: download,
contribute: contribute
},
};

View file

@ -0,0 +1,7 @@
{
"blog": "Blog",
"download": "Télécharger",
"guide": "Guide",
"faq": "FAQ",
"compatibility": "Compatibilité"
}

View file

@ -0,0 +1,12 @@
{
"title1": "Aidez-nous à créer le {0}",
"title2": "meilleur émulateur pour switch",
"subTitle": "Créée par une équipe passionnée, Ryujinx est en développement actif et toute aide est appréciée pour la maintenir.",
"titleContribute": " Comment puis-je contribuer ?",
"areaDevTitle": "Aider au Développement",
"areaDevDescription": "Si vous avez de l'expérience avec le C#, les Homebrew, le design graphique, l'assurance qualité logicielle ou le test logiciel, la gestion de serveur Discord ou n'importe quelle autre compétence que vous pensez utiles pour le projet Ryujinx, veuillez nous contacter sur notre serveur Discord.",
"joinDiscord": "Rejoignez notre Discord",
"becomePatron": "Devenez un Patron",
"areaDonationTitle": "Aider avec les Dons",
"areaDonationDescription": "Si vous ne pouvez pas aider avec l'expérience de développement, il y a d'autres moyens de nous soutenir. Bien que les dons monétaires ne soient en aucun cas nécessaire, nous les apprécions. Ils financeront l\"équipements nécessaire. En retour, il y certaines récompenses que vous recevrez en tant que supporter (l'accès à un canal réservé sur notre Discord)."
}

View file

@ -0,0 +1,22 @@
{
"title1": "Dernier {0}",
"title2": "Télécharger",
"subTitle": "N'oubliez pas de consulter {0} après l'installation",
"startupGuide": "le guide de démarrage",
"download": "Télécharger",
"notSupported": "Actuellement non supporté",
"supportPlanned": "Support prévu",
"supportWindows": "Pour Windows 10 & 11",
"supportLinux": "Pour les distributions Linux les plus courantes",
"buildInformation": "Information sur la version",
"buildRelease": "Cette version a été publiée le {0}",
"assets": "ressources",
"downloads": "téléchargements",
"tag": "Étiquette",
"manualDownload": "Téléchargement manuel",
"olderBuilds": "Anciennes versions",
"ldnBuildTitle": "Vous recherchez la {0} ?",
"ldnBuild": "version LDN",
"ldnBuildDescription": "Rendez-vous sur notre Patreon pour plus d'informations avec le lien de téléchargement gratuit",
"learnMore": "En savoir plus"
}

View file

@ -0,0 +1,26 @@
{
"ourTeam": "Notre équipe",
"ourTeamDescription": "Ces développeurs travaillent sans relâche pour construire le meilleur émulateur pour Switch.",
"aboutProject": "À propos du projet",
"featureDescription": " Écrit à partir de zéro, le développement a commencé en 2017 et continue toujours.",
"openSource": "Open source",
"openSourceDescription": "Développé par une équipe de passionnés, le code source de l'émulateur est disponible sur {0}.",
"github": "GitHub",
"crossPlatform": "Multiplateforme",
"crossPlatformDescription": "Ryujinx est actuellement disponible pour les Windows 10/11 et Linux (le support macOS est prévu).",
"compatibility": "Compatibilité",
"compatibilityDescription": "Ryujinx a été testé sur 3.600 jeux, et près de 2.700 sont considérés comme jouables.",
"support": "Soutien",
"supportDescription": "Besoin d'aide ? Rejoignez-le {0} pour obtenir de l'aide ainsi que pour discuter avec d'autres passionnés d'émulation et l'équipe de développement.",
"discord": "serveur Discord Ryujinx",
"supportUs": "Nous soutenir",
"trustedCommunities": "Adopté par la communauté",
"trustedCommunitiesDescription": "Si vous avez des contributions, des suggestions, besoin d'aide pour utiliser l'émulateur ou si vous souhaitez simplement entrer en contact avec l'équipe. Contactez-nous sur Twitter ou Discord ;)",
"githubStar": "Étoiles GitHub",
"playableGames": "Jeux jouables",
"patreonContributors": "Contributeurs Patreon",
"nameQuestion": "Pourquoi le {0} ?",
"name": "nom",
"nameDescription": "Prononcé {0}. Il est basé sur le nom \"Ryujin\", un mythique dieu/dragon de la mer. NX provient du nom de code interne de la Switch.",
"spelled": "Ree-You-Jinx"
}

View file

@ -0,0 +1,75 @@
<template>
<Menu as="div" class="relative inline-block">
<MenuButton
id="tk-dropdown-layouts-user"
type="button"
class="inline-flex justify-center items-center border font-semibold focus:outline-none px-3 py-2 leading-5 rounded border-gray-900 bg-gray-700 shadow-sm hover:bg-opacity-50 hover:shadow focus:ring focus:ring-gray-500 focus:ring-opacity-25 active:bg-opacity-100 active:shadow-none"
>
<img class="w-5 h-5" :src="availableLanguages[getCurrentLang()].image" :alt="availableLanguages[getCurrentLang()].name">
</MenuButton>
<!-- Dropdown -->
<transition
enter-active-class="transition ease-out duration-150"
enter-from-class="transform opacity-0 scale-75"
enter-to-class="transform opacity-100 scale-100"
leave-active-class="transition ease-in duration-100"
leave-from-class="transform opacity-100 scale-100"
leave-to-class="transform opacity-0 scale-75"
>
<MenuItems
ref="languageDropdown"
role="navigation"
aria-labelledby="tk-dropdown-simple"
class="absolute right-0 origin-top-right mt-2 w-48 shadow-xl rounded"
>
<div
class="bg-white ring-1 ring-black ring-opacity-5 rounded divide-y divide-gray-100"
>
<MenuItem
v-for="language in availableLanguages"
:key="language.name"
@click="changeLang(language)"
>
<div class="p-2 space-y-1">
<a
role="menuitem"
href="javascript:void(0)"
class="flex items-center space-x-2 rounded py-2 px-3 text-sm font-medium text-gray-600 hover:bg-gray-100 hover:text-gray-700 focus:outline-none focus:bg-gray-100 focus:text-gray-700"
>
<img class="w-5 h-5 object-center" :src="language.image" :alt="language.name">
<span>{{ language.name }}</span>
</a>
</div>
</MenuItem>
</div>
</MenuItems>
</transition>
</Menu>
</template>
<script setup lang="ts">
import { Menu, MenuButton, MenuItems, MenuItem } from "@headlessui/vue";
import { availableLanguages } from "@/common/constants/languages";
import { Language } from "@/types";
const getCurrentLang = () => {
try {
const storeValue = localStorage.getItem("lang");
const lang = JSON.parse(storeValue as string);
if (lang == undefined) {
return 0;
}
return lang.id;
} catch (e) {
console.error("Invalid lang:" + e);
}
return 0;
};
const changeLang = (language: Language) => {
localStorage.setItem("lang", JSON.stringify(language));
location.reload();
};
</script>

6
src/types/app/i18n.ts Normal file
View file

@ -0,0 +1,6 @@
export type Language = {
id: number;
tag: string;
name: string;
image: string;
};

View file

@ -1,4 +1,4 @@
export * from "./app/i18n";
export * from "./generic/navigation";
export * from "./generic/teams";
export * from "./response/github";