forked from mirrors/pronouns.cc
move some settings to server side
This commit is contained in:
parent
6c8f2b648e
commit
c780470afe
5 changed files with 107 additions and 27 deletions
|
@ -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[];
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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";
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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">
|
||||||
|
|
Loading…
Reference in a new issue