-
-
Notifications
You must be signed in to change notification settings - Fork 392
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: persist selected tag & note locally (#1851)
- Loading branch information
1 parent
6c47f95
commit 4432f1c
Showing
20 changed files
with
421 additions
and
116 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
51 changes: 51 additions & 0 deletions
51
packages/web/src/javascripts/Components/Preferences/Panes/General/Persistence.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
16 changes: 16 additions & 0 deletions
16
packages/web/src/javascripts/Components/Radio/StyledRadioInput.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
2 changes: 1 addition & 1 deletion
2
packages/web/src/javascripts/Components/RevisionHistoryModal/HistoryListItem.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
4 changes: 4 additions & 0 deletions
4
packages/web/src/javascripts/Controllers/Abstract/Persistable.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export interface Persistable<T> { | ||
getPersistableValue(): T | ||
hydrateFromPersistedValue(value: T | undefined): void | ||
} |
60 changes: 60 additions & 0 deletions
60
packages/web/src/javascripts/Controllers/Abstract/PersistenceService.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import { WebApplication } from '@/Application/Application' | ||
import { ShouldPersistNoteStateKey } from '@/Components/Preferences/Panes/General/Persistence' | ||
import { ApplicationEvent, InternalEventBus } from '@standardnotes/snjs' | ||
import { CrossControllerEvent } from '../CrossControllerEvent' | ||
|
||
const MasterPersistenceKey = 'master-persistence-key' | ||
|
||
export enum PersistenceKey { | ||
SelectedItemsController = 'selected-items-controller', | ||
NavigationController = 'navigation-controller', | ||
ItemListController = 'item-list-controller', | ||
} | ||
|
||
export type MasterPersistedValue = Record<PersistenceKey, unknown> | ||
|
||
export class PersistenceService { | ||
private unsubAppEventObserver: () => void | ||
|
||
constructor(private application: WebApplication, private eventBus: InternalEventBus) { | ||
this.unsubAppEventObserver = this.application.addEventObserver(async (eventName) => { | ||
if (!this.application) { | ||
return | ||
} | ||
|
||
void this.onAppEvent(eventName) | ||
}) | ||
} | ||
|
||
async onAppEvent(eventName: ApplicationEvent) { | ||
if (eventName === ApplicationEvent.LocalDataLoaded) { | ||
let shouldHydrateState = this.application.getValue(ShouldPersistNoteStateKey) | ||
|
||
if (typeof shouldHydrateState === 'undefined') { | ||
this.application.setValue(ShouldPersistNoteStateKey, true) | ||
shouldHydrateState = true | ||
} | ||
|
||
this.eventBus.publish({ | ||
type: CrossControllerEvent.HydrateFromPersistedValues, | ||
payload: shouldHydrateState ? this.getPersistedValues() : undefined, | ||
}) | ||
} | ||
} | ||
|
||
persistValues(values: MasterPersistedValue): void { | ||
if (!this.application.isDatabaseLoaded()) { | ||
return | ||
} | ||
|
||
this.application.setValue(MasterPersistenceKey, values) | ||
} | ||
|
||
getPersistedValues(): MasterPersistedValue { | ||
return this.application.getValue(MasterPersistenceKey) as MasterPersistedValue | ||
} | ||
|
||
deinit() { | ||
this.unsubAppEventObserver() | ||
} | ||
} |
2 changes: 2 additions & 0 deletions
2
packages/web/src/javascripts/Controllers/CrossControllerEvent.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,6 @@ | ||
export enum CrossControllerEvent { | ||
TagChanged = 'TagChanged', | ||
ActiveEditorChanged = 'ActiveEditorChanged', | ||
HydrateFromPersistedValues = 'HydrateFromPersistedValues', | ||
RequestValuePersistence = 'RequestValuePersistence', | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.