fix: Window Explorer liệt kê ổ đĩa thật + xử lý lỗi API
This commit is contained in:
+27
-14
@@ -9045,7 +9045,8 @@ const MediaExplorerPanel = ({ height }) => {
|
||||
const fileDuration = f => {
|
||||
if (!f) return 0;
|
||||
if (isMidiFile(f)) return (f.lengthQn || 16) * 60 / (f.bpm || 120);
|
||||
return f.duration || (audioBuffer && selected && (selected.file_id || selected.fileId) === (f.file_id || f.fileId) ? audioBuffer.duration : 0) || 0;
|
||||
const matches = selected && ((f.path && f.path === selected.path) || (!f.path && (f.file_id || f.fileId) === (selected.file_id || selected.fileId)));
|
||||
return f.duration || (audioBuffer && matches ? audioBuffer.duration : 0) || 0;
|
||||
};
|
||||
|
||||
const folderFiles = React.useMemo(() => {
|
||||
@@ -9097,18 +9098,26 @@ const MediaExplorerPanel = ({ height }) => {
|
||||
|
||||
const openMyComputer = async () => {
|
||||
setFolder('computer');
|
||||
if (!computerRoots) {
|
||||
try {
|
||||
const resp = await fetch(`${API_BASE_URL}/api/v1/media/computer`);
|
||||
const data = await resp.json();
|
||||
setComputerRoots(data.roots || []);
|
||||
} catch (e) { setComputerRoots([]); }
|
||||
if (computerRoots) return;
|
||||
setComputerRoots(null);
|
||||
try {
|
||||
const resp = await fetch(`${API_BASE_URL}/api/v1/media/computer`);
|
||||
if (!resp.ok) throw new Error('HTTP ' + resp.status);
|
||||
const data = await resp.json();
|
||||
const roots = data.roots || [];
|
||||
setComputerRoots(roots.length ? roots : [{ path: '/', name: 'Root (/)', is_dir: true }]);
|
||||
if (!roots.length) window.showToast && window.showToast('Không tìm thấy ổ đĩa nào', 'warning');
|
||||
} catch (e) {
|
||||
setComputerRoots([{ path: '/', name: 'Root (/)', is_dir: true }]);
|
||||
window.showToast && window.showToast('Không thể truy cập My Computer: ' + e.message, 'error');
|
||||
}
|
||||
};
|
||||
|
||||
const browseComputerDir = async (path) => {
|
||||
if (!path) return;
|
||||
try {
|
||||
const resp = await fetch(`${API_BASE_URL}/api/v1/media/browse?path=${encodeURIComponent(path)}`);
|
||||
if (!resp.ok) throw new Error('HTTP ' + resp.status);
|
||||
const data = await resp.json();
|
||||
setComputerPath(data.path);
|
||||
setComputerFiles(data.files || []);
|
||||
@@ -9117,8 +9126,7 @@ const MediaExplorerPanel = ({ height }) => {
|
||||
stopMediaPlayback();
|
||||
setComputerTree(prev => ({ ...prev, [path]: { dirs: data.dirs || [], expanded: true } }));
|
||||
} catch (e) {
|
||||
setComputerPath(path);
|
||||
setComputerFiles([]);
|
||||
window.showToast && window.showToast('Không thể mở thư mục: ' + e.message, 'error');
|
||||
}
|
||||
};
|
||||
|
||||
@@ -9133,10 +9141,15 @@ const MediaExplorerPanel = ({ height }) => {
|
||||
|
||||
const goComputerParent = () => {
|
||||
if (!computerPath) return;
|
||||
const parent = computerPath.split(/[\\/]/).filter(Boolean);
|
||||
parent.pop();
|
||||
const parentPath = (parent.length === 0 ? (computerPath.startsWith('/') ? '/' : '') : (computerPath.startsWith('/') ? '/' + parent.join('/') : parent.join('\\')));
|
||||
browseComputerDir(parentPath);
|
||||
const isUnix = computerPath.startsWith('/');
|
||||
const parts = computerPath.split(/[\\/]/).filter(Boolean);
|
||||
parts.pop();
|
||||
if (isUnix) {
|
||||
browseComputerDir(parts.length ? '/' + parts.join('/') : '/');
|
||||
} else {
|
||||
// Windows: quay về root ổ đĩa nếu đã lên tới đỉnh
|
||||
browseComputerDir(parts.length ? parts.join('\\') : computerPath.split(/[\\/]/)[0] + '\\');
|
||||
}
|
||||
};
|
||||
|
||||
const filePreviewUrl = (f) => {
|
||||
@@ -9416,7 +9429,7 @@ const MediaExplorerPanel = ({ height }) => {
|
||||
return (
|
||||
<tr key={(f.file_id || f.name) + i} className={`cursor-pointer hover:bg-blue-100 ${isSel ? 'file-row-selected' : ''}`} onClick={() => handleSelect(f)}>
|
||||
<td className="py-1 px-2"><i className={`fa-solid ${isMidi ? 'fa-music text-purple-600' : 'fa-file-audio text-emerald-600'} mr-2`}></i>{f.name || f.original_name}</td>
|
||||
{viewMode === 'details' && <td className="py-1 px-2">{f.size_mb != null ? f.size_mb.toFixed(2) + ' MB' : (isMidi ? f.tpqn + ' TPQN' : '-')}</td>}
|
||||
{viewMode === 'details' && <td className="py-1 px-2">{f.size_mb != null ? f.size_mb.toFixed(2) + ' MB' : (isMidi ? (f.tpqn || 'MIDI') + ' TPQN' : '-')}</td>}
|
||||
</tr>
|
||||
);
|
||||
})}
|
||||
|
||||
Reference in New Issue
Block a user