Initial commit
This commit is contained in:
commit
05c65aad4d
155 changed files with 93617 additions and 0 deletions
117
viewer/extract-helper.js
Normal file
117
viewer/extract-helper.js
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
import { unzipSync } from 'fflate';
|
||||
import { loadDroppedModel } from "./sandbox.js";
|
||||
import { core } from "./core.js";
|
||||
import { toastHelper } from './viewer-utils.js';
|
||||
|
||||
let archiveFileMap = {};
|
||||
|
||||
async function extractZip (archiveFile) {
|
||||
const buffer = await archiveFile.arrayBuffer();
|
||||
|
||||
const unzipped = unzipSync(new Uint8Array(buffer));
|
||||
|
||||
const files = [];
|
||||
|
||||
Object.entries(unzipped).forEach(([path, data]) => {
|
||||
// Skip folders
|
||||
if (path.endsWith('/')) {
|
||||
return;
|
||||
}
|
||||
|
||||
files.push(
|
||||
new File(
|
||||
[data],
|
||||
path,
|
||||
{
|
||||
type: 'application/octet-stream'
|
||||
}
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
return files;
|
||||
};
|
||||
|
||||
function cleanupArchiveUrls() {
|
||||
Object.values(archiveFileMap).forEach(url => {
|
||||
try {
|
||||
URL.revokeObjectURL(url);
|
||||
} catch (e) {}
|
||||
});
|
||||
|
||||
archiveFileMap = {};
|
||||
};
|
||||
|
||||
function buildArchiveFileMap (files) {
|
||||
cleanupArchiveUrls();
|
||||
|
||||
files.forEach(file => {
|
||||
const normalized = file.name.replace(/^\/+/, '');
|
||||
archiveFileMap[normalized] = URL.createObjectURL(file);
|
||||
});
|
||||
};
|
||||
|
||||
export async function loadDroppedArchive (archiveFile) {
|
||||
try {
|
||||
const extension = archiveFile.name.split('.').pop().toLowerCase();
|
||||
|
||||
let extractedFiles = [];
|
||||
|
||||
switch (extension) {
|
||||
case 'zip':
|
||||
extractedFiles = await extractZip(archiveFile);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Error(`Unsupported archive type: ${extension}`);
|
||||
}
|
||||
|
||||
if (!extractedFiles.length) {
|
||||
throw new Error('Archive is empty');
|
||||
}
|
||||
|
||||
const modelFile = findMainModelFile(extractedFiles);
|
||||
|
||||
if (!modelFile) {
|
||||
throw new Error('No supported model file found in archive');
|
||||
}
|
||||
|
||||
buildArchiveFileMap(extractedFiles);
|
||||
|
||||
await loadDroppedModel(modelFile);
|
||||
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
toastHelper("unsupportedFormat", "error");
|
||||
}
|
||||
};
|
||||
|
||||
function findMainModelFile (files) {
|
||||
const priority = core.SUPPORTED_EXTENSIONS;
|
||||
|
||||
for (const ext of priority) {
|
||||
const found = files.find(file => {
|
||||
const fileExt = file.name.split('.').pop().toLowerCase();
|
||||
return fileExt === ext;
|
||||
});
|
||||
|
||||
if (found) {
|
||||
return found;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
function resolveArchiveUrl (url) {
|
||||
if (!url) {
|
||||
return url;
|
||||
}
|
||||
|
||||
const clean = url
|
||||
.replace(/^(\.\/)+/, '')
|
||||
.replace(/^\/+/, '');
|
||||
|
||||
return archiveFileMap[clean] || url;
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue