You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
165 lines
4.7 KiB
165 lines
4.7 KiB
/*
|
|
* @Description: 抽取代码编辑器
|
|
* @Author: tangjiang
|
|
* @Github:
|
|
* @Date: 2019-11-27 15:02:52
|
|
* @LastEditors: tangjiang
|
|
* @LastEditTime: 2019-12-13 16:16:56
|
|
*/
|
|
import './index.scss';
|
|
import React, { useState, useRef, useEffect } from 'react';
|
|
import { Drawer, Modal } from 'antd';
|
|
import { fromStore } from 'educoder';
|
|
import { connect } from 'react-redux';
|
|
import MonacoEditor from '@monaco-editor/react';
|
|
import SettingDrawer from '../../components/monacoSetting';
|
|
import CONST from '../../../../constants';
|
|
import MyIcon from '../../../../common/components/MyIcon';
|
|
|
|
// import actions from '../../../../redux/actions';
|
|
|
|
const { fontSetting, opacitySetting } = CONST;
|
|
|
|
function MyMonacoEditor (props, ref) {
|
|
|
|
const {
|
|
language,
|
|
identifier,
|
|
showOrHideControl,
|
|
// saveUserInputCode,
|
|
onCodeChange,
|
|
onRestoreInitialCode
|
|
} = props;
|
|
|
|
const [showDrawer, setShowDrawer] = useState(false); // 控制配置滑框
|
|
const [editCode, setEditCode] = useState('');
|
|
// const [curLang, setCurLang] = useState('C');
|
|
const [fontSize, setFontSize] = useState(() => { // 字体
|
|
return +fromStore('oj_fontSize') || 14;
|
|
});
|
|
const [theme, setTheme] = useState(() => { // 主题 theme
|
|
return fromStore('oj_theme') || 'dark';
|
|
});
|
|
const [ height, setHeight ] = useState('calc(100% - 56px)');
|
|
const editorRef = useRef(null);
|
|
|
|
useEffect(() => {
|
|
if (props.code) {
|
|
setEditCode(props.code);
|
|
}
|
|
}, [props]);
|
|
|
|
useEffect(() => {
|
|
setHeight(showOrHideControl ? 'calc(100% - 382px)' : 'calc(100% - 56px)');
|
|
}, [showOrHideControl]);
|
|
|
|
// 控制侧边栏设置的显示
|
|
const handleShowDrawer = () => {
|
|
setShowDrawer(true);
|
|
}
|
|
// 关闭设置
|
|
const handleDrawerClose = () => {
|
|
setShowDrawer(false);
|
|
}
|
|
// 侧边栏改变字体大小
|
|
const handleChangeFontSize = (value) => {
|
|
setFontSize(value);
|
|
}
|
|
// 改变主题
|
|
const handleChangeTheme = (value) => {
|
|
setTheme(value);
|
|
}
|
|
|
|
// 文本框内容变化时,记录文本框内容
|
|
const handleEditorChange = (origin, monaco) => {
|
|
editorRef.current = monaco; // 获取当前monaco实例
|
|
setEditCode(origin); // 保存编辑器初始值
|
|
editorRef.current.onDidChangeModelContent(e => { // 监听编辑器内容的变化
|
|
// TODO 需要优化 节流
|
|
const val = editorRef.current.getValue();
|
|
setEditCode(val);
|
|
onCodeChange(val);
|
|
// 值一变化保存当前代码值
|
|
// saveUserInputCode(val);
|
|
});
|
|
}
|
|
|
|
// 配置编辑器属性
|
|
const editorOptions = {
|
|
selectOnLineNumbers: true,
|
|
automaticLayout: true,
|
|
fontSize: `${fontSize}px`
|
|
}
|
|
|
|
// 恢复初始代码
|
|
const handleRestoreCode = () => {
|
|
Modal.confirm({
|
|
content: '确定要恢复代码吗?',
|
|
okText: '确定',
|
|
cancelText: '取消',
|
|
onOk () {
|
|
onRestoreInitialCode && onRestoreInitialCode();
|
|
}
|
|
})
|
|
}
|
|
|
|
const renderRestore = identifier ? (
|
|
<MyIcon type="iconzaicizairu" />
|
|
) : '';
|
|
return (
|
|
<React.Fragment>
|
|
<div className={"monaco_editor_area"}>
|
|
<div className="code_title">
|
|
{/* 未保存时 ? '学员初始代码文件' : main.x */}
|
|
<span className='flex_strict' style={{ color: '#fff'}}>{identifier ? '' : '学员初始代码文件'}</span>
|
|
<span className='flex_strict'>{identifier ? '已保存' : ''}</span>
|
|
<span onClick={handleRestoreCode} className="flex_normal">{renderRestore}</span>
|
|
{/* <Icon className={'code-icon'} type="setting" onClick={handleShowDrawer}/> */}
|
|
<MyIcon className='code-icon' type="iconshezhi" onClick={handleShowDrawer}/>
|
|
</div>
|
|
<MonacoEditor
|
|
height={height}
|
|
width="100%"
|
|
language={language && language.toLowerCase()}
|
|
value={editCode}
|
|
options={editorOptions}
|
|
theme={theme} // dark || light
|
|
editorDidMount={handleEditorChange}
|
|
/>
|
|
</div>
|
|
|
|
<Drawer
|
|
className={'setting_drawer'}
|
|
placement="right"
|
|
closable={false}
|
|
onClose={handleDrawerClose}
|
|
visible={showDrawer}
|
|
>
|
|
<SettingDrawer
|
|
{...fontSetting}
|
|
onChangeFontSize={handleChangeFontSize}
|
|
onChangeTheme={handleChangeTheme}
|
|
/>
|
|
<SettingDrawer {...opacitySetting}/>
|
|
</Drawer>
|
|
</React.Fragment>
|
|
)
|
|
};
|
|
|
|
const mapStateToProps = (state) => {
|
|
const { showOrHideControl } = state.commonReducer;
|
|
return {
|
|
showOrHideControl
|
|
}
|
|
};
|
|
|
|
const mapDispatchToProps = (dispatch) => ({
|
|
// saveUserInputCode: (code) => dispatch(actions.saveUserInputCode(code)),
|
|
});
|
|
|
|
// MyMonacoEditor = React.forwardRef(MyMonacoEditor);
|
|
export default connect(
|
|
mapStateToProps,
|
|
mapDispatchToProps
|
|
)(MyMonacoEditor);
|