• Operand
  • license? go ahead.

gram:page

> ./src/App.tsx

Lenses
(coming soon!)


import "./App.css"
import { AutomergeUrl } from "@automerge/automerge-repo"
import { useHandle } from "@automerge/automerge-repo-react-hooks"
import { useEffect, useRef, useState } from "react"
import {EditorState} from "prosemirror-state"
import {exampleSetup} from "prosemirror-example-setup"
import { init } from "@automerge/prosemirror"
import "prosemirror-example-setup/style/style.css"
import "prosemirror-menu/style/menu.css"
import "prosemirror-view/style/prosemirror.css"
import Spine from "./spine"

function App({ docUrl }: { docUrl: AutomergeUrl }) {
  const handle = useHandle<{ page: string }>(docUrl)
  const spine = useRef<HTMLDivElement>(null)
  const [loaded, setLoaded] = useState(handle && handle.docSync() != null)
  const [page, setPage] = useState<EditorState | null>(null)

  useEffect(() => {
    handle && handle.whenReady().then(() => {
      if(handle.docSync() != null) setLoaded(true) })
  }, [handle])

  useEffect(() => {
    if (loaded) {
      const { pmDoc: doc, schema, plugin } = init(handle!, ["page"])
      const plugins = exampleSetup({schema}).concat(plugin)
      setPage(EditorState.create({ schema, plugins, doc }))
    }
    return  (e) => { if (page!) { setPage(null); } }
  }, [loaded])

  if (import.meta.hot) import.meta.hot.dispose(() => { if (page!) setPage(null) })
  return page && <Spine page={page} />
}

export default App