move some settings to server side

This commit is contained in:
sam 2023-09-09 00:58:02 +02:00
parent 6c8f2b648e
commit c780470afe
No known key found for this signature in database
GPG key ID: B4EF20DDE721CAA1
5 changed files with 107 additions and 27 deletions

View file

@ -62,6 +62,11 @@ export interface MeUser extends User {
timezone: string | null; timezone: string | null;
} }
export interface Settings {
read_changelog: string;
read_settings_notice: string;
}
export interface Field { export interface Field {
name: string; name: string;
entries: FieldEntry[]; entries: FieldEntry[];

View file

@ -11,9 +11,16 @@ export async function apiFetch<T>(
body, body,
token, token,
headers, headers,
}: { method?: string; body?: any; token?: string; headers?: Record<string, string> }, version,
}: {
method?: string;
body?: any;
token?: string;
headers?: Record<string, string>;
version?: number;
},
) { ) {
const resp = await fetch(`${PUBLIC_BASE_URL}/api/v1${path}`, { const resp = await fetch(`${PUBLIC_BASE_URL}/api/v${version || 1}${path}`, {
method: method || "GET", method: method || "GET",
headers: { headers: {
...(token ? { Authorization: token } : {}), ...(token ? { Authorization: token } : {}),
@ -28,12 +35,18 @@ export async function apiFetch<T>(
return data as T; return data as T;
} }
export const apiFetchClient = async <T>(path: string, method = "GET", body: any = null) => { export const apiFetchClient = async <T>(
path: string,
method = "GET",
body: any = null,
version = 1,
) => {
try { try {
const data = await apiFetch<T>(path, { const data = await apiFetch<T>(path, {
method, method,
body, body,
token: localStorage.getItem("pronouns-token") || undefined, token: localStorage.getItem("pronouns-token") || undefined,
version,
}); });
return data; return data;
} catch (e) { } catch (e) {
@ -55,9 +68,16 @@ export async function fastFetch(
body, body,
token, token,
headers, headers,
}: { method?: string; body?: any; token?: string; headers?: Record<string, string> }, version,
}: {
method?: string;
body?: any;
token?: string;
headers?: Record<string, string>;
version?: number;
},
) { ) {
const resp = await fetch(`${PUBLIC_BASE_URL}/api/v1${path}`, { const resp = await fetch(`${PUBLIC_BASE_URL}/api/v${version || 1}${path}`, {
method: method || "GET", method: method || "GET",
headers: { headers: {
...(token ? { Authorization: token } : {}), ...(token ? { Authorization: token } : {}),
@ -71,12 +91,18 @@ export async function fastFetch(
} }
/** Fetches the specified path without parsing the response body. */ /** Fetches the specified path without parsing the response body. */
export const fastFetchClient = async (path: string, method = "GET", body: any = null) => { export const fastFetchClient = async (
path: string,
method = "GET",
body: any = null,
version = 1,
) => {
try { try {
await fastFetch(path, { await fastFetch(path, {
method, method,
body, body,
token: localStorage.getItem("pronouns-token") || undefined, token: localStorage.getItem("pronouns-token") || undefined,
version,
}); });
} catch (e) { } catch (e) {
if ((e as APIError).code === ErrorCode.InvalidToken) { if ((e as APIError).code === ErrorCode.InvalidToken) {

View file

@ -1,7 +1,7 @@
import { writable } from "svelte/store"; import { writable } from "svelte/store";
import { browser } from "$app/environment"; import { browser } from "$app/environment";
import type { MeUser } from "./api/entities"; import type { MeUser, Settings } from "./api/entities";
const initialUserValue = null; const initialUserValue = null;
export const userStore = writable<MeUser | null>(initialUserValue); export const userStore = writable<MeUser | null>(initialUserValue);
@ -13,4 +13,10 @@ const initialThemeValue = browser
export const themeStore = writable<string>(initialThemeValue); export const themeStore = writable<string>(initialThemeValue);
const defaultSettingsValue = {
settings: { read_changelog: "0.0.0", read_settings_notice: "0" } as Settings,
current: false,
};
export const settingsStore = writable(defaultSettingsValue);
export const CURRENT_CHANGELOG = "0.6.0"; export const CURRENT_CHANGELOG = "0.6.0";

View file

@ -17,13 +17,14 @@
} from "sveltestrap"; } from "sveltestrap";
import Logo from "./Logo.svelte"; import Logo from "./Logo.svelte";
import { userStore, themeStore, CURRENT_CHANGELOG } from "$lib/store"; import { userStore, themeStore, CURRENT_CHANGELOG, settingsStore } from "$lib/store";
import { import {
ErrorCode, ErrorCode,
type APIError, type APIError,
type MeUser, type MeUser,
type Report, type Report,
type Warning, type Warning,
type Settings,
} from "$lib/api/entities"; } from "$lib/api/entities";
import { apiFetch, apiFetchClient } from "$lib/api/fetch"; import { apiFetch, apiFetchClient } from "$lib/api/fetch";
import { addToast } from "$lib/toast"; import { addToast } from "$lib/toast";
@ -37,14 +38,11 @@
let isAdmin = false; let isAdmin = false;
let numReports = 0; let numReports = 0;
let numWarnings = 0; let numWarnings = 0;
let changelogRead = "99.99.99";
$: currentUser = $userStore; $: currentUser = $userStore;
$: theme = $themeStore; $: theme = $themeStore;
onMount(() => { onMount(() => {
changelogRead = localStorage.getItem("changelog-read") || "0.0.0";
const localUser = localStorage.getItem("pronouns-user"); const localUser = localStorage.getItem("pronouns-user");
userStore.set(localUser ? JSON.parse(localUser) : null); userStore.set(localUser ? JSON.parse(localUser) : null);
@ -78,6 +76,38 @@
}); });
} }
apiFetchClient<Settings>("/users/@me/settings", "GET", null, 2)
.then((data) => {
settingsStore.set({ current: true, settings: data });
})
.catch((e) => {
console.log("getting user settings:", e);
});
// TODO: is there a cleaner way to do this? also, remove this eventually
const oldChangelogRead = localStorage.getItem("changelog-read");
const oldSettingsNotice = localStorage.getItem("alert-1681976313");
if (oldChangelogRead || oldSettingsNotice) {
localStorage.removeItem("changelog-read");
localStorage.removeItem("alert-1681976313");
apiFetchClient<Settings>(
"/users/@me/settings",
"PATCH",
{
read_changelog: oldChangelogRead ? oldChangelogRead : undefined,
read_settings_notice: oldSettingsNotice ? "1681976313" : undefined,
},
2,
)
.then((data) => {
settingsStore.set({ current: true, settings: data });
})
.catch((e) => {
console.log("updating user settings:", e);
});
}
apiFetchClient<Warning[]>("/auth/warnings") apiFetchClient<Warning[]>("/auth/warnings")
.then((warnings) => { .then((warnings) => {
if (warnings.length !== 0) { if (warnings.length !== 0) {
@ -157,7 +187,7 @@
</NavLink> </NavLink>
</NavItem> </NavItem>
{/if} {/if}
{#if changelogRead < CURRENT_CHANGELOG} {#if $settingsStore.current && $settingsStore.settings.read_changelog < CURRENT_CHANGELOG}
<NavItem> <NavItem>
<NavLink href="/page/changelog" active={$page.url.pathname === "/page/changelog"}> <NavLink href="/page/changelog" active={$page.url.pathname === "/page/changelog"}>
Changelog <Badge color="secondary">v{CURRENT_CHANGELOG}</Badge> Changelog <Badge color="secondary">v{CURRENT_CHANGELOG}</Badge>

View file

@ -6,12 +6,13 @@
type APIError, type APIError,
MAX_MEMBERS, MAX_MEMBERS,
MAX_FIELDS, MAX_FIELDS,
type Settings,
} from "$lib/api/entities"; } from "$lib/api/entities";
import { apiFetchClient, fastFetchClient } from "$lib/api/fetch"; import { apiFetchClient, fastFetchClient } from "$lib/api/fetch";
import { usernameRegex } from "$lib/api/regex"; import { usernameRegex } from "$lib/api/regex";
import ErrorAlert from "$lib/components/ErrorAlert.svelte"; import ErrorAlert from "$lib/components/ErrorAlert.svelte";
import FallbackImage from "$lib/components/FallbackImage.svelte"; import FallbackImage from "$lib/components/FallbackImage.svelte";
import { userStore } from "$lib/store"; import { settingsStore, userStore } from "$lib/store";
import { addToast } from "$lib/toast"; import { addToast } from "$lib/toast";
import { import {
Alert, Alert,
@ -91,21 +92,36 @@
} }
}; };
const DONATE_ALERT_STORE = "alert-1681976313"; const CURRENT_ALERT = "1681976313";
let donateAlertOpen = false; const closeDonateAlert = async () => {
const closeDonateAlert = () => { try {
donateAlertOpen = false; const settings = await apiFetchClient<Settings>(
localStorage.setItem(DONATE_ALERT_STORE, "dismissed"); "/users/@me/settings",
}; "PATCH",
{
read_settings_notice: CURRENT_ALERT,
},
2,
);
onMount(() => { settingsStore.set({ current: true, settings });
if (!localStorage.getItem(DONATE_ALERT_STORE)) { error = null;
donateAlertOpen = true; } catch (e) {
error = e as APIError;
} }
}); };
</script> </script>
<Alert color="secondary" fade={false} isOpen={donateAlertOpen} toggle={closeDonateAlert}> {#if error}
<ErrorAlert {error} />
{/if}
<Alert
color="secondary"
fade={false}
isOpen={$settingsStore.current && $settingsStore.settings.read_settings_notice < CURRENT_ALERT}
toggle={closeDonateAlert}
>
If you find pronouns.cc useful and have the means, I would really appreciate a <a If you find pronouns.cc useful and have the means, I would really appreciate a <a
href="https://liberapay.com/u1f320/" href="https://liberapay.com/u1f320/"
target="_blank">donation</a target="_blank">donation</a
@ -150,9 +166,6 @@
{/if} {/if}
</p> </p>
{/if} {/if}
{#if error}
<ErrorAlert {error} />
{/if}
</div> </div>
<div class="col-lg-4"> <div class="col-lg-4">
<p class="text-center"> <p class="text-center">