Compare commits
4 Commits
feat/tempo
...
feat/templ
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
027b2c8ed4 | ||
|
|
b4ca360661 | ||
|
|
ad947be0bc | ||
|
|
f739d4da34 |
@@ -11,6 +11,7 @@ import Container from "./Container";
|
|||||||
import dark from "../theme/editor/amy.json";
|
import dark from "../theme/editor/amy.json";
|
||||||
import light from "../theme/editor/xcode_default.json";
|
import light from "../theme/editor/xcode_default.json";
|
||||||
import { saveFile } from "../state/actions";
|
import { saveFile } from "../state/actions";
|
||||||
|
import { apiHeaderFiles } from "../state/constants";
|
||||||
import state from "../state";
|
import state from "../state";
|
||||||
|
|
||||||
import EditorNavigation from "./EditorNavigation";
|
import EditorNavigation from "./EditorNavigation";
|
||||||
@@ -26,12 +27,26 @@ loader.config({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const validateWritability = (editor: monaco.editor.IStandaloneCodeEditor) => {
|
||||||
|
const currPath = editor.getModel()?.uri.path;
|
||||||
|
if (apiHeaderFiles.find(h => currPath?.endsWith(h))) {
|
||||||
|
editor.updateOptions({ readOnly: true });
|
||||||
|
} else {
|
||||||
|
editor.updateOptions({ readOnly: false });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const HooksEditor = () => {
|
const HooksEditor = () => {
|
||||||
const editorRef = useRef<monaco.editor.IStandaloneCodeEditor>();
|
const editorRef = useRef<monaco.editor.IStandaloneCodeEditor>();
|
||||||
const subscriptionRef = useRef<ReconnectingWebSocket | null>(null);
|
const subscriptionRef = useRef<ReconnectingWebSocket | null>(null);
|
||||||
const snap = useSnapshot(state);
|
const snap = useSnapshot(state);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { theme } = useTheme();
|
const { theme } = useTheme();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (editorRef.current) validateWritability(editorRef.current);
|
||||||
|
}, [snap.active]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
return () => {
|
return () => {
|
||||||
subscriptionRef?.current?.close();
|
subscriptionRef?.current?.close();
|
||||||
@@ -58,9 +73,9 @@ const HooksEditor = () => {
|
|||||||
language={snap.files?.[snap.active]?.language}
|
language={snap.files?.[snap.active]?.language}
|
||||||
path={`file://tmp/c/${snap.files?.[snap.active]?.name}`}
|
path={`file://tmp/c/${snap.files?.[snap.active]?.name}`}
|
||||||
defaultValue={snap.files?.[snap.active]?.content}
|
defaultValue={snap.files?.[snap.active]?.content}
|
||||||
beforeMount={(monaco) => {
|
beforeMount={monaco => {
|
||||||
if (!snap.editorCtx) {
|
if (!snap.editorCtx) {
|
||||||
snap.files.forEach((file) =>
|
snap.files.forEach(file =>
|
||||||
monaco.editor.createModel(
|
monaco.editor.createModel(
|
||||||
file.content,
|
file.content,
|
||||||
file.language,
|
file.language,
|
||||||
@@ -86,7 +101,7 @@ const HooksEditor = () => {
|
|||||||
// listen when the web socket is opened
|
// listen when the web socket is opened
|
||||||
listen({
|
listen({
|
||||||
webSocket: webSocket as WebSocket,
|
webSocket: webSocket as WebSocket,
|
||||||
onConnection: (connection) => {
|
onConnection: connection => {
|
||||||
// create and start the language client
|
// create and start the language client
|
||||||
const languageClient = createLanguageClient(connection);
|
const languageClient = createLanguageClient(connection);
|
||||||
const disposable = languageClient.start();
|
const disposable = languageClient.start();
|
||||||
@@ -125,12 +140,10 @@ const HooksEditor = () => {
|
|||||||
enabled: true,
|
enabled: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
editor.addCommand(
|
editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS, () => {
|
||||||
monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS,
|
saveFile();
|
||||||
() => {
|
});
|
||||||
saveFile();
|
validateWritability(editor)
|
||||||
}
|
|
||||||
);
|
|
||||||
}}
|
}}
|
||||||
theme={theme === "dark" ? "dark" : "light"}
|
theme={theme === "dark" ? "dark" : "light"}
|
||||||
/>
|
/>
|
||||||
@@ -148,9 +161,7 @@ const HooksEditor = () => {
|
|||||||
<Box css={{ display: "inline-flex", pl: "35px" }}>
|
<Box css={{ display: "inline-flex", pl: "35px" }}>
|
||||||
<ArrowBendLeftUp size={30} />
|
<ArrowBendLeftUp size={30} />
|
||||||
</Box>
|
</Box>
|
||||||
<Box
|
<Box css={{ pl: "0px", pt: "15px", flex: 1, display: "inline-flex" }}>
|
||||||
css={{ pl: "0px", pt: "15px", flex: 1, display: "inline-flex" }}
|
|
||||||
>
|
|
||||||
<Text
|
<Text
|
||||||
css={{
|
css={{
|
||||||
fontSize: "14px",
|
fontSize: "14px",
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import {
|
|||||||
DialogTrigger,
|
DialogTrigger,
|
||||||
} from "./Dialog";
|
} from "./Dialog";
|
||||||
import PanelBox from "./PanelBox";
|
import PanelBox from "./PanelBox";
|
||||||
|
import { templateFileIds } from '../state/constants';
|
||||||
|
|
||||||
const Navigation = () => {
|
const Navigation = () => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@@ -82,12 +83,8 @@ const Navigation = () => {
|
|||||||
<Spinner />
|
<Spinner />
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<Heading css={{ lineHeight: 1 }}>
|
<Heading css={{ lineHeight: 1 }}>{snap.files?.[0]?.name || "XRPL Hooks"}</Heading>
|
||||||
{snap.files?.[0]?.name || "XRPL Hooks"}
|
<Text css={{ fontSize: "$xs", color: "$mauve10", lineHeight: 1 }}>
|
||||||
</Heading>
|
|
||||||
<Text
|
|
||||||
css={{ fontSize: "$xs", color: "$mauve10", lineHeight: 1 }}
|
|
||||||
>
|
|
||||||
{snap.files.length > 0 ? "Gist: " : "Playground"}
|
{snap.files.length > 0 ? "Gist: " : "Playground"}
|
||||||
<Text css={{ color: "$mauve12" }}>
|
<Text css={{ color: "$mauve12" }}>
|
||||||
{snap.files.length > 0 &&
|
{snap.files.length > 0 &&
|
||||||
@@ -99,10 +96,7 @@ const Navigation = () => {
|
|||||||
</Flex>
|
</Flex>
|
||||||
{router.isReady && (
|
{router.isReady && (
|
||||||
<ButtonGroup css={{ marginLeft: "auto" }}>
|
<ButtonGroup css={{ marginLeft: "auto" }}>
|
||||||
<Dialog
|
<Dialog open={snap.mainModalOpen} onOpenChange={open => (state.mainModalOpen = open)}>
|
||||||
open={snap.mainModalOpen}
|
|
||||||
onOpenChange={(open) => (state.mainModalOpen = open)}
|
|
||||||
>
|
|
||||||
<DialogTrigger asChild>
|
<DialogTrigger asChild>
|
||||||
<Button outline>
|
<Button outline>
|
||||||
<FolderOpen size="15px" />
|
<FolderOpen size="15px" />
|
||||||
@@ -163,12 +157,9 @@ const Navigation = () => {
|
|||||||
mb: "$7",
|
mb: "$7",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Hooks add smart contract functionality to the XRP
|
Hooks add smart contract functionality to the XRP Ledger.
|
||||||
Ledger.
|
|
||||||
</Text>
|
</Text>
|
||||||
<Flex
|
<Flex css={{ flexDirection: "column", gap: "$2", mt: "$2" }}>
|
||||||
css={{ flexDirection: "column", gap: "$2", mt: "$2" }}
|
|
||||||
>
|
|
||||||
<Text
|
<Text
|
||||||
css={{
|
css={{
|
||||||
display: "inline-flex",
|
display: "inline-flex",
|
||||||
@@ -253,43 +244,29 @@ const Navigation = () => {
|
|||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<PanelBox
|
<PanelBox as="a" href={`/develop/${templateFileIds.starter}`}>
|
||||||
as="a"
|
|
||||||
href="/develop/be088224fb37c0075e84491da0e602c1"
|
|
||||||
>
|
|
||||||
<Heading>Starter</Heading>
|
<Heading>Starter</Heading>
|
||||||
<Text>
|
<Text>Just an empty starter with essential imports</Text>
|
||||||
Just an empty starter with essential imports
|
|
||||||
</Text>
|
|
||||||
</PanelBox>
|
</PanelBox>
|
||||||
<PanelBox
|
<PanelBox as="a" href={`/develop/${templateFileIds.starter}`}>
|
||||||
as="a"
|
|
||||||
href="/develop/be088224fb37c0075e84491da0e602c1"
|
|
||||||
>
|
|
||||||
<Heading>Firewall</Heading>
|
<Heading>Firewall</Heading>
|
||||||
<Text>
|
<Text>This Hook essentially checks a blacklist of accounts</Text>
|
||||||
This Hook essentially checks a blacklist of accounts
|
|
||||||
</Text>
|
|
||||||
</PanelBox>
|
</PanelBox>
|
||||||
<PanelBox
|
<PanelBox as="a" href={`/develop/${templateFileIds.accept}`}>
|
||||||
as="a"
|
|
||||||
href="/develop/be088224fb37c0075e84491da0e602c1"
|
|
||||||
>
|
|
||||||
<Heading>Accept</Heading>
|
<Heading>Accept</Heading>
|
||||||
<Text>
|
<Text>This hook just accepts any transaction coming through it</Text>
|
||||||
This hook just accepts any transaction coming through
|
|
||||||
it
|
|
||||||
</Text>
|
|
||||||
</PanelBox>
|
</PanelBox>
|
||||||
<PanelBox
|
<PanelBox as="a" href={`/develop/${templateFileIds.notary}`}>
|
||||||
as="a"
|
<Heading>Notary</Heading>
|
||||||
href="/develop/be088224fb37c0075e84491da0e602c1"
|
<Text>Collecting signatures for multi-sign transactions</Text>
|
||||||
>
|
</PanelBox>
|
||||||
<Heading>Accept</Heading>
|
<PanelBox as="a" href={`/develop/${templateFileIds.carbon}`}>
|
||||||
<Text>
|
<Heading>Carbon</Heading>
|
||||||
This hook just accepts any transaction coming through
|
<Text>Send a percentage of sum to an address</Text>
|
||||||
it
|
</PanelBox>
|
||||||
</Text>
|
<PanelBox as="a" href={`/develop/${templateFileIds.peggy}`}>
|
||||||
|
<Heading>Peggy</Heading>
|
||||||
|
<Text>An oracle based stabe coin hook</Text>
|
||||||
</PanelBox>
|
</PanelBox>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
@@ -336,42 +313,18 @@ const Navigation = () => {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<ButtonGroup>
|
<ButtonGroup>
|
||||||
<Link
|
<Link href={gistId ? `/develop/${gistId}` : "/develop"} passHref shallow>
|
||||||
href={gistId ? `/develop/${gistId}` : "/develop"}
|
<Button as="a" outline={!router.pathname.includes("/develop")} uppercase>
|
||||||
passHref
|
|
||||||
shallow
|
|
||||||
>
|
|
||||||
<Button
|
|
||||||
as="a"
|
|
||||||
outline={!router.pathname.includes("/develop")}
|
|
||||||
uppercase
|
|
||||||
>
|
|
||||||
Develop
|
Develop
|
||||||
</Button>
|
</Button>
|
||||||
</Link>
|
</Link>
|
||||||
<Link
|
<Link href={gistId ? `/deploy/${gistId}` : "/deploy"} passHref shallow>
|
||||||
href={gistId ? `/deploy/${gistId}` : "/deploy"}
|
<Button as="a" outline={!router.pathname.includes("/deploy")} uppercase>
|
||||||
passHref
|
|
||||||
shallow
|
|
||||||
>
|
|
||||||
<Button
|
|
||||||
as="a"
|
|
||||||
outline={!router.pathname.includes("/deploy")}
|
|
||||||
uppercase
|
|
||||||
>
|
|
||||||
Deploy
|
Deploy
|
||||||
</Button>
|
</Button>
|
||||||
</Link>
|
</Link>
|
||||||
<Link
|
<Link href={gistId ? `/test/${gistId}` : "/test"} passHref shallow>
|
||||||
href={gistId ? `/test/${gistId}` : "/test"}
|
<Button as="a" outline={!router.pathname.includes("/test")} uppercase>
|
||||||
passHref
|
|
||||||
shallow
|
|
||||||
>
|
|
||||||
<Button
|
|
||||||
as="a"
|
|
||||||
outline={!router.pathname.includes("/test")}
|
|
||||||
uppercase
|
|
||||||
>
|
|
||||||
Test
|
Test
|
||||||
</Button>
|
</Button>
|
||||||
</Link>
|
</Link>
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import { Octokit } from "@octokit/core";
|
import { Octokit } from "@octokit/core";
|
||||||
import Router from "next/router";
|
import Router from "next/router";
|
||||||
import state from '../index';
|
import state from '../index';
|
||||||
|
import { templateFileIds } from '../constants';
|
||||||
|
|
||||||
|
|
||||||
const octokit = new Octokit();
|
const octokit = new Octokit();
|
||||||
|
|
||||||
@@ -17,6 +19,17 @@ export const fetchFiles = (gistId: string) => {
|
|||||||
|
|
||||||
octokit
|
octokit
|
||||||
.request("GET /gists/{gist_id}", { gist_id: gistId })
|
.request("GET /gists/{gist_id}", { gist_id: gistId })
|
||||||
|
.then(res => {
|
||||||
|
if (!Object.values(templateFileIds).includes(gistId)) {
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
// in case of templates, fetch header file(s) and append to res
|
||||||
|
return octokit.request("GET /gists/{gist_id}", { gist_id: templateFileIds.headers }).then(({ data: { files: headerFiles } }) => {
|
||||||
|
const files = { ...res.data.files, ...headerFiles }
|
||||||
|
res.data.files = files
|
||||||
|
return res
|
||||||
|
})
|
||||||
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.data.files && Object.keys(res.data.files).length > 0) {
|
if (res.data.files && Object.keys(res.data.files).length > 0) {
|
||||||
const files = Object.keys(res.data.files).map((filename) => ({
|
const files = Object.keys(res.data.files).map((filename) => ({
|
||||||
@@ -44,6 +57,7 @@ export const fetchFiles = (gistId: string) => {
|
|||||||
state.loading = false;
|
state.loading = false;
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
|
// console.error(err)
|
||||||
state.loading = false;
|
state.loading = false;
|
||||||
state.logs.push({
|
state.logs.push({
|
||||||
type: "error",
|
type: "error",
|
||||||
|
|||||||
1
state/constants/index.ts
Normal file
1
state/constants/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export * from './templates'
|
||||||
11
state/constants/templates.ts
Normal file
11
state/constants/templates.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
export const templateFileIds = {
|
||||||
|
'starter': '1d14e51e2e02dc0a508cb0733767a914', // TODO currently same as accept
|
||||||
|
'accept': '1d14e51e2e02dc0a508cb0733767a914',
|
||||||
|
'firewall': 'bcd6d0c0fcbe52545ddb802481ff9d26',
|
||||||
|
'notary': 'a789c75f591eeab7932fd702ed8cf9ea',
|
||||||
|
'carbon': '43925143fa19735d8c6505c34d3a6a47',
|
||||||
|
'peggy': 'ceaf352e2a65741341033ab7ef05c448',
|
||||||
|
'headers': '9b448e8a55fab11ef5d1274cb59f9cf3'
|
||||||
|
}
|
||||||
|
|
||||||
|
export const apiHeaderFiles = ['hookapi.h', 'sfcodes.h', 'hookmacro.h']
|
||||||
Reference in New Issue
Block a user