structure refacto & file documentation
All checks were successful
Deploy Sokko G / deploy (push) Successful in 7s
All checks were successful
Deploy Sokko G / deploy (push) Successful in 7s
This commit is contained in:
parent
d7871736c8
commit
895fec2b40
84 changed files with 2629 additions and 2313 deletions
135
website/src/features/toolboxes/storage/useIndexedToolboxes.js
Normal file
135
website/src/features/toolboxes/storage/useIndexedToolboxes.js
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
// Rôle : synchronise les toolboxes, données d'outils, liens de jeux et quota via IndexedDB.
|
||||
import { useEffect, useState } from "react";
|
||||
import {
|
||||
getAllModuleData as dbGetAllModuleData,
|
||||
getLinks as dbGetLinks,
|
||||
getStorageEstimate,
|
||||
getToolboxes as dbGetToolboxes,
|
||||
removeModuleData as dbRemoveModuleData,
|
||||
removeModuleDataKeys as dbRemoveModuleDataKeys,
|
||||
setLinks as dbSetLinks,
|
||||
setModuleData as dbSetModuleData,
|
||||
setToolboxes as dbSetToolboxes
|
||||
} from "../../../utils/indexedDbStorage.js";
|
||||
import {
|
||||
compactToolboxesForStorage,
|
||||
moduleStorageKey,
|
||||
normalizeToolbox,
|
||||
prepareModuleDataForStorage
|
||||
} from "./toolboxStorage.js";
|
||||
|
||||
export function useIndexedToolboxes(onError) {
|
||||
const [ready, setReady] = useState(false);
|
||||
const [toolboxes, setToolboxesState] = useState([]);
|
||||
const [links, setLinksState] = useState({});
|
||||
const [moduleData, setModuleDataState] = useState({});
|
||||
const [storageUsage, setStorageUsage] = useState({ used: 0, limit: 0, ratio: 0 });
|
||||
|
||||
async function refreshQuota() {
|
||||
try {
|
||||
const estimate = await getStorageEstimate();
|
||||
const used = estimate.usage || 0;
|
||||
const limit = estimate.quota || 0;
|
||||
setStorageUsage({ used, limit, ratio: limit ? Math.min(1, used / limit) : 0 });
|
||||
} catch {
|
||||
setStorageUsage({ used: 0, limit: 0, ratio: 0 });
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
let cancelled = false;
|
||||
async function loadStore() {
|
||||
try {
|
||||
const [storedToolboxes, storedLinks, storedModules] = await Promise.all([
|
||||
dbGetToolboxes(),
|
||||
dbGetLinks(),
|
||||
dbGetAllModuleData()
|
||||
]);
|
||||
if (cancelled) return;
|
||||
setToolboxesState((Array.isArray(storedToolboxes) ? storedToolboxes : []).map(normalizeToolbox).filter(Boolean));
|
||||
setLinksState(storedLinks && typeof storedLinks === "object" ? storedLinks : {});
|
||||
setModuleDataState(Object.fromEntries((storedModules || []).map((entry) => [entry.key, entry.data])));
|
||||
setReady(true);
|
||||
refreshQuota();
|
||||
} catch (error) {
|
||||
if (!cancelled) {
|
||||
setReady(true);
|
||||
onError(error.message || "Stockage IndexedDB indisponible.");
|
||||
}
|
||||
}
|
||||
}
|
||||
loadStore();
|
||||
return () => { cancelled = true; };
|
||||
}, []);
|
||||
|
||||
function persistToolboxes(nextToolboxes) {
|
||||
const normalized = compactToolboxesForStorage(nextToolboxes).map(normalizeToolbox).filter(Boolean);
|
||||
setToolboxesState(normalized);
|
||||
dbSetToolboxes(compactToolboxesForStorage(normalized))
|
||||
.then(refreshQuota)
|
||||
.catch((error) => onError(error.message));
|
||||
return true;
|
||||
}
|
||||
|
||||
function persistLinks(nextLinks) {
|
||||
setLinksState(nextLinks);
|
||||
dbSetLinks(nextLinks)
|
||||
.then(refreshQuota)
|
||||
.catch((error) => onError(error.message));
|
||||
return true;
|
||||
}
|
||||
|
||||
function getModuleData(toolboxId, moduleId, fallback) {
|
||||
const value = moduleData[moduleStorageKey(toolboxId, moduleId)];
|
||||
return value == null ? fallback : value;
|
||||
}
|
||||
|
||||
function updateModuleData(toolboxId, moduleId, value, moduleType = "") {
|
||||
const compact = prepareModuleDataForStorage(toolboxes, toolboxId, moduleId, value, moduleType);
|
||||
const key = moduleStorageKey(toolboxId, moduleId);
|
||||
setModuleDataState((state) => {
|
||||
const nextState = { ...state };
|
||||
if (compact == null) delete nextState[key];
|
||||
else nextState[key] = compact;
|
||||
return nextState;
|
||||
});
|
||||
const operation = compact == null ? dbRemoveModuleData(key) : dbSetModuleData(key, compact);
|
||||
operation.then(refreshQuota).catch((error) => onError(error.message));
|
||||
return true;
|
||||
}
|
||||
|
||||
function removeModuleData(toolboxId, moduleId) {
|
||||
const key = moduleStorageKey(toolboxId, moduleId);
|
||||
setModuleDataState((state) => {
|
||||
const nextState = { ...state };
|
||||
delete nextState[key];
|
||||
return nextState;
|
||||
});
|
||||
dbRemoveModuleData(key).then(refreshQuota).catch((error) => onError(error.message));
|
||||
}
|
||||
|
||||
function removeToolboxModuleData(toolbox) {
|
||||
const keys = (toolbox?.modules || []).map((module) => moduleStorageKey(toolbox.id, module.id));
|
||||
setModuleDataState((state) => {
|
||||
const nextState = { ...state };
|
||||
keys.forEach((key) => delete nextState[key]);
|
||||
return nextState;
|
||||
});
|
||||
dbRemoveModuleDataKeys(keys).then(refreshQuota).catch((error) => onError(error.message));
|
||||
}
|
||||
|
||||
return {
|
||||
ready,
|
||||
toolboxes,
|
||||
links,
|
||||
moduleData,
|
||||
storageUsage,
|
||||
setToolboxes: persistToolboxes,
|
||||
setLinks: persistLinks,
|
||||
getModuleData,
|
||||
updateModuleData,
|
||||
removeModuleData,
|
||||
removeToolboxModuleData,
|
||||
refreshQuota
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue