Use function HTTP interceptor for UI tick fallback

pull/1163/head
voc0der 2 months ago
parent 13591840c7
commit d017ce7ecc

@ -37,7 +37,7 @@ import { TextFieldModule } from '@angular/cdk/text-field';
import { ScrollingModule } from '@angular/cdk/scrolling';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { HTTP_INTERCEPTORS, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
import { provideHttpClient, withInterceptors } from '@angular/common/http';
import { PostsService } from 'app/posts.services';
import { RouterModule } from '@angular/router';
import { AppRoutingModule } from './app-routing.module';
@ -83,7 +83,7 @@ import { CustomPlaylistsComponent } from './components/custom-playlists/custom-p
import { EditCategoryDialogComponent } from './dialogs/edit-category-dialog/edit-category-dialog.component';
import { TwitchChatComponent } from './components/twitch-chat/twitch-chat.component';
import { LinkifyPipe, SeeMoreComponent } from './components/see-more/see-more.component';
import { H401Interceptor } from './http.interceptor';
import { h401InterceptorFn } from './http.interceptor';
import { ConcurrentStreamComponent } from './components/concurrent-stream/concurrent-stream.component';
import { SkipAdButtonComponent } from './components/skip-ad-button/skip-ad-button.component';
import { TasksComponent } from './components/tasks/tasks.component';
@ -206,9 +206,8 @@ registerLocaleData(es, 'es');
],
providers: [
PostsService,
{ provide: HTTP_INTERCEPTORS, useClass: H401Interceptor, multi: true },
DatePipe,
provideHttpClient(withInterceptorsFromDi())
provideHttpClient(withInterceptors([h401InterceptorFn]))
],
bootstrap: [AppComponent]
})

@ -1,34 +1,50 @@
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { HttpErrorResponse, HttpInterceptorFn } from '@angular/common/http';
import { ApplicationRef, inject } from '@angular/core';
import { MatSnackBar } from '@angular/material/snack-bar';
import { Router } from '@angular/router';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { throwError } from 'rxjs';
import { catchError, tap } from 'rxjs/operators';
@Injectable()
export class H401Interceptor implements HttpInterceptor {
let tickQueued = false;
constructor(private router: Router, private snackBar: MatSnackBar) { }
function scheduleUiTick(appRef: ApplicationRef): void {
if (tickQueued) {
return;
}
tickQueued = true;
setTimeout(() => {
tickQueued = false;
try {
appRef.tick();
} catch {
// Ignore if Angular is mid-navigation or being destroyed.
}
});
}
export const h401InterceptorFn: HttpInterceptorFn = (request, next) => {
const router = inject(Router);
const snackBar = inject(MatSnackBar);
const appRef = inject(ApplicationRef);
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request).pipe(catchError(err => {
return next(request).pipe(
tap({
next: () => scheduleUiTick(appRef),
error: () => scheduleUiTick(appRef),
complete: () => scheduleUiTick(appRef)
}),
catchError((err: HttpErrorResponse) => {
if (err.status === 401) {
localStorage.setItem('jwt_token', null);
if (this.router.url !== '/login' && !this.router.url.includes('player')) {
this.router.navigate(['/login']).then(() => {
this.openSnackBar('Login expired, please login again.');
if (router.url !== '/login' && !router.url.includes('player')) {
router.navigate(['/login']).then(() => {
snackBar.open('Login expired, please login again.', '', { duration: 2000 });
});
}
}
const error = err.error.message || err.statusText;
const error = err?.error?.message || err?.statusText || 'Request failed';
return throwError(error);
}));
}
public openSnackBar(message: string, action: string = '') {
this.snackBar.open(message, action, {
duration: 2000,
});
}
}
})
);
};

Loading…
Cancel
Save