Skip to content

Commit

Permalink
Only load required languages
Browse files Browse the repository at this point in the history
  • Loading branch information
Carlgo11 committed Nov 20, 2024
1 parent 23efbd1 commit b4605e7
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 52 deletions.
56 changes: 27 additions & 29 deletions src/components/search.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import { html } from "htm/preact";
import { render } from "preact";
import { useEffect, useState } from "preact/hooks";
import algoliasearch from "algoliasearch";
import Table from "./table";
import { html } from 'htm/preact';
import { render } from 'preact';
import { useEffect, useState, useRef } from 'preact/hooks';
import algoliasearch from 'algoliasearch';
import Table from './table';
import useTranslation from '../hooks/useTranslation.js';

const t = useTranslation();

const client = algoliasearch(
import.meta.env.VITE_ALGOLIA_APP_ID,
import.meta.env.VITE_ALGOLIA_API_KEY,
Expand Down Expand Up @@ -119,32 +117,32 @@ function sendSearch(query) {
}

function Search() {
const [query, setQuery] = useState("");
let timeout = null;

useEffect(async () => {
const searchParams = new URLSearchParams(window.location.search);
if (searchParams.has("q")) {
const query = searchParams.get("q");
setQuery(query);
sendSearch(query);
}
const [query, setQuery] = useState('');
const timeout = useRef(null);
const t = useTranslation();

useEffect(() => {
const fetchInitialQuery = async () => {
const searchParams = new URLSearchParams(window.location.search);
if (searchParams.has('q')) {
const query = searchParams.get('q');
setQuery(query);
sendSearch(query);
}
};
fetchInitialQuery();
}, []);

/**
* Search and update query parameter without reloading the page
*
* @param {string} query - The query
*/
const search = (query) => {
sendSearch(query);

if (query) {
// Source: https://stackoverflow.com/a/70591485
const url = new URL(window.location.href);
url.searchParams.set("q", query);
window.history.pushState(null, "", url.toString());
} else window.history.pushState(null, "", window.location.pathname);
url.searchParams.set('q', query);
window.history.pushState(null, '', url.toString());
} else {
window.history.pushState(null, '', window.location.pathname);
}
};

return html`
Expand All @@ -156,8 +154,8 @@ function Search() {
spellcheck="false"
aria-keyshortcuts="s"
onInput=${(event) => {
if (timeout) clearTimeout(timeout);
timeout = setTimeout(() => search(event.target.value), 1000);
if (timeout.current) clearTimeout(timeout.current);
timeout.current = setTimeout(() => search(event.target.value), 1000);
}}
value=${query}
/>
Expand All @@ -166,4 +164,4 @@ function Search() {
`;
}

render(html`<${Search} />`, document.getElementById("search"));
render(html`<${Search} />`, document.getElementById('search'));
14 changes: 6 additions & 8 deletions src/hooks/useTranslation.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
import { useState, useEffect } from 'preact/hooks';
import { useState, useEffect, useMemo } from 'preact/hooks';
import i18n from '../i18n';

function useTranslation() {
const [loaded, setLoaded] = useState(i18n.isLoaded);
const [, forceUpdate] = useState(0);

useEffect(() => {
if (!i18n.isLoaded) {
const onLoad = () => setLoaded(true);
i18n.subscribe(onLoad);
return () => i18n.unsubscribe(onLoad);
}
const onLoad = () => forceUpdate((n) => n + 1);
i18n.subscribe(onLoad);
return () => i18n.unsubscribe(onLoad);
}, []);

return i18n.get.bind(i18n);
return useMemo(() => i18n.get.bind(i18n), [i18n.translations]);
}

export default useTranslation;
42 changes: 27 additions & 15 deletions src/i18n.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,31 @@ class i18n {
}

async _loadLanguages() {
const languageFiles = import.meta.glob('../lang/*.json'); // Import all JSON files in the lang folder
const translations = {};

try {
await Promise.all(
Object.entries(languageFiles).map(async ([path, load]) => {
const language = path.match(/\.\/lang\/(.*)\.json$/)[1]; // Extract language code
const content = await load(); // Dynamically import the JSON file
translations[language] = content.default; // Store the language data
})
);
console.debug('Languages loaded:', Object.keys(translations));
this.translations = translations;
// Use import.meta.glob to create a mapping of language files
const languageFiles = import.meta.glob('../lang/*.json');

// Load the default language
const defaultLangPath = `../lang/${this.defaultLanguage}.json`;
if (languageFiles[defaultLangPath]) {
const defaultLangModule = await languageFiles[defaultLangPath]();
this.translations[this.defaultLanguage] = defaultLangModule.default;
} else {
console.error(`Default language file not found at ${defaultLangPath}`);
}

// If current language is different from default, load it as well
if (this.currentLanguage !== this.defaultLanguage) {
const currentLangPath = `../lang/${this.currentLanguage}.json`;
if (languageFiles[currentLangPath]) {
const currentLangModule = await languageFiles[currentLangPath]();
this.translations[this.currentLanguage] = currentLangModule.default;
} else {
console.warn(`Language file for ${this.currentLanguage} not found at ${currentLangPath}, falling back to default language.`);
}
}

console.debug('Languages loaded:', Object.keys(this.translations));
this.isLoaded = true;
this._notifyListeners();
} catch (error) {
Expand All @@ -35,14 +47,14 @@ class i18n {
return translations[currentLanguage][key];
} else if (translations[defaultLanguage] && translations[defaultLanguage][key]) {
return translations[defaultLanguage][key];
} else {
return key; // Fallback to the key if not found
}
}

// Subscription management
subscribe(listener) {
this.listeners.push(listener);
if (!this.listeners.includes(listener)) {
this.listeners.push(listener);
}
}

unsubscribe(listener) {
Expand Down

0 comments on commit b4605e7

Please sign in to comment.