import React, {forwardRef, useEffect, useRef} from 'react'; import type {MousetrapInstance} from 'mousetrap'; import Mousetrap from 'mousetrap'; import {connect} from '../utils/plugins'; import * as uiActions from '../actions/ui'; import {getRegisteredKeys, getCommandHandler, shouldPreventDefault} from '../command-registry'; import stylis from 'stylis'; import {HeaderContainer} from './header'; import TermsContainer from './terms'; import NotificationsContainer from './notifications'; import type {HyperState, HyperProps, HyperDispatch} from '../hyper'; import type Terms from '../components/terms'; const isMac = /Mac/.test(navigator.userAgent); const Hyper = forwardRef((props, ref) => { const mousetrap = useRef(null); const terms = useRef(null); useEffect(() => { void attachKeyListeners(); }, [props.lastConfigUpdate]); useEffect(() => { handleFocusActive(props.activeSession); }, [props.activeSession]); const handleFocusActive = (uid?: string | null) => { const term = uid && terms.current?.getTermByUid(uid); if (term) { term.focus(); } }; const handleSelectAll = () => { const term = terms.current?.getActiveTerm(); if (term) { term.selectAll(); } }; const attachKeyListeners = async () => { if (!mousetrap.current) { // eslint-disable-next-line @typescript-eslint/no-unsafe-call mousetrap.current = new (Mousetrap as any)(window, true); mousetrap.current!.stopCallback = () => { // All events should be intercepted even if focus is in an input/textarea return false; }; } else { mousetrap.current.reset(); } const keys = await getRegisteredKeys(); Object.keys(keys).forEach((commandKeys) => { mousetrap.current?.bind( commandKeys, (e) => { const command = keys[commandKeys]; // We should tell xterm to ignore this event. (e as any).catched = true; props.execCommand(command, getCommandHandler(command), e); shouldPreventDefault(command) && e.preventDefault(); }, 'keydown' ); }); }; useEffect(() => { void attachKeyListeners(); window.rpc.on('term selectAll', handleSelectAll); }, []); const onTermsRef = (_terms: Terms | null) => { terms.current = _terms; window.focusActiveTerm = (uid?: string) => { if (uid) { handleFocusActive(uid); } else { terms.current?.getActiveTerm()?.focus(); } }; }; useEffect(() => { return () => { mousetrap.current?.reset(); }; }, []); const {isMac: isMac_, customCSS, uiFontFamily, borderColor, maximized, fullScreen} = props; const borderWidth = isMac_ ? '' : `${maximized ? '0' : '1'}px`; stylis.set({prefix: false}); return (
{props.customInnerChildren}
{props.customChildren} {/* Add custom CSS to Hyper. We add a scope to the customCSS so that it can get around the weighting applied by styled-jsx */}