feat(MediaManager): add folder configuration functionality and update .config handling

This commit is contained in:
Jaime Idolpx 2026-06-08 19:22:56 -04:00
parent 08b84680a4
commit 65799180c5

View File

@ -52,6 +52,7 @@ import {
copyPath, copyPath,
createFolder, createFolder,
deletePath, deletePath,
fileExists,
getFileContents, getFileContents,
humanFileSize, humanFileSize,
joinPath, joinPath,
@ -268,6 +269,7 @@ function EntryIcon({ entry }: { entry: EntryInfo }) {
interface FolderManagementActions { interface FolderManagementActions {
onMountFolder: () => void; onMountFolder: () => void;
onConfigureFolder: () => void;
onNewFolder: () => void; onNewFolder: () => void;
onNewFile: () => void; onNewFile: () => void;
onUpload: () => void; onUpload: () => void;
@ -315,6 +317,10 @@ function ActionsModal({ entry, onClose, onOpen, onMount, onDownload, onRename, o
className="w-full text-left px-4 py-3 rounded border border-neutral-200 hover:bg-blue-50 hover:border-blue-300 inline-flex items-center gap-3"> className="w-full text-left px-4 py-3 rounded border border-neutral-200 hover:bg-blue-50 hover:border-blue-300 inline-flex items-center gap-3">
<HardDrive className="w-4 h-4 text-amber-600" /> <span>Mount Folder</span> <HardDrive className="w-4 h-4 text-amber-600" /> <span>Mount Folder</span>
</button> </button>
<button onClick={() => { onClose(); fm.onConfigureFolder(); }}
className="w-full text-left px-4 py-3 rounded border border-neutral-200 hover:bg-blue-50 hover:border-blue-300 inline-flex items-center gap-3">
<SlidersHorizontal className="w-4 h-4 text-violet-600" /> <span>Configure Folder</span>
</button>
<div className="border-t border-neutral-100" /> <div className="border-t border-neutral-100" />
<button onClick={() => { onClose(); fm.onNewFolder(); }} <button onClick={() => { onClose(); fm.onNewFolder(); }}
className="w-full text-left px-4 py-3 rounded border border-neutral-200 hover:bg-neutral-50 inline-flex items-center gap-3"> className="w-full text-left px-4 py-3 rounded border border-neutral-200 hover:bg-neutral-50 inline-flex items-center gap-3">
@ -659,6 +665,18 @@ export default function MediaManager({ initialPath = '/', rootPath, title, confi
const key = _cacheKey(viewEntry.path, viewEntry.size, viewEntry.lastModified?.toISOString() ?? null); const key = _cacheKey(viewEntry.path, viewEntry.size, viewEntry.lastModified?.toISOString() ?? null);
_sessionCache.set(key, bytes); _sessionCache.set(key, bytes);
_lsSet(key, bytes); _lsSet(key, bytes);
// If this is the folder .config, update folderConfig immediately so base_url etc. take effect
if (viewEntry.name === '.config' && typeof content === 'string') {
const cfg: Record<string, string> = {};
for (const line of content.split('\n')) {
const t = line.trim();
if (!t || t.startsWith('#')) continue;
const eq = t.indexOf('=');
if (eq >= 0) cfg[t.slice(0, eq).trim()] = t.slice(eq + 1).trim();
}
setFolderConfig(Object.keys(cfg).length ? cfg : null);
closeViewer();
}
toast.success(`Saved ${viewEntry.name}`); toast.success(`Saved ${viewEntry.name}`);
void load(path); void load(path);
}; };
@ -815,6 +833,19 @@ export default function MediaManager({ initialPath = '/', rootPath, title, confi
void load(path); void load(path);
}; };
// ── Configure folder ─────────────────────────────────────────────────────
const handleConfigureFolder = async () => {
const configPath = joinPath(path, '.config');
try {
if (!await fileExists(configPath)) {
await putFileContents(configPath, '');
}
} catch { /* open anyway */ }
const entry: EntryInfo = { name: '.config', path: configPath, type: 'file', size: 0, lastModified: null, contentType: null };
void openEntry(entry, 'config');
};
// ── New folder ─────────────────────────────────────────────────────────── // ── New folder ───────────────────────────────────────────────────────────
const handleCreateFolder = async () => { const handleCreateFolder = async () => {
@ -1201,6 +1232,7 @@ export default function MediaManager({ initialPath = '/', rootPath, title, confi
onDelete={e => void deleteEntry(e)} onDelete={e => void deleteEntry(e)}
folderManagement={folderActionOpen ? { folderManagement={folderActionOpen ? {
onMountFolder: () => setMountEntry({ name: splitPath(path).name || '/', path, type: 'folder', size: 0, lastModified: null, contentType: null }), onMountFolder: () => setMountEntry({ name: splitPath(path).name || '/', path, type: 'folder', size: 0, lastModified: null, contentType: null }),
onConfigureFolder: () => void handleConfigureFolder(),
onNewFolder: () => { setShowNewFolder(true); setShowNewFile(false); }, onNewFolder: () => { setShowNewFolder(true); setShowNewFile(false); },
onNewFile: () => { setShowNewFile(true); setShowNewFolder(false); }, onNewFile: () => { setShowNewFile(true); setShowNewFolder(false); },
onUpload: () => fileInputRef.current?.click(), onUpload: () => fileInputRef.current?.click(),