import { WebApplication } from '@/Application/WebApplication' import { ComponentArea, ContentType, FeatureIdentifier, GetFeatures, SNComponent } from '@standardnotes/snjs' import { observer } from 'mobx-react-lite' import { FunctionComponent, useCallback, useEffect, useRef, useState } from 'react' import Icon from '@/Components/Icon/Icon' import FocusModeSwitch from './FocusModeSwitch' import ThemesMenuButton from './ThemesMenuButton' import { ThemeItem } from './ThemeItem' import { sortThemes } from '@/Utils/SortThemes' import HorizontalSeparator from '../Shared/HorizontalSeparator' import { QuickSettingsController } from '@/Controllers/QuickSettingsController' import PanelSettingsSection from './PanelSettingsSection' import Menu from '../Menu/Menu' import MenuSwitchButtonItem from '../Menu/MenuSwitchButtonItem' import MenuRadioButtonItem from '../Menu/MenuRadioButtonItem' type MenuProps = { quickSettingsMenuController: QuickSettingsController application: WebApplication } const QuickSettingsMenu: FunctionComponent = ({ application, quickSettingsMenuController }) => { const { focusModeEnabled, setFocusModeEnabled } = application.paneController const { closeQuickSettingsMenu } = quickSettingsMenuController const [themes, setThemes] = useState([]) const [toggleableComponents, setToggleableComponents] = useState([]) const defaultThemeOn = !themes.map((item) => item?.component).find((theme) => theme?.active && !theme.isLayerable()) const prefsButtonRef = useRef(null) const defaultThemeButtonRef = useRef(null) const reloadThemes = useCallback(() => { const themes = application.items .getDisplayableComponents() .filter((component) => component.isTheme()) .map((item) => { return { name: item.displayName, identifier: item.identifier, component: item, } }) as ThemeItem[] GetFeatures() .filter((feature) => feature.content_type === ContentType.Theme && !feature.layerable) .forEach((theme) => { if (themes.findIndex((item) => item.identifier === theme.identifier) === -1) { themes.push({ name: theme.name as string, identifier: theme.identifier, }) } }) setThemes(themes.sort(sortThemes)) }, [application]) const reloadToggleableComponents = useCallback(() => { const toggleableComponents = application.items .getDisplayableComponents() .filter( (component) => !component.isTheme() && [ComponentArea.EditorStack].includes(component.area) && component.identifier !== FeatureIdentifier.DeprecatedFoldersComponent, ) setToggleableComponents(toggleableComponents) }, [application]) useEffect(() => { if (!themes.length) { reloadThemes() } }, [reloadThemes, themes.length]) useEffect(() => { const cleanupItemStream = application.streamItems(ContentType.Theme, () => { reloadThemes() }) return () => { cleanupItemStream() } }, [application, reloadThemes]) useEffect(() => { const cleanupItemStream = application.streamItems(ContentType.Component, () => { reloadToggleableComponents() }) return () => { cleanupItemStream() } }, [application, reloadToggleableComponents]) useEffect(() => { prefsButtonRef.current?.focus() }, []) const toggleComponent = useCallback( (component: SNComponent) => { if (component.isTheme()) { application.mutator.toggleTheme(component).catch(console.error) } else { application.mutator.toggleComponent(component).catch(console.error) } }, [application], ) const deactivateAnyNonLayerableTheme = useCallback(() => { const activeTheme = themes.map((item) => item.component).find((theme) => theme?.active && !theme.isLayerable()) if (activeTheme) { application.mutator.toggleTheme(activeTheme).catch(console.error) } }, [application, themes]) const toggleDefaultTheme = useCallback(() => { deactivateAnyNonLayerableTheme() }, [deactivateAnyNonLayerableTheme]) return ( {toggleableComponents.length > 0 && ( <>
Tools
{toggleableComponents.map((component) => ( { toggleComponent(component) }} checked={component.active} key={component.uuid} > {component.displayName} ))} )}
Appearance
Default {themes.map((theme) => ( ))}
) } export default observer(QuickSettingsMenu)