Add i18n support for data

This commit is contained in:
BlossomiShymae
2024-09-09 15:58:00 -05:00
parent b0491d569a
commit 90de82ba20
18 changed files with 210 additions and 41 deletions

54
composables/useLocale.ts Normal file
View File

@@ -0,0 +1,54 @@
const locales = {
"ar_ae": "Arabic (United Arab Emirates)",
"cs_cz": "Czech (Czech Republic)",
"de_de": "German (Germany)",
"default": "English (United States)",
"el_gr": "Greek (Greece)",
"en_au": "English (Australia)",
"en_gb": "English (United Kingdom)",
"en_ph": "English (Philippines)",
"en_sg": "English (Singapore)",
"es_ar": "Spanish (Argentina)",
"es_es": "Spanish (Spain)",
"es_mx": "Spanish (Mexico)",
"fr_fr": "French (France)",
"hu_hu": "Hungarian (Hungary)",
"it_it": "Italian (Italy)",
"ja_jp": "Japanese (Japan)",
"ko_kr": "Korean (South Korea)",
"pl_pl": "Polish (Poland)",
"pt_br": "Portuguese (Brazil)",
"ro_ro": "Romanian (Romania)",
"ru_ru": "Russian (Russia)",
"th_th": "Thai (Thailand)",
"tr_tr": "Turkish (Turkey)",
"vi_vn": "Vietnamese (Vietnam)",
"zh_cn": "Chinese",
"zh_my": "Chinese (Malaysia)",
"zh_tw": "Chinese (Taiwan)"
};
const currentLocale = ref(getLocale());
function getLocale(): string {
var currentLocale: string | null = localStorage.getItem("locale");
if (currentLocale == null) {
currentLocale = "default";
setLocale(currentLocale);
}
return currentLocale;
}
function setLocale(locale: string): void {
localStorage.setItem("locale", locale);
currentLocale.value = locale;
}
export default function useLocale() {
return {
locales,
currentLocale,
setLocale
};
}

View File

@@ -73,6 +73,9 @@
<a class="text-decoration-none text-light" href="https://github.com/BlossomiShymae/clean-cuts" referrerpolicy="no-referrer">
<MaterialIcon name="github" :size="24" /> GitHub
</a>
<NuxtLink class="text-decoration-none text-light" to="/settings">
<MaterialIcon name="earth" :size="24" /> Settings
</NuxtLink>
<a class="text-decoration-none text-light" href="https://blossomishymae.github.io/" referrerpolicy="no-referrer">blossomishymae.github.io</a>
<a class="text-decoration-none text-light" href="https://communitydragon.org" referrerpolicy="no-referrer">CommunityDragon</a>
<!-- <a class="text-decoration-none text-light" href="https://discord.com/invite/riotgamesdevrel" referrerpolicy="no-referrer">DevRel Discord</a> -->

5
package-lock.json generated
View File

@@ -10,6 +10,7 @@
"aos": "^2.3.4",
"axios": "^1.6.8",
"nuxt": "^3.11.2",
"nuxt-app": "file:",
"vue": "^3.4.21",
"vue-router": "^4.3.0"
},
@@ -7507,6 +7508,10 @@
}
}
},
"node_modules/nuxt-app": {
"resolved": "",
"link": true
},
"node_modules/nypm": {
"version": "0.3.8",
"resolved": "https://registry.npmjs.org/nypm/-/nypm-0.3.8.tgz",

View File

@@ -13,6 +13,7 @@
"aos": "^2.3.4",
"axios": "^1.6.8",
"nuxt": "^3.11.2",
"nuxt-app": "file:",
"vue": "^3.4.21",
"vue-router": "^4.3.0"
},

View File

@@ -37,9 +37,15 @@
<script setup lang="ts">
import useClient from '../../composables/useClient';
import useLocale from "../../composables/useLocale";
const { client } = useClient();
const { currentLocale } = useLocale();
const getSummaries = async () => (await client.championSummaries.listAsync({locale: currentLocale.value, version: "latest"}))
.filter((x) => x.id != -1);
const summaries = (await client.championSummaries.listAsync({locale: "default", version: "latest"}))
.filter((x) => x.id != -1);
const summaries = ref(await getSummaries());
watch(currentLocale, async () => {
summaries.value = await getSummaries();
});
</script>

View File

@@ -49,14 +49,22 @@
import Badge from '~/components/Badge.vue';
import { useRoute } from 'vue-router';
import useClient from '../../../composables/useClient';
import useLocale from '~/composables/useLocale';
const route = useRoute();
const id = route.params.id as unknown;
const { client } = useClient();
const champion = await client.champions.getAsync(id as number, {locale: "default", version: "latest"});
const currentSkin = ref(champion.skins[0].getLoadScreen('latest'));
const { currentLocale } = useLocale();
const getChampion = async () => await client.champions.getAsync(id as number, {locale: currentLocale.value, version: "latest"});
const champion = ref(await getChampion());
watch(currentLocale, async () => {
champion.value = await getChampion();
});
const currentSkin = ref(champion.value.skins[0].getLoadScreen('latest'));
const swapLoadScreen = (id: number) => {
currentSkin.value = champion.skins.find((x) => x.id == id)?.getLoadScreen('latest') as string;
currentSkin.value = champion.value.skins.find((x) => x.id == id)?.getLoadScreen('latest') as string;
}
</script>

View File

@@ -50,23 +50,29 @@
<script setup lang="ts">
import Pagination from "../../components/Pagination.vue";
import useClient from "../../composables/useClient";
import useLocale from "~/composables/useLocale";
import useIsNumeric from "../../composables/useIsNumeric";
import usePagination from "../../composables/usePagination";
const { client } = useClient();
const { currentLocale } = useLocale();
const getCompanions = async () => (await client.companions.listAsync({locale: currentLocale.value, version: "latest"}))
.sort((a, b) => a.itemId - b.itemId);
const query = ref("");
const companions = (await client.companions.listAsync({locale: "default", version: "latest"}))
.sort((a, b) => a.itemId - b.itemId);
const companions = ref(await getCompanions());
watch(currentLocale, async() => {
companions.value = await getCompanions();
});
const { isNumeric } = useIsNumeric();
const p = computed(() => {
let filtered = [];
if (isNumeric(query.value))
filtered = companions.filter((x) => x.itemId == parseInt(query.value, 10));
filtered = companions.value.filter((x) => x.itemId == parseInt(query.value, 10));
else
filtered = companions.filter((x) => x.name.toLowerCase().includes(query.value.toLowerCase()));
filtered = companions.value.filter((x) => x.name.toLowerCase().includes(query.value.toLowerCase()));
return usePagination(filtered, 100);
})

View File

@@ -19,6 +19,7 @@
<script setup lang="ts">
import Badge from "../../../components/Badge.vue";
import useClient from "../../../composables/useClient";
import useLocale from "~/composables/useLocale";
import { Companion } from "~/core/models";
import { useRoute } from "vue-router";
@@ -26,7 +27,13 @@ const route = useRoute();
const id = route.params.id as unknown;
const { client } = useClient();
const { currentLocale } = useLocale();
const getCompanions = async () => await client.companions.listAsync({locale: currentLocale.value, version: "latest"});
const companions = await client.companions.listAsync({locale: "default", version: "latest"});
const companion = companions.find((x) => x.itemId == id) || new Companion({});
const companions = ref(await getCompanions());
watch(currentLocale, async() => {
companions.value = await getCompanions();
});
const companion = companions.value.find((x) => x.itemId == id) || new Companion({});
</script>

View File

@@ -43,7 +43,14 @@
<script setup lang="ts">
import useClient from '../../composables/useClient';
import useLocale from '~/composables/useLocale';
const { client } = useClient();
const items = await client.items.listAsync({ locale: "default", version: "latest"});
const { currentLocale } = useLocale();
const getItems = async () => await client.items.listAsync({ locale: currentLocale.value, version: "latest"});
const items = ref(await getItems());
watch(currentLocale, async () => {
items.value = await getItems();
});
</script>

View File

@@ -47,6 +47,7 @@
<script setup lang="ts">
import { useRoute } from 'vue-router';
import useClient from '../../../composables/useClient';
import useLocale from '~/composables/useLocale';
import { Item } from '~/core/models';
import Badge from '~/components/Badge.vue';
@@ -54,12 +55,15 @@ const route = useRoute();
const id = route.params.id as unknown;
const { client } = useClient();
const items = await client.items.listAsync({locale: "default", version: "latest"});
const { currentLocale } = useLocale();
const getItems = async () => await client.items.listAsync({locale: currentLocale.value, version: "latest"});
const items = ref(await getItems());
const _default = new Item({});
const item = items.find((x) => x.id == id) || _default;
const components = item.from.map((id) => items.find((x) => x.id == id) || _default);
const composites = item.to.map((id) => items.find((x) => x.id == id) || _default);
const item = computed(() => items.value.find((x) => x.id == id) || _default);
const components = computed(() => item.value.from.map((id) => items.value.find((x) => x.id == id) || _default));
const composites = computed(() => item.value.to.map((id) => items.value.find((x) => x.id == id) || _default));
</script>

View File

@@ -41,42 +41,51 @@
import MaterialIcon from '../../components/MaterialIcon.vue';
import Pagination from "../../components/Pagination.vue";
import useClient from '../../composables/useClient';
import useLocale from '~/composables/useLocale';
import useIsNumeric from "../../composables/useIsNumeric";
import usePagination from '../../composables/usePagination';
import { Loot } from '../../core/models';
const { client } = useClient();
const { currentLocale } = useLocale();
const query = ref("");
const filter = ref("");
const getLoots = async () => (await client.loots.listAsync({locale: currentLocale.value, version: "latest"}))
.sort((a, b) => a.id.localeCompare(b.id))
.filter((x) => x.id != "");
const getSummaries = async () => await client.championSummaries.listAsync({locale: currentLocale.value, version: "latest"});
const clearFilter = () => filter.value = "";
const applyFilter = (category: string) => filter.value = category;
// Alphanumerically sort by id, remove null entries
const loots = (await client.loots.listAsync({locale: "default", version: "latest"}))
.sort((a, b) => a.id.localeCompare(b.id))
.filter((x) => x.id != "");
const loots = ref(await getLoots());
const categories = new Set(loots.map((x) => x.type));
const categories = new Set(loots.value.map((x) => x.type));
const { isNumeric } = useIsNumeric();
const p = computed(() => {
let filtered = [];
filtered = loots.filter((x) => x.name.toLowerCase().includes(query.value.toLowerCase()));
filtered = loots.value.filter((x) => x.name.toLowerCase().includes(query.value.toLowerCase()));
if (filter.value != "")
filtered = loots.filter((x) => x.type == filter.value);
filtered = loots.value.filter((x) => x.type == filter.value);
return usePagination(filtered, 100);
});
const summaries = await client.championSummaries.listAsync({locale: "default", version: "latest"});
const summaries = ref(await getSummaries());
const getLootImage = (loot: Loot) => {
if (loot.type.includes('Statstone'))
return summaries.find((x) => loot.name.toLowerCase().includes(x.name.toLowerCase()))?.getIcon({locale: "default", version: "latest"});
return summaries.value.find((x) => loot.name.toLowerCase().includes(x.name.toLowerCase()))?.getIcon({locale: "default", version: "latest"});
return loot.getImage('latest');
}
watch(currentLocale, async() => {
loots.value = await getLoots();
summaries.value = await getSummaries();
});
</script>

View File

@@ -35,8 +35,15 @@
<script setup lang="ts">
import useClient from '../../composables/useClient';
import useLocale from '~/composables/useLocale';
const { client } = useClient();
const runes = (await client.perks.listAsync({locale: "default", version: "latest"}))
.sort((a, b) => a.id - b.id);
const { currentLocale } = useLocale();
const getRunes = async () => (await client.perks.listAsync({locale: currentLocale.value, version: "latest"}))
.sort((a, b) => a.id - b.id)
const runes = ref(await getRunes());
watch(currentLocale, async() => {
runes.value = await getRunes();
});
</script>

20
pages/settings.vue Normal file
View File

@@ -0,0 +1,20 @@
<template>
<div>
<div class="row">
<h1 class="display-4 mb-4">Settings</h1>
<div class="d-flex flex-column justify-items-stretch gap-1">
<div v-for="(value, key, index) in locales">
<button class="btn border border-1 w-100" :class="{'btn-secondary': currentLocale == key}" @click="setLocale(key)" >
{{ value }}
</button>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import useLocale from "../composables/useLocale";
const { locales, currentLocale, setLocale } = useLocale();
</script>

View File

@@ -31,23 +31,29 @@
import Pagination from '../../components/Pagination.vue';
import Badge from '~/components/Badge.vue';
import useClient from '../../composables/useClient';
import useLocale from '~/composables/useLocale';
import useIsNumeric from '../../composables/useIsNumeric';
import usePagination from '../../composables/usePagination';
const { client } = useClient();
const { currentLocale } = useLocale();
const getEmotes = async () => (await client.summonerEmotes.listAsync({locale: currentLocale.value, version: "latest"}))
.sort((a, b) => a.id - b.id);
const query = ref("");
const emotes = (await client.summonerEmotes.listAsync({locale: "default", version: "latest"}))
.sort((a, b) => a.id - b.id);
const emotes = ref(await getEmotes());
watch(currentLocale, async() => {
emotes.value = await getEmotes();
});
const { isNumeric } = useIsNumeric();
const p = computed(() => {
let filtered = [];
if (isNumeric(query.value))
filtered = emotes.filter((x) => x.id == parseInt(query.value, 10));
filtered = emotes.value.filter((x) => x.id == parseInt(query.value, 10));
else
filtered = emotes.filter((x) => x.name.toLowerCase().includes(query.value.toLowerCase()));
filtered = emotes.value.filter((x) => x.name.toLowerCase().includes(query.value.toLowerCase()));
return usePagination(filtered, 24);
})

View File

@@ -49,23 +49,29 @@
<script setup lang="ts">
import Pagination from '~/components/Pagination.vue';
import useClient from '../../composables/useClient';
import useLocale from '~/composables/useLocale';
import usePagination from '../../composables/usePagination';
import useIsNumeric from '../../composables/useIsNumeric';
const { client } = useClient();
const { currentLocale } = useLocale();
const getIcons = async () => (await client.summonerIcons.listAsync({locale: currentLocale.value, version: "latest"}))
.sort((a, b) => a.id - b.id);
const query = ref("")
const icons = (await client.summonerIcons.listAsync({locale: "default", version: "latest"}))
.sort((a, b) => a.id - b.id);
const icons = ref(await getIcons());
watch(currentLocale, async() => {
icons.value = await getIcons();
});
const { isNumeric } = useIsNumeric();
const p = computed(() => {
let filtered = [];
if (isNumeric(query.value))
filtered = icons.filter((x) => x.id == parseInt(query.value, 10));
filtered = icons.value.filter((x) => x.id == parseInt(query.value, 10));
else
filtered = icons.filter((x) => x.title.toLowerCase().includes(query.value.toLowerCase()));
filtered = icons.value.filter((x) => x.title.toLowerCase().includes(query.value.toLowerCase()));
return usePagination(filtered, 100);
});

View File

@@ -20,13 +20,20 @@
import Badge from '~/components/Badge.vue';
import { useRoute } from 'vue-router';
import useClient from '../../../composables/useClient';
import useLocale from '~/composables/useLocale';
import { SummonerIcon } from '~/core/models';
const route = useRoute();
const id = route.params.id as unknown;
const { client } = useClient();
const { currentLocale } = useLocale();
const getIcons = async () => await client.summonerIcons.listAsync({locale: currentLocale.value, version: "latest"});
const icons = await client.summonerIcons.listAsync({locale: "default", version: "latest"});
const icon = icons.find((x) => x.id == id) || new SummonerIcon({});
const icons = ref(await getIcons());
watch(currentLocale, async() => {
icons.value = await getIcons();
});
const icon = icons.value.find((x) => x.id == id) || new SummonerIcon({});
</script>

View File

@@ -49,22 +49,28 @@
<script setup lang="ts">
import Pagination from '../../components/Pagination.vue';
import useClient from '../../composables/useClient';
import useLocale from '~/composables/useLocale';
import useIsNumeric from '../../composables/useIsNumeric';
import usePagination from '../../composables/usePagination';
const { client } = useClient();
const { currentLocale } = useLocale();
const getSkins = async () => await client.wardSkins.listAsync({locale: currentLocale.value, version: "latest"});
const query = ref("");
const skins = await client.wardSkins.listAsync({locale: "default", version: "latest"});
const skins = ref(await getSkins());
watch(currentLocale, async() => {
skins.value = await getSkins();
});
const { isNumeric } = useIsNumeric();
const p = computed(() => {
let filtered = [];
if (isNumeric(query.value))
filtered = skins.filter((x) => x.id == parseInt(query.value, 10));
filtered = skins.value.filter((x) => x.id == parseInt(query.value, 10));
else
filtered = skins.filter((x) => x.name.toLowerCase().includes(query.value.toLowerCase()));
filtered = skins.value.filter((x) => x.name.toLowerCase().includes(query.value.toLowerCase()));
return usePagination(filtered, 100);
});

View File

@@ -21,13 +21,20 @@
import { WardSkin } from '~/core/models';
import Badge from '../../../components/Badge.vue';
import useClient from '../../../composables/useClient';
import useLocale from '~/composables/useLocale';
import { useRoute } from 'vue-router';
const route = useRoute();
const id = route.params.id as unknown;
const { client } = useClient();
const { currentLocale } = useLocale();
const getSkins = async () => await client.wardSkins.listAsync({locale: currentLocale.value, version: "latest"});
const skins = await client.wardSkins.listAsync({locale: "default", version: "latest"});
const skin = skins.find((x) => x.id == id) || new WardSkin({});
const skins = ref(await getSkins());
watch(currentLocale, async() => {
skins.value = await getSkins();
});
const skin = skins.value.find((x) => x.id == id) || new WardSkin({});
</script>