260 lines
6.5 KiB
TypeScript
260 lines
6.5 KiB
TypeScript
import { Component, HostListener } from '@angular/core';
|
|
import { Router } from '@angular/router';
|
|
import { DomSanitizer } from '@angular/platform-browser';
|
|
import { MatIconRegistry } from '@angular/material/icon';
|
|
import { DateAdapter } from '@angular/material/core';
|
|
import { fromEvent } from 'rxjs';
|
|
|
|
import { AuthService } from '../../services/auth.service';
|
|
import { UserService } from '../../services/user.service';
|
|
import { I18nService } from '../../services/i18n.service';
|
|
import { SettingsService } from '../../services/settings.service';
|
|
|
|
import packageJson from '../../../../package.json';
|
|
import { SwUpdate } from '@angular/service-worker';
|
|
|
|
@Component({
|
|
selector: 'ui-main',
|
|
templateUrl: './main.ui.html',
|
|
styleUrls: ['./main.ui.scss']
|
|
})
|
|
export class UiMain {
|
|
|
|
opened: boolean = true;
|
|
darkTheme: boolean = false;
|
|
title = 'bstlboard';
|
|
currentLocale: String;
|
|
datetimeformat: String;
|
|
locales;
|
|
authenticated: boolean = false;
|
|
moderator: boolean = false;
|
|
searchFocus: boolean = false;
|
|
hasUpdate: boolean = false;
|
|
|
|
touchThresh: number = 150;
|
|
touchStartX: number;
|
|
touchX: number;
|
|
|
|
version = packageJson.version;
|
|
|
|
constructor(
|
|
private i18n: I18nService,
|
|
private authService: AuthService,
|
|
private userService: UserService,
|
|
private settingsService: SettingsService,
|
|
private router: Router,
|
|
private iconRegistry: MatIconRegistry,
|
|
private sanitizer: DomSanitizer,
|
|
private _adapter: DateAdapter<any>, private swUpdate: SwUpdate) {
|
|
iconRegistry.addSvgIcon('logo', sanitizer.bypassSecurityTrustResourceUrl('assets/icons/logo.svg'));
|
|
|
|
this.swUpdate.versionUpdates.subscribe({
|
|
next: (evt) => {
|
|
if (evt.type == 'VERSION_READY') {
|
|
this.hasUpdate = true;
|
|
} else if (evt.type == 'VERSION_INSTALLATION_FAILED') {
|
|
console.error(`Failed to install version '${evt.version.hash}': ${evt.error}`);
|
|
}
|
|
}
|
|
})
|
|
|
|
if (this.swUpdate.isEnabled) {
|
|
// check for PWA update every 30s
|
|
setInterval(() => {
|
|
this.swUpdate.checkForUpdate();
|
|
}, 30000);
|
|
}
|
|
}
|
|
|
|
async ngOnInit() {
|
|
this.datetimeformat = this.i18n.get('format.datetime', []);
|
|
this.currentLocale = this.i18n.getLocale();
|
|
this.locales = this.i18n.getLocales();
|
|
this.authService.auth.subscribe({
|
|
next: (auth) => {
|
|
this.authenticated = true;
|
|
for (let role of auth.authorities) {
|
|
if (role.authority == 'ROLE_ADMIN' || role.authority == 'ROLE_MOD') {
|
|
this.moderator = true;
|
|
}
|
|
}
|
|
},
|
|
error: (error) => {
|
|
this.authenticated = false;
|
|
}
|
|
})
|
|
|
|
this._adapter.setLocale(this.currentLocale);
|
|
|
|
const width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
|
|
if (width < 768) {
|
|
this.opened = false;
|
|
} else {
|
|
this.opened = true;
|
|
}
|
|
|
|
if (localStorage.getItem("bstlboard.darkTheme") == "true") {
|
|
this.darkTheme = true;
|
|
window.document.body.classList.add("dark-theme");
|
|
}
|
|
|
|
await this.settingsService.getSettings();
|
|
|
|
this.touchEvents();
|
|
}
|
|
|
|
setLocale(locale) {
|
|
localStorage.setItem("bstlboard.locale", locale);
|
|
|
|
if (this.authenticated) {
|
|
this.userService.get().subscribe({
|
|
next: (user: any) => {
|
|
user.locale = locale;
|
|
this.userService.update(user).subscribe({
|
|
next: () => {
|
|
window.location.reload();
|
|
}
|
|
})
|
|
}
|
|
});
|
|
} else {
|
|
window.location.reload();
|
|
}
|
|
}
|
|
|
|
close() {
|
|
this.opened = false;
|
|
this.searchFocus = false;
|
|
}
|
|
|
|
preventClose(event) {
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
}
|
|
|
|
search(text, event) {
|
|
event.target.value = '';
|
|
event.target.blur();
|
|
if (!this.isBiggerScreen()) {
|
|
this.close();
|
|
}
|
|
if (text) {
|
|
this.router.navigate(["search"], { queryParams: { q: text } });
|
|
}
|
|
}
|
|
|
|
toggleDarkTheme() {
|
|
this.darkTheme = !this.darkTheme;
|
|
|
|
localStorage.setItem("bstlboard.darkTheme", this.darkTheme ? "true" : "false");
|
|
|
|
if (this.authenticated) {
|
|
this.userService.get().subscribe({
|
|
next: (user: any) => {
|
|
user.darkTheme = this.darkTheme;
|
|
this.userService.update(user).subscribe({
|
|
next: () => {
|
|
window.location.reload();
|
|
}
|
|
})
|
|
}
|
|
});
|
|
} else {
|
|
window.location.reload();
|
|
}
|
|
|
|
}
|
|
|
|
logout() {
|
|
localStorage.removeItem("bstlboard.autologin");
|
|
this.authService.logout().subscribe({
|
|
next: () => {
|
|
this.router.navigate([""]).then(() => {
|
|
window.location.reload();
|
|
});
|
|
}
|
|
})
|
|
}
|
|
|
|
isBiggerScreen() {
|
|
const width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
|
|
if (width < 768) {
|
|
return false;
|
|
} else {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
openExternal(event, url, target = '_self') {
|
|
window.open(url, target);
|
|
this.preventClose(event);
|
|
}
|
|
|
|
@HostListener('window:resize', ['$event'])
|
|
onResize(event) {
|
|
if (event.target.innerWidth < 768) {
|
|
this.opened = false;
|
|
} else {
|
|
this.opened = true;
|
|
}
|
|
}
|
|
|
|
touchEvents(): void {
|
|
fromEvent(document, 'touchstart').subscribe({
|
|
next: (event: TouchEvent) => {
|
|
if (event.touches[0]) {
|
|
this.touchStartX = event.touches[0].screenX;
|
|
}
|
|
}
|
|
})
|
|
|
|
fromEvent(document, 'touchmove').subscribe({
|
|
next: (event: TouchEvent) => {
|
|
if (event.touches[0]) {
|
|
this.touchX = event.touches[0].screenX;
|
|
}
|
|
}
|
|
})
|
|
|
|
fromEvent(document, 'touchend').subscribe({
|
|
next: () => {
|
|
if (this.touchX != 0) {
|
|
const touchDiff = this.touchStartX - this.touchX;
|
|
this.touchStartX = 0;
|
|
this.touchX = 0;
|
|
if (touchDiff < 0 && touchDiff < (this.touchThresh * -1) && !this.opened) {
|
|
this.opened = true;
|
|
} else if (touchDiff > 0 && touchDiff > this.touchThresh && this.opened) {
|
|
this.opened = false;
|
|
}
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
updateSw(force: boolean = false): void {
|
|
if (this.hasUpdate || force) {
|
|
if (this.swUpdate.isEnabled) {
|
|
this.swUpdate.activateUpdate().then(() => {
|
|
this.clearAndRefresh();
|
|
});
|
|
} else {
|
|
this.clearAndRefresh();
|
|
}
|
|
}
|
|
}
|
|
|
|
clearAndRefresh() {
|
|
if ('caches' in window) {
|
|
caches.keys()
|
|
.then(function (keyList) {
|
|
return Promise.all(keyList.map(function (key) {
|
|
return caches.delete(key);
|
|
}));
|
|
})
|
|
}
|
|
window.location.reload()
|
|
}
|
|
}
|
|
|