* Only send customizer params when it's open * Add customizer reset button and have two modes of customizer vs not depending of if the customizer is open. * Remove re-render on customizer open/close in project profile
84 lines
2.5 KiB
TypeScript
84 lines
2.5 KiB
TypeScript
import { useEffect } from 'react'
|
|
import { flow } from 'lodash/fp'
|
|
|
|
import { useIdeContext } from 'src/helpers/hooks/useIdeContext'
|
|
import { useRender } from 'src/components/IdeWrapper/useRender'
|
|
import { encode, decode } from 'src/helpers/compress'
|
|
import { isBrowser } from '@redwoodjs/prerender/browserUtils'
|
|
import type { State } from 'src/helpers/hooks/useIdeState'
|
|
|
|
const scriptKey = 'encoded_script'
|
|
const scriptKeyV2 = 'encoded_script_v2'
|
|
const fetchText = 'fetch_text_v1'
|
|
|
|
export const githubSafe = (url: string): string =>
|
|
url.includes('github.com')
|
|
? url
|
|
.replace('github.com', 'raw.githubusercontent.com')
|
|
.replace('/blob/', '/')
|
|
: url
|
|
|
|
export const prepareEncodedUrl = flow(decodeURIComponent, githubSafe)
|
|
|
|
const prepareDecodedUrl = flow(githubSafe, encodeURIComponent)
|
|
|
|
export function makeEncodedLink(code: string): string {
|
|
const encodedScript = encode(code)
|
|
return `${location.origin}${location.pathname}#${scriptKeyV2}=${encodedScript}`
|
|
}
|
|
|
|
export function makeExternalUrl(resourceUrl: string): string {
|
|
return `${location.origin}${
|
|
location.pathname
|
|
}#${fetchText}=${prepareDecodedUrl(resourceUrl)}`
|
|
}
|
|
|
|
export function useIdeInit(
|
|
cadPackage: State['ideType'],
|
|
code = '',
|
|
viewerContext: State['viewerContext'] = 'ide'
|
|
) {
|
|
const { thunkDispatch } = useIdeContext()
|
|
const handleRender = useRender()
|
|
useEffect(() => {
|
|
thunkDispatch({
|
|
type: 'initIde',
|
|
payload: { cadPackage, code, viewerContext },
|
|
})
|
|
if (code) {
|
|
return
|
|
}
|
|
// load code from hash if it's there
|
|
const triggerRender = () =>
|
|
setTimeout(() => {
|
|
// definitely a little hacky, timeout with no delay is just to push it into the next event loop.
|
|
handleRender()
|
|
})
|
|
let hash
|
|
if (isBrowser) {
|
|
hash = window.location.hash
|
|
}
|
|
const [key, encodedScript] = hash.slice(1).split('=')
|
|
if (key === scriptKey) {
|
|
const script = atob(encodedScript)
|
|
thunkDispatch({ type: 'updateCode', payload: script })
|
|
triggerRender()
|
|
} else if (key === scriptKeyV2) {
|
|
const script = decode(encodedScript)
|
|
thunkDispatch({ type: 'updateCode', payload: script })
|
|
triggerRender()
|
|
} else if (key === fetchText) {
|
|
const url = prepareEncodedUrl(encodedScript)
|
|
fetch(url).then((response) =>
|
|
response.text().then((script) => {
|
|
thunkDispatch({ type: 'updateCode', payload: script })
|
|
triggerRender()
|
|
})
|
|
)
|
|
} else {
|
|
triggerRender()
|
|
}
|
|
window.location.hash = ''
|
|
}, [cadPackage])
|
|
}
|