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 ChallengeModal from '@/Components/ChallengeModal/ChallengeModal'
|
||||||
import NotesContextMenu from '@/Components/NotesContextMenu/NotesContextMenu'
|
import NotesContextMenu from '@/Components/NotesContextMenu/NotesContextMenu'
|
||||||
import PurchaseFlowWrapper from '@/Components/PurchaseFlow/PurchaseFlowWrapper'
|
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 RevisionHistoryModal from '@/Components/RevisionHistoryModal/RevisionHistoryModal'
|
||||||
import PremiumModalProvider from '@/Hooks/usePremiumModal'
|
import PremiumModalProvider from '@/Hooks/usePremiumModal'
|
||||||
import ConfirmSignoutContainer from '@/Components/ConfirmSignoutModal/ConfirmSignoutModal'
|
import ConfirmSignoutContainer from '@/Components/ConfirmSignoutModal/ConfirmSignoutModal'
|
||||||
@@ -35,13 +35,14 @@ type Props = {
|
|||||||
|
|
||||||
const ApplicationView: FunctionComponent<Props> = ({ application, mainApplicationGroup }) => {
|
const ApplicationView: FunctionComponent<Props> = ({ application, mainApplicationGroup }) => {
|
||||||
const platformString = getPlatformString()
|
const platformString = getPlatformString()
|
||||||
const [appClass, setAppClass] = useState('')
|
|
||||||
const [launched, setLaunched] = useState(false)
|
const [launched, setLaunched] = useState(false)
|
||||||
const [needsUnlock, setNeedsUnlock] = useState(true)
|
const [needsUnlock, setNeedsUnlock] = useState(true)
|
||||||
const [challenges, setChallenges] = useState<Challenge[]>([])
|
const [challenges, setChallenges] = useState<Challenge[]>([])
|
||||||
|
|
||||||
const viewControllerManager = application.getViewControllerManager()
|
const viewControllerManager = application.getViewControllerManager()
|
||||||
|
|
||||||
|
const appColumnContainerRef = useRef<HTMLDivElement>(null)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const desktopService = application.getDesktopService()
|
const desktopService = application.getDesktopService()
|
||||||
|
|
||||||
@@ -125,15 +126,27 @@ const ApplicationView: FunctionComponent<Props> = ({ application, mainApplicatio
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const removeObserver = application.addWebEventObserver(async (eventName, data) => {
|
const removeObserver = application.addWebEventObserver(async (eventName, data) => {
|
||||||
if (eventName === WebAppEvent.PanelResized) {
|
if (eventName === WebAppEvent.PanelResized) {
|
||||||
|
if (!appColumnContainerRef.current) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const { panel, collapsed } = data as PanelResizedData
|
const { panel, collapsed } = data as PanelResizedData
|
||||||
let appClass = ''
|
|
||||||
if (panel === PANEL_NAME_NOTES && collapsed) {
|
if (panel === PANEL_NAME_NOTES) {
|
||||||
appClass += 'collapsed-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) {
|
} else if (eventName === WebAppEvent.WindowDidFocus) {
|
||||||
if (!(await application.isLocked())) {
|
if (!(await application.isLocked())) {
|
||||||
application.sync.sync().catch(console.error)
|
application.sync.sync().catch(console.error)
|
||||||
@@ -180,7 +193,7 @@ const ApplicationView: FunctionComponent<Props> = ({ application, mainApplicatio
|
|||||||
<ResponsivePaneProvider>
|
<ResponsivePaneProvider>
|
||||||
<PremiumModalProvider application={application} viewControllerManager={viewControllerManager}>
|
<PremiumModalProvider application={application} viewControllerManager={viewControllerManager}>
|
||||||
<div className={platformString + ' main-ui-view sn-component'}>
|
<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
|
<FileDragNDropProvider
|
||||||
application={application}
|
application={application}
|
||||||
featuresController={viewControllerManager.featuresController}
|
featuresController={viewControllerManager.featuresController}
|
||||||
|
|||||||
@@ -100,6 +100,7 @@ export const ICONS = {
|
|||||||
unarchive: icons.UnarchiveIcon,
|
unarchive: icons.UnarchiveIcon,
|
||||||
unpin: icons.UnpinIcon,
|
unpin: icons.UnpinIcon,
|
||||||
user: icons.UserIcon,
|
user: icons.UserIcon,
|
||||||
|
view: icons.ViewIcon,
|
||||||
warning: icons.WarningIcon,
|
warning: icons.WarningIcon,
|
||||||
window: icons.WindowIcon,
|
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 RadioIndicator from '../RadioIndicator/RadioIndicator'
|
||||||
import HorizontalSeparator from '../Shared/HorizontalSeparator'
|
import HorizontalSeparator from '../Shared/HorizontalSeparator'
|
||||||
import { QuickSettingsController } from '@/Controllers/QuickSettingsController'
|
import { QuickSettingsController } from '@/Controllers/QuickSettingsController'
|
||||||
|
import PanelSettingsSection from './PanelSettingsSection'
|
||||||
|
|
||||||
const focusModeAnimationDuration = 1255
|
const focusModeAnimationDuration = 1255
|
||||||
|
|
||||||
@@ -174,6 +175,7 @@ const QuickSettingsMenu: FunctionComponent<MenuProps> = ({ application, quickSet
|
|||||||
onClose={closeQuickSettingsMenu}
|
onClose={closeQuickSettingsMenu}
|
||||||
isEnabled={focusModeEnabled}
|
isEnabled={focusModeEnabled}
|
||||||
/>
|
/>
|
||||||
|
<PanelSettingsSection application={application} />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,5 @@ export default styled(Tooltip)`
|
|||||||
background-color: var(--sn-stylekit-contrast-background-color);
|
background-color: var(--sn-stylekit-contrast-background-color);
|
||||||
color: var(--sn-stylekit-foreground-color);
|
color: var(--sn-stylekit-foreground-color);
|
||||||
border-color: var(--sn-stylekit-border-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,
|
notes: observable,
|
||||||
notesToDisplay: observable,
|
notesToDisplay: observable,
|
||||||
panelTitle: observable,
|
panelTitle: observable,
|
||||||
|
panelWidth: observable,
|
||||||
renderedItems: observable,
|
renderedItems: observable,
|
||||||
showDisplayOptionsMenu: observable,
|
showDisplayOptionsMenu: observable,
|
||||||
|
|
||||||
@@ -453,17 +454,21 @@ export class ItemListController extends AbstractViewController implements Intern
|
|||||||
this.displayOptions = newDisplayOptions
|
this.displayOptions = newDisplayOptions
|
||||||
this.webDisplayOptions = newWebDisplayOptions
|
this.webDisplayOptions = newWebDisplayOptions
|
||||||
|
|
||||||
|
const newWidth = this.application.getPreference(PrefKey.NotesPanelWidth)
|
||||||
|
if (newWidth && newWidth !== this.panelWidth) {
|
||||||
|
this.panelWidth = newWidth
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!displayOptionsChanged) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if (displayOptionsChanged) {
|
if (displayOptionsChanged) {
|
||||||
this.reloadNotesDisplayOptions()
|
this.reloadNotesDisplayOptions()
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.reloadItems(ItemsReloadSource.DisplayOptionsChange)
|
await this.reloadItems(ItemsReloadSource.DisplayOptionsChange)
|
||||||
|
|
||||||
const width = this.application.getPreference(PrefKey.NotesPanelWidth)
|
|
||||||
if (width) {
|
|
||||||
this.panelWidth = width
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newDisplayOptions.sortBy !== currentSortBy) {
|
if (newDisplayOptions.sortBy !== currentSortBy) {
|
||||||
await this.selectFirstItem()
|
await this.selectFirstItem()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
--z-index-lock-screen: 10000;
|
--z-index-lock-screen: 10000;
|
||||||
--z-index-modal: 10000;
|
--z-index-modal: 10000;
|
||||||
--z-index-toast: 11000;
|
--z-index-toast: 11000;
|
||||||
--z-index-tooltip: 12000;
|
|
||||||
|
|
||||||
--sn-stylekit-base-font-size: 0.813rem;
|
--sn-stylekit-base-font-size: 0.813rem;
|
||||||
--sn-stylekit-simplified-chinese-font: 'Microsoft Yahei', '微软雅黑体';
|
--sn-stylekit-simplified-chinese-font: 'Microsoft Yahei', '微软雅黑体';
|
||||||
|
|||||||
Reference in New Issue
Block a user