Merge branch 'dev_hjm_tpi_float_reader' into dev_aliyun

dev_hss
hjm 5 years ago
commit cebff50e9e

@ -219,6 +219,7 @@ class Index extends Component {
praisePlus={context.praisePlus}
git_url={context.git_url}
mirror_name={context.mirror_name}
challenge={context.challenge}
myshixun={context.myshixun}

@ -13,7 +13,7 @@ import ChooseEvaluateView from './main/ChooseEvaluateView'
import { CircularProgress } from 'material-ui/Progress';
import Button from 'material-ui/Button';
import VNCDisplay from './VNCDisplay'
import VNCContainer from './VNCContainer'
import './tpiPage.css';
import './tpiPageForMobile.css';
@ -94,9 +94,13 @@ class MainContent extends Component {
<div className="fl pr tip-right-con" id="update_game_tip"></div>
</div>*/}
{ showIframeContent && vnc_url ? <VNCDisplay
{ showIframeContent && vnc_url ?
<CodeRepositoryViewContainer { ...this.props } isOnlyContainer={true}>
<VNCContainer
vnc_url={vnc_url}
></VNCDisplay>
{...this.props}
></VNCContainer>
</CodeRepositoryViewContainer>
:
<React.Fragment>

@ -0,0 +1,17 @@
.float_button {
background-image: url(./images/float_switch.jpg);
height: 112px;
width: 38px;
position: absolute;
left: -38px;
top: 32%;
cursor: pointer;
}
.float_button .text {
position: relative;
writing-mode: vertical-rl;
top: 36px;
color: #fff;
left: 13px;
user-select: none;
}

@ -0,0 +1,184 @@
import React, { Component } from 'react';
import axios from 'axios'
import { Spin } from 'antd'
import ClipboardJS from 'clipboard'
import VNCDisplay from './VNCDisplay'
import FloatButton from './component/FloatButton'
import SecondDrawer from './component/SecondDrawer'
import RepoTree from './component/repo/RepoTree'
import TPIMonaco from './component/monaco/TPIMonaco'
import notEditablePathImg from '../../images/tpi/notEditablePath.png'
import './VNC.css'
const $ = window.$;
const firstDrawerWidth = 260;
class VNCContainer extends Component {
constructor(props) {
super(props)
this.state = {
fileTreeSelectedKeys: [],
repositoryCode: ''
}
}
componentDidMount() {
if (!this.clipboard) {
const clipboard = new ClipboardJS('.copybtn');
clipboard.on('success', (e) => {
this.props.showSnackbar('复制成功')
});
this.clipboard = clipboard
}
}
getSecondDrawerWidth = () => {
return $('#game_right_contents').width() - firstDrawerWidth
}
renderSecondDrawerChildren = () => {
const { readingCodeLoading, repositoryCode } = this.state;
const height = $(window).height() - 130
const isEditablePath = false;
return (
<Spin tip="加载中..." spinning={readingCodeLoading}>
<div style={{ height: `${height}px` }}>
<div className="codemirrorBackground"
style={{ backgroundImage: `url('${notEditablePathImg}')`, display: (isEditablePath ? 'none' : 'block') }}></div>
<TPIMonaco
{...this.state}
codeLoading={readingCodeLoading}
repositoryCode={repositoryCode}
isEditablePath={false}
></TPIMonaco>
</div>
</Spin>);
}
fetchReadRepositoryCode = (path) => {
const status = 1
const fetchRepoCodeUrl = `/tasks/${this.props.game.identifier}/rep_content.json?path=${path}&status=${status}`
this.setState({ readingCodeLoading: true });
axios.get(fetchRepoCodeUrl, {
}).then((fetchReadRepositoryCodeResponse) => {
if (fetchReadRepositoryCodeResponse.data.content || fetchReadRepositoryCodeResponse.data.content == "") {
this.setState({
repositoryCode: fetchReadRepositoryCodeResponse.data.content,
readingCodeLoading: false
})
} else {
this.setState({ readingCodeLoading: false });
}
// this.setState({ isEditablePath, currentPath: path });
}).catch(error =>{
console.log(error)
this.setState({ readingCodeLoading: false });
this.props.showSnackbar(`服务端异常,请联系管理员!`);
})
}
onTreeSelect = (selectedKeys, info) => {
const isLeaf = info.node.props.isLeaf;
if (isLeaf) { // 叶子节点
selectedKeys.length && this.setState({
fileTreeSelectedKeys: selectedKeys
})
this.refs["secondDrawer"].showSecondDrawer()
console.log('leaf clicked')
const nodePath = info.node.props.eventKey;
if (nodePath) {
const filetype = nodePath.split('.').pop().toLowerCase();
if (filetype == 'jpg' || filetype == 'png' || filetype == 'gif' || filetype == 'jpeg'
|| filetype == 'jar'
|| filetype == 'doc' || filetype == 'pdf' || filetype == 'xsl' || filetype == 'ppt') {
this.props.showSnackbar(`不支持加载${filetype}类型的文件。`)
return;
}
this.fetchReadRepositoryCode(nodePath);
} else {
console.error('no eventKey:', info.node)
}
}
}
/*
selectedKeys={fileTreeSelectedKeys}
onSelect={onTreeSelect}
*/
render() {
const { challenge, vnc_url, git_url } = this.props
const secondDrawerChildren = this.renderSecondDrawerChildren();
return (
<React.Fragment>
<SecondDrawer
ref="secondDrawer"
floatText={'版本库'}
maskClosable={false}
secondDrawerChildren={secondDrawerChildren}
firstDrawerWidth={firstDrawerWidth}
getSecondDrawerWidth={this.getSecondDrawerWidth}
firstDrawerClassName="repoFilesDrawer vncDrawer"
secondDrawerClassName="codeInDrawer"
>
<style>{`
.vncDrawer .ant-drawer-body {
padding: 0px;
}
.vncDrawer .rc-tree {
padding: 16px;
max-width: 220px;
}
.vncDrawer .ant-drawer-wrapper-body {
background: #242324;
}
.codeInDrawer .ant-drawer-wrapper-body {
background: #1D1C1D;
}
.vncDrawer .ant-drawer-header, .codeInDrawer .ant-drawer-header {
border-bottom: 0;
}
.vncDrawer > div:nth-child(2) {
top: 0px !important;
height: 100% !important;
min-width: unset;
}
.codeInDrawer .ant-spin-nested-loading > div > .ant-spin .ant-spin-text {
text-shadow: none;
}
`}</style>
<div style={{ 'padding': '16px', 'border-bottom': '1px solid #3A383A' }}>
<div style={{ color: '#888888' }}>网址克隆</div>
<div>
<input value={git_url} readonly={true} style={{ color: '#BABABA', width: '190px', background: 'transparent', border: 'none' }}></input>
<i class="iconfont icon-fuzhi font-14 ml10 copybtn"
style={{color: '#4CACFF', cursor: 'pointer', verticalAlign: 'baseline'}} data-clipboard-text={git_url} ></i>
</div>
</div>
<RepoTree
{...this.props}
fileTreeSelectedKeys={this.state.fileTreeSelectedKeys}
onTreeSelect={this.onTreeSelect}
></RepoTree>
</SecondDrawer>
<FloatButton></FloatButton>
<VNCDisplay
{...this.props}
></VNCDisplay>
</React.Fragment>
);
}
}
export default VNCContainer;

@ -0,0 +1,24 @@
import React, { Component } from 'react';
const $ = window.$;
class FloatButton extends Component {
componentDidMount() {
}
render() {
const { challenge, vnc_url, children } = this.props
return (
<div className="float_button" onClick={this.props.onClick}>
<style>{`
`}</style>
<span class="text">{children || '版本库'}</span>
</div>
);
}
}
export default FloatButton;

@ -0,0 +1,100 @@
import React from "react";
import ReactDOM from "react-dom";
import { Drawer } from "antd";
import FloatButton from './FloatButton'
import PropTypes from 'prop-types';
class SecondDrawer extends React.Component {
state = { visible: false, childrenDrawer: false };
showDrawer = () => {
this.setState({
visible: true
});
};
onClose = () => {
this.setState({
visible: false
});
};
showSecondDrawer = () => {
this.setState({
childrenDrawer: true
});
};
onChildrenDrawerClose = () => {
this.setState({
childrenDrawer: false
});
};
swtichFirstDrawer = () => {
this.setState({
visible: !this.state.visible,
childrenDrawer: false
});
};
componentDidMount() {
this.setState({ visible: true }, () => {
this.setState({ visible: false });
});
}
render() {
const { floatText, maskClosable, children, secondDrawerChildren, firstDrawerWidth, getSecondDrawerWidth
,firstDrawerClassName, secondDrawerClassName
} = this.props
const secondDrawerWidth = getSecondDrawerWidth();
// 180 不知道为什么会偏移 180px
return (
<Drawer
// mask={!this.state.visible}
title=" "
width={this.state.childrenDrawer ? secondDrawerWidth + firstDrawerWidth - 180 : firstDrawerWidth}
closable={false}
onClose={this.onClose}
visible={this.state.visible}
maskClosable={maskClosable}
className={firstDrawerClassName}
>
{/* <button type="primary" onClick={this.showSecondDrawer}>
Two-level drawer
</button> */}
<FloatButton onClick={this.swtichFirstDrawer}>{floatText}</FloatButton>
{ children }
<Drawer
mask={false}
title=" "
width={secondDrawerWidth}
closable={false}
onClose={this.onChildrenDrawerClose}
visible={this.state.childrenDrawer}
className={secondDrawerClassName}
>
{ secondDrawerChildren }
{/* <button
style={{
marginRight: 8
}}
onClick={this.onChildrenDrawerClose}
>
Cancel
</button> */}
</Drawer>
</Drawer>
);
}
}
SecondDrawer.propTypes = {
floatText: PropTypes.string,
maskClosable: PropTypes.bool,
secondDrawerChildren: PropTypes.element,
};
// firstDrawerWidth={firstDrawerWidth}
// getSecondDrawerWidth={this.getSecondDrawerWidth}
export default SecondDrawer

@ -271,6 +271,7 @@ class TPIMonaco extends Component {
const lang = getLanguageByMirrorName(this.props.mirror_name);
const editor = window.monaco.editor.create(document.getElementById('extend-challenge-file-edit'), {
value: value,
readOnly: !this.props.isEditablePath,
// 属性说明
// http://testeduplus2.educoder.net/react/build/static/node_modules/_monaco-editor@0.15.6@monaco-editor/esm/vs/editor/common/config/commonEditorConfig.js
// https://github.com/Microsoft/monaco-editor/issues/29
@ -303,7 +304,7 @@ class TPIMonaco extends Component {
notCallCodeMirrorOnChangeFlag = false
return;
}
this.props.onRepositoryCodeUpdate(editor.getValue())
this.props.onRepositoryCodeUpdate && this.props.onRepositoryCodeUpdate(editor.getValue())
})
this.props.codemirrorDidMount && this.props.codemirrorDidMount()

@ -0,0 +1,54 @@
import React, { useState, useEffect, useContext, useRef, memo } from 'react';
// import { Tree } from 'antd';
// const { TreeNode } = Tree;
import Tree, { TreeNode } from 'rc-tree';
import 'rc-tree/assets/index.css';
const $ = window.$;
export default function RepoTree(props) {
const { fileTreeData, onLoadData, onTreeSelect, fileTreeSelectedKeys, loadRepoFiles } = props;
const [expandedKeys, setExpandedKeys] = useState([])
useEffect(() => {
loadRepoFiles()
}, [])
if (!fileTreeData || fileTreeData.length === 0) {
return ""
}
const onExpand = (expandedKeys) => {
// console.log('onExpand', arguments);
// if not set autoExpandParent to false, if children expanded, parent can not collapse.
// or, you can remove all expanded children keys.
setExpandedKeys(expandedKeys)
}
const loop = (data) => {
return data.map((item) => {
if (item.children) {
return <TreeNode title={item.name} key={item.key}>{loop(item.children)}</TreeNode>;
}
return (
<TreeNode title={item.name} key={item.key} isLeaf={item.isLeaf} />
);
});
};
const treeNodes = loop(fileTreeData);
// selectable={false}
return (
<Tree
onExpand={onExpand}
expandedKeys={expandedKeys}
// autoExpandParent={this.state.autoExpandParent}
loadData={onLoadData}
selectedKeys={fileTreeSelectedKeys}
onSelect={onTreeSelect}
>
{treeNodes}
</Tree>
)
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

@ -101,6 +101,11 @@ class CodeRepositoryViewContainer extends Component {
drawerOpen: open,
})
}
loadRepoFiles = () => {
if (!this.state.fileTreeData) {
this.fetchRepoFiles();
}
}
componentWillReceiveProps(newProps, oldProps) {
@ -271,16 +276,32 @@ class CodeRepositoryViewContainer extends Component {
render() {
return (
<React.Fragment>
{this.props.isOnlyContainer == true ?
React.Children.map(this.props.children, child => {
if(!child) {
return ''
}
return React.cloneElement(child, Object.assign({...this.state}, {
loadRepoFiles: this.loadRepoFiles,
onTreeSelect: this.onTreeSelect,
onLoadData: this.onLoadData,
}))
})
:
<CodeRepositoryView {...this.props}
{...this.state}
showFilesDrawer={this.showFilesDrawer}
loadRepoFiles={this.loadRepoFiles}
onLoadData={this.onLoadData}
onTreeSelect={ this.onTreeSelect }
onRepositoryViewExpand={this.onRepositoryViewExpand}
tabIndexChange={this.tabIndexChange}
showSettingDrawer={this.showSettingDrawer}
></CodeRepositoryView>
></CodeRepositoryView> }
</React.Fragment>
);
}
}

Loading…
Cancel
Save