|
|
|
|
@ -1,23 +1,12 @@
|
|
|
|
|
import { useSignal, signal, useComputed, batch, effect } from '@preact/signals'
|
|
|
|
|
import { useSignal, signal, useComputed, batch, effect, Signal } from '@preact/signals'
|
|
|
|
|
import clsx from 'clsx'
|
|
|
|
|
|
|
|
|
|
import { TreeView, EXAMPLE_TREE } from '@/client/components/TreeView.jsx'
|
|
|
|
|
import { TreeView } from '@/client/components/TreeView.jsx'
|
|
|
|
|
import { Editor } from '@/client/components/Editor.jsx'
|
|
|
|
|
import clsx from 'clsx'
|
|
|
|
|
import { useEffect, useState } from 'preact/hooks'
|
|
|
|
|
import { fetchJson } from '../utils.js'
|
|
|
|
|
import { useEffect } from 'preact/hooks'
|
|
|
|
|
import { Terminal } from './Terminal.jsx'
|
|
|
|
|
|
|
|
|
|
function ensurePrefix(s, prefix) {
|
|
|
|
|
return s.slice(0, prefix.length) === prefix ? s : prefix + s
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function stripPrefix(s, prefix) {
|
|
|
|
|
return s.slice(0, prefix.length) === prefix ? s.slice(prefix.length) : s
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function clamp(min, value, max) {
|
|
|
|
|
return Math.max(min, Math.min(value, max))
|
|
|
|
|
}
|
|
|
|
|
import { clamp, fetchJson, stripPrefix } from '@/client/utils.js'
|
|
|
|
|
|
|
|
|
|
export const Ide = ({}) => {
|
|
|
|
|
const ws = useSignal(null)
|
|
|
|
|
@ -38,16 +27,8 @@ export const Ide = ({}) => {
|
|
|
|
|
|
|
|
|
|
const activeTab = useSignal(null)
|
|
|
|
|
|
|
|
|
|
const tabs = useSignal([
|
|
|
|
|
// {
|
|
|
|
|
// id: '/project/main.c',
|
|
|
|
|
// content: signal('...main.c...'),
|
|
|
|
|
// },
|
|
|
|
|
// {
|
|
|
|
|
// id: '/project/data.csv',
|
|
|
|
|
// content: signal('...data.csv...'),
|
|
|
|
|
// },
|
|
|
|
|
])
|
|
|
|
|
/** @type {Signal<{ id: string, content: Signal<string> }[]>} */
|
|
|
|
|
const tabs = useSignal([])
|
|
|
|
|
|
|
|
|
|
const activePath = useComputed(() => {
|
|
|
|
|
if (activeTab.value === null) return null
|
|
|
|
|
@ -61,15 +42,6 @@ export const Ide = ({}) => {
|
|
|
|
|
return tabs.value[activeTab.value].content
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
effect(() => {
|
|
|
|
|
const path = activePath.value
|
|
|
|
|
const contentSig = activeContent.value
|
|
|
|
|
|
|
|
|
|
if (contentSig === null || path === null) return
|
|
|
|
|
|
|
|
|
|
console.log(path, contentSig.value)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div class="ide">
|
|
|
|
|
<div class="sidebar">
|
|
|
|
|
@ -161,27 +133,44 @@ export const Ide = ({}) => {
|
|
|
|
|
<button class="icon">
|
|
|
|
|
<div class="material-symbols-outlined">terminal</div>
|
|
|
|
|
</button>
|
|
|
|
|
<button
|
|
|
|
|
class="run"
|
|
|
|
|
onClick={() => {
|
|
|
|
|
console.log('Running file:', activePath.value)
|
|
|
|
|
if (!activePath.value) return
|
|
|
|
|
<div class="popup-region run-style">
|
|
|
|
|
<div class="region">
|
|
|
|
|
<button class="compound">
|
|
|
|
|
<span
|
|
|
|
|
class="part"
|
|
|
|
|
onClick={() => {
|
|
|
|
|
console.log('Running file:', activePath.value)
|
|
|
|
|
if (!activePath.value) return
|
|
|
|
|
|
|
|
|
|
const fullPath = '/project' + activePath.value
|
|
|
|
|
const fullPath = '/project' + activePath.value
|
|
|
|
|
|
|
|
|
|
if (fullPath.endsWith('.sh')) {
|
|
|
|
|
ws.value.send(`sh ${fullPath}\n`)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if (fullPath.endsWith('.js')) {
|
|
|
|
|
ws.value.send(`node ${fullPath}\n`)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<div class="material-symbols-outlined">play_arrow</div>
|
|
|
|
|
Run File
|
|
|
|
|
</button>
|
|
|
|
|
if (fullPath.endsWith('.sh')) {
|
|
|
|
|
ws.value.send(`sh ${fullPath}\n`)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if (fullPath.endsWith('.js')) {
|
|
|
|
|
ws.value.send(`node ${fullPath}\n`)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
Run
|
|
|
|
|
</span>
|
|
|
|
|
<span class="part">
|
|
|
|
|
<span class="material-symbols-outlined">keyboard_arrow_down</span>
|
|
|
|
|
</span>
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="popup anchor-mode-1">
|
|
|
|
|
<div class="menu">
|
|
|
|
|
<div class="item">Run</div>
|
|
|
|
|
<div class="item">Debug</div>
|
|
|
|
|
<div class="item">Test</div>
|
|
|
|
|
<div class="item">Profile</div>
|
|
|
|
|
<div class="item">Bench</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="tabbed-editor">
|
|
|
|
|
|