C2DH / journal-of-digital-history

frontend app for our Digital Journal
GNU General Public License v3.0
20 stars 4 forks source link

Add loader for the guidelines between the different sub-item / first time need to reclick in order to have it #561

Closed eliselavy closed 1 year ago

eliselavy commented 1 year ago

The first time

There is a loader - but introduction is empty , need to click on other item of the menu (for example: preview article) and come back in order to have it:

Screenshot 2023-06-28 at 14 25 35

Some strange situation between the sub-item

Windows button and still Mac page

Screenshot 2023-06-28 at 14 11 54
danieleguido commented 1 year ago

@eliselavy I've noticed it as well, it looks like a weird cache problem

danieleguido commented 1 year ago

The error is due to a weird behaviour of the ArticleFlow component that gets the previous version of the articletree, the instance that contains the parsed notebook cells. The computation of articleTree for big notebook could freeze the UI. I tested if workers could relieve this, but it turns out that building a worker having both MarkdownIt and Cite (citation-js) is tricky, e.g; fo rinstance this error:

Screenshot 2023-07-03 at 12 46 08

for future references, I've created a worker file i,porting both Markdown and Cite parsers, but it doesn't owrk as workers only want non functional arguments:

import { markdownParser } from '../logic/parser'
import Cite from 'citation-js'
import { getArticleTreeFromIpynb } from '../logic/ipynb'

onmessage = ({ id, cells, metadata }) => {
  console.info('[worker]', '\n - id:', id, '\n - sample:', cells.length ? cells[0].source[0] : null)
  const startTime = new Date().getTime()
  const tree = getArticleTreeFromIpynb({ id, cells, metadata, markdownParser }, [Cite])
  postMessage({
    tree,
    time: new Date().getTime() - startTime,
  })
}

with this rollup configuration

const { nodeResolve } = require('@rollup/plugin-node-resolve')
const commonjs = require('@rollup/plugin-commonjs')
// @rollup/plugin-json
const json = require('@rollup/plugin-json')

module.exports = {
  input: 'src/workers/ipynb.js',
  output: {
    file: 'public/workers/ipynb.bundle.js',
    format: 'iife',
    sourcemap: true,
  },
  plugins: [nodeResolve(), json()],
}

then in package.json the yarn run bundle-worker would bundle the worker and its dep libraries in one big file, in public folder

"scripts": {
  "bundle-worker": "rollup -c src/workers/rollup.config.js"
}

To use a worker in react component, I had created a useIpynbNotebookParagraphs that would spawn the worker.

const W = new window.Worker('/workers/ipynb.bundle.js')
export const useIpynbNotebookParagraphs = ({ id, cells = [], metadata, enabled = false }) => {
  const worker = useState(W)
  const status = useState(StatusIdle)

  useEffect(() => {
    W.onerror = (err) => {
      console.error(err)
    }
    W.onmessage = (e) => {
      console.log(e.data)
    }
    return () => {
      W.terminate()
    }
  }, [])

  useEffect(() => {
    if (!enabled || !worker) {
      return
    }
    console.info(
      '[useIpynbNotebookParagraphs] postMessage... \n - id:',
      id,
      '\n - n. cells:',
      cells.length,
      enabled ? '\n - enabled' : '\n - disabled',
    )
    W.postMessage({ id, cells, metadata, markdownParser, Cite })
  }, [id])

  return { status, data: null }
}

Note that is an unfinished hook, to be continued...

eliselavy commented 1 year ago

In production v4.2.0 yesterday