unoffical wafrn mirror wafrn.net
atproto social-network activitypub
at angular21 174 lines 6.3 kB view raw
1import { Component, Injector, OnInit, DOCUMENT, HostBinding, ElementRef, effect, inject } from '@angular/core' 2import { SwUpdate } from '@angular/service-worker' 3import { LoginService } from './services/login.service' 4import { EnvironmentService } from './services/environment.service' 5import { TranslateService } from '@ngx-translate/core' 6import { SwPush } from '@angular/service-worker' 7import { Title } from '@angular/platform-browser' 8import { GlobalData } from './services/global-data.service' 9import { WebsocketService } from './services/websocket.service' 10import { NavigationError, Router } from '@angular/router' 11import { filter, map } from 'rxjs' 12import { MessageService } from './services/message.service' 13import { supportedLanguages } from './lists/languages' 14import { ThemeService } from './services/theme.service' 15 16@Component({ 17 selector: 'app-root', 18 templateUrl: './app.component.html', 19 styleUrls: ['./app.component.scss'], 20 standalone: false 21}) 22export class AppComponent implements OnInit { 23 private swUpdate = inject(SwUpdate); 24 private swPush = inject(SwPush); 25 private injector = inject(Injector); 26 private loginService = inject(LoginService); 27 private environmentService = inject(EnvironmentService); 28 private document = inject<Document>(DOCUMENT); 29 private translateService = inject(TranslateService); 30 private websocketService = inject(WebsocketService); 31 private router = inject(Router); 32 private messages = inject(MessageService); 33 private titleService = inject(Title); 34 35 title = 'wafrn' 36 37 @HostBinding('attr.data-additional-style-modes') dataAdditionalStyleModes: string | null = null 38 39 constructor() { 40 const swUpdate = this.swUpdate; 41 const translateService = this.translateService; 42 const router = this.router; 43 const themeService = inject(ThemeService); 44 45 this.title = this.titleService.getTitle() 46 GlobalData.appDefaultTitle = this.title 47 48 this.translateService.addLangs([...supportedLanguages]) 49 this.translateService.setDefaultLang('en') 50 51 // User specified language 52 const userLanguage = localStorage?.getItem('appLanguage') 53 if (userLanguage !== null && translateService.langs.includes(userLanguage)) { 54 // Given the above call to add languages is correct to what we have, this should always succeed 55 translateService.use(userLanguage) 56 } 57 58 // Keep the 'lang' property up to date 59 const currentLang = this.translateService.currentLang || this.translateService.getDefaultLang() || 'en' 60 this.document.documentElement.lang = currentLang 61 this.translateService.onLangChange.subscribe((event) => { 62 this.document.documentElement.lang = event.lang 63 }) 64 65 router.events 66 .pipe( 67 filter((evt) => evt instanceof NavigationError), 68 map((evt) => evt as NavigationError) 69 ) 70 .subscribe((evt) => { 71 if (evt.error instanceof Error && evt.error.name == 'ChunkLoadError') { 72 window.location.assign(evt.url) 73 } 74 }) 75 swUpdate.unrecoverable.subscribe((event) => { 76 navigator.serviceWorker.getRegistrations().then(function (registrations) { 77 for (const registration of registrations) { 78 registration.unregister() 79 } 80 window.location.reload() 81 }) 82 }) 83 84 // Sync data value of additional style modes to root 85 effect(() => { 86 const attributeValue = Object.entries(themeService.additionalStyleModes) 87 .filter(([_, value]) => value()) 88 .map(([mode, _]) => mode) 89 .join(' ') 90 this.dataAdditionalStyleModes = attributeValue || null 91 }) 92 } 93 94 ngOnInit() { 95 // unregister serviceworkers 96 /*navigator.serviceWorker.getRegistrations().then(function (registrations) { 97 for (const registration of registrations) { 98 registration.unregister(); 99 } 100 });*/ 101 const wafrnUpdated = localStorage.getItem('wafrnUpdated') 102 if (wafrnUpdated == 'true') { 103 localStorage.removeItem('wafrnUpdated') 104 this.messages.add({ severity: 'success', summary: 'Wafrn has been updated!' }) 105 } 106 if (this.swUpdate.isEnabled) { 107 console.log('SOFTWARE UPDATES ACTIVE - This is a PWA') 108 this.swUpdate.checkForUpdate().then((updateAvaiable) => { 109 if (EnvironmentService.environment.disablePWA) { 110 if ('caches' in window) { 111 caches.keys().then(function (keyList) { 112 return Promise.all( 113 keyList.map(function (key) { 114 return caches.delete(key) 115 }) 116 ) 117 }) 118 } 119 if (window.navigator && navigator.serviceWorker) { 120 navigator.serviceWorker.getRegistrations().then(function (registrations) { 121 for (const registration of registrations) { 122 registration.unregister() 123 } 124 }) 125 } 126 } 127 // we are no longer asking nicely 128 if (updateAvaiable) { 129 localStorage.setItem('wafrnUpdated', 'true') 130 if (window.location.toString().toLowerCase().endsWith('/editor')) { 131 if (confirm('There is an update available, would you like to update?')) { 132 window.location.reload() 133 } else { 134 alert('Please reload manualy after writing the post!') 135 } 136 } else { 137 window.location.reload() 138 } 139 } 140 }) 141 } 142 143 if (EnvironmentService.environment.disablePWA) { 144 if ('caches' in window) { 145 caches.keys().then(function (keyList) { 146 return Promise.all( 147 keyList.map(function (key) { 148 return caches.delete(key) 149 }) 150 ) 151 }) 152 } 153 if (window.navigator && navigator.serviceWorker) { 154 navigator.serviceWorker.getRegistrations().then(function (registrations) { 155 for (const registration of registrations) { 156 registration.unregister() 157 } 158 }) 159 } 160 } 161 // TODO lets keep with this later 162 /* 163 if (this.swPush.isEnabled && EnvironmentService.environment.webpushPublicKey) { 164 this.swPush 165 .requestSubscription({ 166 serverPublicKey: EnvironmentService.environment.webpushPublicKey 167 }) 168 .then((notificationSubscription) => { 169 console.log(notificationSubscription) 170 }) 171 } 172 */ 173 } 174}