// SPDX-License-Identifier: MIT // Copyright (c) 2021-2022 The Pybricks Authors import { AnchorButton, Button, ButtonGroup, Classes, ControlGroup, Drawer, DrawerSize, FormGroup, Icon, InputGroup, Intent, Label, Switch, } from '@blueprintjs/core'; import { Tooltip2 } from '@blueprintjs/popover2'; import { useI18n } from '@shopify/react-i18n'; import React, { useCallback, useState } from 'react'; import { useDispatch } from 'react-redux'; import { useTernaryDarkMode } from 'usehooks-ts'; import AboutDialog from '../about/AboutDialog'; import { appCheckForUpdate, appReload, appShowInstallPrompt } from '../app/actions'; import { pybricksBugReportsUrl, pybricksGitterUrl, pybricksProjectsUrl, pybricksSupportUrl, tooltipDelay, } from '../app/constants'; import { pseudolocalize } from '../i18n'; import { useSelector } from '../reducers'; import ExternalLinkIcon from '../utils/ExternalLinkIcon'; import { isMacOS } from '../utils/os'; import { useSettingFlashCurrentProgram, useSettingHubName, useSettingIsShowDocsEnabled, } from './hooks'; import { I18nId } from './i18n'; import './settings.scss'; type SettingsProps = { isOpen: boolean; onClose(): void; }; const SettingsDrawer: React.VoidFunctionComponent = ({ isOpen, onClose, }) => { const { isSettingShowDocsEnabled, setIsSettingShowDocsEnabled } = useSettingIsShowDocsEnabled(); const [isAboutDialogOpen, setIsAboutDialogOpen] = useState(false); const { isDarkMode, setTernaryDarkMode } = useTernaryDarkMode(); const [isFlashCurrentProgramEnabled, setIsFlashCurrentProgramEnabled] = useSettingFlashCurrentProgram(); const isServiceWorkerRegistered = useSelector( (s) => s.app.isServiceWorkerRegistered, ); const checkingForUpdate = useSelector((s) => s.app.checkingForUpdate); const updateAvailable = useSelector((s) => s.app.updateAvailable); const hasUnresolvedInstallPrompt = useSelector( (s) => s.app.hasUnresolvedInstallPrompt, ); const promptingInstall = useSelector((s) => s.app.promptingInstall); const readyForOfflineUse = useSelector((s) => s.app.readyForOfflineUse); const { hubName, isHubNameValid, setHubName } = useSettingHubName(); const dispatch = useDispatch(); // istanbul ignore next: babel-loader rewrites this line const [i18n] = useI18n(); // HACK: set additional attributes that are not supported via Drawer props const handleDrawerOpening = useCallback<(node: HTMLElement) => void>((n) => { n.setAttribute('role', 'dialog'); n.setAttribute('aria-modal', 'true'); n.setAttribute('aria-labelledby', 'settings-drawer-dialog-title'); }, []); return ( {i18n.translate(I18nId.Title)} } onOpening={handleDrawerOpening} onClose={onClose} // work around https://github.com/palantir/blueprint/issues/5169 shouldReturnFocusOnClose={false} >
{isMacOS() ? 'Cmd' : 'Ctrl'}-+, out: {isMacOS() ? 'Cmd' : 'Ctrl'}--, })} > setIsSettingShowDocsEnabled( (e.target as HTMLInputElement).checked, ) } /> setTernaryDarkMode( (e.target as HTMLInputElement).checked ? 'dark' : 'light', ) } /> setIsFlashCurrentProgramEnabled( (e.target as HTMLInputElement).checked, ) } /> setHubName(e.currentTarget.value)} onMouseOver={(e) => e.preventDefault()} className="pb-hub-name-input" intent={isHubNameValid ? Intent.NONE : Intent.DANGER} placeholder="Pybricks Hub" rightElement={ isHubNameValid ? undefined : ( ) } /> {i18n.translate(I18nId.HelpProjectsLabel)} {i18n.translate(I18nId.HelpSupportLabel)} {i18n.translate(I18nId.HelpChatLabel)} {i18n.translate(I18nId.HelpBugsLabel)} setIsAboutDialogOpen(false)} /> {hasUnresolvedInstallPrompt && ( )} {isServiceWorkerRegistered && !updateAvailable && ( )} {isServiceWorkerRegistered && updateAvailable && ( )} {process.env.NODE_ENV === 'development' && ( pseudolocalize(!i18n.pseudolocalize)} label="Pseudolocalize" /> )}
); }; export default SettingsDrawer;