Skip to content

Commit

Permalink
Configure Vite
Browse files Browse the repository at this point in the history
  • Loading branch information
ibolton336 committed Oct 17, 2024
1 parent a586d8e commit 5bec3b1
Show file tree
Hide file tree
Showing 26 changed files with 954 additions and 1,589 deletions.
Binary file removed vscode/assets/kantra
Binary file not shown.
3 changes: 0 additions & 3 deletions vscode/media/styles.css

This file was deleted.

219 changes: 93 additions & 126 deletions vscode/src/KonveyorGUIWebviewViewProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,179 +7,146 @@ import {
WebviewViewProvider,
WebviewViewResolveContext,
Disposable,
window,
Uri,
} from "vscode";
import { getUri } from "./utilities/getUri";
import { Extension } from "./helpers/Extension";
import { getNonce } from "./utilities/getNonce";

export class KonveyorGUIWebviewViewProvider implements WebviewViewProvider {
public static readonly viewType = "konveyor.konveyorGUIView";
private static instance: KonveyorGUIWebviewViewProvider;
private _disposables: Disposable[] = [];
private _view?: WebviewView;
private _webviewView?: WebviewView;
private _isWebviewReady: boolean = false;

constructor(private readonly _extensionState: ExtensionState) {}
private constructor(private readonly _extensionState: ExtensionState) {}

public static getInstance(_extensionState: ExtensionState): KonveyorGUIWebviewViewProvider {
public static getInstance(extensionState: ExtensionState): KonveyorGUIWebviewViewProvider {
if (!KonveyorGUIWebviewViewProvider.instance) {
KonveyorGUIWebviewViewProvider.instance = new KonveyorGUIWebviewViewProvider(_extensionState);
KonveyorGUIWebviewViewProvider.instance = new KonveyorGUIWebviewViewProvider(extensionState);
}

return KonveyorGUIWebviewViewProvider.instance;
}

resolveWebviewView(
public resolveWebviewView(
webviewView: WebviewView,
_context: WebviewViewResolveContext,
_token: CancellationToken,
) {
context: WebviewViewResolveContext,

Check warning on line 33 in vscode/src/KonveyorGUIWebviewViewProvider.ts

View workflow job for this annotation

GitHub Actions / Build (linux)

'context' is defined but never used. Allowed unused args must match /^_/u

Check warning on line 33 in vscode/src/KonveyorGUIWebviewViewProvider.ts

View workflow job for this annotation

GitHub Actions / Build (macos)

'context' is defined but never used. Allowed unused args must match /^_/u

Check warning on line 33 in vscode/src/KonveyorGUIWebviewViewProvider.ts

View workflow job for this annotation

GitHub Actions / Build (windows)

'context' is defined but never used. Allowed unused args must match /^_/u
token: CancellationToken,

Check warning on line 34 in vscode/src/KonveyorGUIWebviewViewProvider.ts

View workflow job for this annotation

GitHub Actions / Build (linux)

'token' is defined but never used. Allowed unused args must match /^_/u

Check warning on line 34 in vscode/src/KonveyorGUIWebviewViewProvider.ts

View workflow job for this annotation

GitHub Actions / Build (macos)

'token' is defined but never used. Allowed unused args must match /^_/u

Check warning on line 34 in vscode/src/KonveyorGUIWebviewViewProvider.ts

View workflow job for this annotation

GitHub Actions / Build (windows)

'token' is defined but never used. Allowed unused args must match /^_/u
): void | Thenable<void> {
this._view = webviewView;

this._view.webview.options = {
webviewView.webview.options = {
enableScripts: true,
localResourceRoots: [this._extensionState.extensionContext.extensionUri],
};

// webviewView.webview.html = getWebviewContent(
// this._extensionState.extensionContext,
// webviewView.webview,
// true,
// );
this._view.webview.html = this._getHtmlForWebview(this._view.webview);
this._setWebviewMessageListener(this._view.webview);

// webviewView.webview.onDidReceiveMessage((message) => {
// if (message.type === "webviewReady") {
// console.log("Webview is ready, setting up message listener");
// setupWebviewMessageListener(webviewView.webview, this.extensionState);

// console.log("Populating webview with stored rulesets");
// this.extensionState.analyzerClient.populateWebviewWithStoredRulesets(webviewView.webview);
// }
// });
}
public dispose() {
while (this._disposables.length) {
const disposable = this._disposables.pop();
if (disposable) {
disposable.dispose();
}
}
webviewView.webview.html = this._getHtmlForWebview(webviewView.webview);
this._setWebviewMessageListener(webviewView.webview);
}

public _getHtmlForWebview(webview: Webview, isFullScreen: boolean = false) {
const file = "src/index.tsx";
const localPort = "5173";
const localServerUrl = `localhost:${localPort}`;

// The CSS file from the React build output
const stylesUri = getUri(webview, this._extensionState.extensionContext.extensionUri, [
"webview-ui",
"build",
"assets",
"index.css",
]);

let scriptUri;
const isProd = Extension.getInstance().isProductionMode;
if (isProd) {
scriptUri = getUri(webview, this._extensionState.extensionContext.extensionUri, [
"webview-ui",
"build",
"assets",
"index.js",
]);
} else {
scriptUri = `http://${localServerUrl}/${file}`;
}

private _getHtmlForWebview(webview: Webview): string {
const stylesUri = this._getUri(webview, ["webview-ui", "build", "assets", "index.css"]);
const scriptUri = this._getScriptUri(webview);
const nonce = getNonce();

const reactRefresh = /*html*/ `
<script type="module">
import RefreshRuntime from "http://localhost:5173/@react-refresh"
RefreshRuntime.injectIntoGlobalHook(window)
window.$RefreshReg$ = () => {}
window.$RefreshSig$ = () => (type) => type
window.__vite_plugin_react_preamble_installed__ = true
</script>`;

const reactRefreshHash = "sha256-YmMpkm5ow6h+lfI3ZRp0uys+EUCt6FOyLkJERkfVnTY=";

const csp = [
`default-src 'none';`,
`script-src 'unsafe-eval' https://* ${
isProd
? `'nonce-${nonce}'`
: `http://${localServerUrl} http://0.0.0.0:${localPort} '${reactRefreshHash}'`
}`,
`style-src ${webview.cspSource} 'self' 'unsafe-inline' https://*`,
`font-src ${webview.cspSource}`,
`connect-src https://* ${
isProd
? ``
: `ws://${localServerUrl} ws://0.0.0.0:${localPort} http://${localServerUrl} http://0.0.0.0:${localPort}`
}`,
];

return /*html*/ `<!DOCTYPE html>
<html lang="en">
return `<!DOCTYPE html>
<html lang="en" class="pf-v6-theme-dark">
<head>
<meta charset="UTF-8" />
<meta http-equiv="Content-Security-Policy" content="${csp.join("; ")}">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="Content-Security-Policy" content="${this._getContentSecurityPolicy(nonce)}">
<link rel="stylesheet" type="text/css" href="${stylesUri}">
<title>VSCode React Starter</title>
<title>Konveyor IDE Extension</title>
</head>
<body>
<div id="root"></div>
${isProd ? "" : reactRefresh}
<script type="module" src="${scriptUri}">
window.addEventListener('load', function() {
window.vscode.postMessage({ type: 'webviewReady', isFullScreen: ${isFullScreen} });
console.log('HTML started up. Full screen:', ${isFullScreen});
});
${this._getReactRefreshScript(nonce)}
<script nonce="${nonce}">
const vscode = acquireVsCodeApi();
window.addEventListener('DOMContentLoaded', function() {
vscode.postMessage({ command: 'webviewReady' });
});
</script>
<script type="module" nonce="${nonce}" src="${scriptUri}"></script>
</body>
</html>`;
}

/**
* Sets up an event listener to listen for messages passed from the webview context and
* executes code based on the message that is recieved.
*
* @param webview A reference to the extension webview
* @param context A reference to the extension context
*/
private _getContentSecurityPolicy(nonce: string): string {
const isProd = false; // Replace with actual production check
const localServerUrl = "localhost:5173";
return [
`default-src 'none';`,
`script-src 'unsafe-eval' https://* ${
isProd ? `'nonce-${nonce}'` : `http://${localServerUrl} 'nonce-${nonce}' 'unsafe-inline'`
};`,
`style-src ${this._view!.webview.cspSource} 'unsafe-inline' https://*;`,
`font-src ${this._view!.webview.cspSource};`,
`connect-src https://* ${isProd ? `` : `ws://${localServerUrl} http://${localServerUrl}`};`,
`img-src https: data:;`,
].join(" ");
}

private _getScriptUri(webview: Webview): Uri {
const isProd = false; // Replace with actual production check
return isProd
? this._getUri(webview, ["webview-ui", "build", "assets", "index.js"])
: Uri.parse("http://localhost:5173/src/index.tsx");
}

private _getReactRefreshScript(nonce: string): string {
const isProd = false; // Replace with actual production check
return isProd
? ""
: `
<script type="module" nonce="${nonce}">
import RefreshRuntime from "http://localhost:5173/@react-refresh"
RefreshRuntime.injectIntoGlobalHook(window)
window.$RefreshReg$ = () => {}
window.$RefreshSig$ = () => (type) => type
window.__vite_plugin_react_preamble_installed__ = true
</script>`;
}

private _getUri(webview: Webview, pathList: string[]): Uri {
return getUri(webview, this._extensionState.extensionContext.extensionUri, pathList);
}

private _setWebviewMessageListener(webview: Webview) {
setupWebviewMessageListener(webview, this._extensionState);

webview.onDidReceiveMessage(
(message: any) => {
const command = message.command;
const text = message.text;

switch (command) {
case "webviewReady": {
console.log("Webview is ready, setting up message listener");
setupWebviewMessageListener(webview, this._extensionState);
console.log("Populating webview with stored rulesets");
this._extensionState.analyzerClient.populateWebviewWithStoredRulesets(webview);
break;
}

case "hello":
// Code that should run in response to the hello message command
window.showInformationMessage(text);
return;
// Add more switch case statements here as more webview message commands
// are created within the webview context (i.e. inside media/main.js)
(message) => {
if (message.command === "webviewReady") {
this._isWebviewReady = true;
this._loadInitialContent();
console.log("Webview is ready");
}
},
undefined,
this._disposables,
);
}

private _loadInitialContent() {
if (this._isWebviewReady && this._view) {
this._extensionState.analyzerClient.populateWebviewWithStoredRulesets(this._view.webview);
this._view.webview.postMessage({
command: "loadInitialData",
data: "Your initial data here",
});
}
}

public dispose() {
while (this._disposables.length) {
const disposable = this._disposables.pop();
if (disposable) {
disposable.dispose();
}
}
}

public get webview(): Webview | undefined {
return this._view?.webview;
}
Expand Down
Loading

0 comments on commit 5bec3b1

Please sign in to comment.