diff --git a/src/components/controllers/repl-page.jsx b/src/components/controllers/repl-page.jsx index 6fc75d0c1..a482bef43 100644 --- a/src/components/controllers/repl-page.jsx +++ b/src/components/controllers/repl-page.jsx @@ -1,6 +1,6 @@ import { useLocation, useRoute } from 'preact-iso'; import { Repl } from './repl'; -import { useExample } from './repl/examples'; +import { fetchExample } from './repl/examples'; import { useContent, useResource } from '../../lib/use-resource'; import { useTitle, useDescription } from './utils'; import { useLanguage } from '../../lib/i18n'; @@ -15,7 +15,7 @@ export default function ReplPage() { useTitle(meta.title); useDescription(meta.description); - const [code] = initialCode(query); + const code = useResource(() => getInitialCode(query), [query]); return (
@@ -38,35 +38,31 @@ export default function ReplPage() { * * ?code -> ?example -> localStorage -> simple counter example */ -function initialCode(query) { +async function getInitialCode(query) { const { route } = useLocation(); - let code, slug; + let code; if (query.code) { - try { - code = useResource(() => querySafetyCheck(atob(query.code)), [query.code]); - } catch (e) {} + code = querySafetyCheck(atob(query.code)); } else if (query.example) { - code = useExample([query.example]); - if (code) { - slug = query.example; - route(`/repl?example=${encodeURIComponent(slug)}`, true); + code = await fetchExample(query.example); + if (!code) { + route('/repl', true); } - else route('/repl', true); } if (!code) { if (typeof window !== 'undefined' && localStorage.getItem('preact-www-repl-code')) { code = localStorage.getItem('preact-www-repl-code'); } else { - slug = 'counter'; + const slug = 'counter'; if (typeof window !== 'undefined') { route(`/repl?example=${encodeURIComponent(slug)}`, true); } - code = useExample([slug]); + code = await fetchExample(slug); } } - return [code, slug]; + return code; } async function querySafetyCheck(code) { diff --git a/src/components/controllers/repl/examples.js b/src/components/controllers/repl/examples.js index 26a5f0512..baf23b95d 100644 --- a/src/components/controllers/repl/examples.js +++ b/src/components/controllers/repl/examples.js @@ -1,5 +1,3 @@ -import { useResource } from '../../../lib/use-resource'; - import simpleCounterExample from './examples/simple-counter.txt?url'; import counterWithHtmExample from './examples/counter-with-htm.txt?url'; import todoExample from './examples/todo-list.txt?url'; @@ -68,16 +66,8 @@ export function getExample(slug, list = EXAMPLES) { } } -/** - * @param {[ slug: string ]} args - * @returns {string | undefined} - */ -export function useExample([slug]) { +export async function fetchExample(slug) { const example = getExample(slug); if (!example) return; - return useResource(() => loadExample(example.url), ['example', slug]); -} - -export async function loadExample(exampleUrl) { - return await fetch(exampleUrl).then(r => r.text()); + return await fetch(example.url).then(r => r.text()); } diff --git a/src/components/controllers/repl/index.jsx b/src/components/controllers/repl/index.jsx index a5e6d8a89..36baa683d 100644 --- a/src/components/controllers/repl/index.jsx +++ b/src/components/controllers/repl/index.jsx @@ -1,8 +1,8 @@ -import { useState } from 'preact/hooks'; +import { useState, useCallback } from 'preact/hooks'; import { useLocation, useRoute } from 'preact-iso'; import { Splitter } from '../../splitter'; import { ErrorOverlay } from './error-overlay'; -import { EXAMPLES, getExample, loadExample } from './examples'; +import { EXAMPLES, fetchExample } from './examples'; import { useStoredValue } from '../../../lib/localstorage'; import { useResource } from '../../../lib/use-resource'; import { parseStackTrace } from './errors'; @@ -33,14 +33,14 @@ export function Repl({ code }) { ]).then(([CodeEditor, Runner]) => ({ CodeEditor: CodeEditor.default, Runner: Runner.default })), ['repl']); const applyExample = (slug) => { - loadExample(getExample(slug).url) + fetchExample(slug) .then(code => { setEditorCode(code); route(`/repl?example=${encodeURIComponent(slug)}`, true); }); }; - const onEditorInput = (value) => { + const onEditorInput = useCallback((value) => { setEditorCode(value); // Clears the example & code query params when a user @@ -48,7 +48,7 @@ export function Repl({ code }) { if (query.example || query.code) { route('/repl', true); } - }; + }, [query]); const share = () => { // No reason to share semi-sketchy btoa'd code if there's