import React, { Component } from 'react'; import './index.scss' import Container from '../container' import Terminal from '../terminal' import AceEditor from 'react-ace' import 'ace-builds/src-min-noconflict/theme-dracula' import 'ace-builds/src-min-noconflict/mode-python' import StatusBar from './status-bar' import { http } from "@/utils" import { Toast } from "antd-mobile"; import { questionType } from '../consts' const {First, Normal, Pass, Error, InputTip, Skipped, Finished} = StatusBar class Program extends Component { userEditor = null icon = 'https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/interactive_tutorial/study/program-icon.png' ws = null state = { editorWidth: '', showTerminal: false, code: '', answer: '', showAnswer: false, result: '', filename: '', executing: false, } componentDidMount() { const contentElem = document.querySelector('.container .content') const contentStyles = window.getComputedStyle(contentElem) const contentWidth = contentElem.clientWidth const contentPaddingLeft = parseFloat(contentStyles.getPropertyValue('padding-left')) const {type, code_ques, content, user_answer} = this.props.question let code = content let answer = '', result = '', showTerminal = false if (type === questionType.program) { code = code_ques.code answer = code_ques.answer if (user_answer && user_answer.is_finish && user_answer.result) { result = user_answer.result showTerminal = true } } this.setState({ editorWidth: `${contentWidth - contentPaddingLeft}px`, code, answer, result, showTerminal, }) } onLoad = editor => { this.userEditor = editor } execute = () => { // this.getAuthenticationData() this.uploadCode().then(filename => { this.setState({ filename, executing: true, showTerminal: true, }) }) } uploadCode = () => { return http.post(`${API.home}/web/python/practice/file`, { code: this.userEditor.getValue(), }).then(res => { const {code, msg, data} = res.data if (code === 200) { return data.filename } else { Toast.fail(msg, 2) } }) } render() { const {editorWidth, showTerminal, code, answer, showAnswer, result, executing, filename} = this.state const {user, question: {type, user_answer, content}, isProgramShowed} = this.props return ( <> { content && type !== questionType.codeBlock && <Container content={content}></Container> } <Container user={this.icon} content={ <div className="program"> <AceEditor name={'ace-editor'} mode={'python'} theme={'dracula'} readOnly={true} value={code} width={editorWidth} height={'141px'} onLoad={this.onLoad} /> { showAnswer && <AceEditor name={'ace-editor'} mode={'python'} theme={'dracula'} readOnly={true} value={answer} width={editorWidth} height={'141px'} /> } { type !== questionType.codeBlock && <ToolBar isProgramShowed={isProgramShowed} userAnswer={user_answer} execute={this.execute}/> } { showTerminal && <Terminal result={result} executing={executing} filename={filename}/> } </div> } /> </> ); } } function ToolBar({isProgramShowed, userAnswer, isSuccessful, execute}) { if (userAnswer && userAnswer.is_finish) { if (userAnswer.is_jump) { return <Skipped/> } return <Finished/> } return isProgramShowed > 1 ? <Normal/> : <First execute={execute}/> } export default Program;