Skip to content

Commit 567c49e

Browse files
committed
Merge branch 'feature/project-improvments' into develop
2 parents 33efe01 + d9f3206 commit 567c49e

File tree

14 files changed

+209
-17
lines changed

14 files changed

+209
-17
lines changed

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ Typedoc is generated with command ```npm run build:docs``` into directoy ```docs
226226
- [X] Add typedocs
227227
- [ ] Add greenkeeper
228228
- [ ] Add electron
229-
- [ ] VSC frontend debugging https://github.com/AngularClass/angular2-webpack-starter/blob/master/.vscode/launch.json
230-
- [ ] VSC add tasks https://code.visualstudio.com/docs/editor/tasks
231-
229+
- [ ] Add pipline example
230+
- [ ] Add utility converters https://www.npmjs.com/package/aurelia-utility-converters
231+
- [ ] Add validation example
232+
- [ ] Add configure http client example

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@
9191
"aurelia-templating-router": "^1.0.0",
9292
"bootstrap-sass": "^3.3.7",
9393
"font-awesome": "^4.7.0",
94+
"i18next-browser-languagedetector": "^1.0.1",
9495
"isomorphic-fetch": "^2.2.1",
9596
"jquery": "^3.1.1",
9697
"moment": "^2.16.0"

src/app/app.vm.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,22 @@
11
import { Lazy, inject } from 'aurelia-framework';
22
import { Router, RouterConfiguration } from 'aurelia-router';
33
import { I18N } from 'aurelia-i18n';
4+
45
import { AppConfigService } from './services/app-config.service';
56
import { CordovaService } from './services/cordova.service';
7+
import { EventBusService, EventBusEvents } from './services/event-bus.service';
8+
import { LanguageService } from './services/language.service';
69

7-
@inject(I18N, AppConfigService, Lazy.of(CordovaService))
10+
@inject(I18N, AppConfigService, Lazy.of(CordovaService), EventBusService, LanguageService)
811
export class AppViewModel {
912
public router: Router;
1013

1114
constructor(
1215
private i18n: I18N,
1316
private appConfigService: AppConfigService,
14-
private cordovaServiceFn: () => CordovaService
17+
private cordovaServiceFn: () => CordovaService,
18+
private eventBusService: EventBusService,
19+
private languageService: LanguageService,
1520
) { }
1621

1722
public configureRouter(config: RouterConfiguration, router: Router): void {
@@ -45,7 +50,14 @@ export class AppViewModel {
4550
title: 'Child Router'
4651
}
4752
]);
53+
config.mapUnknownRoutes({ route: '', redirect: '' });
4854

4955
this.router = router;
5056
}
57+
58+
private configureMoment(): void {
59+
const locale = this.languageService.getCurrentLocale();
60+
moment.locale(locale);
61+
this.eventBusService.addSubscription(EventBusEvents.IDS.i18n.locale.changed, (a) => moment.locale(a.newValue));
62+
}
5163
}

src/app/main.ts

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,14 @@ import { ConsoleAppender } from 'aurelia-logging-console';
1818
/**
1919
* Locals i18n imports
2020
*/
21-
import i18nEnglish from './../locales/en.json';
21+
import en_USTranslation from './../locales/en_US.json';
22+
import de_CHTranslation from './../locales/de_CH.json';
2223

2324
/**
24-
* Polyfill fetch
25+
* Third Party Libraries and polyfill
2526
*/
2627
import 'isomorphic-fetch';
28+
import LanguageDetector from 'i18next-browser-languagedetector';
2729

2830
/**
2931
* Aurelia configruation
@@ -42,16 +44,30 @@ export async function configure(aurelia: Aurelia): Promise<void> {
4244
* See: https://github.com/aurelia/i18n
4345
*/
4446
.plugin('aurelia-i18n', (instance) => {
47+
instance.i18next.use(LanguageDetector);
4548
// adapt options to your needs (see http://i18next.com/docs/options/)
4649
// make sure to return the promise of the setup method, in order to guarantee proper loading
4750
return instance.setup({
4851
resources: {
49-
en: {
50-
translation: i18nEnglish
52+
'en-US': {
53+
translation: en_USTranslation
54+
},
55+
'de-CH': {
56+
translation: de_CHTranslation
5157
}
5258
},
53-
lng: 'en',
54-
fallbackLng: 'en'
59+
fallbackLng: {
60+
'de': ['de-CH', 'en-US'],
61+
'de-DE': ['de-CH', 'en-US'],
62+
'default': ['en-US']
63+
},
64+
debug: false,
65+
detection: {
66+
order: ['localStorage', 'navigator'],
67+
lookupCookie: 'i18next',
68+
lookupLocalStorage: 'i18nextLng',
69+
caches: ['localStorage']
70+
}
5571
});
5672
})
5773
// Uncomment the line below to enable animation.

src/app/modules/welcome/welcome.vm.html

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,11 @@ <h3>Custom global attribute</h3>
2525

2626
<h3>Global value converter</h3>
2727
<p>${currentDate | dateFormat}</p>
28+
29+
<h3>Switch Language</h3>
30+
<button click.delegate="switchLanguage()" class="btn btn-primary">Click me!</button>
31+
<br/><br/>
32+
<p>Everything is: <span t="TR_ATTR"></span></p>
33+
<p>Signalr example: ${ 'TR_SIGNALER' | t & signal:'locale:changed' }</p>
2834
</section>
2935
</template>

src/app/modules/welcome/welcome.vm.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { autoinject } from 'aurelia-framework';
2+
23
import { LogManager, Logger} from './../../services/logger.service';
34
import { AppConfigService } from './../../services/app-config.service';
5+
import { LanguageService } from './../../services/language.service';
46

57
@autoinject
68
export class Welcome {
@@ -13,7 +15,8 @@ export class Welcome {
1315
public currentDate: Date = new Date();
1416

1517
constructor(
16-
private appConfigService: AppConfigService
18+
private appConfigService: AppConfigService,
19+
private languageService: LanguageService
1720
) {
1821
this.logger = LogManager.getLogger('Welcome VM');
1922
this.logger.info('appConfig => name:', appConfigService.getName());
@@ -43,6 +46,15 @@ export class Welcome {
4346
}
4447
return true;
4548
}
49+
50+
public switchLanguage(): void {
51+
const lang = this.languageService.getCurrentLang();
52+
if (lang === this.languageService.getSupportedLanguages()[0]) {
53+
this.languageService.setLocale(this.languageService.getSupportedLanguages()[1]);
54+
} else {
55+
this.languageService.setLocale(this.languageService.getSupportedLanguages()[0]);
56+
}
57+
}
4658
}
4759

4860
export class UpperValueConverter {
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { autoinject, transient } from 'aurelia-framework';
2+
import { EventAggregator, Subscription } from 'aurelia-event-aggregator';
3+
4+
export class EventBusEvents {
5+
public static IDS = {
6+
i18n: {
7+
locale: {
8+
changed: 'i18n:locale:changed'
9+
}
10+
}
11+
};
12+
}
13+
14+
@transient()
15+
@autoinject
16+
export class EventBusService {
17+
18+
private disposables: Subscription[] = [];
19+
20+
constructor(
21+
public eventAggregator: EventAggregator
22+
) { }
23+
24+
public addSubscription(eventId: string, callback: Function): EventBusService {
25+
this.disposables.push(this.eventAggregator.subscribe(eventId, callback));
26+
return this;
27+
}
28+
29+
public dispose(): void {
30+
this.disposables.forEach(d => d.dispose());
31+
}
32+
33+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import { autoinject } from 'aurelia-framework';
2+
import { I18N } from 'aurelia-i18n';
3+
import { BindingSignaler } from 'aurelia-templating-resources';
4+
import * as moment from 'moment/moment';
5+
6+
import { Logger, LogManager} from './logger.service';
7+
8+
export const LocaleChangedSignal: string = 'locale:changed';
9+
10+
@autoinject
11+
export class LanguageService {
12+
13+
private logger: Logger;
14+
15+
constructor(
16+
private i18n: I18N,
17+
private bindingSignaler: BindingSignaler
18+
) {
19+
this.logger = LogManager.getLogger('LanguageService');
20+
this.logger.debug('initialized');
21+
this.logger.debug(`current locale: ${this.getCurrentLocale()}`);
22+
}
23+
24+
/**
25+
* Return the language: en, de, fr, it
26+
*/
27+
public getCurrentLang(): string {
28+
return this.getCurrentLocale().split('-')[0];
29+
}
30+
31+
/**
32+
* Get the list of all supported locales from our translations,
33+
* then get the current browser locale, if we have a translation
34+
* returns the language or fallback to default -> en
35+
*/
36+
public getCurrentUILanguage(): string {
37+
const supported = this.getSupportedLanguages();
38+
const currentLanguage = this.getCurrentLang();
39+
return supported.indexOf(currentLanguage) > -1 ? currentLanguage : 'en';
40+
}
41+
42+
/**
43+
* Get a list of current configured languages which has a translation.
44+
*/
45+
public getSupportedLanguages(): string[] {
46+
const languages = Object.keys(this.i18n.i18next.options.fallbackLng)
47+
.map(key => this.i18n.i18next.options.fallbackLng[key][0].split('-')[0])
48+
.filter((value, index, array) => {
49+
return array.indexOf (value) === index;
50+
});
51+
return languages;
52+
}
53+
54+
public getCurrentLocale(): string {
55+
return this.i18n.getLocale();
56+
}
57+
58+
public setLocale(locale: string): void {
59+
moment.locale(locale);
60+
this.i18n.setLocale(locale);
61+
this.bindingSignaler.signal(LocaleChangedSignal);
62+
this.logger.debug(`changed locale to: ${locale}`);
63+
}
64+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
export class WindowLocationService {
2+
3+
public static changeLocation(destination: string): void {
4+
window.location.assign(destination);
5+
}
6+
7+
public static changeLocationAfterPageLoad(destination: string): void {
8+
// Wait for resources to load before redirect. Without this Safari would fail
9+
// to load/activate resources, like fonts.
10+
const waitForPageLoad = () => {
11+
if (document.readyState === 'complete') {
12+
WindowLocationService.changeLocation(destination);
13+
} else {
14+
setTimeout(waitForPageLoad, 500);
15+
}
16+
};
17+
waitForPageLoad();
18+
}
19+
20+
public static getHashQueryString(): string {
21+
return window.location.hash.substring(1);
22+
}
23+
24+
public static getLocationOrigin(): string {
25+
if (window.location.origin) {
26+
return window.location.origin;
27+
}
28+
// IE11 fix, when window.location.origin is undefined
29+
let locationOrigin = `${window.location.protocol}//${window.location.hostname}`;
30+
locationOrigin += window.location.port ? ':' + window.location.port : '';
31+
return locationOrigin;
32+
}
33+
}

src/locales/de_CH.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"TITLE": "Übersetztungs Titel",
3+
"TR_ATTR": "...in Deutsch",
4+
"TR_SIGNALER": "Signaler Beispiel funktioniert..."
5+
}

0 commit comments

Comments
 (0)