Skip to content

Commit

Permalink
Gist support
Browse files Browse the repository at this point in the history
  • Loading branch information
skryukov committed Feb 6, 2024
1 parent ad47dc7 commit ee4f44c
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 14 deletions.
17 changes: 10 additions & 7 deletions public/404.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,17 @@
// Note: this 404.html file must be at least 512 bytes for it to work
// with Internet Explorer (it is currently > 512 bytes)

var l = window.location;
l.replace(
l.protocol + '//' + l.hostname + (l.port ? ':' + l.port : '') +
'/?gem=' +
encodeURIComponent(l.pathname.slice(1).split('/').join('/')) +
(l.search ? '&' + l.search.slice(1) : '') + l.hash
);
const l = window.location;
const host = l.protocol + "//" + l.hostname + (l.port ? ":" + l.port : "");
let search = (l.search ? l.search.slice(1) : "");
const paths = l.pathname.slice(1).split("/");
if (paths[0] === "gist") {
search = "gist=" + paths[1] + (search ? "&" + search : "");
} else if (paths[0]) {
search = "gem=" + paths[0] + (search ? "&" + search : "");
}

l.replace(host + "/?" + search + l.hash);
</script>
</head>
<body>
Expand Down
40 changes: 34 additions & 6 deletions src/components/Editor/Editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ import { CreateHandler, DeleteHandler, RenameHandler, Tree, TreeApi, NodeApi } f
import { VscNewFile, VscNewFolder } from "react-icons/vsc";
import { nanoid } from "nanoid";

import importFromGist from "../../gist.ts";
import { runWASI } from "../../engines/wasi";
import { decode, encode, gemFromURI, workDir } from "../../engines/wasi/editorFS.ts";
import { decode, encode, gemFromURI, gistFromURI, workDir } from "../../engines/wasi/editorFS.ts";

import Node from "../Node/Node";
import cs from "../App/styles.module.css";
Expand Down Expand Up @@ -200,13 +201,40 @@ export const Editor = () => {
const canRunCode = useMemo(() => !loading && currentFilePath?.endsWith(".rb"), [currentFilePath, loading]);
const canRunBundleInstall = useMemo(() => !loading && treeData.find((entry) => entry.name === "Gemfile"), [loading, treeData]);

useEffect(() => {
const gist = gistFromURI();
if (gist) {
importFromGist(gist).then(({ files }) => {
files.forEach(({ filename, content }) => {
const parts = filename.split("/");
const name = parts.pop() as string;
let dir = workDir.dir;
parts.forEach((part) => {
if (!dir.contents[part]) {
dir.contents[part] = new Directory({});
}
dir = dir.contents[part] as Directory;
});
workDir.dir.contents[name] = new File(encode(content));
});

setTreeData(sortChildren(workDir.dir));
setTimeout(() => activateFirstFile(), 20);
});
}
}, []);

function activateFirstFile() {
const tree = treeRef.current;
if (tree) {
const node = tree.visibleNodes.find((n) => n.data.name?.endsWith(".rb"));
node ? node.activate() : tree?.firstNode?.activate();
}
}

useEffect(() => {
if (initializing) {
const tree = treeRef.current;
if (tree) {
const node = tree.visibleNodes.find((n) => n.data.name?.endsWith(".rb"));
node ? node.activate() : tree?.firstNode?.activate();
}
activateFirstFile();
} else {
gemFromURI() && bundleInstall();
}
Expand Down
9 changes: 8 additions & 1 deletion src/engines/wasi/editorFS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ export const gemFromURI = () => {
return params.get("gem");
}

export const gistFromURI = () => {
const url = new URL(window.location.href);
const params = new URLSearchParams(url.search);
return params.get("gist");
}

const defaultGem = gemFromURI() || gem;

export const initialRubyCode = `# This is a Ruby WASI playground
Expand All @@ -36,7 +42,8 @@ export const decode = (() => {
return (buffer: Uint8Array) => decoder.decode(buffer);
})();

export const workDir = new PreopenDirectory("/", {
export const workDir = new PreopenDirectory("/", gistFromURI() ? {} : {
"Gemfile": new File(encode(initialGemfile)),
"main.rb": new File(encode(initialRubyCode)),
});

26 changes: 26 additions & 0 deletions src/gist.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const BASE_URL = "https://api.github.com/gists/";

export interface GistFile {
filename: string;
content: string;
}

export default async function importFromGist(gistUrl: string): Promise<{ files: GistFile[] }> {
const id = gistUrl.split("/").pop();

const url = `${BASE_URL}${id}`;

const response = await fetch(url);

if (!response.ok) {
throw new Error(`Gist ${id} not found`);
}

const data = await response.json();

if (!data.files) {
throw new Error(`Gist has no files`);
}

return { files: Object.values(data.files) };
}

0 comments on commit ee4f44c

Please sign in to comment.