unoffical wafrn mirror
wafrn.net
atproto
social-network
activitypub
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}