Add initial valtio global state

This commit is contained in:
Valtteri Karesto
2021-11-19 15:24:08 +02:00
parent b1b524ca0c
commit 2de6478547

163
state.ts
View File

@@ -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))
});