From 01bc76e09a682678c0a32f5894bda774c0e014ca Mon Sep 17 00:00:00 2001 From: Kurt Hutten Date: Tue, 16 Mar 2021 20:26:58 +1100 Subject: [PATCH] Encode code into url to make sharing snippets easy resolves #253 --- web/src/components/IdeEditor/IdeEditor.js | 22 ++++++++++- .../components/IdeToolbarNew/IdeToolbarNew.js | 19 ++++++++-- web/src/helpers/clipboard.js | 37 +++++++++++++++++++ 3 files changed, 73 insertions(+), 5 deletions(-) create mode 100644 web/src/helpers/clipboard.js diff --git a/web/src/components/IdeEditor/IdeEditor.js b/web/src/components/IdeEditor/IdeEditor.js index eda29b4..4dd3fab 100644 --- a/web/src/components/IdeEditor/IdeEditor.js +++ b/web/src/components/IdeEditor/IdeEditor.js @@ -1,10 +1,30 @@ -import { useContext } from 'react' +import { useContext, useEffect } from 'react' +import { isBrowser } from '@redwoodjs/prerender/browserUtils' import { IdeContext } from 'src/components/IdeToolbarNew' import Editor from '@monaco-editor/react' const IdeEditor = () => { const { state, dispatch } = useContext(IdeContext) + const scriptKey = 'encoded_script' + useEffect(() => { + // load code from hash if it's there + let hash + if (isBrowser) { + hash = window.location.hash + } + const [key, scriptBase64] = hash.slice(1).split('=') + if (key === scriptKey) { + const script = atob(scriptBase64) + dispatch({ type: 'updateCode', payload: script }) + } + }, []) + useEffect(() => { + if (isBrowser) { + window.location.hash = '' + } + }, [state.code]) + function handleCodeChange(value, _event) { dispatch({ type: 'updateCode', payload: value }) } diff --git a/web/src/components/IdeToolbarNew/IdeToolbarNew.js b/web/src/components/IdeToolbarNew/IdeToolbarNew.js index fa0f7d6..70b9e8c 100644 --- a/web/src/components/IdeToolbarNew/IdeToolbarNew.js +++ b/web/src/components/IdeToolbarNew/IdeToolbarNew.js @@ -1,9 +1,10 @@ -import IdeContainer from 'src/components/IdeContainer' import { createContext } from 'react' +import IdeContainer from 'src/components/IdeContainer' +import { isBrowser } from '@redwoodjs/prerender/browserUtils' import { useIdeState } from 'src/helpers/hooks/useIdeState' +import { copyTextToClipboard } from 'src/helpers/clipboard' export const IdeContext = createContext() - const IdeToolbarNew = () => { const [state, dispatch] = useIdeState() function setIdeType(ide) { @@ -12,12 +13,19 @@ const IdeToolbarNew = () => { function handleRender() { dispatch({ type: 'render', payload: { code: state.code } }) } + function handleMakeLink() { + if (isBrowser) { + const scriptBase64 = btoa(state.code) + window.location.hash = `encoded_script=${scriptBase64}` + copyTextToClipboard(window.location.href) + } + } return (
diff --git a/web/src/helpers/clipboard.js b/web/src/helpers/clipboard.js new file mode 100644 index 0000000..c783230 --- /dev/null +++ b/web/src/helpers/clipboard.js @@ -0,0 +1,37 @@ +function fallbackCopyTextToClipboard(text) { + var textArea = document.createElement('textarea') + textArea.value = text + + // Avoid scrolling to bottom + textArea.style.top = '0' + textArea.style.left = '0' + textArea.style.position = 'fixed' + + document.body.appendChild(textArea) + textArea.focus() + textArea.select() + + try { + var successful = document.execCommand('copy') + var msg = successful ? 'successful' : 'unsuccessful' + console.log('Fallback: Copying text command was ' + msg) + } catch (err) { + console.error('Fallback: Oops, unable to copy', err) + } + + document.body.removeChild(textArea) +} +export function copyTextToClipboard(text) { + if (!navigator.clipboard) { + fallbackCopyTextToClipboard(text) + return + } + navigator.clipboard.writeText(text).then( + function () { + console.log('Async: Copying to clipboard was successful!') + }, + function (err) { + console.error('Async: Could not copy text: ', err) + } + ) +} -- 2.39.5