feat: add panel settings section in quick settings (#1669)
This commit is contained in:
@@ -12,7 +12,7 @@ import PreferencesViewWrapper from '@/Components/Preferences/PreferencesViewWrap
|
||||
import ChallengeModal from '@/Components/ChallengeModal/ChallengeModal'
|
||||
import NotesContextMenu from '@/Components/NotesContextMenu/NotesContextMenu'
|
||||
import PurchaseFlowWrapper from '@/Components/PurchaseFlow/PurchaseFlowWrapper'
|
||||
import { FunctionComponent, useCallback, useEffect, useMemo, useState } from 'react'
|
||||
import { FunctionComponent, useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||
import RevisionHistoryModal from '@/Components/RevisionHistoryModal/RevisionHistoryModal'
|
||||
import PremiumModalProvider from '@/Hooks/usePremiumModal'
|
||||
import ConfirmSignoutContainer from '@/Components/ConfirmSignoutModal/ConfirmSignoutModal'
|
||||
@@ -35,13 +35,14 @@ type Props = {
|
||||
|
||||
const ApplicationView: FunctionComponent<Props> = ({ application, mainApplicationGroup }) => {
|
||||
const platformString = getPlatformString()
|
||||
const [appClass, setAppClass] = useState('')
|
||||
const [launched, setLaunched] = useState(false)
|
||||
const [needsUnlock, setNeedsUnlock] = useState(true)
|
||||
const [challenges, setChallenges] = useState<Challenge[]>([])
|
||||
|
||||
const viewControllerManager = application.getViewControllerManager()
|
||||
|
||||
const appColumnContainerRef = useRef<HTMLDivElement>(null)
|
||||
|
||||
useEffect(() => {
|
||||
const desktopService = application.getDesktopService()
|
||||
|
||||
@@ -125,15 +126,27 @@ const ApplicationView: FunctionComponent<Props> = ({ application, mainApplicatio
|
||||
useEffect(() => {
|
||||
const removeObserver = application.addWebEventObserver(async (eventName, data) => {
|
||||
if (eventName === WebAppEvent.PanelResized) {
|
||||
if (!appColumnContainerRef.current) {
|
||||
return
|
||||
}
|
||||
|
||||
const { panel, collapsed } = data as PanelResizedData
|
||||
let appClass = ''
|
||||
if (panel === PANEL_NAME_NOTES && collapsed) {
|
||||
appClass += 'collapsed-notes'
|
||||
|
||||
if (panel === PANEL_NAME_NOTES) {
|
||||
if (collapsed) {
|
||||
appColumnContainerRef.current.classList.add('collapsed-notes')
|
||||
} else {
|
||||
appColumnContainerRef.current.classList.remove('collapsed-notes')
|
||||
}
|
||||
}
|
||||
if (panel === PANEL_NAME_NAVIGATION && collapsed) {
|
||||
appClass += ' collapsed-navigation'
|
||||
|
||||
if (panel === PANEL_NAME_NAVIGATION) {
|
||||
if (collapsed) {
|
||||
appColumnContainerRef.current.classList.add('collapsed-navigation')
|
||||
} else {
|
||||
appColumnContainerRef.current.classList.remove('collapsed-navigation')
|
||||
}
|
||||
}
|
||||
setAppClass(appClass)
|
||||
} else if (eventName === WebAppEvent.WindowDidFocus) {
|
||||
if (!(await application.isLocked())) {
|
||||
application.sync.sync().catch(console.error)
|
||||
@@ -180,7 +193,7 @@ const ApplicationView: FunctionComponent<Props> = ({ application, mainApplicatio
|
||||
<ResponsivePaneProvider>
|
||||
<PremiumModalProvider application={application} viewControllerManager={viewControllerManager}>
|
||||
<div className={platformString + ' main-ui-view sn-component'}>
|
||||
<div id="app" className={appClass + ' app app-column-container'}>
|
||||
<div id="app" className="app app-column-container" ref={appColumnContainerRef}>
|
||||
<FileDragNDropProvider
|
||||
application={application}
|
||||
featuresController={viewControllerManager.featuresController}
|
||||
|
||||
@@ -100,6 +100,7 @@ export const ICONS = {
|
||||
unarchive: icons.UnarchiveIcon,
|
||||
unpin: icons.UnpinIcon,
|
||||
user: icons.UserIcon,
|
||||
view: icons.ViewIcon,
|
||||
warning: icons.WarningIcon,
|
||||
window: icons.WindowIcon,
|
||||
}
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { memo, useEffect, useState } from 'react'
|
||||
import { ApplicationEvent, PrefKey } from '@standardnotes/snjs'
|
||||
import MenuItem from '../Menu/MenuItem'
|
||||
import { MenuItemType } from '../Menu/MenuItemType'
|
||||
import { PANEL_NAME_NAVIGATION, PANEL_NAME_NOTES } from '@/Constants/Constants'
|
||||
import HorizontalSeparator from '../Shared/HorizontalSeparator'
|
||||
|
||||
type Props = {
|
||||
application: WebApplication
|
||||
}
|
||||
|
||||
const WidthForCollapsedPanel = 5
|
||||
const MinimumNavPanelWidth = 220
|
||||
const MinimumNotesPanelWidth = 350
|
||||
|
||||
const PanelSettingsSection = ({ application }: Props) => {
|
||||
const [currentNavPanelWidth, setCurrentNavPanelWidth] = useState(
|
||||
application.getPreference(PrefKey.TagsPanelWidth, MinimumNavPanelWidth),
|
||||
)
|
||||
|
||||
const [currentItemsPanelWidth, setCurrentItemsPanelWidth] = useState(
|
||||
application.getPreference(PrefKey.NotesPanelWidth, MinimumNotesPanelWidth),
|
||||
)
|
||||
|
||||
const toggleNavigationPanel = () => {
|
||||
const isCollapsed = currentNavPanelWidth <= WidthForCollapsedPanel
|
||||
if (isCollapsed) {
|
||||
void application.setPreference(PrefKey.TagsPanelWidth, MinimumNavPanelWidth)
|
||||
} else {
|
||||
void application.setPreference(PrefKey.TagsPanelWidth, WidthForCollapsedPanel)
|
||||
}
|
||||
application.publishPanelDidResizeEvent(PANEL_NAME_NAVIGATION, !isCollapsed)
|
||||
}
|
||||
|
||||
const toggleItemsListPanel = () => {
|
||||
const isCollapsed = currentItemsPanelWidth <= WidthForCollapsedPanel
|
||||
if (isCollapsed) {
|
||||
void application.setPreference(PrefKey.NotesPanelWidth, MinimumNotesPanelWidth)
|
||||
} else {
|
||||
void application.setPreference(PrefKey.NotesPanelWidth, WidthForCollapsedPanel)
|
||||
}
|
||||
application.publishPanelDidResizeEvent(PANEL_NAME_NOTES, !isCollapsed)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const removeObserver = application.addEventObserver(async () => {
|
||||
setCurrentNavPanelWidth(application.getPreference(PrefKey.TagsPanelWidth, MinimumNavPanelWidth))
|
||||
setCurrentItemsPanelWidth(application.getPreference(PrefKey.NotesPanelWidth, MinimumNotesPanelWidth))
|
||||
}, ApplicationEvent.PreferencesChanged)
|
||||
|
||||
return removeObserver
|
||||
}, [application])
|
||||
|
||||
return (
|
||||
<div className="hidden text-sm md:block">
|
||||
<HorizontalSeparator classes="my-2" />
|
||||
<div className="my-1 px-3 text-sm font-semibold uppercase text-text">Panel Settings</div>
|
||||
<MenuItem
|
||||
type={MenuItemType.SwitchButton}
|
||||
className="py-1 hover:bg-contrast focus:bg-info-backdrop"
|
||||
checked={currentNavPanelWidth > WidthForCollapsedPanel}
|
||||
onChange={toggleNavigationPanel}
|
||||
>
|
||||
Show navigation panel
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
type={MenuItemType.SwitchButton}
|
||||
className="py-1 hover:bg-contrast focus:bg-info-backdrop"
|
||||
checked={currentItemsPanelWidth > WidthForCollapsedPanel}
|
||||
onChange={toggleItemsListPanel}
|
||||
>
|
||||
Show items list panel
|
||||
</MenuItem>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default memo(PanelSettingsSection)
|
||||
@@ -11,6 +11,7 @@ import { sortThemes } from '@/Utils/SortThemes'
|
||||
import RadioIndicator from '../RadioIndicator/RadioIndicator'
|
||||
import HorizontalSeparator from '../Shared/HorizontalSeparator'
|
||||
import { QuickSettingsController } from '@/Controllers/QuickSettingsController'
|
||||
import PanelSettingsSection from './PanelSettingsSection'
|
||||
|
||||
const focusModeAnimationDuration = 1255
|
||||
|
||||
@@ -174,6 +175,7 @@ const QuickSettingsMenu: FunctionComponent<MenuProps> = ({ application, quickSet
|
||||
onClose={closeQuickSettingsMenu}
|
||||
isEnabled={focusModeEnabled}
|
||||
/>
|
||||
<PanelSettingsSection application={application} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -9,6 +9,5 @@ export default styled(Tooltip)`
|
||||
background-color: var(--sn-stylekit-contrast-background-color);
|
||||
color: var(--sn-stylekit-foreground-color);
|
||||
border-color: var(--sn-stylekit-border-color);
|
||||
z-index: var(--z-index-tooltip);
|
||||
}
|
||||
`
|
||||
|
||||
@@ -188,6 +188,7 @@ export class ItemListController extends AbstractViewController implements Intern
|
||||
notes: observable,
|
||||
notesToDisplay: observable,
|
||||
panelTitle: observable,
|
||||
panelWidth: observable,
|
||||
renderedItems: observable,
|
||||
showDisplayOptionsMenu: observable,
|
||||
|
||||
@@ -453,17 +454,21 @@ export class ItemListController extends AbstractViewController implements Intern
|
||||
this.displayOptions = newDisplayOptions
|
||||
this.webDisplayOptions = newWebDisplayOptions
|
||||
|
||||
const newWidth = this.application.getPreference(PrefKey.NotesPanelWidth)
|
||||
if (newWidth && newWidth !== this.panelWidth) {
|
||||
this.panelWidth = newWidth
|
||||
}
|
||||
|
||||
if (!displayOptionsChanged) {
|
||||
return
|
||||
}
|
||||
|
||||
if (displayOptionsChanged) {
|
||||
this.reloadNotesDisplayOptions()
|
||||
}
|
||||
|
||||
await this.reloadItems(ItemsReloadSource.DisplayOptionsChange)
|
||||
|
||||
const width = this.application.getPreference(PrefKey.NotesPanelWidth)
|
||||
if (width) {
|
||||
this.panelWidth = width
|
||||
}
|
||||
|
||||
if (newDisplayOptions.sortBy !== currentSortBy) {
|
||||
await this.selectFirstItem()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user