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[];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
}
 | 
			
		||||
    `,
 | 
			
		||||
  compiling: boolean;
 | 
			
		||||
  logs: {
 | 
			
		||||
    type: 'error' | 'warning' | 'log',
 | 
			
		||||
    message: string;
 | 
			
		||||
  }[];
 | 
			
		||||
  editorCtx?: typeof monaco.editor;
 | 
			
		||||
  editorSettings: {
 | 
			
		||||
    tabSize: number;
 | 
			
		||||
  }
 | 
			
		||||
];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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