/* * Copyright (C) 2022 StApps * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation, version 3. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ import {AfterContentInit, Component, NgZone} from '@angular/core'; import {Router} from '@angular/router'; import {App, URLOpenListenerEvent} from '@capacitor/app'; import {Platform, ToastController} from '@ionic/angular'; import {SettingsProvider} from './modules/settings/settings.provider'; import {AuthHelperService} from './modules/auth/auth-helper.service'; import {environment} from '../environments/environment'; import {StatusBar, Style} from '@capacitor/status-bar'; import {Capacitor} from '@capacitor/core'; import {ScheduleSyncService} from './modules/background/schedule/schedule-sync.service'; import {NavigationBar} from '@hugotomazi/capacitor-navigation-bar'; import {Keyboard, KeyboardResize} from '@capacitor/keyboard'; /** * TODO */ @Component({ selector: 'app-root', templateUrl: 'app.component.html', }) export class AppComponent implements AfterContentInit { /** * TODO */ pages: Array<{ /** * TODO */ component: unknown; /** * TODO */ title: string; }>; /** * Angular component selectors that should not infulence keyboard state */ ommitedEventSources = ['ion-input', 'ion-searchbar']; /** * * @param platform TODO * @param settingsProvider TODO * @param router The angular router * @param zone The angular zone * @param authHelper Helper service for OAuth providers * @param toastController Toast controller */ constructor( private readonly platform: Platform, private readonly settingsProvider: SettingsProvider, private readonly router: Router, private readonly zone: NgZone, private readonly authHelper: AuthHelperService, private readonly toastController: ToastController, private readonly scheduleSyncService: ScheduleSyncService, ) { void this.initializeApp(); } ngAfterContentInit(): void { this.scheduleSyncService.init(); void this.scheduleSyncService.enable(); } /** * TODO */ async initializeApp() { App.addListener('appUrlOpen', (event: URLOpenListenerEvent) => { this.zone.run(() => { const slug = event.url.split(environment.app_host).pop(); if (slug) { this.router.navigateByUrl(slug); } // If no match, do nothing - let regular routing // logic take over }); }); this.platform.ready().then(async () => { if (Capacitor.isNativePlatform()) { await StatusBar.setStyle({style: Style.Dark}); if (Capacitor.getPlatform() === 'android') { await StatusBar.setBackgroundColor({ color: getComputedStyle(document.documentElement) .getPropertyValue('--ion-color-primary') .trim(), }); await StatusBar.setOverlaysWebView({overlay: false}); await NavigationBar.setColor({ color: getComputedStyle(document.documentElement) .getPropertyValue('--ion-background-color') .trim(), darkButtons: true, }); } } await this.authNotificationsInit(); // set order of categories in settings this.settingsProvider.setCategoriesOrder([ 'profile', 'privacy', 'credentials', 'others', ]); }); window.addEventListener('touchmove', this.touchMoveEvent, true); if (Capacitor.getPlatform() === 'ios') { Keyboard.setResizeMode({mode: KeyboardResize.None}); } } private async authNotificationsInit() { this.authHelper .getProvider('default') .events$.subscribe(action => this.showMessage(this.authHelper.getAuthMessage('default', action)), ); this.authHelper .getProvider('paia') .events$.subscribe(action => this.showMessage(this.authHelper.getAuthMessage('paia', action)), ); } private async showMessage(message?: string) { if (typeof message === 'undefined') { return; } const toast = await this.toastController.create({ message: message, duration: 2000, }); await toast.present(); } /** * Checks if keyboard should be dissmissed */ touchMoveEvent = (event: Event): void => { if ( this.ommitedEventSources.includes( (event?.target as unknown as Record)?.[ 's-hn' ]?.toLowerCase(), ) ) { return; } this.unfocusActiveElement(); }; /** * Loses focus on the currently active element (meant for input fields). * Results in virtual keyboard being dissmissed on native and web plattforms. */ unfocusActiveElement() { const activeElement = document.activeElement; // eslint-disable-next-line @typescript-eslint/no-explicit-any (activeElement as any)?.blur(); } }