Skip to content

Commit 860a653

Browse files
AmirMohammad CheraghaliAmirMohammad Cheraghali
authored andcommitted
feat: re-implement CIF support with generic loadStructure helper
1 parent bbfe0b7 commit 860a653

2 files changed

Lines changed: 35 additions & 18 deletions

File tree

src/components/Controls.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -313,13 +313,13 @@ export const Controls: React.FC<ControlsProps> = ({
313313
</button>
314314
</form>
315315
<div className="relative">
316-
<input type="file" accept=".pdb,.ent" className="hidden" ref={fileInputRef} onChange={handleFileChange} />
316+
<input type="file" accept=".pdb,.cif,.ent,.mmcif" className="hidden" ref={fileInputRef} onChange={handleFileChange} />
317317
<button
318318
onClick={() => fileInputRef.current?.click()}
319319
className={`w-full flex items-center justify-center gap-2 border py-2 rounded-lg transition-all group ${cardBg} hover:opacity-80`}
320320
>
321321
<Upload className="w-4 h-4 group-hover:text-blue-500 transition-colors" />
322-
<span className="text-xs font-medium">Upload PDB</span>
322+
<span className="text-xs font-medium">Upload PDB/CIF</span>
323323
</button>
324324
</div>
325325
</div>

src/components/ProteinViewer.tsx

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -887,25 +887,42 @@ export const ProteinViewer = forwardRef<ProteinViewerRef, ProteinViewerProps>(({
887887
const currentFile = file;
888888

889889
try {
890-
let component;
891-
if (currentFile) {
892-
console.log("Loading from file:", currentFile.name);
893-
component = await stage.loadFile(currentFile, { defaultRepresentation: false });
894-
} else if (currentPdbId) {
895-
const cleanId = String(currentPdbId).trim().toLowerCase();
896-
if (cleanId.length < 3) {
897-
if (isMounted.current) setLoading(false);
898-
return;
890+
// Generic Loader Function
891+
const loadStructure = async () => {
892+
if (currentFile) {
893+
console.log("Loading from file:", currentFile.name);
894+
// Detect extension
895+
const rawExt = currentFile.name.split('.').pop()?.toLowerCase() || 'pdb';
896+
let ext = rawExt;
897+
898+
// Normalize extensions
899+
if (rawExt === 'cif' || rawExt === 'mmcif') {
900+
ext = 'mmcif'; // Explicitly tell NGL to use mmCIF parser
901+
} else if (rawExt === 'ent') {
902+
ext = 'pdb';
903+
}
904+
905+
console.log(`Detected extension: ${rawExt} -> Parsed as: ${ext}`);
906+
return await stage.loadFile(currentFile, { defaultRepresentation: false, ext });
899907
}
900908

901-
const AVAILABLE_LOCAL_PDBS = ['2b3p', '4hhb'];
902-
let url = `https://files.rcsb.org/download/${cleanId}.pdb`;
903-
if (AVAILABLE_LOCAL_PDBS.includes(cleanId)) {
904-
url = `./${cleanId}.pdb`;
909+
if (currentPdbId) {
910+
const cleanId = String(currentPdbId).trim().toLowerCase();
911+
if (cleanId.length < 3) return null;
912+
913+
const AVAILABLE_LOCAL_PDBS = ['2b3p', '4hhb'];
914+
let url = `https://files.rcsb.org/download/${cleanId}.pdb`;
915+
if (AVAILABLE_LOCAL_PDBS.includes(cleanId)) {
916+
url = `./${cleanId}.pdb`;
917+
}
918+
console.log(`Fetching from: ${url}`);
919+
return await stage.loadFile(url, { defaultRepresentation: false });
905920
}
906-
console.log(`Fetching from: ${url}`);
907-
component = await stage.loadFile(url, { defaultRepresentation: false });
908-
} else {
921+
return null;
922+
};
923+
924+
const component = await loadStructure();
925+
if (!component) {
909926
if (isMounted.current) setLoading(false);
910927
return;
911928
}

0 commit comments

Comments
 (0)