150 lines
3.9 KiB
TypeScript
150 lines
3.9 KiB
TypeScript
import { proxy, subscribe } from 'valtio';
|
|
import { devtools } from 'valtio/utils';
|
|
import { Octokit } from '@octokit/core';
|
|
import type monaco from 'monaco-editor';
|
|
import toast from 'react-hot-toast';
|
|
|
|
const octokit = new Octokit();
|
|
|
|
interface File {
|
|
name: string,
|
|
language: string,
|
|
content: string
|
|
}
|
|
|
|
interface IState {
|
|
files: File[],
|
|
active: number;
|
|
loading: boolean;
|
|
compiling: boolean;
|
|
logs: {
|
|
type: 'error' | 'warning' | 'log',
|
|
message: string;
|
|
}[];
|
|
editorCtx?: typeof monaco.editor;
|
|
editorSettings: {
|
|
tabSize: number;
|
|
}
|
|
}
|
|
|
|
let localStorageState: null | string = null;
|
|
let initialState = {
|
|
files: [],
|
|
active: 0,
|
|
loading: false,
|
|
compiling: false,
|
|
logs: [],
|
|
editorCtx: undefined,
|
|
editorSettings: {
|
|
tabSize: 2
|
|
}
|
|
}
|
|
|
|
// if (typeof window !== 'undefined') {
|
|
// try {
|
|
// localStorageState = localStorage.getItem('hooksIdeState');
|
|
// } catch (err) {
|
|
// console.log(`localStorage state broken`);
|
|
// localStorage.removeItem('hooksIdeState');
|
|
// }
|
|
// }
|
|
// if (localStorageState) {
|
|
// initialState = JSON.parse(localStorageState);
|
|
// }
|
|
|
|
// Initialize state
|
|
export const state = proxy<IState>(initialState);
|
|
|
|
// Fetch content from Githug Gists
|
|
export const fetchFiles = (gistId: string) => {
|
|
if (gistId) {
|
|
state.logs.push({ type: 'log', message: `Fetching Gist with id: ${gistId}` });
|
|
octokit.request("GET /gists/{gist_id}", { gist_id: gistId }).then(res => {
|
|
if (res.data.files && Object.keys(res.data.files).length > 0) {
|
|
const files = Object.keys(res.data.files).map(filename => ({
|
|
name: res.data.files?.[filename]?.filename || 'noname.c',
|
|
language: res.data.files?.[filename]?.language?.toLowerCase() || '',
|
|
content: res.data.files?.[filename]?.content || ''
|
|
}))
|
|
state.loading = false;
|
|
if (files.length > 0) {
|
|
state.logs.push({ type: 'log', message: 'Fetched successfully ✅' })
|
|
state.files = files;
|
|
return
|
|
}
|
|
return
|
|
}
|
|
|
|
}).catch(err => {
|
|
state.loading = false;
|
|
state.logs.push({ type: 'error', message: `Couldn't find Gist with id: ${gistId}` })
|
|
return
|
|
})
|
|
return
|
|
}
|
|
state.loading = false;
|
|
// return state.files = initFiles
|
|
}
|
|
|
|
export const updateEditorSettings = (editorSettings: IState['editorSettings']) => {
|
|
state.editorCtx?.getModels().forEach(model => {
|
|
console.log(model.uri)
|
|
model.updateOptions({
|
|
...editorSettings
|
|
})
|
|
});
|
|
return state.editorSettings = editorSettings;
|
|
}
|
|
|
|
export const saveFile = (value: string) => {
|
|
toast.success('Saved successfully', { position: 'bottom-center' })
|
|
}
|
|
|
|
export const createNewFile = (name: string) => {
|
|
state.files.push({ name, language: 'c', content: "" })
|
|
state.active = state.files.length - 1;
|
|
}
|
|
|
|
export const compileCode = async (activeId: number) => {
|
|
if (!process.env.NEXT_PUBLIC_COMPILE_API_ENDPOINT) {
|
|
throw Error('Missing env!')
|
|
};
|
|
if (state.compiling) {
|
|
return;
|
|
}
|
|
state.compiling = true;
|
|
try {
|
|
const res = await fetch(process.env.NEXT_PUBLIC_COMPILE_API_ENDPOINT, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify({
|
|
"output": "wasm",
|
|
"compress": true,
|
|
"files": [
|
|
{
|
|
"type": "c",
|
|
"name": state.files[activeId].name,
|
|
"options": "-g -O3",
|
|
"src": state.files[activeId].content
|
|
}
|
|
]
|
|
})
|
|
});
|
|
const json = await res.json();
|
|
state.compiling = false;
|
|
toast.success('Compiled successfully!');
|
|
console.log(json)
|
|
} catch {
|
|
state.logs.push({ type: 'error', message: 'Error occured while compiling!' })
|
|
state.compiling = false;
|
|
}
|
|
}
|
|
|
|
const unsub = devtools(state, 'Files State');
|
|
|
|
subscribe(state, () => {
|
|
const { editorCtx, ...storedState } = state;
|
|
localStorage.setItem('hooksIdeState', JSON.stringify(storedState))
|
|
}); |