Skip to content

Commit 7ddcded

Browse files
AmirMohammad CheraghaliAmirMohammad Cheraghali
authored andcommitted
Feat: Update Tour Guide with new features (Transparency, Timeline) and add ID hooks
1 parent 36ea075 commit 7ddcded

5 files changed

Lines changed: 31 additions & 13 deletions

File tree

src/components/Controls.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1414,7 +1414,7 @@ export const Controls: React.FC<ControlsProps> = ({
14141414

14151415
{/* ADVANCED COLORS WRAPPER */}
14161416
{setCustomColors && (
1417-
<div className="col-span-2 pt-2 border-t border-white/5 space-y-2">
1417+
<div id="custom-color-controls" className="col-span-2 pt-2 border-t border-white/5 space-y-2">
14181418
<div className="flex items-center justify-between mb-1">
14191419
<div className={`text-[10px] font-bold uppercase tracking-wider ${subtleText} opacity-80`}>
14201420
Advanced Colors
@@ -1602,7 +1602,7 @@ export const Controls: React.FC<ControlsProps> = ({
16021602
{/* TRANSPARENCY WRAPPER */}
16031603
{/* Always render, prop is required */}
16041604
{true && (
1605-
<div className="col-span-2 pt-2 border-t border-white/5 space-y-2">
1605+
<div id="transparency-controls" className="col-span-2 pt-2 border-t border-white/5 space-y-2">
16061606
<div className="flex items-center justify-between mb-1">
16071607
<div className={`text-[10px] font-bold uppercase tracking-wider ${subtleText} opacity-80`}>
16081608
Transparency

src/components/ProteinViewer.tsx

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1667,8 +1667,7 @@ export const ProteinViewer = forwardRef<ProteinViewerRef, ProteinViewerProps>(({
16671667
if (dataSource === 'pubchem' && cleanId.length < 1) return null;
16681668

16691669
let url = getStructureUrl(cleanId, dataSource);
1670-
// Request Biological Unit 1 for proper viral/assembly visualization
1671-
let loadParams: any = { defaultRepresentation: false, assembly: 'bu1' };
1670+
let loadParams: any = { defaultRepresentation: false };
16721671

16731672
// Add extension hint for NGL if needed
16741673
if (dataSource === 'pubchem') loadParams.ext = 'sdf';
@@ -2420,7 +2419,7 @@ export const ProteinViewer = forwardRef<ProteinViewerRef, ProteinViewerProps>(({
24202419
}
24212420

24222421
// Handle "Force Element" for single chains/chemicals when default 'chainid' is picked
2423-
const chainCount = component.structure && component.structure.chainStore ? component.structure.chainStore.count : 0;
2422+
const chainCount = component.structure ? component.structure.chainStore.count : 0;
24242423
if (finalColor === 'chainid' && (chainCount <= 1 || dataSource === 'pubchem')) {
24252424
finalColor = 'element';
24262425
}
@@ -2579,11 +2578,9 @@ export const ProteinViewer = forwardRef<ProteinViewerRef, ProteinViewerProps>(({
25792578
// Fix: High Contrast for Chains
25802579
// If coloring by chain, ignore the global aesthetic palette (often monotonic like Magma)
25812580
// and force a high-contrast Rainbow (Spectral) to ensure distinct chain colors.
2582-
// If coloring by chain, ignore the global aesthetic palette (often monotonic like Magma)
2583-
// and force a high-contrast Rainbow (Spectral) to ensure distinct chain colors.
25842581
if (finalColor === 'chainindex') {
25852582
params.colorScale = 'Spectral';
2586-
} else if (scale && Array.isArray(scale) && scale.length > 0) {
2583+
} else if (scale && scale.length > 0) {
25872584
params.colorScale = scale;
25882585
}
25892586

src/components/TourGuide.tsx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,20 @@ export const startOnboardingTour = (onComplete?: () => void, onHighlight?: (elem
3939
: 'Change representations (Cartoon, Surface) and use Smart Coloring or Custom Colors to highlight specific residues.'
4040
}
4141
},
42+
{
43+
element: '#custom-color-controls',
44+
popover: {
45+
title: 'Advanced Custom Colors',
46+
description: 'Apply specific colors to individual residues or entire chains. Useful for highlighting active sites or specific domains.'
47+
}
48+
},
49+
{
50+
element: '#transparency-controls',
51+
popover: {
52+
title: 'Transparency Rules',
53+
description: 'Make specific parts of the structure transparent to reveal internal details. You can target chains or specific residue ranges.'
54+
}
55+
},
4256
{
4357
element: '#viewport-controls',
4458
popover: {
@@ -55,6 +69,13 @@ export const startOnboardingTour = (onComplete?: () => void, onHighlight?: (elem
5569
: 'Analyze structures with Superposition, Contact Maps, and precise Distance Measurements.'
5670
}
5771
},
72+
{
73+
element: '#video-timeline',
74+
popover: {
75+
title: 'Studio Timeline',
76+
description: 'Edit your recorded sessions. Trim clips, adjust start times, and arrange your production before exporting.'
77+
}
78+
},
5879
// Sequence Track (Atom List) - Desktop Only
5980
...(window.innerWidth >= 768 ? [{
6081
element: '#sequence-track',

src/components/VideoTimeline.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ export const VideoTimeline = ({
393393
const eventBlocks = getEventBlocks();
394394

395395
return (
396-
<div className="space-y-2">
396+
<div id="video-timeline" className="space-y-2">
397397
{/* Timeline Toolbar */}
398398
<div className="flex justify-between items-center text-xs px-1">
399399
<div className="opacity-60 font-mono">

src/utils/pdbUtils.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export const fetchPDBMetadata = async (pdbId: string): Promise<PDBMetadata | nul
2626
const method = data.exptl?.[0]?.method || 'Unknown';
2727

2828
let resolution = 'N/A';
29-
if (data.rcsb_entry_info?.resolution_combined && Array.isArray(data.rcsb_entry_info.resolution_combined) && data.rcsb_entry_info.resolution_combined.length > 0) {
29+
if (data.rcsb_entry_info?.resolution_combined && data.rcsb_entry_info.resolution_combined.length > 0) {
3030
resolution = `${data.rcsb_entry_info.resolution_combined[0].toFixed(2)} Å`;
3131
} else if (data.refine?.[0]?.ls_d_res_high) {
3232
resolution = `${data.refine[0].ls_d_res_high.toFixed(2)} Å`;
@@ -36,9 +36,9 @@ export const fetchPDBMetadata = async (pdbId: string): Promise<PDBMetadata | nul
3636

3737
// Organism from Entity 1
3838
let organism = 'Unknown source';
39-
if (entityData.rcsb_entity_source_organism && Array.isArray(entityData.rcsb_entity_source_organism) && entityData.rcsb_entity_source_organism.length > 0) {
39+
if (entityData.rcsb_entity_source_organism && entityData.rcsb_entity_source_organism.length > 0) {
4040
organism = entityData.rcsb_entity_source_organism[0].scientific_name;
41-
} else if (data.rcsb_entity_source_organism && Array.isArray(data.rcsb_entity_source_organism) && data.rcsb_entity_source_organism.length > 0) {
41+
} else if (data.rcsb_entity_source_organism && data.rcsb_entity_source_organism.length > 0) {
4242
organism = data.rcsb_entity_source_organism[0].scientific_name; // Fallback to entry if present (rare)
4343
}
4444

@@ -76,7 +76,7 @@ export const getStructureUrl = (id: string, source: DataSource): string => {
7676
switch (source) {
7777
case 'pubchem': return `https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/cid/${id}/record/SDF/?record_type=3d`;
7878
case 'alphafold': return `https://alphafold.ebi.ac.uk/files/AF-${id}-F1-model_v4.pdb`;
79-
case 'pdb': default: return `https://models.rcsb.org/${id}.mmtf`; // Use MMTF for efficient Biological Assembly loading
79+
case 'pdb': default: return `https://files.rcsb.org/download/${id}.pdb`; // Explicitly use PDB format
8080
}
8181
};
8282

0 commit comments

Comments
 (0)