Skip to content

Commit

Permalink
Improve TranslationService integration
Browse files Browse the repository at this point in the history
  • Loading branch information
undyingwraith committed Dec 12, 2024
1 parent f5632fb commit 1bf1592
Show file tree
Hide file tree
Showing 12 changed files with 60 additions and 13 deletions.
4 changes: 4 additions & 0 deletions packages/core/src/Application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ export class Application implements IApplication, IApplicationRegistration {
this.container.bind<T>(identifier).toConstantValue(service);
}

public registerConstantMultiple<T>(service: T, identifier: symbol) {
this.container.bind<T>(identifier).toConstantValue(service);
}

public register<T>(service: interfaces.Newable<T>, identifier: symbol) {
if (this.container.isBound(identifier)) {
this.container.unbind(identifier);
Expand Down
7 changes: 7 additions & 0 deletions packages/core/src/IApplicationRegistration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ export interface IApplicationRegistration {
*/
registerConstant<T>(service: T, identifier: symbol): void;

/**
* Registers a new constant without removing previous registrations.
* @param service service to register.
* @param identifier symbol for the service.
*/
registerConstantMultiple<T>(service: T, identifier: symbol): void;

/**
* Registers a {@link IModule}.
* @param module {@link IModule} to use in the {@link IApplication}.
Expand Down
12 changes: 11 additions & 1 deletion packages/core/src/Modules/CoreModule.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,26 @@
import { IIndexManagerSymbol, IKeyValueStoreSymbol, IObjectStoreSymbol, ITranslationServiceSymbol } from 'ipmc-interfaces';
import { IIndexManagerSymbol, IKeyValueStoreSymbol, IObjectStoreSymbol, ITranslationServiceSymbol, ITranslationsSymbol } from 'ipmc-interfaces';
import { MemoryKeyValueStore } from '../Services/MemoryKeyValueStore';
import { ObjectStore } from '../Services/ObjectStore';
import { IModule } from './IModule';
import { IndexManager } from '../Services/IndexManager';
import { TaskManager } from '../Services/TaskManager';
import { ITaskManagerSymbol } from 'ipmc-interfaces';
import { TranslationService } from '../Services/TranslationService';
import en from '../translations/en.json';
import de from '../translations/de.json';

export const CoreModule: IModule = (app) => {
app.register(MemoryKeyValueStore, IKeyValueStoreSymbol);
app.register(ObjectStore, IObjectStoreSymbol);
app.register(IndexManager, IIndexManagerSymbol);
app.register(TaskManager, ITaskManagerSymbol);
app.register(TranslationService, ITranslationServiceSymbol);
app.registerConstantMultiple({
en: {
translation: en,
},
de: {
translation: de,
}
}, ITranslationsSymbol);
};
23 changes: 17 additions & 6 deletions packages/core/src/Services/TranslationService.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,25 @@
import i18next from 'i18next';
import { inject, injectable } from 'inversify';
import { ITranslationService, ITranslationsSymbol } from 'ipmc-interfaces';
import { multiInject, injectable, optional } from 'inversify';
import { ITranslationService, ITranslationsSymbol, ITranslation } from 'ipmc-interfaces';

@injectable()
export class TranslationService implements ITranslationService {
constructor(@inject(ITranslationsSymbol) translations: any) {
constructor(@multiInject(ITranslationsSymbol) @optional() translations: ITranslation[]) {
const resources: ITranslation = {};
for (const translationSet of translations) {
for (const [lang, values] of Object.entries(translationSet)) {
if (!resources.hasOwnProperty(lang)) {
resources[lang] = { translation: {} };
}
resources[lang].translation = { ...resources[lang].translation, ...values.translation };
}
}

i18next.init({
resources: translations,
lng: "en", // language to use, more information here: https://www.i18next.com/overview/configuration-options#languages-namespaces-resources
resources,
lng: "en",
interpolation: {
escapeValue: false // react already safes from xss
escapeValue: false
}
});
}
Expand All @@ -18,6 +28,7 @@ export class TranslationService implements ITranslationService {
if (i18next.exists(key)) {
return i18next.t(key, values);
} else {
console.warn(`Missing translation key <${key}>`);
return `<${key}>`;
}
}
Expand Down
3 changes: 3 additions & 0 deletions packages/core/src/translations/de.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"UpdatingLibrary": "Aktualisieren von {{name}}"
}
3 changes: 3 additions & 0 deletions packages/core/src/translations/en.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"UpdatingLibrary": "Updating library {{name}}"
}
2 changes: 1 addition & 1 deletion packages/core/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
// "resolveJsonModule": true, /* Enable importing .json files. */
"resolveJsonModule": true, /* Enable importing .json files. */
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
/* JavaScript Support */
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export const ITranslationsSymbol = Symbol.for('ITranslations');

export type ITranslation = {
[key: string]: {
translation: {
[key: string]: string;
};
};
};
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
export const ITranslationServiceSymbol = Symbol.for('ITranslationService');

export const ITranslationsSymbol = Symbol.for('ITranslations');

export interface ITranslationService {
translate(key: string, values?: { [key: string]: string; }): string;
}
2 changes: 2 additions & 0 deletions packages/interfaces/src/Services/ITranslationService/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { type ITranslation, ITranslationsSymbol } from './ITranslation';
export { type ITranslationService, ITranslationServiceSymbol } from './ITranslationService';
2 changes: 1 addition & 1 deletion packages/interfaces/src/Services/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
export * from './ITaskManager';
export * from './ITranslationService';
export { type IConfigurationService } from './IConfigurationService';
export { IHotkeyServiceSymbol, type IHotkeyService, type IHotkey } from './IHotkeyService';
export { type IIndexManager, IIndexManagerSymbol } from './IIndexManager';
export { type IIpfsService, IIpfsServiceSymbol } from './IIpfsService';
export { type IKeyValueStore, IKeyValueStoreSymbol } from './IKeyValueStore';
export { type INodeService } from './INodeService';
export { type IObjectStore, IObjectStoreSymbol } from './IObjectStore';
export { type ITranslationService, ITranslationServiceSymbol, ITranslationsSymbol } from './ITranslationService';
4 changes: 2 additions & 2 deletions packages/ui/src/IpmcApp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import { Switch } from 'wouter';
import { AppBar } from './components/organisms/AppBar';
import { LibraryManager } from "./components/pages/LibraryManager";
import { AppContextProvider } from './context';
import { ITranslationsSymbol, ITranslation } from 'ipmc-interfaces';

// Setup translations
import './i18n';
import { ITranslationsSymbol } from 'ipmc-interfaces';

export interface IIpmcAppProps {
setup?: IModule;
Expand All @@ -33,7 +33,7 @@ export function IpmcApp(props: IIpmcAppProps) {
<AppContextProvider setup={(app) => {
app.use(CoreModule);
app.use(BrowserModule);
app.registerConstant<any>(resources, ITranslationsSymbol);
app.registerConstantMultiple<ITranslation>(resources, ITranslationsSymbol);
setup && app.use(setup);
}}>
<AppBar />
Expand Down

0 comments on commit 1bf1592

Please sign in to comment.