improved cache cleanup for offline mode
This commit is contained in:
parent
ff36f318fc
commit
c47adfa7fa
@ -481,9 +481,24 @@ export function useOfflineMode(
|
|||||||
const deleteOfflineData = useCallback(async () => {
|
const deleteOfflineData = useCallback(async () => {
|
||||||
if (!projectId) return;
|
if (!projectId) return;
|
||||||
|
|
||||||
|
// Get storage keys before deleting (to clear in-memory blob URLs)
|
||||||
|
const assets = discoverAssets();
|
||||||
|
const storageKeys = assets.map((a) => a.storageKey);
|
||||||
|
|
||||||
|
// Clear in-memory blob URLs for this project's assets
|
||||||
|
downloadManager.clearBlobUrlsForKeys(storageKeys);
|
||||||
|
|
||||||
|
// Delete from persistent storage
|
||||||
await StorageManager.deleteProjectAssets(projectId);
|
await StorageManager.deleteProjectAssets(projectId);
|
||||||
await OfflineDbManager.deleteProject(projectId);
|
await OfflineDbManager.deleteProject(projectId);
|
||||||
|
|
||||||
|
// Reset refs used for progress tracking
|
||||||
|
assetsRef.current = [];
|
||||||
|
downloadedCountRef.current = 0;
|
||||||
|
downloadedBytesRef.current = 0;
|
||||||
|
|
||||||
|
// Reset state
|
||||||
|
setDiscoveredAssets([]);
|
||||||
setProjectInfo(null);
|
setProjectInfo(null);
|
||||||
setStatus('not_downloaded');
|
setStatus('not_downloaded');
|
||||||
setProgress(0);
|
setProgress(0);
|
||||||
@ -491,7 +506,7 @@ export function useOfflineMode(
|
|||||||
setTotalAssets(0);
|
setTotalAssets(0);
|
||||||
setDownloadedBytes(0);
|
setDownloadedBytes(0);
|
||||||
setTotalBytes(0);
|
setTotalBytes(0);
|
||||||
}, [projectId]);
|
}, [projectId, discoverAssets]);
|
||||||
|
|
||||||
// Check for updates by comparing discovered assets with stored project
|
// Check for updates by comparing discovered assets with stored project
|
||||||
const checkForUpdates = useCallback(async (): Promise<boolean> => {
|
const checkForUpdates = useCallback(async (): Promise<boolean> => {
|
||||||
|
|||||||
@ -756,6 +756,20 @@ class DownloadManagerClass {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear blob URLs for specific storage keys (call when deleting project offline data)
|
||||||
|
*/
|
||||||
|
clearBlobUrlsForKeys(storageKeys: string[]): void {
|
||||||
|
for (const key of storageKeys) {
|
||||||
|
const blobUrl = this.readyBlobUrls.get(key);
|
||||||
|
if (blobUrl) {
|
||||||
|
URL.revokeObjectURL(blobUrl);
|
||||||
|
this.readyBlobUrls.delete(key);
|
||||||
|
}
|
||||||
|
this.partialDownloadsReady.delete(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if URL is an image based on extension
|
* Check if URL is an image based on extension
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import { OFFLINE_CONFIG } from '../../config/offline.config';
|
|||||||
import { PRELOAD_CONFIG } from '../../config/preload.config';
|
import { PRELOAD_CONFIG } from '../../config/preload.config';
|
||||||
import { OfflineDbManager } from '../offlineDb/OfflineDbManager';
|
import { OfflineDbManager } from '../offlineDb/OfflineDbManager';
|
||||||
import { extractStoragePath } from '../assetUrl';
|
import { extractStoragePath } from '../assetUrl';
|
||||||
|
import { logger } from '../logger';
|
||||||
import type {
|
import type {
|
||||||
OfflineAsset,
|
OfflineAsset,
|
||||||
AssetVariantType,
|
AssetVariantType,
|
||||||
@ -260,23 +261,34 @@ export class StorageManager {
|
|||||||
// Delete from IndexedDB
|
// Delete from IndexedDB
|
||||||
await OfflineDbManager.deleteProjectAssets(projectId);
|
await OfflineDbManager.deleteProjectAssets(projectId);
|
||||||
|
|
||||||
// Cache API cleanup is more complex - we'd need to track URLs
|
// Delete from Cache API - iterate through cache and delete entries for this project
|
||||||
// For now, we rely on the service worker to handle this
|
if (typeof caches !== 'undefined') {
|
||||||
|
try {
|
||||||
|
const cache = await caches.open(OFFLINE_CONFIG.cacheNames.assets);
|
||||||
|
const keys = await cache.keys();
|
||||||
|
|
||||||
|
for (const request of keys) {
|
||||||
|
const response = await cache.match(request);
|
||||||
|
if (response) {
|
||||||
|
const cachedProjectId = response.headers.get('X-Project-Id');
|
||||||
|
if (cachedProjectId === projectId) {
|
||||||
|
await cache.delete(request);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
logger.error('[StorageManager] Failed to clear Cache API:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get total storage used
|
* Get total storage used
|
||||||
*/
|
*/
|
||||||
static async getTotalStorageUsed(): Promise<number> {
|
static async getTotalStorageUsed(): Promise<number> {
|
||||||
let total = 0;
|
// IndexedDB storage (primary tracking)
|
||||||
|
const total = await OfflineDbManager.getTotalAssetsSize();
|
||||||
// IndexedDB storage
|
// Note: Cache API size is included in browser's quota.usage but not tracked separately
|
||||||
total += await OfflineDbManager.getTotalAssetsSize();
|
|
||||||
|
|
||||||
// Cache API storage (approximate from quota)
|
|
||||||
const quota = await this.getStorageQuota();
|
|
||||||
// Note: quota.usage includes all storage, not just our caches
|
|
||||||
|
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user