Files
openstapps/src/app/app.component.ts
2022-10-21 16:01:44 +00:00

180 lines
5.3 KiB
TypeScript

/*
* 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 <https://www.gnu.org/licenses/>.
*/
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<string, string>)?.[
'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();
}
}