Add initial valtio global state
This commit is contained in:
163
state.ts
163
state.ts
@@ -1,105 +1,150 @@
|
||||
import { proxy } from 'valtio';
|
||||
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 Files {
|
||||
interface File {
|
||||
name: string,
|
||||
language: string,
|
||||
content: string
|
||||
}
|
||||
|
||||
interface IState {
|
||||
files: {
|
||||
name: string;
|
||||
language: string;
|
||||
content: string;
|
||||
}[] | [],
|
||||
files: File[],
|
||||
active: number;
|
||||
loading: boolean;
|
||||
logs: string[];
|
||||
compiling: boolean;
|
||||
logs: {
|
||||
type: 'error' | 'warning' | 'log',
|
||||
message: string;
|
||||
}[];
|
||||
editorCtx?: typeof monaco.editor;
|
||||
editorSettings: {
|
||||
tabSize: number;
|
||||
}
|
||||
}
|
||||
|
||||
const initFiles = [
|
||||
{
|
||||
name: 'hello.c',
|
||||
language: 'c',
|
||||
content: `
|
||||
#include <stdio.h>
|
||||
int main() {
|
||||
// printf() displays the string inside quotation
|
||||
printf("Hello, World!");
|
||||
return 0;
|
||||
}
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: 'another.c',
|
||||
language: 'c',
|
||||
content: `
|
||||
#include <stdio.h>
|
||||
int main()
|
||||
{
|
||||
/* printf function displays the content that is
|
||||
* passed between the double quotes.
|
||||
*/
|
||||
printf("Hello World");
|
||||
return 0;
|
||||
}
|
||||
`,
|
||||
}
|
||||
];
|
||||
|
||||
const state = proxy<IState>({
|
||||
let localStorageState: null | string = null;
|
||||
let initialState = {
|
||||
files: [],
|
||||
active: 0,
|
||||
loading: false,
|
||||
logs: []
|
||||
});
|
||||
compiling: false,
|
||||
logs: [],
|
||||
editorCtx: undefined,
|
||||
editorSettings: {
|
||||
tabSize: 2
|
||||
}
|
||||
}
|
||||
|
||||
// state.files = initFiles;
|
||||
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);
|
||||
}
|
||||
|
||||
// const initState = ({ gistId }: { gistId?: string }) => {
|
||||
// if (!gistId) {
|
||||
// return initialState;
|
||||
// }
|
||||
// }
|
||||
|
||||
// const state = initialState;
|
||||
// Initialize state
|
||||
export const state = proxy<IState>(initialState);
|
||||
|
||||
// Fetch content from Githug Gists
|
||||
export const fetchFiles = (gistId: string) => {
|
||||
if (gistId) {
|
||||
console.log('callling')
|
||||
state.logs.push({ type: 'log', message: `Fetching Gist with id: ${gistId}` });
|
||||
octokit.request("GET /gists/{gist_id}", { gist_id: gistId }).then(res => {
|
||||
state.logs.push('Fetching files from Github Gists...');
|
||||
|
||||
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.files = initFiles
|
||||
state.loading = false;
|
||||
if (files.length > 0) {
|
||||
state.logs.push('Fetched successfully ✅')
|
||||
state.logs.push({ type: 'log', message: 'Fetched successfully ✅' })
|
||||
state.files = files;
|
||||
return
|
||||
}
|
||||
return state.files = initFiles
|
||||
return
|
||||
}
|
||||
|
||||
}).catch(err => {
|
||||
state.loading = false;
|
||||
return state.files = initFiles
|
||||
state.logs.push({ type: 'error', message: `Couldn't find Gist with id: ${gistId}` })
|
||||
return
|
||||
})
|
||||
return
|
||||
}
|
||||
state.loading = false;
|
||||
return state.files = initFiles
|
||||
// return state.files = initFiles
|
||||
}
|
||||
|
||||
const unsub = devtools(state, 'Files State')
|
||||
export const updateEditorSettings = (editorSettings: IState['editorSettings']) => {
|
||||
state.editorCtx?.getModels().forEach(model => {
|
||||
console.log(model.uri)
|
||||
model.updateOptions({
|
||||
...editorSettings
|
||||
})
|
||||
});
|
||||
return state.editorSettings = editorSettings;
|
||||
}
|
||||
|
||||
export { state };
|
||||
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))
|
||||
});
|
||||
Reference in New Issue
Block a user