1
0
Fork 0
freesewing/packages/react/components/Editor/hooks/useEditorState.mjs
Joost De Cock 51dc1d9732
[breaking]: FreeSewing v4 (#7297)
Refer to the CHANGELOG for all info.

---------

Co-authored-by: Wouter van Wageningen <wouter.vdub@yahoo.com>
Co-authored-by: Josh Munic <jpmunic@gmail.com>
Co-authored-by: Jonathan Haas <haasjona@gmail.com>
2025-04-01 16:15:20 +02:00

86 lines
2 KiB
JavaScript

// Dependenicies
import { atomWithHash } from 'jotai-location'
import { stateUpdateFactory } from '../lib/index.mjs'
// Hooks
import { useAtom } from 'jotai'
import { useMemo, useEffect } from 'react'
/*
* Set up the atom
*/
const urlAtom = atomWithHash('s', {})
/**
* Url state backend
*
* This holds the editor state, using session storage.
* It also provides helper methods to manipulate state.
*
* @params {object} init - Initial pattern settings
* @params {function} setEphemeralState - Method to set the ephemeral state
* @params {object] config - The editor config
* @return {array} return - And array with get, set, and update methods
*/
export const useEditorState = (init = {}, setEphemeralState, config) => {
const [state, setState] = useAtom(urlAtom)
const update = useMemo(() => stateUpdateFactory(setState, setEphemeralState, config), [setState])
/*
* Set the initial state
*/
useEffect(() => {
// Handle state on a hard reload or cold start
if (typeof URLSearchParams !== 'undefined') {
try {
const data = getHashData()
if (typeof data.s === 'object') setState(data.s)
else setState(init)
} catch (err) {
setState(init)
}
}
}, [])
return [state, setState, update]
}
/*
* Our URL state library does not support storing Javascript objects out of the box.
* But it allows us to pass a customer parser to handle them, so this is that parser
*/
const pojoParser = {
parse: (v) => {
let val
try {
val = JSON.parse(v)
} catch (err) {
val = null
}
return val
},
serialize: (v) => {
let val
try {
val = JSON.stringify(v)
} catch (err) {
val = null
}
return val
},
}
function getHashData() {
if (!window) return false
const hash = window.location.hash
.slice(1)
.split('&')
.map((chunk) => chunk.split('='))
const data = {}
for (const [key, val] of hash) {
data[key] = JSON.parse(decodeURIComponent(decodeURI(val)))
}
return data
}