music on atproto
plyr.fm
1import { browser } from '$app/environment';
2import { API_URL } from '$lib/config';
3import type { User } from '$lib/types';
4import type { Preferences } from '$lib/preferences.svelte';
5import type { SensitiveImagesData } from '$lib/moderation.svelte';
6import type { LoadEvent } from '@sveltejs/kit';
7
8export interface LayoutData {
9 user: User | null;
10 isAuthenticated: boolean;
11 preferences: Preferences | null;
12 sensitiveImages: SensitiveImagesData;
13}
14
15const DEFAULT_PREFERENCES: Preferences = {
16 accent_color: null,
17 auto_advance: true,
18 allow_comments: true,
19 hidden_tags: ['ai'],
20 theme: 'dark',
21 enable_teal_scrobbling: false,
22 teal_needs_reauth: false,
23 show_sensitive_artwork: false,
24 show_liked_on_profile: false,
25 support_url: null,
26 ui_settings: {},
27 auto_download_liked: false
28};
29
30export async function load({ fetch, data }: LoadEvent): Promise<LayoutData> {
31 const sensitiveImages = data?.sensitiveImages ?? { image_ids: [], urls: [] };
32
33 if (!browser) {
34 return {
35 user: null,
36 isAuthenticated: false,
37 preferences: null,
38 sensitiveImages
39 };
40 }
41
42 try {
43 const response = await fetch(`${API_URL}/auth/me`, {
44 credentials: 'include'
45 });
46
47 if (response.ok) {
48 const user = await response.json();
49
50 // fetch preferences in parallel once we know user is authenticated
51 let preferences: Preferences = { ...DEFAULT_PREFERENCES };
52 try {
53 const prefsResponse = await fetch(`${API_URL}/preferences/`, {
54 credentials: 'include'
55 });
56 if (prefsResponse.ok) {
57 const prefsData = await prefsResponse.json();
58 // auto_download_liked is stored locally, not on server
59 const storedAutoDownload = typeof localStorage !== 'undefined'
60 ? localStorage.getItem('autoDownloadLiked') === '1'
61 : false;
62 preferences = {
63 accent_color: prefsData.accent_color ?? null,
64 auto_advance: prefsData.auto_advance ?? true,
65 allow_comments: prefsData.allow_comments ?? true,
66 hidden_tags: prefsData.hidden_tags ?? ['ai'],
67 theme: prefsData.theme ?? 'dark',
68 enable_teal_scrobbling: prefsData.enable_teal_scrobbling ?? false,
69 teal_needs_reauth: prefsData.teal_needs_reauth ?? false,
70 show_sensitive_artwork: prefsData.show_sensitive_artwork ?? false,
71 show_liked_on_profile: prefsData.show_liked_on_profile ?? false,
72 support_url: prefsData.support_url ?? null,
73 ui_settings: prefsData.ui_settings ?? {},
74 auto_download_liked: storedAutoDownload
75 };
76 }
77 } catch (e) {
78 console.error('preferences fetch failed:', e);
79 }
80
81 return {
82 user,
83 isAuthenticated: true,
84 preferences,
85 sensitiveImages
86 };
87 }
88 } catch (e) {
89 console.error('auth check failed:', e);
90 }
91
92 return {
93 user: null,
94 isAuthenticated: false,
95 preferences: null,
96 sensitiveImages
97 };
98}