Skip to content

Commit 449a37a

Browse files
authored
chore: fix Super read only state (#2992)
1 parent 7f3d2d0 commit 449a37a

2 files changed

Lines changed: 33 additions & 10 deletions

File tree

packages/web/src/javascripts/Components/SuperEditor/Plugins/ReadonlyPlugin/ReadonlyPlugin.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,26 @@ import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext
33
import { SNNote, ContentType } from '@standardnotes/snjs'
44
import { useState, useEffect } from 'react'
55

6-
const ReadonlyPlugin = ({ note }: { note: SNNote }) => {
6+
const ReadonlyPlugin = ({ note, forceReadonly = false }: { note: SNNote; forceReadonly?: boolean }) => {
77
const application = useApplication()
88
const [editor] = useLexicalComposerContext()
9-
const [readOnly, setReadOnly] = useState(note.locked)
9+
const [noteLocked, setNoteLocked] = useState(note.locked)
1010

1111
useEffect(() => {
1212
return application.items.streamItems<SNNote>(ContentType.TYPES.Note, ({ changed }) => {
1313
const changedNoteItem = changed.find((changedItem) => changedItem.uuid === note.uuid)
1414

1515
if (changedNoteItem) {
16-
setReadOnly(changedNoteItem.locked)
16+
setNoteLocked(changedNoteItem.locked)
1717
}
1818
})
1919
}, [application, note.uuid])
2020

2121
useEffect(() => {
2222
editor.update(() => {
23-
editor.setEditable(!readOnly)
23+
editor.setEditable(!(noteLocked || forceReadonly))
2424
})
25-
}, [editor, readOnly])
25+
}, [editor, noteLocked, forceReadonly])
2626

2727
return null
2828
}

packages/web/src/javascripts/Components/SuperEditor/SuperEditor.tsx

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { WebApplication } from '@/Application/WebApplication'
22
import {
3+
ApplicationEvent,
34
isPayloadSourceRetrieved,
45
NativeFeatureIdentifier,
56
FeatureStatus,
@@ -71,7 +72,7 @@ export const SuperEditor: FunctionComponent<Props> = ({
7172
const getMarkdownPlugin = useRef<GetMarkdownPluginInterface | null>(null)
7273
const [featureStatus, setFeatureStatus] = useState<FeatureStatus>(FeatureStatus.Entitled)
7374

74-
useEffect(() => {
75+
const reloadFeatureStatus = useCallback(() => {
7576
setFeatureStatus(
7677
application.features.getFeatureStatus(
7778
NativeFeatureIdentifier.create(NativeFeatureIdentifier.TYPES.SuperEditor).getValue(),
@@ -82,7 +83,24 @@ export const SuperEditor: FunctionComponent<Props> = ({
8283
)
8384
}, [application.features])
8485

86+
useEffect(() => {
87+
reloadFeatureStatus()
88+
}, [reloadFeatureStatus])
89+
90+
useEffect(() => {
91+
return application.addEventObserver(async (event) => {
92+
switch (event) {
93+
case ApplicationEvent.FeaturesAvailabilityChanged:
94+
case ApplicationEvent.UserRolesChanged:
95+
case ApplicationEvent.LocalDataLoaded:
96+
reloadFeatureStatus()
97+
break
98+
}
99+
})
100+
}, [application, reloadFeatureStatus])
101+
85102
const keyboardService = application.keyboardService
103+
const isEditorReadonly = note.current.locked || Boolean(readonly) || featureStatus !== FeatureStatus.Entitled
86104

87105
useEffect(() => {
88106
return application.commands.addWithShortcut(
@@ -155,6 +173,9 @@ export const SuperEditor: FunctionComponent<Props> = ({
155173
ignoreNextChange.current = false
156174
return
157175
}
176+
if (isEditorReadonly) {
177+
return
178+
}
158179

159180
void controller.saveAndAwaitLocalPropagation({
160181
text: value,
@@ -165,7 +186,7 @@ export const SuperEditor: FunctionComponent<Props> = ({
165186
},
166187
})
167188
},
168-
[controller],
189+
[controller, isEditorReadonly],
169190
)
170191

171192
const handleBubbleRemove = useCallback(
@@ -252,13 +273,13 @@ export const SuperEditor: FunctionComponent<Props> = ({
252273
<ErrorBoundary>
253274
<LinkingControllerProvider controller={linkingController}>
254275
<FilesControllerProvider controller={filesController}>
255-
<BlocksEditorComposer readonly={note.current.locked || readonly} initialValue={note.current.text}>
276+
<BlocksEditorComposer readonly={isEditorReadonly} initialValue={note.current.text}>
256277
<BlocksEditor
257278
onChange={handleChange}
258279
className="blocks-editor h-full resize-none"
259280
previewLength={SuperNotePreviewCharLimit}
260281
spellcheck={spellcheck}
261-
readonly={note.current.locked || readonly}
282+
readonly={isEditorReadonly}
262283
onFocus={handleFocus}
263284
onBlur={onBlur}
264285
>
@@ -271,7 +292,9 @@ export const SuperEditor: FunctionComponent<Props> = ({
271292
/>
272293
<NodeObserverPlugin nodeType={BubbleNode} onRemove={handleBubbleRemove} />
273294
<NodeObserverPlugin nodeType={FileNode} onRemove={handleBubbleRemove} />
274-
{readonly === undefined && <ReadonlyPlugin note={note.current} />}
295+
{readonly === undefined && (
296+
<ReadonlyPlugin note={note.current} forceReadonly={featureStatus !== FeatureStatus.Entitled} />
297+
)}
275298
<AutoFocusPlugin isEnabled={controller.isTemplateNote} />
276299
<BlockPickerMenuPlugin />
277300
<NoteFromSelectionPlugin currentNote={note.current} />

0 commit comments

Comments
 (0)