From a183974d20cfd18fbc28febf71ce1fcee062fa76 Mon Sep 17 00:00:00 2001 From: Leo dev Date: Wed, 15 Oct 2025 11:13:58 +0200 Subject: [PATCH] User profile request caching --- package-lock.json | 47 ++++++++++++++++++++++++++++++++++---- package.json | 3 ++- src/components/Sidebar.tsx | 19 +++++++-------- src/hooks/get-user.ts | 6 ++--- src/lib/auth.ts | 4 ++-- src/lib/request.ts | 32 ++++++++++++++++++++++++++ 6 files changed, 91 insertions(+), 20 deletions(-) create mode 100644 src/lib/request.ts diff --git a/package-lock.json b/package-lock.json index e1c1033..b8236ba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,6 +27,7 @@ "@types/http-status-codes": "^1.2.0", "@types/js-cookie": "^3.0.6", "axios": "^1.12.2", + "axios-cache-interceptor": "^1.8.3", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "cmdk": "^1.1.1", @@ -50,7 +51,7 @@ }, "devDependencies": { "@tailwindcss/postcss": "^4", - "@types/node": "^20.19.11", + "@types/node": "^20.19.21", "@types/pg": "^8.15.5", "@types/react": "^19", "@types/react-dom": "^19", @@ -2322,9 +2323,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "20.19.11", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.11.tgz", - "integrity": "sha512-uug3FEEGv0r+jrecvUUpbY8lLisvIjg6AAic6a2bSP5OEOLeJsDSnvhCDov7ipFFMXS3orMpzlmi0ZcuGkBbow==", + "version": "20.19.21", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.21.tgz", + "integrity": "sha512-CsGG2P3I5y48RPMfprQGfy4JPRZ6csfC3ltBZSRItG3ngggmNY/qs2uZKp4p9VbrpqNNSMzUZNFZKzgOGnd/VA==", "license": "MIT", "dependencies": { "undici-types": "~6.21.0" @@ -2417,6 +2418,26 @@ "proxy-from-env": "^1.1.0" } }, + "node_modules/axios-cache-interceptor": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/axios-cache-interceptor/-/axios-cache-interceptor-1.8.3.tgz", + "integrity": "sha512-ifuSBoCEkVaiugg1UTjVuTdK+SjSOJ35pdv2OrzhRT3wDMr52QiayQxUqs7jd7GDsfPOjMcw3T3ek0TysbyZZw==", + "license": "MIT", + "dependencies": { + "cache-parser": "1.2.5", + "fast-defer": "1.1.8", + "object-code": "1.3.3" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/arthurfiorette/axios-cache-interceptor?sponsor=1" + }, + "peerDependencies": { + "axios": "^1" + } + }, "node_modules/bail": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", @@ -2427,6 +2448,12 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/cache-parser": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/cache-parser/-/cache-parser-1.2.5.tgz", + "integrity": "sha512-Md/4VhAHByQ9frQ15WD6LrMNiVw9AEl/J7vWIXw+sxT6fSOpbtt6LHTp76vy8+bOESPBO94117Hm2bIjlI7XjA==", + "license": "MIT" + }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", @@ -2839,6 +2866,12 @@ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "license": "MIT" }, + "node_modules/fast-defer": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/fast-defer/-/fast-defer-1.1.8.tgz", + "integrity": "sha512-lEJeOH5VL5R09j6AA0D4Uvq7AgsHw0dAImQQ+F3iSyHZuAxyQfWobsagGpTcOPvJr3urmKRHrs+Gs9hV+/Qm/Q==", + "license": "MIT" + }, "node_modules/flairup": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/flairup/-/flairup-1.0.0.tgz", @@ -4513,6 +4546,12 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/object-code": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/object-code/-/object-code-1.3.3.tgz", + "integrity": "sha512-/Ds4Xd5xzrtUOJ+xJQ57iAy0BZsZltOHssnDgcZ8DOhgh41q1YJCnTPnWdWSLkNGNnxYzhYChjc5dgC9mEERCA==", + "license": "MIT" + }, "node_modules/parse-entities": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz", diff --git a/package.json b/package.json index 6b383a7..9106001 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "@types/http-status-codes": "^1.2.0", "@types/js-cookie": "^3.0.6", "axios": "^1.12.2", + "axios-cache-interceptor": "^1.8.3", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "cmdk": "^1.1.1", @@ -53,7 +54,7 @@ }, "devDependencies": { "@tailwindcss/postcss": "^4", - "@types/node": "^20.19.11", + "@types/node": "^20.19.21", "@types/pg": "^8.15.5", "@types/react": "^19", "@types/react-dom": "^19", diff --git a/src/components/Sidebar.tsx b/src/components/Sidebar.tsx index d2ee6d3..a88c951 100644 --- a/src/components/Sidebar.tsx +++ b/src/components/Sidebar.tsx @@ -34,6 +34,7 @@ import { StringMap } from "@/types/typeUtils"; import SettingsDialog from "./settings/SettingsDialog"; import Link from "next/link"; import axios from "axios"; +import { get, Response } from "@/lib/request"; export default function AppSidebar({ children, @@ -327,15 +328,15 @@ function getUser( ) { if (userList[id]) return userList[id]; - axios - .get(`/api/profile/?id=${id}`) - ?.then((res) => { - console.log("Fetched user", res.data); - setUserList((prev) => { - prev[id] = res.data as UserProfile; - return prev; - }); - }) + const onResponse = (res: Response) => { + setUserList((prev) => { + prev[id] = res.data as UserProfile; + return prev; + }); + }; + + get(`/api/profile/?id=${id}`, onResponse) + ?.then(onResponse) .catch((e) => { console.error(e); }); diff --git a/src/hooks/get-user.ts b/src/hooks/get-user.ts index 1c693f9..901c6da 100644 --- a/src/hooks/get-user.ts +++ b/src/hooks/get-user.ts @@ -1,10 +1,10 @@ "use client"; import { ProfileSettings } from "@/types/settings"; -import axios from "axios"; import Cookies from "js-cookie"; import { useRouter } from "next/navigation"; import { useEffect, useState } from "react"; +import { get } from "@/lib/request"; export interface UserProfile extends ProfileSettings { id: string; @@ -23,9 +23,7 @@ export default function useUser() { } try { - const res = (await axios.get("/api/profile")).data as UserProfile; - - setUser(res); + setUser((await get("/api/profile")).data); } catch { router.push("/login"); } diff --git a/src/lib/auth.ts b/src/lib/auth.ts index 083d5fd..9022e5c 100644 --- a/src/lib/auth.ts +++ b/src/lib/auth.ts @@ -1,6 +1,7 @@ import { Message, Server } from "@/types/types"; import axios from "axios"; import { Dispatch, RefObject, SetStateAction } from "react"; +import { get } from "./request"; export default async function auth( id: string, @@ -12,8 +13,7 @@ export default async function auth( ) { console.log("Authenticating with server id:", id); - const ip = ((await axios.get(`/api/server/${id}`)).data as any) - .address as string; + const ip = ((await get(`/api/server/${id}`)).data as any).address as string; console.log("Authenticating with server at:", ip); const server_auth = ( diff --git a/src/lib/request.ts b/src/lib/request.ts new file mode 100644 index 0000000..221ec47 --- /dev/null +++ b/src/lib/request.ts @@ -0,0 +1,32 @@ +import Axios from "axios"; +import { CacheRequestConfig, setupCache } from "axios-cache-interceptor"; + +const axiosInstance = Axios.create({}); +const axios = setupCache(axiosInstance); + +export interface Response { + data: T; + status: number; + statusText: string; + headers: { [index: string]: any }; + cached: boolean; +} + +export async function get( + url: string, + onResponse?: (response: Response) => void, + config?: CacheRequestConfig +): Promise> { + const response = (await axios.get( + url, + config + )) as unknown as Response; + + if (onResponse && response.cached) { + Axios.get(url).then((response) => + onResponse(response as unknown as Response) + ); + } + + return response; +}