file uploaded path correction
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
import { blobCache } from './localFileStore';
|
||||
|
||||
/**
|
||||
* Vite base, e.g. "/citpl_website/" in production and "/" in local dev.
|
||||
* Runtime fallback: if an old/dev build baked base "/" but the page is
|
||||
@@ -26,6 +28,9 @@ export function assetUrl(path) {
|
||||
|
||||
if (/^(data:|blob:)/i.test(path)) return path;
|
||||
|
||||
// Resolve locally uploaded files from IndexedDB blob cache
|
||||
if (blobCache.has(path)) return blobCache.get(path);
|
||||
|
||||
const assetBase = resolveAssetBase();
|
||||
const prefix = assetBase.replace(/\/$/, '');
|
||||
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
/**
|
||||
* Local file store using IndexedDB.
|
||||
* Stores uploaded files as binary blobs keyed by a stable path like /assets/filename.
|
||||
* On load, restores blob URLs so images/videos display correctly.
|
||||
*/
|
||||
|
||||
const DB_NAME = 'citpl_uploads';
|
||||
const STORE = 'files';
|
||||
const DB_VERSION = 1;
|
||||
|
||||
function openDb() {
|
||||
return new Promise((resolve, reject) => {
|
||||
const req = indexedDB.open(DB_NAME, DB_VERSION);
|
||||
req.onupgradeneeded = (e) => e.target.result.createObjectStore(STORE);
|
||||
req.onsuccess = (e) => resolve(e.target.result);
|
||||
req.onerror = () => reject(req.error);
|
||||
});
|
||||
}
|
||||
|
||||
export async function saveFile(key, file) {
|
||||
const db = await openDb();
|
||||
return new Promise((resolve, reject) => {
|
||||
const tx = db.transaction(STORE, 'readwrite');
|
||||
tx.objectStore(STORE).put({ blob: file, name: file.name, type: file.type }, key);
|
||||
tx.oncomplete = () => resolve();
|
||||
tx.onerror = () => reject(tx.error);
|
||||
});
|
||||
}
|
||||
|
||||
export async function getFileUrl(key) {
|
||||
const db = await openDb();
|
||||
return new Promise((resolve) => {
|
||||
const req = db.transaction(STORE).objectStore(STORE).get(key);
|
||||
req.onsuccess = () => {
|
||||
if (req.result) resolve(URL.createObjectURL(req.result.blob));
|
||||
else resolve(null);
|
||||
};
|
||||
req.onerror = () => resolve(null);
|
||||
});
|
||||
}
|
||||
|
||||
export async function getAllKeys() {
|
||||
const db = await openDb();
|
||||
return new Promise((resolve) => {
|
||||
const req = db.transaction(STORE).objectStore(STORE).getAllKeys();
|
||||
req.onsuccess = () => resolve(req.result);
|
||||
req.onerror = () => resolve([]);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Save file locally and return a stable key path like /assets/user_upload_filename.ext
|
||||
*/
|
||||
export async function uploadLocal(file) {
|
||||
const ext = file.name.split('.').pop().toLowerCase();
|
||||
const base = file.name.replace(/[^a-zA-Z0-9-_]/g, '_').replace(/\.[^.]+$/, '').slice(0, 40);
|
||||
const key = `/assets/user_upload_${base}_${Date.now()}.${ext}`;
|
||||
await saveFile(key, file);
|
||||
const url = URL.createObjectURL(file);
|
||||
// Cache the blob URL in memory for this session
|
||||
blobCache.set(key, url);
|
||||
return { url: key, blobUrl: url };
|
||||
}
|
||||
|
||||
// In-memory cache: key → blob URL (valid for current session)
|
||||
export const blobCache = new Map();
|
||||
|
||||
/**
|
||||
* Call once on app init to restore blob URLs for all stored files.
|
||||
* Returns a Map of key → blobUrl.
|
||||
*/
|
||||
export async function restoreAllBlobUrls() {
|
||||
const keys = await getAllKeys();
|
||||
await Promise.all(
|
||||
keys.map(async (key) => {
|
||||
if (!blobCache.has(key)) {
|
||||
const url = await getFileUrl(key);
|
||||
if (url) blobCache.set(key, url);
|
||||
}
|
||||
})
|
||||
);
|
||||
return blobCache;
|
||||
}
|
||||
Reference in New Issue
Block a user