Files
pocket-id/frontend/src/lib/utils/cached-image-util.ts
2025-09-20 21:42:52 +02:00

90 lines
2.3 KiB
TypeScript

type SkipCacheUntil = {
[key: string]: number;
};
type CachableImage = {
getUrl: (...props: any[]) => string;
bustCache: (...props: any[]) => void;
};
export const cachedApplicationLogo: CachableImage = {
getUrl: (light = true) => {
let url = '/api/application-images/logo';
if (!light) {
url += '?light=false';
}
return getCachedImageUrl(url);
},
bustCache: (light = true) => {
let url = '/api/application-images/logo';
if (!light) {
url += '?light=false';
}
bustImageCache(url);
}
};
export const cachedBackgroundImage: CachableImage = {
getUrl: () => getCachedImageUrl('/api/application-images/background'),
bustCache: () => bustImageCache('/api/application-images/background')
};
export const cachedProfilePicture: CachableImage = {
getUrl: (userId: string) => {
const url = `/api/users/${userId}/profile-picture.png`;
return getCachedImageUrl(url);
},
bustCache: (userId: string) => {
const url = `/api/users/${userId}/profile-picture.png`;
bustImageCache(url);
}
};
export const cachedOidcClientLogo: CachableImage = {
getUrl: (clientId: string) => {
const url = `/api/oidc/clients/${clientId}/logo`;
return getCachedImageUrl(url);
},
bustCache: (clientId: string) => {
const url = `/api/oidc/clients/${clientId}/logo`;
bustImageCache(url);
}
};
function getCachedImageUrl(url: string) {
const skipCacheUntil = getSkipCacheUntil(url);
const skipCache = skipCacheUntil > Date.now();
if (skipCache) {
const skipCacheParam = new URLSearchParams();
skipCacheParam.append('skip-cache', skipCacheUntil.toString());
url += '?' + skipCacheParam.toString();
}
return url.toString();
}
function bustImageCache(url: string) {
const skipCacheUntil: SkipCacheUntil = JSON.parse(
localStorage.getItem('skip-cache-until') ?? '{}'
);
skipCacheUntil[hashKey(url)] = Date.now() + 1000 * 60 * 15; // 15 minutes
localStorage.setItem('skip-cache-until', JSON.stringify(skipCacheUntil));
}
function getSkipCacheUntil(url: string) {
const skipCacheUntil: SkipCacheUntil = JSON.parse(
localStorage.getItem('skip-cache-until') ?? '{}'
);
return skipCacheUntil[hashKey(url)] ?? 0;
}
function hashKey(key: string): string {
let hash = 0;
for (let i = 0; i < key.length; i++) {
const char = key.charCodeAt(i);
hash = (hash << 5) - hash + char;
hash = hash & hash;
}
return Math.abs(hash).toString(36);
}