feat(MediaManager): add VMS creation functionality and UI enhancements

This commit is contained in:
Jaime Idolpx 2026-06-11 23:54:12 -04:00
parent e4a5eac676
commit 243a134a9c

View File

@ -21,6 +21,7 @@ import {
Hash,
Home,
Image as ImageIcon,
Layers,
Loader2,
MoreVertical,
Move,
@ -370,9 +371,11 @@ export default function MediaManager({ initialPath, rootPath, title, config, set
const [viewHexData, setViewHexData] = useState<Uint8Array | null>(null);
const [viewLoading, setViewLoading] = useState(false);
// Rename / folder
// Rename / folder / VMS
const [showNewFolder, setShowNewFolder] = useState(false);
const [newFolderName, setNewFolderName] = useState('');
const [showCreateVms, setShowCreateVms] = useState(false);
const [vmsName, setVmsName] = useState('');
const [renameEntry, setRenameEntry] = useState<EntryInfo | null>(null);
const [renameName, setRenameName] = useState('');
const [mountEntry, setMountEntry] = useState<EntryInfo | null>(null);
@ -781,6 +784,36 @@ export default function MediaManager({ initialPath, rootPath, title, config, set
void openEntry(entry, 'config');
};
// ── Create VMS ───────────────────────────────────────────────────────────
const openCreateVms = () => {
const folderName = path.split('/').filter(Boolean).pop() ?? 'playlist';
setVmsName(folderName + '.vms');
setShowNewFolder(false);
setShowCreateVms(true);
};
const handleCreateVms = async () => {
const name = vmsName.trim();
if (!name) return;
const filename = name.endsWith('.vms') ? name : name + '.vms';
const selectedFiles = entries.filter(e => selected.has(e.path) && e.type === 'file');
const content = selectedFiles
.map(e => {
const stem = e.name.includes('.') ? e.name.slice(0, e.name.lastIndexOf('.')) : e.name;
return `${e.name},${stem}`;
})
.join('\n') + '\n';
try {
await putFileContents(joinPath(path, filename), content);
toast.success(`Created "${filename}"`);
setShowCreateVms(false);
setVmsName('');
setSelected(new Set());
void load(path);
} catch (e: any) { toast.error(`Failed to create VMS: ${e?.message ?? e}`); }
};
// ── New folder ───────────────────────────────────────────────────────────
const handleCreateFolder = async () => {
@ -972,6 +1005,28 @@ export default function MediaManager({ initialPath, rootPath, title, config, set
</button>
</div>
)}
{showCreateVms && (
<div className="mt-2 flex items-center gap-2">
<Layers className="w-4 h-4 text-indigo-500 flex-shrink-0" />
<input
value={vmsName}
onChange={e => setVmsName(e.target.value)}
onKeyDown={e => {
if (e.key === 'Enter') void handleCreateVms();
if (e.key === 'Escape') { setShowCreateVms(false); setVmsName(''); }
}}
placeholder="playlist.vms"
className="flex-1 px-2 py-1 text-sm border border-neutral-300 rounded"
autoFocus
/>
<button onClick={() => void handleCreateVms()} className="px-3 py-1 text-sm bg-indigo-600 text-white rounded">
Create
</button>
<button onClick={() => { setShowCreateVms(false); setVmsName(''); }} className="p-1 rounded hover:bg-neutral-200">
<X className="w-4 h-4 text-neutral-500" />
</button>
</div>
)}
</div>
{/* ── Filter + sort bar ── */}
@ -1017,6 +1072,11 @@ export default function MediaManager({ initialPath, rootPath, title, config, set
<button onClick={moveSelected} className="px-2 py-0.5 rounded border border-blue-300 bg-white text-blue-700 hover:bg-blue-100 inline-flex items-center gap-1">
<Move className="w-3.5 h-3.5" /> Move
</button>
{selCount > 1 && (
<button onClick={openCreateVms} className="px-2 py-0.5 rounded border border-blue-300 bg-white text-blue-700 hover:bg-blue-100 inline-flex items-center gap-1">
<Layers className="w-3.5 h-3.5" /> Create VMS
</button>
)}
<button onClick={() => void deleteSelected()} className="px-2 py-0.5 rounded border border-red-300 bg-white text-red-700 hover:bg-red-50 inline-flex items-center gap-1">
<Trash2 className="w-3.5 h-3.5" /> Delete
</button>