import Button from '@mui/material/Button'; import { styled } from '@mui/material/styles'; import TextField from '@mui/material/TextField'; import Typography from '@mui/material/Typography'; import { useCallback, useEffect, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; const Root = styled('div')` display: flex; align-items: center; padding: 0 4px; z-index: 1; height: 41px; border-bottom: 1px solid ${({ theme }) => theme.palette.divider}; width: 100%; `; const InfoContainer = styled('div')` flex: 1; padding: 0 12px; `; export default function FindInPage(): React.JSX.Element | null { const { t } = useTranslation(); const [open, openSetter] = useState(false); const [text, textSetter] = useState(''); const [activeMatch, activeMatchSetter] = useState(0); const [matches, matchesSetter] = useState(0); const inputReference = useRef(null); // https://stackoverflow.com/a/57556594 // Event handler utilizing useCallback ... // ... so that reference never changes. const handleOpenFindInPage = useCallback(() => { openSetter(true); inputReference.current?.focus(); inputReference.current?.select(); }, [inputReference, openSetter]); const handleCloseFindInPage = useCallback(() => { openSetter(false); textSetter(''); activeMatchSetter(0); matchesSetter(0); }, []); const updateFindInPageMatches = useCallback( (_event: Electron.IpcRendererEvent, activeMatchOrdinal: number, matchesResult: number) => { activeMatchSetter(activeMatchOrdinal); matchesSetter(matchesResult); }, [activeMatchSetter, matchesSetter], ); useEffect(() => { window.remote.registerOpenFindInPage(handleOpenFindInPage); window.remote.registerCloseFindInPage(handleCloseFindInPage); window.remote.registerUpdateFindInPageMatches(updateFindInPageMatches); // Remove event listener on cleanup return () => { window.remote.unregisterOpenFindInPage(handleOpenFindInPage); window.remote.unregisterCloseFindInPage(handleCloseFindInPage); window.remote.unregisterUpdateFindInPageMatches(updateFindInPageMatches); }; }, [handleCloseFindInPage, handleOpenFindInPage, updateFindInPageMatches]); if (!open) { return null; } return ( {activeMatch} / {matches} {t('Menu.FindMatches')}
) => { const value = event.target.value; if (typeof value !== 'string') return; textSetter(value); if (value.length > 0) { void window.service.window.findInPage(value, true); } else { void window.service.window.stopFindInPage(); } }} onInput={(event: React.FormEvent) => { const value = event.currentTarget.value; if (typeof value !== 'string') return; textSetter(value); if (value.length > 0) { void window.service.window.findInPage(value, true); } else { void window.service.window.stopFindInPage(); } }} onKeyDown={(event: React.KeyboardEvent) => { if ( event.key === 'Enter' && // Enter text.length > 0 ) { void window.service.window.findInPage(text, true); } if (event.key === 'Escape') { // Escape void window.service.window.stopFindInPage(true); openSetter(false); } if (event.key === 'Backspace' && (event.ctrlKey || event.metaKey)) { textSetter(''); } }} />
); }