diff --git a/src/frontend/src/app/app.component.scss b/src/frontend/src/app/app.component.scss
index 96e55c0..13ef857 100644
--- a/src/frontend/src/app/app.component.scss
+++ b/src/frontend/src/app/app.component.scss
@@ -83,6 +83,19 @@ h1 {
background: rgba(8, 15, 15, 0.9);
}
+.auth-warning {
+ margin: 12px 24px 0;
+ padding: 12px 14px;
+ border: 1px solid rgba(255, 214, 102, 0.35);
+ border-radius: 10px;
+ background: rgba(255, 214, 102, 0.12);
+ color: #ffe3a3;
+}
+
+.auth-warning code {
+ color: #f3fff7;
+}
+
.panel-picker {
display: flex;
gap: 10px;
diff --git a/src/frontend/src/app/app.component.ts b/src/frontend/src/app/app.component.ts
index e743b48..2eae499 100644
--- a/src/frontend/src/app/app.component.ts
+++ b/src/frontend/src/app/app.component.ts
@@ -318,6 +318,7 @@ export class AppComponent implements OnDestroy {
selectedTrack$ = this.trackService.selectedTrack$;
version = this.versionService.getVersion();
spotifyConnected = false;
+ authTokenPresent = Boolean(localStorage.getItem('spooty_auth_token'));
archiveDestination = localStorage.getItem(ARCHIVE_DESTINATION_KEY) || '';
archiveListing?: ArchiveListing;
archiveLoading = false;
@@ -370,6 +371,7 @@ export class AppComponent implements OnDestroy {
}
localStorage.setItem('spooty_auth_token', token);
+ this.authTokenPresent = true;
url.searchParams.delete('token');
window.history.replaceState({}, document.title, url.toString());
}
@@ -377,7 +379,13 @@ export class AppComponent implements OnDestroy {
checkSpotifyStatus(): void {
this.http
.get<{ connected: boolean }>('/api/spotify/status')
- .subscribe((status) => (this.spotifyConnected = status.connected));
+ .subscribe({
+ next: (status) => (this.spotifyConnected = status.connected),
+ error: (error) => {
+ console.error('Failed to check Spotify status', error);
+ this.spotifyConnected = false;
+ },
+ });
}
connectSpotify(): void {
diff --git a/src/frontend/src/app/services/playlist.service.ts b/src/frontend/src/app/services/playlist.service.ts
index 90863da..703783b 100644
--- a/src/frontend/src/app/services/playlist.service.ts
+++ b/src/frontend/src/app/services/playlist.service.ts
@@ -11,7 +11,7 @@ import {
withUIEntities
} from "@ngneat/elf-entities";
import {joinRequestResult, trackRequestResult} from "@ngneat/elf-requests";
-import {combineLatest, filter, first, map, Observable, of, switchMap, tap} from "rxjs";
+import {catchError, combineLatest, filter, first, map, Observable, of, switchMap, tap} from "rxjs";
import {TrackService} from "./track.service";
import {Socket} from "ngx-socket-io";
import {Playlist} from "../models/playlist";
@@ -115,6 +115,14 @@ export class PlaylistService {
fetch(): void {
this.http.get
(ENDPOINT).pipe(
+ catchError((error) => {
+ console.error('Failed to fetch playlists', error);
+ this.store.update(
+ setEntities([]),
+ setEntities([], { ref: UIEntitiesRef }),
+ );
+ return of([]);
+ }),
tap((data: Playlist[]) => this.store.update(
setEntities(data),
setEntities(data.map(item => ({id: item.id, collapsed: false})), {ref: UIEntitiesRef})