[extension] Problem panel
This commit is contained in:
parent
5d48bd0b37
commit
234ce83d9d
@ -1,6 +1,7 @@
|
||||
import * as vscode from 'vscode';
|
||||
import { getNonce } from './getNonce';
|
||||
import { cloneAndOpenRepo } from './extension';
|
||||
import { BWPanel } from './problemPanel';
|
||||
|
||||
export class SidebarProvider implements vscode.WebviewViewProvider {
|
||||
_view?: vscode.WebviewView;
|
||||
@ -24,6 +25,12 @@ export class SidebarProvider implements vscode.WebviewViewProvider {
|
||||
|
||||
webviewView.webview.onDidReceiveMessage(async (data) => {
|
||||
switch (data.type) {
|
||||
case 'onTestAndSubmit': {
|
||||
if (this._context) {
|
||||
BWPanel.createOrShow(this._context?.extensionUri, this._context);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'onStartup': {
|
||||
const token: string | undefined = this._context?.globalState.get('token');
|
||||
if (token) {
|
||||
|
@ -2,6 +2,7 @@ import * as vscode from 'vscode';
|
||||
import { SidebarProvider } from './SidebarProvider';
|
||||
import * as child_process from 'child_process';
|
||||
import * as fs from 'fs-extra';
|
||||
import { BWPanel } from './problemPanel';
|
||||
|
||||
interface BWContestSettings {
|
||||
repoBaseUrl: string;
|
||||
@ -42,7 +43,9 @@ export async function cloneAndOpenRepo(contestId: number, teamId: number) {
|
||||
fs.mkdirSync(`${currentSettings.repoClonePath}/BWContest/${contestId.toString()}`);
|
||||
}
|
||||
|
||||
const clonedRepoPath = `${currentSettings.repoClonePath}/BWContest/${contestId.toString()}/${repoName}`;
|
||||
const clonedRepoPath = `${
|
||||
currentSettings.repoClonePath
|
||||
}/BWContest/${contestId.toString()}/${repoName}`;
|
||||
|
||||
if (fs.existsSync(clonedRepoPath)) {
|
||||
const confirm = await vscode.window.showWarningMessage(
|
||||
@ -88,7 +91,11 @@ export function activate(context: vscode.ExtensionContext) {
|
||||
vscode.window.registerWebviewViewProvider('bwcontest-sidebar', sidebarProvider)
|
||||
);
|
||||
|
||||
context.subscriptions.push(vscode.commands.registerCommand('bwcontest.helloWorld', () => {}));
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand('bwcontest.helloWorld', () => {
|
||||
BWPanel.createOrShow(context.extensionUri, context);
|
||||
})
|
||||
);
|
||||
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand('bwcontest.askQuestion', async () => {
|
||||
|
@ -12,8 +12,10 @@ export class BWPanel {
|
||||
private readonly _panel: vscode.WebviewPanel;
|
||||
private readonly _extensionUri: vscode.Uri;
|
||||
private _disposables: vscode.Disposable[] = [];
|
||||
private static _context?: vscode.ExtensionContext;
|
||||
|
||||
public static createOrShow(extensionUri: vscode.Uri) {
|
||||
public static createOrShow(extensionUri: vscode.Uri, context: vscode.ExtensionContext) {
|
||||
this._context = context;
|
||||
const column = vscode.window.activeTextEditor
|
||||
? vscode.window.activeTextEditor.viewColumn
|
||||
: undefined;
|
||||
@ -99,6 +101,17 @@ export class BWPanel {
|
||||
this._panel.webview.html = this._getHtmlForWebview(webview);
|
||||
webview.onDidReceiveMessage(async (data) => {
|
||||
switch (data.type) {
|
||||
case 'onStartup': {
|
||||
const token: string | undefined = BWPanel._context?.globalState.get('token');
|
||||
|
||||
if (token) {
|
||||
this._panel.webview.postMessage({
|
||||
type: 'onSession',
|
||||
value: token
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'onInfo': {
|
||||
if (!data.value) {
|
||||
return;
|
||||
@ -125,7 +138,7 @@ export class BWPanel {
|
||||
private _getHtmlForWebview(webview: vscode.Webview) {
|
||||
// // And the uri we use to load this script in the webview
|
||||
const scriptUri = webview.asWebviewUri(
|
||||
vscode.Uri.joinPath(this._extensionUri, 'out/compiled', 'HelloWorld.js')
|
||||
vscode.Uri.joinPath(this._extensionUri, 'out/compiled', 'problemPanel.js')
|
||||
);
|
||||
|
||||
// Uri to load styles into webview
|
||||
@ -135,9 +148,9 @@ export class BWPanel {
|
||||
const stylesMainUri = webview.asWebviewUri(
|
||||
vscode.Uri.joinPath(this._extensionUri, 'media', 'vscode.css')
|
||||
);
|
||||
// const cssUri = webview.asWebviewUri(
|
||||
// vscode.Uri.joinPath(this._extensionUri, 'out', 'compiled/swiper.css')
|
||||
// );
|
||||
const cssUri = webview.asWebviewUri(
|
||||
vscode.Uri.joinPath(this._extensionUri, 'out/compiled', 'problemPanel.css')
|
||||
);
|
||||
|
||||
// // Use a nonce to only allow specific scripts to be run
|
||||
const nonce = getNonce();
|
||||
@ -154,6 +167,10 @@ export class BWPanel {
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link href="${stylesResetUri}" rel="stylesheet">
|
||||
<link href="${stylesMainUri}" rel="stylesheet">
|
||||
<link href="${cssUri}" rel="stylesheet">
|
||||
<script nonce="${nonce}">
|
||||
const vscode = acquireVsCodeApi();
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
@ -1,4 +0,0 @@
|
||||
<script lang="ts">
|
||||
</script>
|
||||
|
||||
<h1>Test!</h1>
|
110
extension/bwcontest/webviews/components/ProblemPanel.svelte
Normal file
110
extension/bwcontest/webviews/components/ProblemPanel.svelte
Normal file
@ -0,0 +1,110 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from "svelte";
|
||||
|
||||
function postMessage(message: any) {
|
||||
vscode.postMessage(message);
|
||||
}
|
||||
|
||||
type ProblemData = {
|
||||
id: number,
|
||||
name: string,
|
||||
sampleInput: string,
|
||||
sampleOutput: string
|
||||
}[];
|
||||
|
||||
let activeProblem: ProblemData[0];
|
||||
let sessionToken: string | undefined;
|
||||
let problemData: ProblemData | undefined;
|
||||
|
||||
let sampleInputText: HTMLTextAreaElement;
|
||||
|
||||
$: if (problemData && problemData.length !== 0) {
|
||||
let first = problemData.at(0);
|
||||
if (first) {
|
||||
activeProblem = first;
|
||||
}
|
||||
};
|
||||
|
||||
function resetInput() {
|
||||
sampleInputText.value = activeProblem.sampleInput;
|
||||
}
|
||||
|
||||
async function fetchProblemData() {
|
||||
if (sessionToken) {
|
||||
const res = await fetch(`http://localhost:5173/api/contest/${sessionToken}`);
|
||||
const data = await res.json();
|
||||
if (data.success === true) {
|
||||
problemData = data.problems as ProblemData;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener("message", async (event) => {
|
||||
const message = (event as MessageEvent).data;
|
||||
if (message.type === "onSession") {
|
||||
if (message.value !== "") {
|
||||
sessionToken = message.value;
|
||||
await fetchProblemData();
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
onMount(() => {
|
||||
postMessage({type: "onStartup"});
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<h1>Test & Submit Problems</h1>
|
||||
|
||||
{#if problemData}
|
||||
<div class="tab-container">
|
||||
{#each problemData as problem}
|
||||
<button on:click={() => {
|
||||
activeProblem = problem;
|
||||
}} id={`problem_${problem.id}`} type="button" class={"tab " + (activeProblem.id == problem.id ? "active" : "")}>{problem.name}</button>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if activeProblem}
|
||||
<h2>{activeProblem.name}</h2>
|
||||
<div style="display:flex">
|
||||
<div style="flex:1; margin-right:20px">
|
||||
<h3>Sample Input (You can edit this!)</h3>
|
||||
<textarea bind:this={sampleInputText}>{activeProblem.sampleInput}</textarea>
|
||||
<button style="margin-top:5px" on:click={resetInput} type="button">Reset Input</button>
|
||||
</div>
|
||||
<div style="flex:1">
|
||||
<h3>Output</h3>
|
||||
<textarea disabled>{activeProblem.sampleOutput}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
textarea {
|
||||
resize: vertical;
|
||||
height: 250px;
|
||||
}
|
||||
|
||||
.tab-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 30px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.tab {
|
||||
flex: 1;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.tab.active {
|
||||
background-color: rgb(95, 103, 118);
|
||||
}
|
||||
</style>
|
@ -86,6 +86,10 @@
|
||||
}
|
||||
})
|
||||
|
||||
function onTestAndSubmit() {
|
||||
postMessage({type: 'onTestAndSubmit'});
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
postMessage({type: "onStartup"});
|
||||
})
|
||||
@ -107,5 +111,6 @@
|
||||
<p>TeamID: {teamData.teamId}</p>
|
||||
<p>ContestID: {teamData.contestId}</p>
|
||||
<button on:click={onClone}>Clone and Open Repo</button>
|
||||
<button on:click={onTestAndSubmit}>Test & Submit</button>
|
||||
{/if}
|
||||
{/if}
|
@ -1,4 +1,4 @@
|
||||
import App from '../components/HelloWorld.svelte';
|
||||
import App from '../components/ProblemPanel.svelte';
|
||||
|
||||
const app = new App({
|
||||
target: document.body
|
Loading…
Reference in New Issue
Block a user