From 9588ffc81e5831b51c0d630e923773c5644f6e0c Mon Sep 17 00:00:00 2001 From: Tom Moor Date: Thu, 17 Feb 2022 22:36:46 -0800 Subject: [PATCH] fix: Timestamp under doc title should toggle history sidebar, closes #3120 --- app/components/Editor.tsx | 2 +- app/scenes/Document/components/Document.tsx | 2 +- app/scenes/Document/components/Editor.tsx | 233 ++++++++++---------- app/utils/routeHelpers.ts | 2 + 4 files changed, 121 insertions(+), 118 deletions(-) diff --git a/app/components/Editor.tsx b/app/components/Editor.tsx index a1e3f00cb..22406cf6b 100644 --- a/app/components/Editor.tsx +++ b/app/components/Editor.tsx @@ -103,4 +103,4 @@ function Editor(props: Props, ref: React.Ref) { ); } -export default React.forwardRef(Editor); +export default React.forwardRef(Editor); diff --git a/app/scenes/Document/components/Document.tsx b/app/scenes/Document/components/Document.tsx index f8a832376..690fb737c 100644 --- a/app/scenes/Document/components/Document.tsx +++ b/app/scenes/Document/components/Document.tsx @@ -591,7 +591,7 @@ class DocumentScene extends React.Component { void; - title: string; - id: string; - document: Document; - isDraft: boolean; - multiplayer?: boolean; - onSave: (arg0: { - done?: boolean; - autosave?: boolean; - publish?: boolean; - }) => any; - innerRef: { - current: any; - }; - children: React.ReactNode; - }; +type Props = EditorProps & { + onChangeTitle: (text: string) => void; + title: string; + id: string; + document: Document; + isDraft: boolean; + multiplayer?: boolean; + onSave: (options: { + done?: boolean; + autosave?: boolean; + publish?: boolean; + }) => void; + children: React.ReactNode; +}; -@observer -class DocumentEditor extends React.Component { - @observable - activeLinkEvent: MouseEvent | null | undefined; +/** + * The main document editor includes an editable title with metadata below it, + * and support for hover previews of internal links. + */ +function DocumentEditor(props: Props, ref: React.RefObject) { + const [ + activeLinkEvent, + setActiveLinkEvent, + ] = React.useState(null); + const titleRef = React.useRef(null); + const { t } = useTranslation(); + const match = useRouteMatch(); - ref = React.createRef(); - titleRef = React.createRef(); - - focusAtStart = () => { - if (this.props.innerRef.current) { - this.props.innerRef.current.focusAtStart(); + const focusAtStart = React.useCallback(() => { + if (ref.current) { + ref.current.focusAtStart(); } - }; + }, [ref]); - focusAtEnd = () => { - if (this.props.innerRef.current) { - this.props.innerRef.current.focusAtEnd(); + const focusAtEnd = React.useCallback(() => { + if (ref.current) { + ref.current.focusAtEnd(); } - }; + }, [ref]); - insertParagraph = () => { - if (this.props.innerRef.current) { - const { view } = this.props.innerRef.current; - const { dispatch, state } = view; - dispatch(state.tr.insert(0, state.schema.nodes.paragraph.create())); - } - }; - - handleLinkActive = (event: MouseEvent) => { - this.activeLinkEvent = event; + const handleLinkActive = React.useCallback((event: MouseEvent) => { + setActiveLinkEvent(event); return false; - }; + }, []); - handleLinkInactive = () => { - this.activeLinkEvent = null; - }; + const handleLinkInactive = React.useCallback(() => { + setActiveLinkEvent(null); + }, []); - handleGoToNextInput = (insertParagraph: boolean) => { - if (insertParagraph) { - this.insertParagraph(); - } + const handleGoToNextInput = React.useCallback( + (insertParagraph: boolean) => { + if (insertParagraph && ref.current) { + const { view } = ref.current; + const { dispatch, state } = view; + dispatch(state.tr.insert(0, state.schema.nodes.paragraph.create())); + } - this.focusAtStart(); - }; + focusAtStart(); + }, + [focusAtStart, ref] + ); - render() { - const { - document, - title, - onChangeTitle, - isDraft, - shareId, - readOnly, - innerRef, - children, - multiplayer, - t, - ...rest - } = this.props; - const EditorComponent = multiplayer ? MultiplayerEditor : Editor; + const { + document, + title, + onChangeTitle, + isDraft, + shareId, + readOnly, + children, + multiplayer, + ...rest + } = props; + const EditorComponent = multiplayer ? MultiplayerEditor : Editor; - return ( - - + + {!shareId && ( + - {!shareId && ( - - )} - + {!readOnly && } + {activeLinkEvent && !shareId && ( + - {!readOnly && } - {this.activeLinkEvent && !shareId && ( - - )} - {children} - - ); - } + )} + {children} + + ); } -export default withTranslation()(DocumentEditor); +export default observer(React.forwardRef(DocumentEditor)); diff --git a/app/utils/routeHelpers.ts b/app/utils/routeHelpers.ts index 3fc34c2d7..c19c6dcaa 100644 --- a/app/utils/routeHelpers.ts +++ b/app/utils/routeHelpers.ts @@ -117,3 +117,5 @@ export const matchDocumentSlug = ":documentSlug([0-9a-zA-Z-_~]*-[a-zA-z0-9]{10,15})"; export const matchDocumentEdit = `/doc/${matchDocumentSlug}/edit`; + +export const matchDocumentHistory = `/doc/${matchDocumentSlug}/history/:revisionId?`;