🌐 Added i18next

This commit is contained in:
Mawoka
2022-03-25 18:23:41 +01:00
parent 326780c8d7
commit 8f8e152c32
16 changed files with 4457 additions and 2495 deletions
+46
View File
@@ -0,0 +1,46 @@
import i18next from 'i18next';
import translations from './translations';
import en from './locales/en.json';
import type { i18n, Resource } from 'i18next';
const INITIAL_LANGUAGE = 'en';
export class I18nService {
// expose i18next
i18n: i18n;
constructor() {
this.i18n = i18next;
this.initialize();
this.changeLanguage(INITIAL_LANGUAGE);
}
// Our translation function
t(key: string, replacements?: Record<string, unknown>): string {
return this.i18n.t(key, replacements);
}
// Initializing i18n
initialize() {
this.i18n.init({
lng: INITIAL_LANGUAGE,
fallbackLng: 'en',
debug: false,
defaultNS: 'translation',
fallbackNS: 'common',
resources: translations as Resource,
interpolation: {
escapeValue: false
},
detection: {
order: ['querystring', 'navigator'],
lookupQuerystring: 'lng'
}
});
this.i18n.addResourceBundle('en', 'translation', en);
}
changeLanguage(language: string) {
this.i18n.changeLanguage(language);
}
}
+36
View File
@@ -0,0 +1,36 @@
import { I18nService } from './i18n-service';
import { I18NextTranslationService } from './translation-service';
import type { TType } from './translation-service';
import type { Readable, Writable } from 'svelte/store';
import { getContext, setContext } from 'svelte';
export const initLocalizationContext = () => {
// Initialize our services
const i18n = new I18nService();
const tranlator = new I18NextTranslationService(i18n);
// Setting the Svelte context
setLocalization({
t: tranlator.translate,
currentLanguage: tranlator.locale
});
return {
i18n
};
};
const CONTEXT_KEY = 't';
export type I18nContext = {
t: Readable<TType>;
currentLanguage: Writable<string>;
};
export const setLocalization = (context: I18nContext) => {
return setContext<I18nContext>(CONTEXT_KEY, context);
};
// To make retrieving the t function easier.
export const getLocalization = () => {
return getContext<I18nContext>(CONTEXT_KEY);
};
+75
View File
@@ -0,0 +1,75 @@
{
"index_page": {
"slogan": "The open-source quiz-platform!",
"meta": {
"description": "ClassQuiz is a quiz app like KAHOOT! for students, which is open source and free to use",
"title": "Home"
},
"stats": "Stats",
"features": "Features",
"features_description": {
"1": "ClassQuiz is a quiz-platform that allows you to create and manage quizzes.",
"2": "The main feature is a KAHOOT!-import function that allows you to import quizzes from KAHOOT!-quizzes."
}
},
"overview_page": {
"create": "Create",
"import": "Import",
"logout": "Logout",
"title": "Title",
"created_at": "Created at",
"question_count": "Question count",
"play": "Play",
"edit": "Edit",
"delete": "Delete",
"public": "Public",
"start": "Start"
},
"edit_page": {
"save": "Save",
"success_update_title": "Successfully updated quiz!",
"success_update_body": "Updated the quiz successfully!",
"close": "Close"
},
"create_page": {
"success": {
"title": "Successfully created quiz!",
"body": "Created the quiz successfully!"
},
"close": "Close"
},
"register_page": {
"greeting": "Nice to meet you!",
"create_account": "Create account",
"email": "Email",
"username": "Username",
"password": "Password",
"forgot_password?": "Forgot password?",
"register": "Register",
"already_have_account?": "Already have an account?",
"login": "Login"
},
"login_page": {
"welcome_back": "Welcome back!",
"login_or_create_account": "Login or create an account",
"already_have_account": "Don't have an account?",
"modal": {
"success": {
"success_check_mail": "Login Succeded! Check your mailbox!",
"success": "Login Succeded!",
"description": {
"success_check_mail": "Please check your mailbox, since you should have received a mail, with a link you can click to login.",
"success": "You've successfully logged in!"
}
},
"error": {
"wrong_creds": "Wrong email or password!",
"unexpected": "Unexpected error!",
"description": {
"wrong_creds": "Please make sure that your password and your email are correct!",
"unexpected": "There was the good old unexpected error!"
}
}
}
}
}
@@ -0,0 +1,59 @@
import type { I18nService } from './i18n-service';
import { derived, writable } from 'svelte/store';
import type { Readable, Writable } from 'svelte/store';
export type TType = (text: string, replacements?: Record<string, unknown>) => string;
export interface TranslationService {
locale: Writable<string>;
translate: Readable<TType>;
}
export class I18NextTranslationService implements TranslationService {
public locale: Writable<string>;
public translate: Readable<TType>;
constructor(i18n: I18nService) {
i18n.initialize();
this.locale = this.createLocale(i18n);
this.translate = this.createTranslate(i18n);
}
// Locale initialization.
// 1. Create a writable store
// 2. Create a new set function that changes the i18n locale.
// 3. Create a new update function that changes the i18n locale.
// 4. Return modified writable.
private createLocale(i18n: I18nService) {
const { subscribe, set, update } = writable<string>(i18n.i18n.language);
const setLocale = (newLocale: string) => {
i18n.changeLanguage(newLocale);
set(newLocale);
};
const updateLocale = (updater: (value: string) => string) => {
update((currentValue) => {
const nextLocale = updater(currentValue);
i18n.changeLanguage(nextLocale);
return nextLocale;
});
};
return {
subscribe,
update: updateLocale,
set: setLocale
};
}
// Create a translate function.
// It is derived from the "locale" writable.
// This means it will be updated every time the locale changes.
private createTranslate(i18n: I18nService) {
return derived([this.locale], () => {
return (key: string, replacements?: Record<string, unknown>) =>
i18n.t(key, replacements);
});
}
}
+9
View File
@@ -0,0 +1,9 @@
export default {
en: {
common: {
'ClassQuiz is a quiz app like KAHOOT! for students, which is open source and free to use.':
'ClassQuiz is a quiz app like KAHOOT! for students, which is open source and free to use.',
'The open-source quiz-platform!': 'The open-source quiz-platform!'
}
}
};