// 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, useHotkeys, } from '@blueprintjs/core'; import { Tooltip2 } from '@blueprintjs/popover2'; import { useI18n } from '@shopify/react-i18n'; import React, { useMemo, useState } from 'react'; import { useDispatch } from 'react-redux'; import { useDarkMode } 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 { setString } from './actions'; import { StringSettingId } from './defaults'; import { useSettingFlashCurrentProgram, useSettingIsShowDocsEnabled } from './hooks'; import { SettingsStringId } from './i18n'; import en from './i18n.en.json'; import './settings.scss'; type SettingsProps = { isOpen: boolean; onClose(): void; }; const SettingsDrawer: React.VoidFunctionComponent = ({ isOpen, onClose, }) => { const { isSettingShowDocsEnabled, setIsSettingShowDocsEnabled, toggleIsSettingShowDocsEnabled, } = useSettingIsShowDocsEnabled(); const [isAboutDialogOpen, setIsAboutDialogOpen] = useState(false); const { isDarkMode, toggle: toggleDarkMode } = useDarkMode(); 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 = useSelector((s) => s.settings.hubName); const isHubNameValid = useSelector((s) => s.settings.isHubNameValid); const dispatch = useDispatch(); const [i18n] = useI18n({ id: 'settings', translations: { en }, fallback: en, }); const hotkeys = useMemo( () => [ { combo: 'mod+d', label: i18n.translate(SettingsStringId.AppearanceDocumentationTooltip), global: true, preventDefault: true, onKeyDown: toggleIsSettingShowDocsEnabled, }, ], [i18n, toggleIsSettingShowDocsEnabled], ); useHotkeys(hotkeys); return (
{isMacOS() ? 'Cmd' : 'Ctrl'}-+, out: {isMacOS() ? 'Cmd' : 'Ctrl'}--, }, )} > setIsSettingShowDocsEnabled( (e.target as HTMLInputElement).checked, ) } /> setIsFlashCurrentProgramEnabled( (e.target as HTMLInputElement).checked, ) } /> dispatch( setString( StringSettingId.HubName, 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(SettingsStringId.HelpProjectsLabel)} {i18n.translate(SettingsStringId.HelpSupportLabel)} {i18n.translate(SettingsStringId.HelpChatLabel)} {i18n.translate(SettingsStringId.HelpBugsLabel)} setIsAboutDialogOpen(false)} /> {hasUnresolvedInstallPrompt && ( )} {isServiceWorkerRegistered && !updateAvailable && ( )} {isServiceWorkerRegistered && updateAvailable && ( )} {process.env.NODE_ENV === 'development' && ( pseudolocalize(!i18n.pseudolocalize)} label="Pseudolocalize" /> )}
); }; export default SettingsDrawer;