feat: My Computer hiển thị cây thư mục client-side qua directory picker
This commit is contained in:
+27
-15
@@ -9297,7 +9297,20 @@ const MediaExplorerPanel = ({ height }) => {
|
||||
|
||||
const openMyComputer = async () => {
|
||||
setFolder('computer');
|
||||
// Ưu tiên client-side: nếu có root handle đã lưu (File System Access API) → tự động quét cây client
|
||||
const useClientRoot = async (rootHandle) => {
|
||||
setComputerMode('client');
|
||||
setClientRoot(rootHandle);
|
||||
const rootEntry = { name: rootHandle.name, path: 'root', is_dir: true, handle: rootHandle };
|
||||
setComputerRoots([rootEntry]);
|
||||
setComputerPath('root');
|
||||
setComputerFiles([]);
|
||||
const browsed = await browseComputerDir(rootEntry);
|
||||
if (browsed && browsed.dirs) {
|
||||
browsed.dirs.slice(0, 10).forEach(d => browseComputerDir(d));
|
||||
}
|
||||
return true;
|
||||
};
|
||||
// Ưu tiên client-side: root handle đã lưu (File System Access API) → tự động quét cây client
|
||||
let savedHandle = null;
|
||||
try { savedHandle = await loadClientRootHandle(); } catch (e) {}
|
||||
if (savedHandle && savedHandle.kind === 'directory') {
|
||||
@@ -9312,21 +9325,20 @@ const MediaExplorerPanel = ({ height }) => {
|
||||
}
|
||||
}
|
||||
} catch (e) { permitted = false; }
|
||||
if (permitted) {
|
||||
setComputerMode('client');
|
||||
setClientRoot(savedHandle);
|
||||
const rootEntry = { name: savedHandle.name, path: 'root', is_dir: true, handle: savedHandle };
|
||||
setComputerRoots([rootEntry]);
|
||||
setComputerPath('root');
|
||||
setComputerFiles([]);
|
||||
const browsed = await browseComputerDir(rootEntry);
|
||||
if (browsed && browsed.dirs && browsed.dirs.length) {
|
||||
browsed.dirs.slice(0, 10).forEach(d => browseComputerDir(d));
|
||||
return;
|
||||
if (permitted) return useClientRoot(savedHandle);
|
||||
}
|
||||
// Chưa có quyền client → yêu cầu người dùng chọn thư mục để hiển thị cây phía client
|
||||
if (window.showDirectoryPicker) {
|
||||
try {
|
||||
const picked = await window.showDirectoryPicker({ mode: 'read' });
|
||||
if (picked && picked.kind === 'directory') {
|
||||
return useClientRoot(picked);
|
||||
}
|
||||
} catch (e) {
|
||||
// Người dùng hủy (AbortError) hoặc lỗi khác → rơi xuống quét server
|
||||
}
|
||||
}
|
||||
// Auto-scan ổ đĩa/thư mục hệ thống (server API = máy local), không mở hộp thoại picker
|
||||
// Auto-scan ổ đĩa/thư mục hệ thống (server API = máy local)
|
||||
setComputerMode('server');
|
||||
setComputerRoots(null);
|
||||
try {
|
||||
@@ -9360,7 +9372,7 @@ const MediaExplorerPanel = ({ height }) => {
|
||||
for await (const [name, h] of handle.entries()) {
|
||||
if (name.startsWith('.')) continue;
|
||||
if (h.kind === 'directory') {
|
||||
dirs.push({ name, path: parentPath + '/' + name, is_dir: true, handle: h });
|
||||
dirs.push({ name, path: parentPath + '/' + name, is_dir: true, handle: h, parent: handle });
|
||||
} else {
|
||||
const ext = (name.split('.').pop() || '').toLowerCase();
|
||||
const kind = ext === 'mid' || ext === 'midi' ? 'midi' : (['wav','mp3','ogg','flac','aiff','aif','m4a','aac','opus'].includes(ext) ? 'audio' : 'other');
|
||||
@@ -9389,7 +9401,7 @@ const MediaExplorerPanel = ({ height }) => {
|
||||
if (computerMode === 'client' || entry.handle) {
|
||||
if (entry.handle && entry.handle.entries) {
|
||||
const parentInfo = computerTree[entry.path];
|
||||
return await browseClientDir({ ...entry, parent: parentInfo ? parentInfo.parent : null });
|
||||
return await browseClientDir({ ...entry, parent: parentInfo ? parentInfo.parent : entry.parent });
|
||||
}
|
||||
}
|
||||
const path = entry.path || entry;
|
||||
|
||||
Reference in New Issue
Block a user