feat: persist selected tag & note locally (#1851)
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { KeyboardKey } from '@standardnotes/ui-services'
|
||||
import { UuidString } from '@standardnotes/snjs'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { FunctionComponent, KeyboardEventHandler, UIEventHandler, useCallback } from 'react'
|
||||
import { FOCUSABLE_BUT_NOT_TABBABLE, NOTES_LIST_SCROLL_THRESHOLD } from '@/Constants/Constants'
|
||||
@@ -22,7 +21,7 @@ type Props = {
|
||||
navigationController: NavigationController
|
||||
notesController: NotesController
|
||||
selectionController: SelectedItemsController
|
||||
selectedItems: Record<UuidString, ListableContentItem>
|
||||
selectedUuids: SelectedItemsController['selectedUuids']
|
||||
paginate: () => void
|
||||
}
|
||||
|
||||
@@ -34,7 +33,7 @@ const ContentList: FunctionComponent<Props> = ({
|
||||
navigationController,
|
||||
notesController,
|
||||
selectionController,
|
||||
selectedItems,
|
||||
selectedUuids,
|
||||
paginate,
|
||||
}) => {
|
||||
const { selectPreviousItem, selectNextItem } = selectionController
|
||||
@@ -82,7 +81,7 @@ const ContentList: FunctionComponent<Props> = ({
|
||||
key={item.uuid}
|
||||
application={application}
|
||||
item={item}
|
||||
selected={!!selectedItems[item.uuid]}
|
||||
selected={selectedUuids.has(item.uuid)}
|
||||
hideDate={hideDate}
|
||||
hidePreview={hideNotePreview}
|
||||
hideTags={hideTags}
|
||||
|
||||
@@ -109,7 +109,7 @@ const ContentListView: FunctionComponent<Props> = ({
|
||||
searchBarElement,
|
||||
} = itemListController
|
||||
|
||||
const { selectedItems, selectNextItem, selectPreviousItem } = selectionController
|
||||
const { selectedUuids, selectNextItem, selectPreviousItem } = selectionController
|
||||
|
||||
const isFilesSmartView = useMemo(
|
||||
() => navigationController.selected?.uuid === SystemViewId.Files,
|
||||
@@ -276,7 +276,7 @@ const ContentListView: FunctionComponent<Props> = ({
|
||||
{renderedItems.length ? (
|
||||
<ContentList
|
||||
items={renderedItems}
|
||||
selectedItems={selectedItems}
|
||||
selectedUuids={selectedUuids}
|
||||
application={application}
|
||||
paginate={paginate}
|
||||
filesController={filesController}
|
||||
|
||||
@@ -5,7 +5,7 @@ import { SwitchProps } from '@/Components/Switch/SwitchProps'
|
||||
import { IconType } from '@standardnotes/snjs'
|
||||
import { FOCUSABLE_BUT_NOT_TABBABLE } from '@/Constants/Constants'
|
||||
import { MenuItemType } from './MenuItemType'
|
||||
import RadioIndicator from '../RadioIndicator/RadioIndicator'
|
||||
import RadioIndicator from '../Radio/RadioIndicator'
|
||||
|
||||
type MenuItemProps = {
|
||||
children: ReactNode
|
||||
|
||||
@@ -9,6 +9,7 @@ import LabsPane from './Labs/Labs'
|
||||
import Advanced from '@/Components/Preferences/Panes/General/Advanced/AdvancedSection'
|
||||
import PreferencesPane from '../../PreferencesComponents/PreferencesPane'
|
||||
import PlaintextDefaults from './PlaintextDefaults'
|
||||
import Persistence from './Persistence'
|
||||
|
||||
type Props = {
|
||||
viewControllerManager: ViewControllerManager
|
||||
@@ -18,6 +19,7 @@ type Props = {
|
||||
|
||||
const General: FunctionComponent<Props> = ({ viewControllerManager, application, extensionsLatestVersions }) => (
|
||||
<PreferencesPane>
|
||||
<Persistence application={application} />
|
||||
<PlaintextDefaults application={application} />
|
||||
<Defaults application={application} />
|
||||
<Tools application={application} />
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import StyledRadioInput from '@/Components/Radio/StyledRadioInput'
|
||||
import { useState } from 'react'
|
||||
import { Title } from '../../PreferencesComponents/Content'
|
||||
import PreferencesGroup from '../../PreferencesComponents/PreferencesGroup'
|
||||
import PreferencesSegment from '../../PreferencesComponents/PreferencesSegment'
|
||||
|
||||
type Props = {
|
||||
application: WebApplication
|
||||
}
|
||||
|
||||
export const ShouldPersistNoteStateKey = 'ShouldPersistNoteState'
|
||||
|
||||
const Persistence = ({ application }: Props) => {
|
||||
const [shouldPersistNoteState, setShouldPersistNoteState] = useState(application.getValue(ShouldPersistNoteStateKey))
|
||||
|
||||
const toggleStatePersistence = (shouldPersist: boolean) => {
|
||||
application.setValue(ShouldPersistNoteStateKey, shouldPersist)
|
||||
setShouldPersistNoteState(shouldPersist)
|
||||
}
|
||||
|
||||
return (
|
||||
<PreferencesGroup>
|
||||
<PreferencesSegment>
|
||||
<Title className="mb-2">When opening the app, show...</Title>
|
||||
<label className="mb-2 flex items-center gap-2 text-sm font-medium">
|
||||
<StyledRadioInput
|
||||
name="state-persistence"
|
||||
checked={!shouldPersistNoteState}
|
||||
onChange={(event) => {
|
||||
toggleStatePersistence(!event.target.checked)
|
||||
}}
|
||||
/>
|
||||
The first note in the list
|
||||
</label>
|
||||
<label className="flex items-center gap-2 text-sm font-medium">
|
||||
<StyledRadioInput
|
||||
name="state-persistence"
|
||||
checked={!!shouldPersistNoteState}
|
||||
onChange={(event) => {
|
||||
toggleStatePersistence(event.target.checked)
|
||||
}}
|
||||
/>
|
||||
The last viewed note
|
||||
</label>
|
||||
</PreferencesSegment>
|
||||
</PreferencesGroup>
|
||||
)
|
||||
}
|
||||
|
||||
export default Persistence
|
||||
@@ -16,7 +16,7 @@ import FocusModeSwitch from './FocusModeSwitch'
|
||||
import ThemesMenuButton from './ThemesMenuButton'
|
||||
import { ThemeItem } from './ThemeItem'
|
||||
import { sortThemes } from '@/Utils/SortThemes'
|
||||
import RadioIndicator from '../RadioIndicator/RadioIndicator'
|
||||
import RadioIndicator from '../Radio/RadioIndicator'
|
||||
import HorizontalSeparator from '../Shared/HorizontalSeparator'
|
||||
import { QuickSettingsController } from '@/Controllers/QuickSettingsController'
|
||||
import PanelSettingsSection from './PanelSettingsSection'
|
||||
|
||||
@@ -5,7 +5,7 @@ import Icon from '@/Components/Icon/Icon'
|
||||
import { usePremiumModal } from '@/Hooks/usePremiumModal'
|
||||
import Switch from '@/Components/Switch/Switch'
|
||||
import { ThemeItem } from './ThemeItem'
|
||||
import RadioIndicator from '../RadioIndicator/RadioIndicator'
|
||||
import RadioIndicator from '../Radio/RadioIndicator'
|
||||
import { PremiumFeatureIconClass, PremiumFeatureIconName } from '../Icon/PremiumFeatureIcon'
|
||||
import { isMobileScreen } from '@/Utils'
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import { classNames } from '@/Utils/ConcatenateClassNames'
|
||||
import { ComponentPropsWithoutRef } from 'react'
|
||||
import RadioIndicator from './RadioIndicator'
|
||||
|
||||
type Props = ComponentPropsWithoutRef<'input'>
|
||||
|
||||
const StyledRadioInput = (props: Props) => {
|
||||
return (
|
||||
<div className="flex">
|
||||
<input type="radio" className={classNames('h-0 w-0 opacity-0', props.className)} {...props} />
|
||||
<RadioIndicator checked={!!props.checked} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default StyledRadioInput
|
||||
@@ -1,6 +1,6 @@
|
||||
import { FOCUSABLE_BUT_NOT_TABBABLE } from '@/Constants/Constants'
|
||||
import { FunctionComponent, ReactNode } from 'react'
|
||||
import RadioIndicator from '../RadioIndicator/RadioIndicator'
|
||||
import RadioIndicator from '../Radio/RadioIndicator'
|
||||
|
||||
type HistoryListItemProps = {
|
||||
isSelected: boolean
|
||||
|
||||
@@ -63,7 +63,9 @@ const SmartViewsListItem: FunctionComponent<Props> = ({ view, tagsState }) => {
|
||||
}, [setTitle, view])
|
||||
|
||||
const selectCurrentTag = useCallback(async () => {
|
||||
await tagsState.setSelectedTag(view)
|
||||
await tagsState.setSelectedTag(view, {
|
||||
userTriggered: true,
|
||||
})
|
||||
toggleAppPane(AppPaneId.Items)
|
||||
}, [tagsState, toggleAppPane, view])
|
||||
|
||||
|
||||
@@ -88,7 +88,9 @@ export const TagsListItem: FunctionComponent<Props> = observer(
|
||||
)
|
||||
|
||||
const selectCurrentTag = useCallback(async () => {
|
||||
await tagsState.setSelectedTag(tag)
|
||||
await tagsState.setSelectedTag(tag, {
|
||||
userTriggered: true,
|
||||
})
|
||||
toggleAppPane(AppPaneId.Items)
|
||||
}, [tagsState, tag, toggleAppPane])
|
||||
|
||||
|
||||
Reference in New Issue
Block a user