unoffical wafrn mirror wafrn.net
atproto social-network activitypub
at development 377 lines 12 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' 15import { PostsService } from './services/posts.service' 16 17@Component({ 18 selector: 'app-root', 19 templateUrl: './app.component.html', 20 styleUrls: ['./app.component.scss'], 21 standalone: false 22}) 23export class AppComponent implements OnInit { 24 private swUpdate = inject(SwUpdate); 25 private swPush = inject(SwPush); 26 private injector = inject(Injector); 27 private loginService = inject(LoginService); 28 private environmentService = inject(EnvironmentService); 29 private document = inject<Document>(DOCUMENT); 30 private translateService = inject(TranslateService); 31 private websocketService = inject(WebsocketService); 32 private router = inject(Router); 33 private messages = inject(MessageService); 34 private titleService = inject(Title); 35 private postService = inject(PostsService) 36 37 38 title = 'wafrn' 39 40 @HostBinding('attr.data-additional-style-modes') dataAdditionalStyleModes: string | null = null 41 42 constructor() { 43 const swUpdate = this.swUpdate; 44 const translateService = this.translateService; 45 const router = this.router; 46 const themeService = inject(ThemeService); 47 48 this.title = this.titleService.getTitle() 49 GlobalData.appDefaultTitle = this.title 50 51 this.translateService.addLangs([...supportedLanguages]) 52 this.translateService.setDefaultLang('en') 53 54 // User specified language 55 const userLanguage = localStorage?.getItem('appLanguage') 56 if (userLanguage !== null && translateService.langs.includes(userLanguage)) { 57 // Given the above call to add languages is correct to what we have, this should always succeed 58 translateService.use(userLanguage) 59 } 60 61 // Keep the 'lang' property up to date 62 const currentLang = this.translateService.currentLang || this.translateService.getDefaultLang() || 'en' 63 this.document.documentElement.lang = currentLang 64 this.translateService.onLangChange.subscribe((event) => { 65 this.document.documentElement.lang = event.lang 66 }) 67 68 router.events 69 .pipe( 70 filter((evt) => evt instanceof NavigationError), 71 map((evt) => evt as NavigationError) 72 ) 73 .subscribe((evt) => { 74 if (evt.error instanceof Error && evt.error.name == 'ChunkLoadError') { 75 window.location.assign(evt.url) 76 } 77 }) 78 swUpdate.unrecoverable.subscribe((event) => { 79 navigator.serviceWorker.getRegistrations().then(function (registrations) { 80 for (const registration of registrations) { 81 registration.unregister() 82 } 83 window.location.reload() 84 }) 85 }) 86 87 // Sync data value of additional style modes to root 88 effect(() => { 89 const attributeValue = Object.entries(themeService.additionalStyleModes) 90 .filter(([_, value]) => value()) 91 .map(([mode, _]) => mode) 92 .join(' ') 93 this.dataAdditionalStyleModes = attributeValue || null 94 }) 95 } 96 97 ngOnInit() { 98 99 // lets check for evil websites. fuck them. 100 const referer = document.referrer; 101 if(referer) { 102 console.log(referer) 103 try { 104 let evilUrls = [ 105 '4chan.org', 106 'p.4chan.org', 107 '8chan.org', 108 '8kun.top', 109 'kiwifarms.st', 110 'truthsocial.com', 111 'poast.org', 112 '13bells.com', 113 '1611.social', 114 '4aem.com', 115 '5dollah.click', 116 'adachi.party', 117 'adtension.com', 118 'annihilation.social', 119 'anon-kenkai.com', 120 'asbestos.cafe', 121 'bae.st', 122 'banepo.st', 123 'bassam.social', 124 'battlepenguin.video', 125 'beefyboys.win', 126 'boymoder.biz', 127 'brainsoap.net', 128 'breastmilk.club', 129 'brighteon.social', 130 'cachapa.cc', 131 'cachapa.xyz', 132 'caekis.love', 133 'cawfee.club', 134 'childlove.su', 135 'clew.lol', 136 'clubcyberia.co', 137 'contrapointsfan.club', 138 'cottoncandy.cafe', 139 'crlf.ninja', 140 'crucible.world', 141 'cum.camp', 142 'cum.salon', 143 'cunnyborea.space', 144 'decayable.ink', 145 'dembased.xyz', 146 'detroitriotcity.com', 147 'djsumdog.com', 148 'drinkanddrive.africa', 149 'eientei.org', 150 'eveningzoo.club', 151 'fluf.club', 152 'foxgirl.lol', 153 'freak.university', 154 'freeatlantis.com', 155 'freespeechextremist.com', 156 'froth.zone', 157 'fsebugoutzone.org', 158 'gameliberty.club', 159 'gearlandia.haus', 160 'genderheretics.xyz', 161 'geofront.rocks', 162 'gleasonator.com', 163 'glee.li', 164 'glindr.org', 165 'goyim.social', 166 'h5q.net', 167 'haeder.net', 168 'handholding.io', 169 'harpy.faith', 170 'hitchhiker.social', 171 'iddqd.social', 172 'kitsunemimi.club', 173 'kiwifarms.cc', 174 'kurosawa.moe', 175 'kyaruc.moe', 176 'leafposter.club', 177 'liberdon.com', 178 'ligma.pro', 179 'loli.church', 180 'lolicon.rocks', 181 'lolison.network', 182 'lolison.top', 183 'lovingexpressions.net', 184 'makemysarcophagus.com', 185 'mastinator.com', 186 'merovingian.club', 187 'midwaytrades.com', 188 'mirr0r.city', 189 'morale.ch', 190 'mouse.services', 191 'mugicha.club', 192 'narrativerry.xyz', 193 'nationalist.social', 194 'needs.vodka', 195 'neenster.org', 196 'nicecrew.digital', 197 'nightshift.social', 198 'nnia.space', 199 'noagendasocial.com', 200 'noagendatube.com', 201 'noauthority.social', 202 'nobodyhasthe.biz', 203 'norwoodzero.net', 204 'nyanide.com', 205 'onionfarms.org', 206 'parcero.casa', 207 'pawlicker.com', 208 'pawoo.net', 209 'pedo.school', 210 'peertube.se', 211 'peervideo.club', 212 'piazza.today', 213 'pibvt.net', 214 'pieville.net', 215 'pisskey.io', 216 'plagu.ee', 217 'poa.st', 218 'poast.org', 219 'poast.tv', 220 'poster.place', 221 'prospeech.space', 222 'quodverum.com', 223 'r18.social', 224 'rakket.app', 225 'rapemeat.express', 226 'rapemeat.solutions', 227 'rayci.st', 228 'rebelbase.site', 229 'ryona.agency', 230 'sad.cab', 231 'schwartzwelt.xyz', 232 'seal.cafe', 233 'shaw.app', 234 'shigusegubu.club', 235 'shitpost.cloud', 236 'shortstacksran.ch', 237 'silliness.observer', 238 'skinheads.eu', 239 'skinheads.io', 240 'skinheads.social', 241 'skinheads.uk', 242 'skippers-bin.com', 243 'skyshanty.xyz', 244 'slash.cl', 245 'sleepy.cafe', 246 'smuglo.li', 247 'sneed.social', 248 'sonichu.com', 249 'spinster.xyz', 250 'springbo.cc', 251 'strelizia.net', 252 'subs4social.xyz', 253 'taihou.website', 254 'tastingtraffic.net', 255 'teci.world', 256 'theblab.org', 257 'thechimp.zone', 258 'thenobody.club', 259 'thepostearthdestination.com', 260 'tkammer.de', 261 'trumpislovetrumpis.life', 262 'truthsocial.co.in', 263 'tsundere.love', 264 'usualsuspects.lol', 265 'vampiremaid.cafe', 266 'varishangout.net', 267 'volk.love', 268 'volk.network', 269 'wolfgirl.bar', 270 'xn--p1abe3d.xn--80asehdb', 271 'yggdrasil.social', 272 'youjo.love', 273 'zhub.link', 274 // spanish 4chan 275 'forocoches.com', 276 // finish kiwifarms 277 'ylilauta.org', 278 'hommaforum.org' 279 ] 280 const refererUrl = new URL(referer) 281 if(evilUrls.includes(refererUrl.host)) { 282 while(true) { 283 let i = 0; 284 i ++; 285 } 286 } 287 } catch (error) { 288 // we dont care too much 289 } 290 } 291 292 // unregister serviceworkers 293 /*navigator.serviceWorker.getRegistrations().then(function (registrations) { 294 for (const registration of registrations) { 295 registration.unregister(); 296 } 297 });*/ 298 const wafrnUpdated = localStorage.getItem('wafrnUpdated') 299 if (wafrnUpdated == 'true') { 300 localStorage.removeItem('wafrnUpdated') 301 this.messages.add({ severity: 'success', summary: 'Wafrn has been updated!' }) 302 } 303 if (this.swUpdate.isEnabled) { 304 console.log('SOFTWARE UPDATES ACTIVE - This is a PWA') 305 this.swUpdate.checkForUpdate().then((updateAvaiable) => { 306 if (EnvironmentService.environment.disablePWA) { 307 if ('caches' in window) { 308 caches.keys().then(function (keyList) { 309 return Promise.all( 310 keyList.map(function (key) { 311 return caches.delete(key) 312 }) 313 ) 314 }) 315 } 316 if (window.navigator && navigator.serviceWorker) { 317 navigator.serviceWorker.getRegistrations().then(function (registrations) { 318 for (const registration of registrations) { 319 registration.unregister() 320 } 321 }) 322 } 323 } 324 // we are no longer asking nicely 325 if (updateAvaiable) { 326 localStorage.setItem('wafrnUpdated', 327 'true') 328 if (window.location.toString().toLowerCase().endsWith('/editor')) { 329 if (confirm('There is an update available, would you like to update?')) { 330 window.location.reload() 331 } else { 332 alert('Please reload manualy after writing the post!') 333 } 334 } else { 335 window.location.reload() 336 } 337 } 338 }) 339 } 340 341 if (EnvironmentService.environment.disablePWA) { 342 if ('caches' in window) { 343 caches.keys().then(function (keyList) { 344 return Promise.all( 345 keyList.map(function (key) { 346 return caches.delete(key) 347 }) 348 ) 349 }) 350 } 351 if (window.navigator && navigator.serviceWorker) { 352 navigator.serviceWorker.getRegistrations().then(function (registrations) { 353 for (const registration of registrations) { 354 registration.unregister() 355 } 356 }) 357 } 358 } 359 // TODO lets keep with this later 360 /* 361 if (this.swPush.isEnabled && EnvironmentService.environment.webpushPublicKey) { 362 this.swPush 363 .requestSubscription({ 364 serverPublicKey: EnvironmentService.environment.webpushPublicKey 365 }) 366 .then((notificationSubscription) => { 367 console.log(notificationSubscription) 368 }) 369 } 370 */ 371 372 373 this.postService.loadFollowers().then(() => { 374 }) 375 376 } 377}