@@ -782,24 +782,86 @@ function App() {
782782 // --- GLOBAL SHORTCUTS ---
783783 useEffect ( ( ) => {
784784 const handleKeyDown = ( e : KeyboardEvent ) => {
785- // Command Palette Trigger
785+ // Ignore text inputs
786+ if (
787+ e . target instanceof HTMLInputElement ||
788+ e . target instanceof HTMLTextAreaElement ||
789+ e . target instanceof HTMLSelectElement
790+ ) {
791+ return ;
792+ }
793+
794+ // Toggle Command Palette
786795 if ( ( e . metaKey || e . ctrlKey ) && e . key === 'k' ) {
787796 e . preventDefault ( ) ;
788- setIsCommandPaletteOpen ( prev => ! prev ) ;
797+ setIsCommandPaletteOpen ( ( prev ) => ! prev ) ;
789798 return ;
790799 }
791800
792- // Exit Publication Mode on Escape
801+ // Exit modes on Escape
793802 if ( e . key === 'Escape' ) {
794803 setIsPublicationMode ( false ) ;
795- setIsMeasurementMode ( false ) ; // Also good UX to exit measurement mode
796- setIsCommandPaletteOpen ( false ) ; // Close other overlays
804+ setIsMeasurementMode ( false ) ;
805+ setIsCommandPaletteOpen ( false ) ;
797806 setIsLibraryOpen ( false ) ;
807+ setShowContactMap ( false ) ;
808+ return ;
809+ }
810+
811+ // Only process below shortcuts if no modals are open
812+ if ( isLibraryOpen || isCommandPaletteOpen || showContactMap ) return ;
813+
814+ switch ( e . key . toLowerCase ( ) ) {
815+ // General
816+ case 'f' :
817+ e . preventDefault ( ) ;
818+ if ( ! document . fullscreenElement ) {
819+ document . documentElement . requestFullscreen ( ) . catch ( ( err ) => console . error ( err ) ) ;
820+ } else {
821+ document . exitFullscreen ( ) ;
822+ }
823+ break ;
824+ case 't' :
825+ setIsLightMode ( prev => ! prev ) ;
826+ break ;
827+
828+ // View Controls
829+ case 'r' :
830+ viewerRef . current ?. resetCamera ( ) ;
831+ break ;
832+ case ' ' :
833+ e . preventDefault ( ) ; // Prevent scroll
834+ setIsSpinning ( prev => ! prev ) ;
835+ break ;
836+ case 's' :
837+ // Screenshot
838+ viewerRef . current ?. captureImage ( ) ;
839+ break ;
840+
841+ // Tools
842+ case 'm' :
843+ setIsMeasurementMode ( prev => ! prev ) ;
844+ break ;
845+ case 'c' :
846+ setShowContactMap ( prev => ! prev ) ;
847+ break ;
848+
849+ // Representations (1-4)
850+ case '1' : setRepresentation ( 'cartoon' ) ; break ;
851+ case '2' : setRepresentation ( 'spacefill' ) ; break ;
852+ case '3' : setRepresentation ( 'surface' ) ; break ;
853+ case '4' : setRepresentation ( 'licorice' ) ; break ;
854+
855+ // Coloring
856+ case 'q' : setColoring ( 'chainid' ) ; break ;
857+ case 'w' : setColoring ( 'element' as ColoringType ) ; break ;
858+ case 'e' : setColoring ( 'hydrophobicity' ) ; break ;
859+ case 'a' : setColoring ( 'bfactor' ) ; break ; // pLDDT is usually bfactor
798860 }
799861 } ;
800862 window . addEventListener ( 'keydown' , handleKeyDown ) ;
801863 return ( ) => window . removeEventListener ( 'keydown' , handleKeyDown ) ;
802- } , [ ] ) ;
864+ } , [ isLibraryOpen , isCommandPaletteOpen , showContactMap ] ) ;
803865
804866 const commandActions : CommandAction [ ] = useMemo ( ( ) => [
805867 // --- FILES & LOADING ---
0 commit comments