diff --git a/public/react/package.json b/public/react/package.json index 7b00881d5..19b8286d9 100644 --- a/public/react/package.json +++ b/public/react/package.json @@ -3,6 +3,8 @@ "version": "0.1.0", "private": true, "dependencies": { + "@novnc/novnc": "^1.1.0", + "@flatten/array": "^1.1.7", "@icedesign/base": "^0.2.5", "antd": "^3.6.5", diff --git a/public/react/src/modules/page/Index.js b/public/react/src/modules/page/Index.js index 7d89462b9..5a37c8c66 100644 --- a/public/react/src/modules/page/Index.js +++ b/public/react/src/modules/page/Index.js @@ -223,6 +223,10 @@ class Index extends Component { challenge={context.challenge} myshixun={context.myshixun} shixun={context.shixun} + + vnc_url={context.vnc_url} + zip_path={context.zip_path} + loading={context.loading} discusses_count={context.discusses_count} hide_code={context.hide_code} diff --git a/public/react/src/modules/page/MainContent.js b/public/react/src/modules/page/MainContent.js index bfe53f0ac..c49b037f9 100644 --- a/public/react/src/modules/page/MainContent.js +++ b/public/react/src/modules/page/MainContent.js @@ -13,6 +13,7 @@ import ChooseEvaluateView from './main/ChooseEvaluateView' import { CircularProgress } from 'material-ui/Progress'; import Button from 'material-ui/Button'; +import VNCDisplay from './VNCDisplay' import './tpiPage.css'; import './tpiPageForMobile.css'; @@ -32,7 +33,7 @@ class MainContent extends Component { } render() { const { challenge, output_sets, onRunCodeTest, latest_output, record, st, readRepoTimeout, - onTestSetHeaderClick, loading, codeLoading } = this.props + onTestSetHeaderClick, loading, codeLoading, shixun} = this.props // if (output_sets && output_sets.test_sets) { // const test_sets_array = JSON.parse("[" + output_sets.test_sets + "]"); @@ -47,6 +48,9 @@ class MainContent extends Component { } const newProps = Object.assign({}, this.props); delete newProps.testSetsExpandedArray + + const showIframeContent = shixun && shixun.vnc == true + return (
+ id="game_left_contents" style={{ width: '35%'}}> {/* style={{width: '694px'}} */} {/* 左侧任务说明等功能的区域 */} @@ -82,6 +86,10 @@ class MainContent extends Component {
*/} + {/* { showIframeContent && vnc_url ? */} +
diff --git a/public/react/src/modules/page/MainContentContainer.js b/public/react/src/modules/page/MainContentContainer.js index 7595f933d..daa4b65b6 100644 --- a/public/react/src/modules/page/MainContentContainer.js +++ b/public/react/src/modules/page/MainContentContainer.js @@ -237,6 +237,10 @@ class MainContentContainer extends Component { // arg_path 点击文件目录树时,传入的点击节点对应的path fetchRepositoryCode( props, arg_path, type, isRetry) { const { challenge, showSnackbar, game, shixun, myshixun, hide_code } = props ? props : this.props; + if (shixun.vnc == true) { + // vnc模式下不需要加载代码 + return true; + } if ( // true || hide_code) { // 隐藏code的实训 diff --git a/public/react/src/modules/page/VNCDisplay.js b/public/react/src/modules/page/VNCDisplay.js new file mode 100644 index 000000000..b8840fe02 --- /dev/null +++ b/public/react/src/modules/page/VNCDisplay.js @@ -0,0 +1,154 @@ +// import React, { Component } from 'react'; + +// import RFB from '@novnc/novnc/lib/rfb.js'; + +// const $ = window.$; +// // const showIframeContent = window.location.search.indexOf('vnc=1') != -1; +// class VNCDisplay extends Component { +// componentDidMount() { +// console.log(RFB) + +// let rfb; +// let desktopName; +// // When this function is called we have +// // successfully connected to a server +// function connectedToServer(e) { +// status("Connected to " + desktopName); +// } +// // This function is called when we are disconnected +// function disconnectedFromServer(e) { +// if (e.detail.clean) { +// status("Disconnected"); +// } else { +// status("Something went wrong, connection is closed"); +// } +// } +// // When this function is called, the server requires +// // credentials to authenticate +// function credentialsAreRequired(e) { +// const password = prompt("Password Required:"); +// rfb.sendCredentials({ password: password }); +// } +// // When this function is called we have received +// // a desktop name from the server +// function updateDesktopName(e) { +// desktopName = e.detail.name; +// } +// // Since most operating systems will catch Ctrl+Alt+Del +// // before they get a chance to be intercepted by the browser, +// // we provide a way to emulate this key sequence. +// function sendCtrlAltDel() { +// rfb.sendCtrlAltDel(); +// return false; +// } +// // Show a status text in the top bar +// function status(text) { +// document.getElementById('status').textContent = text; +// } +// // This function extracts the value of one variable from the +// // query string. If the variable isn't defined in the URL +// // it returns the default value instead. +// function readQueryVariable(name, defaultValue) { +// // A URL with a query parameter can look like this: +// // https://www.example.com?myqueryparam=myvalue +// // +// // Note that we use location.href instead of location.search +// // because Firefox < 53 has a bug w.r.t location.search +// const re = new RegExp('.*[?&]' + name + '=([^&#]*)'), +// match = document.location.href.match(re); +// if (typeof defaultValue === 'undefined') { defaultValue = null; } +// if (match) { +// // We have to decode the URL since want the cleartext value +// return decodeURIComponent(match[1]); +// } +// return defaultValue; +// } +// document.getElementById('sendCtrlAltDelButton') +// .onclick = sendCtrlAltDel; +// // Read parameters specified in the URL query string +// // By default, use the host and port of server that served this file + +// // const host = readQueryVariable('host', window.location.hostname); +// // let port = readQueryVariable('port', window.location.port); +// // const password = readQueryVariable('password', ''); + +// const { vnc_url } = this.props; +// // http://117.50.12.63:43149/vnc_lite.html?password=headless +// let _ar1 = vnc_url.split('/'); +// let ipAndPort = _ar1[2].split(':') +// let passwordAr = _ar1[3].split('password=') +// const host = ipAndPort[0] +// let port = ipAndPort[1] +// const password = passwordAr[1].split('&')[0] + +// const path = readQueryVariable('path', 'websockify'); +// // | | | | | | +// // | | | Connect | | | +// // v v v v v v +// status("Connecting"); +// // Build the websocket URL used to connect +// let url; +// if (vnc_url.indexOf("https:") != -1) { +// url = 'wss'; +// } else { +// url = 'ws'; +// } +// url += '://' + host; +// if(port) { +// url += ':' + port; +// } +// url += '/' + path; +// // Creating a new RFB object will start a new connection +// rfb = new RFB(document.getElementById('screen'), url, +// { credentials: { password: password } }); +// // Add listeners to important events from the RFB module +// rfb.addEventListener("connect", connectedToServer); +// rfb.addEventListener("disconnect", disconnectedFromServer); +// rfb.addEventListener("credentialsrequired", credentialsAreRequired); +// rfb.addEventListener("desktopname", updateDesktopName); +// // Set parameters that can be changed on an active connection +// rfb.viewOnly = readQueryVariable('view_only', false); +// rfb.scaleViewport = readQueryVariable('scale', false); +// } + +// render() { +// const { challenge, vnc_url } = this.props + + +// return ( +//
+// +//
+//
Loading
+//
Send CtrlAltDel
+//
+//
+//
+// ); +// } +// } + +// export default VNCDisplay;