Move encoded script logic together
This commit is contained in:
17
app/web/src/components/EncodedUrl/FullScriptEncoding.tsx
Normal file
17
app/web/src/components/EncodedUrl/FullScriptEncoding.tsx
Normal 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
|
||||||
67
app/web/src/components/EncodedUrl/helpers.ts
Normal file
67
app/web/src/components/EncodedUrl/helpers.ts
Normal 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])
|
||||||
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
import { Popover } from '@headlessui/react'
|
import { Popover } from '@headlessui/react'
|
||||||
import { Tab, Tabs, TabList, TabPanel } from 'react-tabs';
|
import { Tab, Tabs, TabList, TabPanel } from 'react-tabs';
|
||||||
import { copyTextToClipboard } from 'src/helpers/clipboard'
|
import FullScriptEncoding from 'src/components/EncodedUrl/FullScriptEncoding'
|
||||||
import { encode } from 'src/helpers/compress'
|
|
||||||
|
|
||||||
const TopButton = ({
|
const TopButton = ({
|
||||||
onClick,
|
onClick,
|
||||||
@@ -34,7 +33,6 @@ const IdeHeader = ({handleRender}: {handleRender: () => void}) => {
|
|||||||
|
|
||||||
<Popover className="relative outline-none w-full h-full">
|
<Popover className="relative outline-none w-full h-full">
|
||||||
{({open}) => {
|
{({open}) => {
|
||||||
const encodedLink = makeEncodedLink('bing bong')
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Popover.Button className="h-full w-full outline-none">
|
<Popover.Button className="h-full w-full outline-none">
|
||||||
@@ -46,12 +44,11 @@ const IdeHeader = ({handleRender}: {handleRender: () => void}) => {
|
|||||||
selectedTabClassName="bg-gray-200"
|
selectedTabClassName="bg-gray-200"
|
||||||
>
|
>
|
||||||
<TabPanel className="p-4">
|
<TabPanel className="p-4">
|
||||||
<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>
|
<FullScriptEncoding />
|
||||||
<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>
|
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
<TabPanel>
|
<TabPanel>
|
||||||
<h2 className="h-32">Any content 2</h2>
|
<p>blah</p>
|
||||||
|
<input onPaste={(e) => console.log(e)} />
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
|
|
||||||
<TabList className="flex whitespace-nowrap text-gray-700 border-t border-gray-700">
|
<TabList className="flex whitespace-nowrap text-gray-700 border-t border-gray-700">
|
||||||
@@ -71,10 +68,3 @@ const IdeHeader = ({handleRender}: {handleRender: () => void}) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default IdeHeader
|
export default IdeHeader
|
||||||
|
|
||||||
const scriptKeyV2 = 'encoded_script_v2' // todo don't leave here
|
|
||||||
|
|
||||||
function makeEncodedLink(code: string): string {
|
|
||||||
const encodedScript = encode(code)
|
|
||||||
return `${location.href}#${scriptKeyV2}=${encodedScript}`
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,68 +1,16 @@
|
|||||||
import { useContext, useEffect, useState } from 'react'
|
import { useState } from 'react'
|
||||||
import IdeContainer from 'src/components/IdeContainer'
|
import IdeContainer from 'src/components/IdeContainer/IdeContainer'
|
||||||
import { IdeContext } from 'src/pages/DevIdePage/DevIdePage'
|
|
||||||
import { isBrowser } from '@redwoodjs/prerender/browserUtils'
|
|
||||||
import { useRender } from './useRender'
|
import { useRender } from './useRender'
|
||||||
import { decode } from 'src/helpers/compress'
|
import OutBound from 'src/components/OutBound/OutBound'
|
||||||
import { flow } from 'lodash/fp'
|
import IdeSideBar from 'src/components/IdeSideBar/IdeSideBar'
|
||||||
import OutBound from 'src/components/OutBound'
|
import IdeHeader from 'src/components/IdeHeader/IdeHeader'
|
||||||
import IdeSideBar from 'src/components/IdeSideBar'
|
import Svg from 'src/components/Svg/Svg'
|
||||||
import IdeHeader from 'src/components/IdeHeader'
|
import { useIdeInit } from 'src/components/EncodedUrl/helpers'
|
||||||
import Svg from 'src/components/Svg'
|
|
||||||
|
|
||||||
export const githubSafe = (url) =>
|
|
||||||
url.includes('github.com')
|
|
||||||
? url
|
|
||||||
.replace('github.com', 'raw.githubusercontent.com')
|
|
||||||
.replace('/blob/', '/')
|
|
||||||
: url
|
|
||||||
|
|
||||||
const prepareEncodedUrl = flow(decodeURIComponent, githubSafe)
|
|
||||||
|
|
||||||
const IdeToolbarNew = ({ cadPackage }) => {
|
const IdeToolbarNew = ({ cadPackage }) => {
|
||||||
const { state, thunkDispatch } = useContext(IdeContext)
|
|
||||||
const [shouldShowConstructionMessage, setShouldShowConstructionMessage] = useState(true)
|
const [shouldShowConstructionMessage, setShouldShowConstructionMessage] = useState(true)
|
||||||
const handleRender = useRender()
|
const handleRender = useRender()
|
||||||
const scriptKey = 'encoded_script'
|
useIdeInit(cadPackage)
|
||||||
const scriptKeyV2 = 'encoded_script_v2'
|
|
||||||
const fetchText = 'fetch_text_v1'
|
|
||||||
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])
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="h-full flex">
|
<div className="h-full flex">
|
||||||
|
|||||||
6
app/web/src/helpers/hooks/useIdeContext.ts
Normal file
6
app/web/src/helpers/hooks/useIdeContext.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import { IdeContext } from 'src/pages/DevIdePage/DevIdePage'
|
||||||
|
import { useContext } from 'react'
|
||||||
|
|
||||||
|
export function useIdeContext() {
|
||||||
|
return useContext(IdeContext)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user