mirror of
https://github.com/decaf-dev/obsidian-vault-explorer.git
synced 2026-07-22 10:10:31 +00:00
Add social image cache (#223)
* feat: add social image cache * feat: add cached entry expiration time
This commit is contained in:
parent
2c733540ef
commit
bfd291e7d6
4 changed files with 73 additions and 4 deletions
BIN
bun.lockb
BIN
bun.lockb
Binary file not shown.
|
|
@ -36,6 +36,7 @@
|
|||
"typescript": "4.7.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"idb": "^8.0.0",
|
||||
"js-logger": "^1.6.1",
|
||||
"lodash": "^4.17.21",
|
||||
"nanoid": "^5.0.7",
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
import Icon from "src/svelte/shared/components/icon.svelte";
|
||||
import { getIconIdForFile } from "../services/file-icon";
|
||||
import License from "src/svelte/shared/services/license";
|
||||
import { fetchSocialMediaImage } from "../services/social-media-image";
|
||||
import { fetchSocialImage } from "../services/social-media-image";
|
||||
import { PluginEvent } from "src/event/types";
|
||||
import GridCardContainer from "./grid-card-container.svelte";
|
||||
import GridCardTitle from "./grid-card-title.svelte";
|
||||
|
|
@ -144,7 +144,7 @@
|
|||
if (!loadSocialMediaImage) return;
|
||||
|
||||
if (imageUrl === null && url !== null) {
|
||||
imgSrc = await fetchSocialMediaImage(url);
|
||||
imgSrc = await fetchSocialImage(url);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,33 @@
|
|||
import { DBSchema, IDBPDatabase, openDB } from "idb";
|
||||
import Logger from "js-logger";
|
||||
import { requestUrl } from "obsidian";
|
||||
|
||||
export const fetchSocialMediaImage = async (url: string) => {
|
||||
const DATABASE_NAME = "vaultexplorer";
|
||||
const STORE_NAME = "socialMediaImage";
|
||||
const ENTRY_EXPIRATION_TIME = 1000 * 60 * 60 * 24 * 7; //1 week
|
||||
|
||||
interface SocialImageDB extends DBSchema {
|
||||
socialMediaImage: {
|
||||
key: string;
|
||||
value: {
|
||||
url: string;
|
||||
socialImageUrl: string;
|
||||
timestamp: number;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export const clearSocialImageCache = async () => {
|
||||
Logger.trace({
|
||||
fileName: "social-media-image.ts",
|
||||
functionName: "clearSocialMediaImageCache",
|
||||
message: "called",
|
||||
});
|
||||
const db = await openDatabase();
|
||||
await db.clear(STORE_NAME);
|
||||
};
|
||||
|
||||
export const fetchSocialImage = async (url: string) => {
|
||||
Logger.trace({
|
||||
fileName: "social-media-image.ts",
|
||||
functionName: "fetchSocialMediaImage",
|
||||
|
|
@ -9,6 +35,28 @@ export const fetchSocialMediaImage = async (url: string) => {
|
|||
});
|
||||
|
||||
try {
|
||||
const entry = await getCachedSocialImageEntry(url);
|
||||
if (entry !== null) {
|
||||
Logger.trace(
|
||||
{
|
||||
fileName: "social-media-image.ts",
|
||||
functionName: "fetchSocialMediaImage",
|
||||
message: "found cached entry",
|
||||
},
|
||||
entry
|
||||
);
|
||||
if (Date.now() - entry.timestamp < ENTRY_EXPIRATION_TIME) {
|
||||
const { socialImageUrl } = entry;
|
||||
Logger.debug({
|
||||
fileName: "social-media-image.ts",
|
||||
functionName: "fetchSocialMediaImage",
|
||||
message:
|
||||
"timestamp is within expiration time. returning cached image url",
|
||||
});
|
||||
return socialImageUrl;
|
||||
}
|
||||
}
|
||||
|
||||
const response = await requestUrl({
|
||||
url,
|
||||
method: "GET",
|
||||
|
|
@ -32,6 +80,7 @@ export const fetchSocialMediaImage = async (url: string) => {
|
|||
},
|
||||
{ imageUrl }
|
||||
);
|
||||
await putSocialImageUrl(url, imageUrl);
|
||||
} else {
|
||||
Logger.warn(
|
||||
{
|
||||
|
|
@ -51,7 +100,7 @@ export const fetchSocialMediaImage = async (url: string) => {
|
|||
functionName: "fetchSocialMediaImage",
|
||||
message: "failed to fetch",
|
||||
},
|
||||
{ url, error }
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
|
@ -63,3 +112,22 @@ const getMetaTagContent = (document: Document, property: string) => {
|
|||
document.querySelector(`meta[name='${property}']`);
|
||||
return tag ? tag.getAttribute("content") : "";
|
||||
};
|
||||
|
||||
const putSocialImageUrl = async (url: string, socialImageUrl: string) => {
|
||||
const db = await openDatabase();
|
||||
db.put(STORE_NAME, { url, socialImageUrl, timestamp: Date.now() });
|
||||
};
|
||||
|
||||
const getCachedSocialImageEntry = async (url: string) => {
|
||||
const db = await openDatabase();
|
||||
const cachedEntry = await db.get(STORE_NAME, url);
|
||||
return cachedEntry ?? null;
|
||||
};
|
||||
|
||||
const openDatabase = (): Promise<IDBPDatabase<SocialImageDB>> => {
|
||||
return openDB<SocialImageDB>(DATABASE_NAME, 1, {
|
||||
upgrade(db) {
|
||||
db.createObjectStore(STORE_NAME, { keyPath: "url" });
|
||||
},
|
||||
});
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue