chore: prettier files

This commit is contained in:
Mo
2022-05-03 10:51:40 -05:00
parent f5a90060ea
commit 43d94fbcbf
127 changed files with 1365 additions and 2428 deletions

View File

@@ -9,8 +9,7 @@ export const quickSettingsKeyDownHandler = (
themesMenuOpen: boolean,
) => {
if (quickSettingsMenuRef?.current) {
const items: NodeListOf<HTMLButtonElement> =
quickSettingsMenuRef.current.querySelectorAll(':scope > button')
const items: NodeListOf<HTMLButtonElement> = quickSettingsMenuRef.current.querySelectorAll(':scope > button')
const currentFocusedIndex = Array.from(items).findIndex((btn) => btn === document.activeElement)
if (!themesMenuOpen) {
@@ -45,9 +44,7 @@ export const themesMenuKeyDownHandler = (
) => {
if (themesMenuRef?.current) {
const themes = themesMenuRef.current.querySelectorAll('button')
const currentFocusedIndex = Array.from(themes).findIndex(
(themeBtn) => themeBtn === document.activeElement,
)
const currentFocusedIndex = Array.from(themes).findIndex((themeBtn) => themeBtn === document.activeElement)
switch (event.key) {
case 'Escape':

View File

@@ -14,15 +14,9 @@ type Props = {
isEnabled: boolean
}
export const FocusModeSwitch: FunctionComponent<Props> = ({
application,
onToggle,
onClose,
isEnabled,
}) => {
export const FocusModeSwitch: FunctionComponent<Props> = ({ application, onToggle, onClose, isEnabled }) => {
const premiumModal = usePremiumModal()
const isEntitled =
application.features.getFeatureStatus(FeatureIdentifier.FocusMode) === FeatureStatus.Entitled
const isEntitled = application.features.getFeatureStatus(FeatureIdentifier.FocusMode) === FeatureStatus.Entitled
const toggle = useCallback(
(e: JSXInternal.TargetedMouseEvent<HTMLButtonElement>) => {
@@ -40,10 +34,7 @@ export const FocusModeSwitch: FunctionComponent<Props> = ({
return (
<>
<button
className="sn-dropdown-item focus:bg-info-backdrop focus:shadow-none justify-between"
onClick={toggle}
>
<button className="sn-dropdown-item focus:bg-info-backdrop focus:shadow-none justify-between" onClick={toggle}>
<div className="flex items-center">
<Icon type="menu-close" className="color-neutral mr-2" />
Focused Writing

View File

@@ -25,10 +25,7 @@ export const ThemesMenuButton: FunctionComponent<Props> = ({ application, item,
() => application.features.getFeatureStatus(item.identifier) === FeatureStatus.Entitled,
[application, item.identifier],
)
const canActivateTheme = useMemo(
() => isEntitledToTheme || isThirdPartyTheme,
[isEntitledToTheme, isThirdPartyTheme],
)
const canActivateTheme = useMemo(() => isEntitledToTheme || isThirdPartyTheme, [isEntitledToTheme, isThirdPartyTheme])
const toggleTheme: JSXInternal.MouseEventHandler<HTMLButtonElement> = (e) => {
e.preventDefault()
@@ -61,14 +58,8 @@ export const ThemesMenuButton: FunctionComponent<Props> = ({ application, item,
) : (
<>
<div className="flex items-center">
<div
className={`pseudo-radio-btn ${
item.component?.active ? 'pseudo-radio-btn--checked' : ''
} mr-2`}
></div>
<span className={item.component?.active ? 'font-semibold' : undefined}>
{item.name}
</span>
<div className={`pseudo-radio-btn ${item.component?.active ? 'pseudo-radio-btn--checked' : ''} mr-2`}></div>
<span className={item.component?.active ? 'font-semibold' : undefined}>{item.name}</span>
</div>
{item.component && canActivateTheme ? (
<div

View File

@@ -1,14 +1,7 @@
import { WebApplication } from '@/UIModels/Application'
import { AppState } from '@/UIModels/AppState'
import { Disclosure, DisclosureButton, DisclosurePanel } from '@reach/disclosure'
import {
ComponentArea,
ContentType,
FeatureIdentifier,
GetFeatures,
SNComponent,
SNTheme,
} from '@standardnotes/snjs'
import { ComponentArea, ContentType, FeatureIdentifier, GetFeatures, SNComponent, SNTheme } from '@standardnotes/snjs'
import { observer } from 'mobx-react-lite'
import { FunctionComponent } from 'preact'
import { useCallback, useEffect, useRef, useState } from 'preact/hooks'
@@ -25,8 +18,7 @@ import { sortThemes } from '@/Utils/SortThemes'
const focusModeAnimationDuration = 1255
const MENU_CLASSNAME =
'sn-menu-border sn-dropdown min-w-80 max-h-120 max-w-xs flex flex-col py-2 overflow-y-auto'
const MENU_CLASSNAME = 'sn-menu-border sn-dropdown min-w-80 max-h-120 max-w-xs flex flex-col py-2 overflow-y-auto'
type MenuProps = {
appState: AppState
@@ -48,266 +40,241 @@ const toggleFocusMode = (enabled: boolean) => {
}
}
export const QuickSettingsMenu: FunctionComponent<MenuProps> = observer(
({ application, appState, onClickOutside }) => {
const {
closeQuickSettingsMenu,
shouldAnimateCloseMenu,
focusModeEnabled,
setFocusModeEnabled,
} = appState.quickSettingsMenu
const [themes, setThemes] = useState<ThemeItem[]>([])
const [toggleableComponents, setToggleableComponents] = useState<SNComponent[]>([])
const [themesMenuOpen, setThemesMenuOpen] = useState(false)
const [themesMenuPosition, setThemesMenuPosition] = useState({})
const [defaultThemeOn, setDefaultThemeOn] = useState(false)
export const QuickSettingsMenu: FunctionComponent<MenuProps> = observer(({ application, appState, onClickOutside }) => {
const { closeQuickSettingsMenu, shouldAnimateCloseMenu, focusModeEnabled, setFocusModeEnabled } =
appState.quickSettingsMenu
const [themes, setThemes] = useState<ThemeItem[]>([])
const [toggleableComponents, setToggleableComponents] = useState<SNComponent[]>([])
const [themesMenuOpen, setThemesMenuOpen] = useState(false)
const [themesMenuPosition, setThemesMenuPosition] = useState({})
const [defaultThemeOn, setDefaultThemeOn] = useState(false)
const themesMenuRef = useRef<HTMLDivElement>(null)
const themesButtonRef = useRef<HTMLButtonElement>(null)
const prefsButtonRef = useRef<HTMLButtonElement>(null)
const quickSettingsMenuRef = useRef<HTMLDivElement>(null)
const defaultThemeButtonRef = useRef<HTMLButtonElement>(null)
const themesMenuRef = useRef<HTMLDivElement>(null)
const themesButtonRef = useRef<HTMLButtonElement>(null)
const prefsButtonRef = useRef<HTMLButtonElement>(null)
const quickSettingsMenuRef = useRef<HTMLDivElement>(null)
const defaultThemeButtonRef = useRef<HTMLButtonElement>(null)
const mainRef = useRef<HTMLDivElement>(null)
useCloseOnClickOutside(mainRef, () => {
onClickOutside()
const mainRef = useRef<HTMLDivElement>(null)
useCloseOnClickOutside(mainRef, () => {
onClickOutside()
})
useEffect(() => {
toggleFocusMode(focusModeEnabled)
}, [focusModeEnabled])
const reloadThemes = useCallback(() => {
const themes = application.items.getDisplayableItems<SNTheme>(ContentType.Theme).map((item) => {
return {
name: item.name,
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))
setDefaultThemeOn(!themes.map((item) => item?.component).find((theme) => theme?.active && !theme.isLayerable()))
}, [application])
const reloadToggleableComponents = useCallback(() => {
const toggleableComponents = application.items
.getDisplayableItems<SNComponent>(ContentType.Component)
.filter(
(component) =>
[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()
})
useEffect(() => {
toggleFocusMode(focusModeEnabled)
}, [focusModeEnabled])
return () => {
cleanupItemStream()
}
}, [application, reloadThemes])
const reloadThemes = useCallback(() => {
const themes = application.items
.getDisplayableItems<SNTheme>(ContentType.Theme)
.map((item) => {
return {
name: item.name,
identifier: item.identifier,
component: item,
}
}) as ThemeItem[]
useEffect(() => {
const cleanupItemStream = application.streamItems(ContentType.Component, () => {
reloadToggleableComponents()
})
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,
})
}
})
return () => {
cleanupItemStream()
}
}, [application, reloadToggleableComponents])
setThemes(themes.sort(sortThemes))
useEffect(() => {
if (themesMenuOpen) {
defaultThemeButtonRef.current?.focus()
}
}, [themesMenuOpen])
setDefaultThemeOn(
!themes
.map((item) => item?.component)
.find((theme) => theme?.active && !theme.isLayerable()),
)
}, [application])
useEffect(() => {
prefsButtonRef.current?.focus()
}, [])
const reloadToggleableComponents = useCallback(() => {
const toggleableComponents = application.items
.getDisplayableItems<SNComponent>(ContentType.Component)
.filter(
(component) =>
[ComponentArea.EditorStack].includes(component.area) &&
component.identifier !== FeatureIdentifier.DeprecatedFoldersComponent,
)
const [closeOnBlur] = useCloseOnBlur(themesMenuRef, setThemesMenuOpen)
setToggleableComponents(toggleableComponents)
}, [application])
useEffect(() => {
if (!themes.length) {
reloadThemes()
}
}, [reloadThemes, themes.length])
useEffect(() => {
const cleanupItemStream = application.streamItems(ContentType.Theme, () => {
reloadThemes()
const toggleThemesMenu = () => {
if (!themesMenuOpen && themesButtonRef.current) {
const themesButtonRect = themesButtonRef.current.getBoundingClientRect()
setThemesMenuPosition({
left: themesButtonRect.right,
bottom: document.documentElement.clientHeight - themesButtonRect.bottom,
})
setThemesMenuOpen(true)
} else {
setThemesMenuOpen(false)
}
}
return () => {
cleanupItemStream()
}
}, [application, reloadThemes])
const openPreferences = () => {
closeQuickSettingsMenu()
appState.preferences.openPreferences()
}
useEffect(() => {
const cleanupItemStream = application.streamItems(ContentType.Component, () => {
reloadToggleableComponents()
})
const toggleComponent = (component: SNComponent) => {
if (component.isTheme()) {
application.mutator.toggleTheme(component).catch(console.error)
} else {
application.mutator.toggleComponent(component).catch(console.error)
}
}
return () => {
cleanupItemStream()
}
}, [application, reloadToggleableComponents])
useEffect(() => {
if (themesMenuOpen) {
defaultThemeButtonRef.current?.focus()
}
}, [themesMenuOpen])
useEffect(() => {
prefsButtonRef.current?.focus()
}, [])
const [closeOnBlur] = useCloseOnBlur(themesMenuRef, setThemesMenuOpen)
const toggleThemesMenu = () => {
if (!themesMenuOpen && themesButtonRef.current) {
const themesButtonRect = themesButtonRef.current.getBoundingClientRect()
setThemesMenuPosition({
left: themesButtonRect.right,
bottom: document.documentElement.clientHeight - themesButtonRect.bottom,
})
setThemesMenuOpen(true)
} else {
const handleBtnKeyDown: React.KeyboardEventHandler<HTMLButtonElement> = (event) => {
switch (event.key) {
case 'Escape':
setThemesMenuOpen(false)
}
themesButtonRef.current?.focus()
break
case 'ArrowRight':
if (!themesMenuOpen) {
toggleThemesMenu()
}
}
}
const openPreferences = () => {
closeQuickSettingsMenu()
appState.preferences.openPreferences()
const handleQuickSettingsKeyDown: JSXInternal.KeyboardEventHandler<HTMLDivElement> = (event) => {
quickSettingsKeyDownHandler(closeQuickSettingsMenu, event, quickSettingsMenuRef, themesMenuOpen)
}
const handlePanelKeyDown: React.KeyboardEventHandler<HTMLDivElement> = (event) => {
themesMenuKeyDownHandler(event, themesMenuRef, setThemesMenuOpen, themesButtonRef)
}
const toggleDefaultTheme = () => {
const activeTheme = themes.map((item) => item.component).find((theme) => theme?.active && !theme.isLayerable())
if (activeTheme) {
application.mutator.toggleTheme(activeTheme).catch(console.error)
}
}
const toggleComponent = (component: SNComponent) => {
if (component.isTheme()) {
application.mutator.toggleTheme(component).catch(console.error)
} else {
application.mutator.toggleComponent(component).catch(console.error)
}
}
const handleBtnKeyDown: React.KeyboardEventHandler<HTMLButtonElement> = (event) => {
switch (event.key) {
case 'Escape':
setThemesMenuOpen(false)
themesButtonRef.current?.focus()
break
case 'ArrowRight':
if (!themesMenuOpen) {
toggleThemesMenu()
}
}
}
const handleQuickSettingsKeyDown: JSXInternal.KeyboardEventHandler<HTMLDivElement> = (
event,
) => {
quickSettingsKeyDownHandler(
closeQuickSettingsMenu,
event,
quickSettingsMenuRef,
themesMenuOpen,
)
}
const handlePanelKeyDown: React.KeyboardEventHandler<HTMLDivElement> = (event) => {
themesMenuKeyDownHandler(event, themesMenuRef, setThemesMenuOpen, themesButtonRef)
}
const toggleDefaultTheme = () => {
const activeTheme = themes
.map((item) => item.component)
.find((theme) => theme?.active && !theme.isLayerable())
if (activeTheme) {
application.mutator.toggleTheme(activeTheme).catch(console.error)
}
}
return (
<div ref={mainRef} className="sn-component">
<div
className={`sn-quick-settings-menu absolute ${MENU_CLASSNAME} ${
shouldAnimateCloseMenu ? 'slide-up-animation' : 'sn-dropdown--animated'
}`}
ref={quickSettingsMenuRef}
onKeyDown={handleQuickSettingsKeyDown}
>
<div className="px-3 mt-1 mb-2 font-semibold color-text uppercase">Quick Settings</div>
<Disclosure open={themesMenuOpen} onChange={toggleThemesMenu}>
<DisclosureButton
onKeyDown={handleBtnKeyDown}
onBlur={closeOnBlur}
ref={themesButtonRef}
className="sn-dropdown-item justify-between focus:bg-info-backdrop focus:shadow-none"
>
<div className="flex items-center">
<Icon type="themes" className="color-neutral mr-2" />
Themes
</div>
<Icon type="chevron-right" className="color-neutral" />
</DisclosureButton>
<DisclosurePanel
onBlur={closeOnBlur}
ref={themesMenuRef}
onKeyDown={handlePanelKeyDown}
style={{
...themesMenuPosition,
}}
className={`${MENU_CLASSNAME} fixed sn-dropdown--animated`}
>
<div className="px-3 my-1 font-semibold color-text uppercase">Themes</div>
<button
className="sn-dropdown-item focus:bg-info-backdrop focus:shadow-none"
onClick={toggleDefaultTheme}
onBlur={closeOnBlur}
ref={defaultThemeButtonRef}
>
<div
className={`pseudo-radio-btn ${
defaultThemeOn ? 'pseudo-radio-btn--checked' : ''
} mr-2`}
></div>
Default
</button>
{themes.map((theme) => (
<ThemesMenuButton
item={theme}
application={application}
key={theme.component?.uuid ?? theme.identifier}
onBlur={closeOnBlur}
/>
))}
</DisclosurePanel>
</Disclosure>
{toggleableComponents.map((component) => (
<button
className="sn-dropdown-item justify-between focus:bg-info-backdrop focus:shadow-none"
onClick={() => {
toggleComponent(component)
}}
>
<div className="flex items-center">
<Icon type="window" className="color-neutral mr-2" />
{component.name}
</div>
<Switch checked={component.active} className="px-0" />
</button>
))}
<FocusModeSwitch
application={application}
onToggle={setFocusModeEnabled}
onClose={closeQuickSettingsMenu}
isEnabled={focusModeEnabled}
/>
<div className="h-1px my-2 bg-border"></div>
<button
className="sn-dropdown-item focus:bg-info-backdrop focus:shadow-none"
onClick={openPreferences}
ref={prefsButtonRef}
return (
<div ref={mainRef} className="sn-component">
<div
className={`sn-quick-settings-menu absolute ${MENU_CLASSNAME} ${
shouldAnimateCloseMenu ? 'slide-up-animation' : 'sn-dropdown--animated'
}`}
ref={quickSettingsMenuRef}
onKeyDown={handleQuickSettingsKeyDown}
>
<div className="px-3 mt-1 mb-2 font-semibold color-text uppercase">Quick Settings</div>
<Disclosure open={themesMenuOpen} onChange={toggleThemesMenu}>
<DisclosureButton
onKeyDown={handleBtnKeyDown}
onBlur={closeOnBlur}
ref={themesButtonRef}
className="sn-dropdown-item justify-between focus:bg-info-backdrop focus:shadow-none"
>
<Icon type="more" className="color-neutral mr-2" />
Open Preferences
<div className="flex items-center">
<Icon type="themes" className="color-neutral mr-2" />
Themes
</div>
<Icon type="chevron-right" className="color-neutral" />
</DisclosureButton>
<DisclosurePanel
onBlur={closeOnBlur}
ref={themesMenuRef}
onKeyDown={handlePanelKeyDown}
style={{
...themesMenuPosition,
}}
className={`${MENU_CLASSNAME} fixed sn-dropdown--animated`}
>
<div className="px-3 my-1 font-semibold color-text uppercase">Themes</div>
<button
className="sn-dropdown-item focus:bg-info-backdrop focus:shadow-none"
onClick={toggleDefaultTheme}
onBlur={closeOnBlur}
ref={defaultThemeButtonRef}
>
<div className={`pseudo-radio-btn ${defaultThemeOn ? 'pseudo-radio-btn--checked' : ''} mr-2`}></div>
Default
</button>
{themes.map((theme) => (
<ThemesMenuButton
item={theme}
application={application}
key={theme.component?.uuid ?? theme.identifier}
onBlur={closeOnBlur}
/>
))}
</DisclosurePanel>
</Disclosure>
{toggleableComponents.map((component) => (
<button
className="sn-dropdown-item justify-between focus:bg-info-backdrop focus:shadow-none"
onClick={() => {
toggleComponent(component)
}}
>
<div className="flex items-center">
<Icon type="window" className="color-neutral mr-2" />
{component.name}
</div>
<Switch checked={component.active} className="px-0" />
</button>
</div>
))}
<FocusModeSwitch
application={application}
onToggle={setFocusModeEnabled}
onClose={closeQuickSettingsMenu}
isEnabled={focusModeEnabled}
/>
<div className="h-1px my-2 bg-border"></div>
<button
className="sn-dropdown-item focus:bg-info-backdrop focus:shadow-none"
onClick={openPreferences}
ref={prefsButtonRef}
>
<Icon type="more" className="color-neutral mr-2" />
Open Preferences
</button>
</div>
)
},
)
</div>
)
})