mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-17 09:36:08 +08:00
ui: add editor setting (#622)
This commit is contained in:
1 parent
3615d13ce2
commit
2dabe3194e
4 files changed
+100
-1
No files matched your search
@@ -8,11 +8,16 @@ interface ScratchpadOptions {
|
||||
value?: string;
|
||||
language?: string;
|
||||
handleUpdateCode?: (str: string, event: monaco.editor.IModelContentChangedEvent) => void;
|
||||
settings?: any;
|
||||
pendingCommand?: string;
|
||||
commandDone?: () => void;
|
||||
}
|
||||
|
||||
export default connect((state: any) => ({
|
||||
value: state.editor.code,
|
||||
language: window.LANGS[state.editor.lang]?.monaco,
|
||||
settings: state.ui.settings.config,
|
||||
pendingCommand: state.ui.pendingCommand,
|
||||
}), (dispatch) => ({
|
||||
handleUpdateCode: (code: string) => {
|
||||
dispatch({
|
||||
@@ -20,6 +25,12 @@ export default connect((state: any) => ({
|
||||
payload: code,
|
||||
});
|
||||
},
|
||||
commandDone: () => {
|
||||
dispatch({
|
||||
type: 'SCRATCHPAD_TRIGGER_EDITOR_COMMAND',
|
||||
payload: { command: '' },
|
||||
});
|
||||
},
|
||||
}))(class MonacoEditor extends React.PureComponent<ScratchpadOptions> {
|
||||
disposable: monaco.IDisposable[] = [];
|
||||
__prevent_trigger_change_event = false;
|
||||
@@ -36,8 +47,8 @@ export default connect((state: any) => ({
|
||||
if (this.containerElement) {
|
||||
const config: monaco.editor.IStandaloneEditorConstructionOptions = {
|
||||
theme: 'vs-light',
|
||||
...customOptions,
|
||||
fontFamily: UserContext.codeFontFamily,
|
||||
...customOptions,
|
||||
lineNumbers: 'on',
|
||||
glyphMargin: true,
|
||||
lightbulb: { enabled: true },
|
||||
@@ -88,6 +99,14 @@ export default connect((state: any) => ({
|
||||
this.model = monaco.editor.getModel(uri) || monaco.editor.createModel(val, language, uri);
|
||||
editor.setModel(this.model);
|
||||
}
|
||||
if (editor && this.props.settings) {
|
||||
editor.updateOptions(this.props.settings);
|
||||
}
|
||||
if (this.props.pendingCommand) {
|
||||
editor.focus();
|
||||
editor.getAction(this.props.pendingCommand)?.run();
|
||||
this.props.commandDone();
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
import React from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { i18n } from 'vj/utils';
|
||||
import { RootState } from './reducers';
|
||||
|
||||
export default function ScratchpadSettings() {
|
||||
const config = useSelector((state: RootState) => state.ui.settings.config);
|
||||
const parsed = React.useMemo(() => {
|
||||
const settings = { fontSize: 14, tabSize: 4 };
|
||||
try {
|
||||
Object.assign(settings, config);
|
||||
} catch (e) { }
|
||||
return settings;
|
||||
}, [config]);
|
||||
const dispatch = useDispatch();
|
||||
function dispatcher(setting: string, numeric = false) {
|
||||
return (ev) => {
|
||||
const val = ev?.target?.value || ev;
|
||||
dispatch({ type: 'SCRATCHPAD_SETTING_UPDATE', payload: { setting, value: numeric ? +val : val } });
|
||||
};
|
||||
}
|
||||
function openThemeSelect() {
|
||||
dispatch({ type: 'SCRATCHPAD_TRIGGER_EDITOR_COMMAND', payload: { command: 'hydro.changeEditorTheme' } });
|
||||
}
|
||||
// TODO update style
|
||||
return <div>
|
||||
<div className="row"><div className="medium-6 columns">
|
||||
<label>
|
||||
{i18n('Font size')}:
|
||||
<div className="textbox-container">
|
||||
<input type="number" step="1" value={parsed.fontSize} onChange={dispatcher('fontSize', true)} className="textbox" />
|
||||
</div>
|
||||
</label>
|
||||
</div></div>
|
||||
<div className="row"><div className="medium-6 columns">
|
||||
<label>
|
||||
{i18n('Tab size')}:
|
||||
<div className="textbox-container">
|
||||
<input type="number" step="1" value={parsed.tabSize} onChange={dispatcher('tabSize', true)} className="textbox" />
|
||||
</div>
|
||||
</label>
|
||||
</div></div>
|
||||
<div className="row"><div className="columns">
|
||||
<p>{i18n('Theme')}: </p>
|
||||
<button className="rounded primary button" onClick={openThemeSelect}>{i18n('Open theme select')}</button>
|
||||
</div></div>
|
||||
</div>;
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import ProblemIcon from '@vscode/codicons/src/icons/file.svg?react';
|
||||
import SettingsIcon from '@vscode/codicons/src/icons/settings-gear.svg?react';
|
||||
import { Allotment } from 'allotment';
|
||||
import $ from 'jquery';
|
||||
import _ from 'lodash';
|
||||
@@ -10,6 +11,7 @@ import { Context, ctx, Service } from 'vj/context';
|
||||
import ScratchpadEditor from './ScratchpadEditorContainer';
|
||||
import ScratchpadPretest from './ScratchpadPretestContainer';
|
||||
import ScratchpadRecords from './ScratchpadRecordsContainer';
|
||||
import ScratchpadSettings from './ScratchpadSettings';
|
||||
import ScratchpadToolbar from './ScratchpadToolbarContainer';
|
||||
|
||||
const pages = {
|
||||
@@ -17,6 +19,10 @@ const pages = {
|
||||
icon: () => <ProblemIcon />,
|
||||
component: () => <Dom childDom={$('.problem-content').get(0)} />,
|
||||
},
|
||||
settings: {
|
||||
icon: () => <SettingsIcon />,
|
||||
component: () => <ScratchpadSettings />,
|
||||
},
|
||||
};
|
||||
|
||||
let rerenderCallback = null;
|
||||
|
||||
@@ -11,11 +11,16 @@ export default function reducer(state = {
|
||||
visible: UiContext.canViewRecord && localStorage.getItem('scratchpad/records') === 'true',
|
||||
isLoading: false,
|
||||
},
|
||||
settings: {
|
||||
visible: false,
|
||||
config: JSON.parse(localStorage.getItem('editor.config') || '{}'),
|
||||
},
|
||||
isPosting: false,
|
||||
pretestWaitSec: 0,
|
||||
submitWaitSec: 0,
|
||||
lastTick: 0,
|
||||
activePage: 'problem',
|
||||
pendingCommand: '',
|
||||
}, action: any = {}) {
|
||||
switch (action.type) {
|
||||
case 'SCRATCHPAD_UI_SET_VISIBILITY': {
|
||||
@@ -40,6 +45,27 @@ export default function reducer(state = {
|
||||
},
|
||||
};
|
||||
}
|
||||
case 'SCRATCHPAD_SETTING_UPDATE': {
|
||||
const { setting, value } = action.payload;
|
||||
const config = {
|
||||
...state.settings.config,
|
||||
[setting]: value,
|
||||
};
|
||||
localStorage.setItem('editor.config', JSON.stringify(config));
|
||||
return {
|
||||
...state,
|
||||
settings: {
|
||||
...state.settings,
|
||||
config,
|
||||
},
|
||||
};
|
||||
}
|
||||
case 'SCRATCHPAD_TRIGGER_EDITOR_COMMAND': {
|
||||
return {
|
||||
...state,
|
||||
pendingCommand: action.payload.command,
|
||||
};
|
||||
}
|
||||
case 'SCRATCHPAD_POST_PRETEST_PENDING':
|
||||
case 'SCRATCHPAD_POST_SUBMIT_PENDING': {
|
||||
return {
|
||||
|
||||
Reference in new issue
Block a user