From aabf5c5a3c84de4f4d043bac649cadafc173fbb8 Mon Sep 17 00:00:00 2001 From: Beebles <102569435+beebls@users.noreply.github.com> Date: Sat, 1 Feb 2025 12:55:51 -0700 Subject: [PATCH] fix theme starring --- .../decky-backend-repository-impl.ts | 4 +- .../repositories/backend-repository.ts | 6 ++- src/backend/services/backend-service.ts | 6 ++- src/backend/state/theme-store.ts | 52 ++++++++++++------- .../context/ExpandedViewStore.tsx | 7 ++- .../theme-store/context/ThemeBrowserStore.tsx | 8 ++- 6 files changed, 57 insertions(+), 26 deletions(-) diff --git a/src/backend-impl/decky-backend-repository-impl.ts b/src/backend-impl/decky-backend-repository-impl.ts index 3130ed2..8356551 100644 --- a/src/backend-impl/decky-backend-repository-impl.ts +++ b/src/backend-impl/decky-backend-repository-impl.ts @@ -14,13 +14,15 @@ class DeckyBackendRepository implements IBackendRepository { ); } } - async fetch(url: string, request: RequestInit, mode: "json" | "text" = "json") { + async fetch(url: string, request: RequestInit, mode: "json" | "text" | "void" = "json") { try { console.debug("CSSLOADER FETCH", url, request); const res = await fetchNoCors(url, request); if (!res.ok) { throw new Error(`Res Not Okay - Code ${res.status}`); } + // TODO: Potentially handle void mode better + if (mode === "void") return undefined as Return; if (mode === "text") { return res.text() as Return; } diff --git a/src/backend/repositories/backend-repository.ts b/src/backend/repositories/backend-repository.ts index e1433a2..a87d784 100644 --- a/src/backend/repositories/backend-repository.ts +++ b/src/backend/repositories/backend-repository.ts @@ -1,5 +1,9 @@ export interface IBackendRepository { call: (methodName: string, args: Args) => Promise; toast: (title: string, body?: string) => void; - fetch: (url: string, request: RequestInit, mode?: "json" | "text") => Promise; + fetch: ( + url: string, + request: RequestInit, + mode?: "json" | "text" | "void" + ) => Promise; } diff --git a/src/backend/services/backend-service.ts b/src/backend/services/backend-service.ts index 304a1cf..8330047 100644 --- a/src/backend/services/backend-service.ts +++ b/src/backend/services/backend-service.ts @@ -104,7 +104,11 @@ export class Backend { async deleteTheme(themeName: string) { return await Backend.repository.call<[string], void>("delete_theme", [themeName]); } - async fetch(url: string, request: RequestInit = {}, mode: "json" | "text" = "json") { + async fetch( + url: string, + request: RequestInit = {}, + mode: "json" | "text" | "void" = "json" + ) { return Backend.repository.fetch(url, request, mode); } diff --git a/src/backend/state/theme-store.ts b/src/backend/state/theme-store.ts index fb09732..6a24fcb 100644 --- a/src/backend/state/theme-store.ts +++ b/src/backend/state/theme-store.ts @@ -50,11 +50,7 @@ export interface CSSLoaderStateActions { reloadPlugin: () => Promise; reloadThemes: () => Promise; refreshToken: () => Promise; - apiFetch: ( - url: string, - request?: RequestInit, - requiresAuth?: boolean | string - ) => Promise; + apiFetch: (url: string, request?: RequestInit, options?: FetchOptions) => Promise; logInWithShortToken: (newToken?: string) => Promise; logOut: () => void; getThemes: () => Promise; @@ -87,6 +83,12 @@ export interface CSSLoaderStateActions { setWatchState: (state: boolean) => Promise; } +export interface FetchOptions { + requiresAuth?: boolean; + customAuthToken?: string; + responseMode?: "json" | "text" | "void"; +} + export interface ICSSLoaderState extends CSSLoaderStateValues, CSSLoaderStateActions {} export const createCSSLoaderStore = (backend: Backend) => @@ -94,23 +96,26 @@ export const createCSSLoaderStore = (backend: Backend) => async function apiFetch( fetchPath: string, request?: RequestInit, - // Can be a boolean (to automatically fetch token), or a string (to use a custom token) - requiresAuth?: boolean | string + options?: FetchOptions ) { try { const { refreshToken } = get(); let authToken = undefined; - if (requiresAuth) { - authToken = typeof requiresAuth === "string" ? requiresAuth : await refreshToken(); + if (options?.requiresAuth) { + authToken = options?.customAuthToken ?? (await refreshToken()); } - return await backend.fetch(`${apiUrl}${fetchPath}`, { - method: "GET", - ...request, - headers: { - ...(request?.headers || {}), - Authorization: `Bearer ${authToken}`, + return await backend.fetch( + `${apiUrl}${fetchPath}`, + { + method: "GET", + ...request, + headers: { + ...(request?.headers || {}), + Authorization: `Bearer ${authToken}`, + }, }, - }); + options?.responseMode ?? "json" + ); } catch (error) { if (error instanceof FetchError) { throw error; @@ -121,7 +126,13 @@ export const createCSSLoaderStore = (backend: Backend) => async function getPatrons() { try { - const data = await backend.fetch(`${apiUrl}/patrons`, {}, "text"); + const data = await apiFetch( + `${apiUrl}/patrons`, + {}, + { + responseMode: "text", + } + ); if (data) { return data.split("\n"); } @@ -157,7 +168,8 @@ export const createCSSLoaderStore = (backend: Backend) => hiddenMotdId: "", serverState: false, watchState: false, - translationsBranch: "-1", + // Not entirely sure why but unless I manually type this it errors + translationsBranch: "-1" as "-1", patrons: [], initializeStore: async () => { @@ -282,7 +294,9 @@ export const createCSSLoaderStore = (backend: Backend) => apiFullToken: json.token, apiTokenExpireDate: new Date().valueOf() + 1000 * 10 * 60, }); - const meJson = await apiFetch("/auth/me", undefined, true); + const meJson = await apiFetch("/auth/me", undefined, { + requiresAuth: true, + }); if (meJson) { set({ apiMeData: meJson }); } diff --git a/src/modules/expanded-view/context/ExpandedViewStore.tsx b/src/modules/expanded-view/context/ExpandedViewStore.tsx index 4a2b2e9..d9bb68f 100644 --- a/src/modules/expanded-view/context/ExpandedViewStore.tsx +++ b/src/modules/expanded-view/context/ExpandedViewStore.tsx @@ -84,7 +84,7 @@ const expandedViewStore = createStore((set, get) => { const starResponse = await apiFetch<{ starred: boolean }>( `/users/me/stars/${themeId}`, {}, - true + { requiresAuth: true } ); if (!starResponse) { // Silently error @@ -110,7 +110,10 @@ const expandedViewStore = createStore((set, get) => { { method: isStarred ? "DELETE" : "POST", }, - true + { + requiresAuth: true, + responseMode: "void", + } ); const newIsStarred = !isStarred; set({ diff --git a/src/modules/theme-store/context/ThemeBrowserStore.tsx b/src/modules/theme-store/context/ThemeBrowserStore.tsx index c242109..83c9d06 100644 --- a/src/modules/theme-store/context/ThemeBrowserStore.tsx +++ b/src/modules/theme-store/context/ThemeBrowserStore.tsx @@ -118,7 +118,9 @@ export function ThemeBrowserStoreProvider({ const response = await apiFetch( `${filterPath}?type=${typeMapping[themeType]}`, {}, - requiresAuth + { + requiresAuth, + } ); if (response.filters) { set({ filterOptions: response }); @@ -147,7 +149,9 @@ export function ThemeBrowserStoreProvider({ const response = await apiFetch( `${themePath}?${generateParamStr(searchOpts, themeType)}`, {}, - requiresAuth + { + requiresAuth, + } ); if (response.items) { set({ themeTotal: response.total });