6b7e4f1dee
Web client posts Intl.DateTimeFormat().resolvedOptions().timeZone to PUT /api/me/timezone after every successful login, register, and bootstrap when the locally-stored tz_last_sent_at is >7 days old. Cadence tracked in localStorage keeps the server stateless on the "is this stale?" check. Failures swallowed: the server's UTC default + last-known value keep the scheduler functioning until the next successful attempt. SSR- safe via the typeof window guard. For #392 Half B. Companion Flutter change in next commit. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
65 lines
2.1 KiB
TypeScript
65 lines
2.1 KiB
TypeScript
import { createQuery } from '@tanstack/svelte-query';
|
|
import { api } from './client';
|
|
import { qk } from './queries';
|
|
|
|
export type SystemPlaylistsStatus = {
|
|
in_flight: boolean;
|
|
last_run_at: string | null;
|
|
last_error: string | null;
|
|
};
|
|
|
|
export async function getSystemPlaylistsStatus(): Promise<SystemPlaylistsStatus> {
|
|
return api.get<SystemPlaylistsStatus>('/api/me/system-playlists-status');
|
|
}
|
|
|
|
// Refresh aggressively while a build is in_flight so the building → built
|
|
// transition appears live on the home page. Stale-time is short; manual
|
|
// invalidations on the server's POST endpoints are out of scope.
|
|
export function createSystemPlaylistsStatusQuery() {
|
|
return createQuery({
|
|
queryKey: qk.systemPlaylistsStatus(),
|
|
queryFn: getSystemPlaylistsStatus,
|
|
staleTime: 10_000
|
|
});
|
|
}
|
|
|
|
// Self-service profile / password / API-token endpoints (U3) ---------------
|
|
|
|
export type MyProfile = {
|
|
id: string;
|
|
username: string;
|
|
display_name: string | null;
|
|
email: string | null;
|
|
is_admin: boolean;
|
|
};
|
|
|
|
export type APITokenResponse = { api_token: string };
|
|
|
|
export async function changePassword(currentPassword: string, newPassword: string): Promise<void> {
|
|
await api.put('/api/me/password', {
|
|
current_password: currentPassword,
|
|
new_password: newPassword,
|
|
});
|
|
}
|
|
|
|
export async function updateProfile(input: { display_name?: string; email?: string }): Promise<MyProfile> {
|
|
return api.put<MyProfile>('/api/me/profile', input);
|
|
}
|
|
|
|
export async function getAPIToken(): Promise<APITokenResponse> {
|
|
return api.get<APITokenResponse>('/api/me/api-token');
|
|
}
|
|
|
|
export async function regenerateAPIToken(): Promise<APITokenResponse> {
|
|
return api.post<APITokenResponse>('/api/me/api-token', {});
|
|
}
|
|
|
|
// Submits the browser's current IANA timezone for the authenticated
|
|
// user. Called from the auth store on login + bootstrap + once weekly
|
|
// (cadence tracked client-side in localStorage). Failures are
|
|
// non-fatal — the server's UTC fallback keeps the scheduler working
|
|
// until the next attempt.
|
|
export async function putMyTimezone(timezone: string): Promise<void> {
|
|
await api.put<void>('/api/me/timezone', { timezone });
|
|
}
|