IDE redesign, initial implementation #362

Merged
Irev-Dev merged 17 commits from kurt/update-ide-panel-toolbar-360 into main 2021-06-15 10:05:03 +02:00
5 changed files with 102 additions and 74 deletions
Showing only changes of commit c142860433 - Show all commits

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 = () => {
Irev-Dev commented 2021-06-14 02:29:31 +02:00 (Migrated from github.com)
Review

image

![image](https://user-images.githubusercontent.com/29681384/121826523-65b2b400-ccfb-11eb-8c97-3d9b03505ea8.png)
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
Irev-Dev commented 2021-06-14 02:32:54 +02:00 (Migrated from github.com)
Review

All of the logic in this hook I had in the IdeToolbarNew because that was the main wrapping component that had the context provider, so it made sense to have init useEffects there. However since most of the logic relates to checking if there is something encoded in the URL, I thought it made sense to bundle the logic here with the rest of the encoded url code, and bring it into IdeToolbarNew as a custom hook.

I've also now rename IdeToolbarNew to IdeWrapper

All of the logic in this hook I had in the `IdeToolbarNew` because that was the main wrapping component that had the context provider, so it made sense to have init useEffects there. However since most of the logic relates to checking if there is something encoded in the URL, I thought it made sense to bundle the logic here with the rest of the encoded url code, and bring it into `IdeToolbarNew` as a custom hook. I've also now rename `IdeToolbarNew` to `IdeWrapper`
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])
}

View File

@@ -1,7 +1,6 @@
import { Popover } from '@headlessui/react'
import { Tab, Tabs, TabList, TabPanel } from 'react-tabs';
import { copyTextToClipboard } from 'src/helpers/clipboard'
import { encode } from 'src/helpers/compress'
import FullScriptEncoding from 'src/components/EncodedUrl/FullScriptEncoding'
const TopButton = ({
onClick,
@@ -34,7 +33,6 @@ const IdeHeader = ({handleRender}: {handleRender: () => void}) => {
<Popover className="relative outline-none w-full h-full">
{({open}) => {
const encodedLink = makeEncodedLink('bing bong')
return (
<>
<Popover.Button className="h-full w-full outline-none">
@@ -46,12 +44,11 @@ const IdeHeader = ({handleRender}: {handleRender: () => void}) => {
selectedTabClassName="bg-gray-200"
>
<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>
<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>
<FullScriptEncoding />
</TabPanel>
<TabPanel>
<h2 className="h-32">Any content 2</h2>
<p>blah</p>
<input onPaste={(e) => console.log(e)} />
</TabPanel>
<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
const scriptKeyV2 = 'encoded_script_v2' // todo don't leave here
function makeEncodedLink(code: string): string {
const encodedScript = encode(code)
return `${location.href}#${scriptKeyV2}=${encodedScript}`
}

View File

@@ -1,68 +1,16 @@
import { useContext, useEffect, useState } from 'react'
import IdeContainer from 'src/components/IdeContainer'
import { IdeContext } from 'src/pages/DevIdePage/DevIdePage'
import { isBrowser } from '@redwoodjs/prerender/browserUtils'
import { useState } from 'react'
import IdeContainer from 'src/components/IdeContainer/IdeContainer'
import { useRender } from './useRender'
import { decode } from 'src/helpers/compress'
import { flow } from 'lodash/fp'
import OutBound from 'src/components/OutBound'
import IdeSideBar from 'src/components/IdeSideBar'
import IdeHeader from 'src/components/IdeHeader'
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)
import OutBound from 'src/components/OutBound/OutBound'
import IdeSideBar from 'src/components/IdeSideBar/IdeSideBar'
import IdeHeader from 'src/components/IdeHeader/IdeHeader'
import Svg from 'src/components/Svg/Svg'
import { useIdeInit } from 'src/components/EncodedUrl/helpers'
const IdeToolbarNew = ({ cadPackage }) => {
const { state, thunkDispatch } = useContext(IdeContext)
const [shouldShowConstructionMessage, setShouldShowConstructionMessage] = useState(true)
const handleRender = useRender()
const scriptKey = 'encoded_script'
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])
useIdeInit(cadPackage)
return (
<div className="h-full flex">

View File

@@ -0,0 +1,6 @@
import { IdeContext } from 'src/pages/DevIdePage/DevIdePage'
import { useContext } from 'react'
export function useIdeContext() {
return useContext(IdeContext)
}