import ProblemIcon from '@vscode/codicons/src/icons/file.svg?react'; import { Allotment } from 'allotment'; import $ from 'jquery'; import _ from 'lodash'; import type * as monaco from 'monaco-editor'; import React from 'react'; import { useDispatch, useSelector, useStore } from 'react-redux'; import Dom from 'vj/components/react/DomComponent'; import { Context, ctx, Service } from 'vj/context'; import ScratchpadEditor from './ScratchpadEditorContainer'; import ScratchpadPretest from './ScratchpadPretestContainer'; import ScratchpadRecords from './ScratchpadRecordsContainer'; import ScratchpadToolbar from './ScratchpadToolbarContainer'; const pages = { problem: { icon: () => , component: () => , }, }; let rerenderCallback = null; class ScratchpadService extends Service { constructor(public store) { super(ctx, 'scratchpad', true); this.load = new Promise((resolve) => { this.loadCallback = resolve; }); } pages = pages; load: Promise; loadCallback: () => void; editor: monaco.editor.IStandaloneCodeEditor; monaco: typeof import('monaco-editor'); init(editor: monaco.editor.IStandaloneCodeEditor, monaco: typeof import('monaco-editor')) { this.editor = editor; this.monaco = monaco; this.loadCallback(); } addPage(key, icon, component) { pages[key] = { icon, component, }; rerenderCallback?.(); } } Context.service('scratchpad', ScratchpadService); declare module '../../context' { interface Context { scratchpad: ScratchpadService; } } export default function ScratchpadContainer() { const store = useStore(); ctx.scratchpad ||= new ScratchpadService(store); const [, updateState] = React.useState(); const forceUpdate = React.useCallback(() => updateState({}), []); React.useEffect(() => { rerenderCallback = forceUpdate; }, []); const dispatch = useDispatch(); const ui = useSelector((state) => state.ui, _.isEqual); const handleChangeSize = _.debounce(() => { ctx.scratchpad.editor?.layout?.(); $('#scratchpad').trigger('vjScratchpadRelayout'); forceUpdate(); }, 500); const switchToPage = (target) => { dispatch({ type: 'SCRATCHPAD_SWITCH_TO_PAGE', payload: target, }); }; return ( 1} minSize={50} maxSize={50}>
{Object.keys(pages).map((key) => { const Component = pages[key].icon; return (
switchToPage(key)} >
); })}
{Object.keys(pages).map((key) => { const Component = pages[key].component; return (
); })}
); }