import { Component, OnInit, OnDestroy, signal, ApplicationRef } from '@angular/core'; import { CommonModule } from '@angular/common'; 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 { ApiService } from './services'; import { Subscription, interval, concat } from 'rxjs'; import { filter, first } from 'rxjs/operators'; import { environment } from '../environments/environment'; import { SwUpdate } from '@angular/service-worker'; @Component({ selector: 'app-root', imports: [RouterOutlet, HeaderComponent, FooterComponent, BackButtonComponent, CommonModule], templateUrl: './app.html', styleUrl: './app.scss' }) export class App implements OnInit, OnDestroy { protected title = environment.brandName; serverAvailable = signal(true); checkingServer = signal(true); isHomePage = signal(true); private pingSubscription?: Subscription; private updateSubscription?: Subscription; private routerSubscription?: Subscription; constructor( private apiService: ApiService, private titleService: Title, private swUpdate: SwUpdate, private appRef: ApplicationRef, private router: Router ) {} ngOnInit(): void { // Устанавливаем заголовок страницы в зависимости от бренда this.titleService.setTitle(`${environment.brandFullName} - Маркетплейс товаров и услуг`); this.checkServerHealth(); this.setupAutoUpdates(); // Track route changes to show/hide back button this.routerSubscription = this.router.events .pipe(filter(event => event instanceof NavigationEnd)) .subscribe((event) => { const url = (event as NavigationEnd).urlAfterRedirects || (event as NavigationEnd).url; this.isHomePage.set(url === '/' || url === '/home' || url === ''); }); } checkServerHealth(): void { this.pingSubscription = this.apiService.ping().subscribe({ next: (response) => { // Server is available this.serverAvailable.set(true); this.checkingServer.set(false); }, error: (err) => { console.error('Server health check failed:', err); // Allow app to continue even if server is unreachable this.serverAvailable.set(true); this.checkingServer.set(false); } }); } setupAutoUpdates(): void { if (!this.swUpdate.isEnabled) { return; } // Check for updates every 6 hours const appIsStable$ = this.appRef.isStable.pipe(first(isStable => isStable === true)); const every6Hours$ = interval(6 * 60 * 60 * 1000); const checkInterval$ = concat(appIsStable$, every6Hours$); this.updateSubscription = checkInterval$.subscribe(async () => { try { await this.swUpdate.checkForUpdate(); } catch (err) { console.error('Update check failed:', err); } }); // Silently activate updates when ready this.swUpdate.versionUpdates.subscribe(event => { if (event.type === 'VERSION_READY') { // Update will activate on next navigation/reload automatically console.log('New app version ready'); } }); } ngOnDestroy(): void { this.pingSubscription?.unsubscribe(); this.updateSubscription?.unsubscribe(); this.routerSubscription?.unsubscribe(); } retryConnection(): void { this.checkingServer.set(true); this.checkServerHealth(); } }