import { Component, OnInit, signal, ApplicationRef, inject, DestroyRef } from '@angular/core'; import { Router, RouterOutlet, NavigationEnd } from '@angular/router'; import { Title } from '@angular/platform-browser'; import { HeaderComponent } from './components/header/header.component'; import { FooterComponent } from './components/footer/footer.component'; import { BackButtonComponent } from './components/back-button/back-button.component'; import { TelegramLoginComponent } from './components/telegram-login/telegram-login.component'; import { ApiService } from './services'; import { interval, concat } from 'rxjs'; import { filter, first } from 'rxjs/operators'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { environment } from '../environments/environment'; import { SwUpdate } from '@angular/service-worker'; import { TranslatePipe } from './i18n/translate.pipe'; import { TranslateService } from './i18n/translate.service'; @Component({ selector: 'app-root', imports: [RouterOutlet, HeaderComponent, FooterComponent, BackButtonComponent, TelegramLoginComponent, TranslatePipe], templateUrl: './app.html', styleUrl: './app.scss' }) export class App implements OnInit { protected title = environment.brandName; isHomePage = signal(true); checkingServer = signal(true); serverAvailable = signal(false); private destroyRef = inject(DestroyRef); private apiService = inject(ApiService); private titleService = inject(Title); private swUpdate = inject(SwUpdate); private appRef = inject(ApplicationRef); private router = inject(Router); private i18n = inject(TranslateService); ngOnInit(): void { this.titleService.setTitle(`${environment.brandFullName} - ${this.i18n.t('app.pageTitle')}`); this.checkServerHealth(); this.setupAutoUpdates(); // Track route changes to show/hide back button this.router.events .pipe( filter(event => event instanceof NavigationEnd), takeUntilDestroyed(this.destroyRef) ) .subscribe((event) => { const navEnd = event as NavigationEnd; const url = navEnd.urlAfterRedirects || navEnd.url; // Home pages: /ru, /en, /hy (with or without trailing slash) this.isHomePage.set(/^\/[a-z]{2}\/?$/.test(url) || url === '/' || url === ''); }); } private checkServerHealth(): void { this.checkingServer.set(true); this.apiService.ping() .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe({ next: () => { this.serverAvailable.set(true); this.checkingServer.set(false); }, error: () => { this.serverAvailable.set(false); this.checkingServer.set(false); } }); } retryConnection(): void { this.checkServerHealth(); } private setupAutoUpdates(): void { if (!this.swUpdate.isEnabled) { return; } const appIsStable$ = this.appRef.isStable.pipe(first(isStable => isStable === true)); const every6Hours$ = interval(6 * 60 * 60 * 1000); const checkInterval$ = concat(appIsStable$, every6Hours$); checkInterval$ .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(async () => { try { await this.swUpdate.checkForUpdate(); } catch (err) { console.error('Update check failed:', err); } }); this.swUpdate.versionUpdates .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(event => { if (event.type === 'VERSION_READY') { console.log('New app version ready'); } }); } }