diff --git a/src/app/app.html b/src/app/app.html
new file mode 100644
index 0000000..e69f15c
--- /dev/null
+++ b/src/app/app.html
@@ -0,0 +1,36 @@
+
+ {{ 'APP.TITLE' | translate }}
+
+
+
+
+
+
+
+
+ {{ lang.lang() === 'de' ? ('LANG.DE' | translate) : ('LANG.EN' | translate) }}
+
+
+
+
+
+ {{ 'LANG.DE' | translate }}
+
+
+
+
+ {{ 'LANG.EN' | translate }}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/app/app.scss b/src/app/app.scss
new file mode 100644
index 0000000..4120908
--- /dev/null
+++ b/src/app/app.scss
@@ -0,0 +1,13 @@
+.spacer { flex: 1 1 auto; }
+.container { max-width: 960px; margin: 24px auto; padding: 0 16px; }
+mat-form-field { --mdc-outlined-text-field-container-shape: 20px; }
+
+.flag-icon {
+ width: 20px;
+ height: 14px;
+ object-fit: cover;
+ border-radius: 2px;
+ box-shadow: 0 0 0 1px rgba(0,0,0,.08) inset;
+ vertical-align: -2px;
+}
+mat-option .flag-icon { margin-right: 8px; }
diff --git a/src/app/app.ts b/src/app/app.ts
index 87053ce..7ed0683 100644
--- a/src/app/app.ts
+++ b/src/app/app.ts
@@ -1,4 +1,4 @@
-import { Component, computed, inject } from '@angular/core';
+import {Component, computed, effect, inject} from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { MatToolbarModule } from '@angular/material/toolbar';
import { MatIconModule } from '@angular/material/icon';
@@ -22,35 +22,8 @@ import {LanguageService} from './service/language.service';
FormsModule,
TranslateModule
],
- template: `
-
- {{ 'APP.TITLE' | translate }}
-
-
-
-
-
- {{ 'LANG.DE' | translate }}
- {{ 'LANG.EN' | translate }}
-
-
-
-
-
-
-
-
-
-
-
-
- `,
+ templateUrl: './app.html',
+ styleUrl: './app.scss',
})
export class App {
readonly theme = inject(ThemeService);
diff --git a/src/app/constants/Constants.ts b/src/app/constants/Constants.ts
index a2935ca..e1b8d9c 100644
--- a/src/app/constants/Constants.ts
+++ b/src/app/constants/Constants.ts
@@ -2,4 +2,6 @@
static readonly THEME_KEY = 'theme';
static readonly LANGUAGE_KEY = 'lang';
+
+ static readonly RELOAD_ALL_LANG_LISTENER_KEY = 'language_dirty_flag';
}
diff --git a/src/app/service/language.service.ts b/src/app/service/language.service.ts
index 71c90d6..4556eb1 100644
--- a/src/app/service/language.service.ts
+++ b/src/app/service/language.service.ts
@@ -12,6 +12,7 @@ export class LanguageService {
constructor() {
this.translate.addLangs(['de', 'en']);
this.translate.setFallbackLang('en');
+ this.lang.set(this.getInitial());
this.use(this.lang());
}
diff --git a/src/app/service/reload.service.ts b/src/app/service/reload.service.ts
new file mode 100644
index 0000000..e05c006
--- /dev/null
+++ b/src/app/service/reload.service.ts
@@ -0,0 +1,32 @@
+import { Injectable, NgZone, signal } from '@angular/core';
+import {Constants} from '../constants/Constants';
+
+
+@Injectable({ providedIn: 'root' })
+export class ReloadService {
+ private readonly _reloadTick = signal(0);
+ readonly reloadTick = this._reloadTick.asReadonly();
+
+ private readonly _languageChangedTick = signal(0);
+ readonly languageChangedTick = this._languageChangedTick.asReadonly();
+
+ constructor(zone: NgZone) {
+ zone.runOutsideAngular(() => {
+ globalThis.addEventListener('storage', (e: StorageEvent) => {
+ this.informListeners(e, zone);
+ });
+ });
+ }
+
+
+ private informListeners(e: StorageEvent, zone: NgZone) {
+ if (e.key === Constants.LANGUAGE_KEY) {
+ zone.run(() => this._languageChangedTick.update(v => v + 1));
+ }
+ }
+
+ bumpLanguageChanged(): void {
+ this._reloadTick.update(v => v + 1);
+ localStorage.setItem(Constants.RELOAD_ALL_LANG_LISTENER_KEY, String(Date.now()));
+ }
+}
diff --git a/src/assets/flags/de.svg b/src/assets/flags/de.svg
new file mode 100644
index 0000000..296b079
--- /dev/null
+++ b/src/assets/flags/de.svg
@@ -0,0 +1,5 @@
+
diff --git a/src/assets/flags/gb.svg b/src/assets/flags/gb.svg
new file mode 100644
index 0000000..5a7c458
--- /dev/null
+++ b/src/assets/flags/gb.svg
@@ -0,0 +1,10 @@
+