Move encoded script logic together

This commit is contained in:
Kurt Hutten
2021-06-13 06:17:01 +10:00
parent e591eb8ff8
commit c142860433
5 changed files with 102 additions and 74 deletions

View File

@@ -0,0 +1,17 @@
import { makeEncodedLink } from './helpers'
import { copyTextToClipboard } from 'src/helpers/clipboard'
import {useIdeContext} from 'src/helpers/hooks/useIdeContext'
const FullScriptEncoding = () => {
const {state} = useIdeContext()
const encodedLink = makeEncodedLink(state.code)
return (
<>
<p className="text-sm pb-4 border-b border-gray-700">Encodes your CodeCad script into a URL so that you can share your work</p>
<input value={encodedLink.replace(/^.+:\/\//g, '')} readOnly className="p-1 mt-4 text-xs rounded-t border border-gray-700 w-full" />
<button className="w-full bg-gray-700 py-1 rounded-b text-gray-300" onClick={() => copyTextToClipboard(encodedLink)} >Copy URL</button>
</>
)
}
export default FullScriptEncoding

View File

@@ -0,0 +1,67 @@
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'
const scriptKey = 'encoded_script'
const scriptKeyV2 = 'encoded_script_v2'
const fetchText = 'fetch_text_v1'
export function makeEncodedLink(code: string): string {
const encodedScript = encode(code)
return `${location.origin}${location.pathname}#${scriptKeyV2}=${encodedScript}`
}
export const githubSafe = (url: string): string =>
url.includes('github.com')
? url
.replace('github.com', 'raw.githubusercontent.com')
.replace('/blob/', '/')
: url
const prepareEncodedUrl = flow(decodeURIComponent, githubSafe)
export function useIdeInit(cadPackage: string) {
const {thunkDispatch} = useIdeContext()
const handleRender = useRender()
useEffect(() => {
thunkDispatch({
type: 'initIde',
payload: { cadPackage },
})
// 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])
}