Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ NEXTAUTH_SECRET="1234"
GITHUB_SECRET=""
GITHUB_ID=""
NEXT_PUBLIC_COMPILE_API_ENDPOINT="http://localhost:9000/api/build"
NEXT_PUBLIC_JS_COMPILE_API_ENDPOINT="http://localhost:9000/api/build/js"
NEXT_PUBLIC_COMPILE_API_BASE_URL="http://localhost:9000"
NEXT_PUBLIC_LANGUAGE_SERVER_API_ENDPOINT="ws://localhost:9000/language-server/c"
NEXT_PUBLIC_TESTNET_URL="xahau-test.net"
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,6 @@ yarn-error.log*
# yarn
.yarnrc.yml
.yarn/

# esbuild
public/esbuild.wasm
23 changes: 12 additions & 11 deletions components/DeployEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ const DeployEditor = () => {
const renderNav = () => (
<Tabs activeIndex={snap.activeWat} onChangeActive={idx => (state.activeWat = idx)}>
{compiledFiles.map((file, index) => {
return <Tab key={file.name} header={`${file.name}.wat`} />
const compiledViewableExtension = file.compiledExtension === 'wasm' ? 'wat' : 'js'
return <Tab key={file.name} header={`${file.name.split('.')[0]}.${compiledViewableExtension}`} />
})}
</Tabs>
)
Expand All @@ -41,8 +42,8 @@ const DeployEditor = () => {
compiledSize > FILESIZE_BREAKPOINTS[1]
? '$error'
: compiledSize > FILESIZE_BREAKPOINTS[0]
? '$warning'
: '$success'
? '$warning'
: '$success'

const isContentChanged = activeFile && activeFile.compiledValueSnapshot !== activeFile.content
// const hasDeployErrors = activeFile && activeFile.containsErrors;
Expand All @@ -58,7 +59,7 @@ const DeployEditor = () => {
}}
>
<Flex row align="center">
<Text css={{ mr: '$1' }}>Compiled {activeFile.name.split('.')[0] + '.wasm'}</Text>
<Text css={{ mr: '$1' }}>Compiled {activeFile.name.split('.')[0] + '.' + activeFile.compiledExtension}</Text>
{activeFile?.lastCompiled && <ReactTimeAgo date={activeFile.lastCompiled} locale="en-US" />}

{activeFile.compiledContent?.byteLength && (
Expand All @@ -73,7 +74,7 @@ const DeployEditor = () => {
</Flex>
)}
<Button variant="link" onClick={() => setShowContent(true)}>
View as WAT-file
{activeFile.compiledExtension === 'wasm' ? 'View as WAT-file' : 'View as JS-file'}
</Button>
{isContentChanged && (
<Text warning>
Expand Down Expand Up @@ -128,14 +129,14 @@ const DeployEditor = () => {
) : (
<Monaco
className="hooks-editor"
defaultLanguage={'wat'}
language={'wat'}
path={`file://tmp/c/${activeFile?.name}.wat`}
defaultLanguage={activeFile?.compiledExtension === 'wasm' ? 'wat' : 'javascript'}
language={activeFile?.compiledExtension === 'wasm' ? 'wat' : 'javascript'}
path={`file://tmp/c/${activeFile?.name}.${activeFile?.language}`}
value={activeFile?.compiledWatContent || ''}
beforeMount={monaco => {
monaco.languages.register({ id: 'wat' })
monaco.languages.setLanguageConfiguration('wat', wat.config)
monaco.languages.setMonarchTokensProvider('wat', wat.tokens)
monaco.languages.register({ id: activeFile.language })
monaco.languages.setLanguageConfiguration(activeFile.language, wat.config)
monaco.languages.setMonarchTokensProvider(activeFile.language, wat.tokens)
}}
onMount={editor => {
editor.updateOptions({
Expand Down
33 changes: 24 additions & 9 deletions components/HooksEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -200,15 +200,15 @@ const HooksEditor = () => {
defaultValue={file?.content}
// onChange={val => (state.files[snap.active].content = val)} // Auto save?
beforeMount={monaco => {
// if (!snap.editorCtx) {
// snap.files.forEach(file =>
// monaco.editor.createModel(
// file.content,
// file.language,
// monaco.Uri.parse(`file:///work/c/${file.name}`)
// )
// )
// }
if (!snap.editorCtx) {
snap.files.forEach(file =>
monaco.editor.createModel(
file.content,
file.language,
monaco.Uri.parse(`file:///work/c/${file.name}`)
)
)
}

// create the web socket
if (!subscriptionRef.current) {
Expand All @@ -223,6 +223,21 @@ const HooksEditor = () => {
extensions: ['.txt'],
mimetypes: ['text/plain'],
})

monaco.languages.register({
id: 'typescript',
extensions: ['.ts', '.js'],
mimetypes: ['text/plain'],
})

// Set global variables
snap.files.filter(file => file.content.includes('declare global'))
.forEach(file => {
monaco.languages.typescript.javascriptDefaults.addExtraLib(
file.content
)
})

MonacoServices.install(monaco)
const webSocket = createWebSocket(
process.env.NEXT_PUBLIC_LANGUAGE_SERVER_API_ENDPOINT || ''
Expand Down
81 changes: 60 additions & 21 deletions components/Navigation.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react'
import React, { useState } from 'react'
import Link from 'next/link'

import { useSnapshot } from 'valtio'
Expand Down Expand Up @@ -27,8 +27,9 @@ import {
DialogTrigger
} from './Dialog'
import PanelBox from './PanelBox'
import { templateFileIds } from '../state/constants'
import { templateCFileIds, templateJSFileIds } from '../state/constants'
import { styled } from '../stitches.config'
import { Tab, Tabs } from './Tabs'

const ImageWrapper = styled(Flex, {
position: 'relative',
Expand All @@ -45,9 +46,17 @@ const ImageWrapper = styled(Flex, {
}
})

const cEnabled = !!process.env.NEXT_PUBLIC_COMPILE_API_ENDPOINT
const jsEnabled = !!process.env.NEXT_PUBLIC_JS_COMPILE_API_ENDPOINT

type Languages = 'C' | 'JavaScript'

const defaultLanguage: Languages = cEnabled ? 'C' : 'JavaScript'

const Navigation = () => {
const router = useRouter()
const snap = useSnapshot(state)
const [language, setLanguage] = useState<Languages>(defaultLanguage)
const slug = router.query?.slug
const gistId = Array.isArray(slug) ? slug[0] : null

Expand Down Expand Up @@ -261,34 +270,64 @@ const Navigation = () => {

<Flex
css={{
display: 'grid',
gridTemplateColumns: '1fr',
gridTemplateRows: 'max-content',
flex: 1,
p: '$7',
pb: '$16',
gap: '$3',
alignItems: 'normal',
alignItems: 'center',
justifyContent: 'center',
flexWrap: 'wrap',
backgroundColor: '$mauve1',
'@md': {
gridTemplateColumns: '1fr 1fr',
gridTemplateRows: 'max-content'
},
'@lg': {
gridTemplateColumns: '1fr 1fr 1fr',
gridTemplateRows: 'max-content'
}
flexDirection: 'column',
width: '100%'
}}
>
{Object.values(templateFileIds).map(template => (
<PanelBox key={template.id} as="a" href={`/develop/${template.id}`}>
<ImageWrapper>{template.icon()}</ImageWrapper>
<Heading>{template.name}</Heading>
{cEnabled && jsEnabled && (
<Box css={{ alignSelf: 'center' }}>
<Tabs css={{ marginLeft: '$4' }} onChangeActive={(_, header) => setLanguage(header as Languages)}>
<Tab header="C" />
<Tab header="JavaScript" />
</Tabs>
</Box>
)}
<Flex
css={{
display: 'grid',
gridTemplateColumns: '1fr',
gridTemplateRows: 'max-content',
flex: 1,
p: '$7',
pb: '$16',
gap: '$3',
alignItems: 'normal',
flexWrap: 'wrap',
backgroundColor: '$mauve1',
'@md': {
gridTemplateColumns: '1fr 1fr',
gridTemplateRows: 'max-content'
},
'@lg': {
gridTemplateColumns: '1fr 1fr 1fr',
gridTemplateRows: 'max-content'
}
}}
>
{language === 'C' ? Object.values(templateCFileIds).map(template => (
<PanelBox key={template.id} as="a" href={`/develop/${template.id}`}>
<ImageWrapper>{template.icon()}</ImageWrapper>
<Heading>{template.name}</Heading>

<Text>{template.description}</Text>
</PanelBox>
)) : Object.values(templateJSFileIds).map(template => (
<PanelBox key={template.id} as="a" href={`/develop/${template.id}`}>
<ImageWrapper>{template.icon()}</ImageWrapper>
<Heading>{template.name}</Heading>

<Text>{template.description}</Text>
</PanelBox>
))}
<Text>{template.description}</Text>
</PanelBox>
))}
</Flex>
</Flex>
</Flex>
<DialogClose asChild>
Expand Down
2 changes: 1 addition & 1 deletion components/RunScript/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ const RunScript: React.FC<{ file: IFile }> = ({ file: { content, name } }) => {
setIframeCode('')
}}
>
<Play weight="bold" size="16px" /> {name}
<Play weight="bold" size="16px" /> Run Script
</Button>
</DialogTrigger>
<DialogContent>
Expand Down
39 changes: 36 additions & 3 deletions components/SetHookDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -276,8 +276,41 @@ export const SetHookDialog: React.FC<{ accountAddress: string }> = React.memo(
</Button>
</Stack>
</Box>
{activeFile?.language === 'javascript' &&
<Box css={{ width: '100%', position: 'relative' }}>
<Label>Hook Fee</Label>
<Box css={{ display: 'flex', alignItems: 'center' }}>
<Input
type="number"
{...register('JSHookFee', { required: true })}
autoComplete={'off'}
onKeyPress={e => {
if (e.key === '.' || e.key === ',') {
e.preventDefault()
}
}}
step="1"
defaultValue={10000}
css={{
'-moz-appearance': 'textfield',
'&::-webkit-outer-spin-button': {
'-webkit-appearance': 'none',
margin: 0
},
'&::-webkit-inner-spin-button ': {
'-webkit-appearance': 'none',
margin: 0
}
}}
/>
</Box>
{errors.JSHookFee?.type === 'required' && (
<Box css={{ display: 'inline', color: '$red11' }}>Hook Fee is required</Box>
)}
</Box>
}
<Box css={{ width: '100%', position: 'relative' }}>
<Label>Fee</Label>
<Label>SetHook Fee</Label>
<Box css={{ display: 'flex', alignItems: 'center' }}>
<Input
type="number"
Expand Down Expand Up @@ -329,7 +362,7 @@ export const SetHookDialog: React.FC<{ accountAddress: string }> = React.memo(
setValue('Fee', Math.round(Number(res.base_fee || '')).toString())
}
}
} catch (err) {}
} catch (err) { }

setEstimateLoading(false)
}}
Expand All @@ -338,7 +371,7 @@ export const SetHookDialog: React.FC<{ accountAddress: string }> = React.memo(
</Button>
</Box>
{errors.Fee?.type === 'required' && (
<Box css={{ display: 'inline', color: '$red11' }}>Fee is required</Box>
<Box css={{ display: 'inline', color: '$red11' }}>SetHook Fee is required</Box>
)}
</Box>
{/* <Box css={{ width: "100%" }}>
Expand Down
49 changes: 26 additions & 23 deletions components/Tabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ interface Props {
regex: string | RegExp
error: string
}
css?: Record<string, any>
onCreateNewTab?: (name: string) => any
onRenameTab?: (index: number, nwName: string, oldName?: string) => any
onCloseTab?: (index: number, header?: string) => any
Expand All @@ -65,7 +66,8 @@ export const Tabs = ({
headerExtraValidation,
extensionRequired,
defaultExtension = '',
allowedExtensions
allowedExtensions,
css
}: Props) => {
const [active, setActive] = useState(activeIndex || 0)
const tabs: TabProps[] = children.map(elem => elem.props)
Expand Down Expand Up @@ -205,7 +207,8 @@ export const Tabs = ({
flexWrap: 'nowrap',
marginBottom: '$2',
width: '100%',
overflow: 'auto'
overflow: 'auto',
...css
}}
>
{tabs.map((tab, idx) => (
Expand Down Expand Up @@ -347,28 +350,28 @@ export const Tabs = ({
)}
{keepAllAlive
? tabs.map((tab, idx) => {
// TODO Maybe rule out fragments as children
if (!isValidElement(tab.children)) {
if (active !== idx) return null
return tab.children
}
let key = tab.children.key || tab.header || idx
let { children } = tab
let { style, ...props } = children.props
return (
<children.type
key={key}
{...props}
style={{
...style,
display: active !== idx ? 'none' : undefined
}}
/>
)
})
// TODO Maybe rule out fragments as children
if (!isValidElement(tab.children)) {
if (active !== idx) return null
return tab.children
}
let key = tab.children.key || tab.header || idx
let { children } = tab
let { style, ...props } = children.props
return (
<children.type
key={key}
{...props}
style={{
...style,
display: active !== idx ? 'none' : undefined
}}
/>
)
})
: tabs[active] && (
<Fragment key={tabs[active].header || active}>{tabs[active].children}</Fragment>
)}
<Fragment key={tabs[active].header || active}>{tabs[active].children}</Fragment>
)}
</>
)
}
Loading