179 lines
5.8 KiB
TypeScript
179 lines
5.8 KiB
TypeScript
import * as vscode from 'vscode';
|
|
|
|
const BETA_TOOLS_ENABLED_KEY = 'hplToolbox.betaTools.enabled';
|
|
|
|
interface ToolDefinition {
|
|
command: string;
|
|
title: string;
|
|
description: string;
|
|
beta?: boolean;
|
|
}
|
|
|
|
const TOOLS: ToolDefinition[] = [
|
|
{
|
|
command: 'hplToolbox.openPlecUpload',
|
|
title: 'PLEC Upload',
|
|
description: 'Upload HTML to internal PLEC server',
|
|
},
|
|
{
|
|
command: 'hplToolbox.openApplovinUpload',
|
|
title: 'AppLovin Playable Preview',
|
|
description: 'Upload to p.applov.in (QR preview)',
|
|
},
|
|
{
|
|
command: 'hplToolbox.openBase64Scanner',
|
|
title: 'Base64 Scanner',
|
|
description: 'Find non-base64 assets in HTML',
|
|
},
|
|
{
|
|
command: 'hplToolbox.openMraidChecker',
|
|
title: 'MRAID Checker',
|
|
description: 'Check MRAID requirements and best practices',
|
|
beta: true,
|
|
},
|
|
{
|
|
command: 'hplToolbox.openSendToMobile',
|
|
title: 'Send To Mobile',
|
|
description: 'Share HTML to a phone via LAN + QR',
|
|
},
|
|
{
|
|
command: 'hplToolbox.openPlayworksConverter',
|
|
title: 'Playworks Converter',
|
|
description: 'Convert Playworks HTML to per-network variants',
|
|
beta: true,
|
|
},
|
|
];
|
|
|
|
export class LauncherViewProvider implements vscode.WebviewViewProvider {
|
|
constructor(private readonly context: vscode.ExtensionContext) { }
|
|
|
|
resolveWebviewView(view: vscode.WebviewView) {
|
|
view.webview.options = { enableScripts: true };
|
|
const version = this.context.extension.packageJSON.version as string;
|
|
const betaToolsEnabled = this.context.globalState.get<boolean>(BETA_TOOLS_ENABLED_KEY, false);
|
|
view.webview.html = getHtml(version, betaToolsEnabled);
|
|
view.webview.onDidReceiveMessage(async (msg) => {
|
|
if (msg?.type === 'open' && typeof msg.command === 'string') {
|
|
vscode.commands.executeCommand(msg.command);
|
|
} else if (msg?.type === 'setBetaToolsEnabled' && typeof msg.enabled === 'boolean') {
|
|
await this.context.globalState.update(BETA_TOOLS_ENABLED_KEY, msg.enabled);
|
|
view.webview.html = getHtml(version, msg.enabled);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
function getHtml(version: string, betaToolsEnabled: boolean): string {
|
|
const visibleTools = sortToolsForDisplay(TOOLS.filter(tool => betaToolsEnabled || !tool.beta));
|
|
const hiddenBetaCount = TOOLS.filter(tool => tool.beta).length - visibleTools.filter(tool => tool.beta).length;
|
|
const toolButtons = visibleTools.map(renderToolButton).join('\n');
|
|
return `<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<style>
|
|
body {
|
|
min-height: calc(100vh - 24px);
|
|
display: flex;
|
|
flex-direction: column;
|
|
font-family: var(--vscode-font-family);
|
|
color: var(--vscode-foreground);
|
|
padding: 12px 8px;
|
|
}
|
|
.tools { flex: 1; }
|
|
.tool-btn {
|
|
display: block; width: 100%; text-align: left;
|
|
padding: 8px 10px; margin-bottom: 6px;
|
|
background: var(--vscode-button-secondaryBackground);
|
|
color: var(--vscode-button-secondaryForeground);
|
|
border: 1px solid var(--vscode-panel-border);
|
|
border-radius: 3px; cursor: pointer; font-size: 13px;
|
|
}
|
|
.tool-btn:hover {
|
|
background: var(--vscode-button-secondaryHoverBackground);
|
|
}
|
|
.tool-title { display: flex; align-items: center; gap: 6px; }
|
|
.tool-desc { display: block; font-size: 11px; opacity: 0.7; margin-top: 2px; }
|
|
.beta-badge {
|
|
padding: 1px 5px;
|
|
border: 1px solid var(--vscode-panel-border);
|
|
border-radius: 3px;
|
|
color: var(--vscode-descriptionForeground);
|
|
font-size: 10px;
|
|
text-transform: uppercase;
|
|
}
|
|
.beta-toggle {
|
|
margin-top: 12px;
|
|
padding-top: 10px;
|
|
border-top: 1px solid var(--vscode-panel-border);
|
|
}
|
|
.beta-toggle button {
|
|
width: 100%;
|
|
padding: 7px 10px;
|
|
background: var(--vscode-button-secondaryBackground);
|
|
color: var(--vscode-button-secondaryForeground);
|
|
border: 1px solid var(--vscode-panel-border);
|
|
border-radius: 3px;
|
|
cursor: pointer;
|
|
text-align: left;
|
|
}
|
|
.beta-toggle button:hover {
|
|
background: var(--vscode-button-secondaryHoverBackground);
|
|
}
|
|
.beta-note { display: block; margin-top: 3px; color: var(--vscode-descriptionForeground); font-size: 11px; }
|
|
.footer {
|
|
margin-top: 10px;
|
|
color: var(--vscode-descriptionForeground);
|
|
font-size: 8px;
|
|
text-align: right;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="tools">
|
|
${toolButtons}
|
|
</div>
|
|
<div class="beta-toggle">
|
|
<button id="betaToggle" data-enabled="${betaToolsEnabled ? 'true' : 'false'}">
|
|
${betaToolsEnabled ? 'Disable Beta Tools' : 'Enable Beta Tools'}
|
|
<span class="beta-note">${betaToolsEnabled ? 'Beta tools are visible in this launcher.' : `${hiddenBetaCount} beta tool(s) hidden until enabled.`}</span>
|
|
</button>
|
|
</div>
|
|
<div class="footer">${version} - JJGC 00784</div>
|
|
<script>
|
|
const vscode = acquireVsCodeApi();
|
|
document.querySelectorAll('.tool-btn').forEach((btn) => {
|
|
btn.addEventListener('click', () => {
|
|
vscode.postMessage({ type: 'open', command: btn.dataset.cmd });
|
|
});
|
|
});
|
|
document.getElementById('betaToggle').addEventListener('click', (event) => {
|
|
const enabled = event.currentTarget.dataset.enabled === 'true';
|
|
vscode.postMessage({ type: 'setBetaToolsEnabled', enabled: !enabled });
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>`;
|
|
}
|
|
|
|
function sortToolsForDisplay(tools: ToolDefinition[]): ToolDefinition[] {
|
|
return [...tools].sort((a, b) => Number(Boolean(a.beta)) - Number(Boolean(b.beta)));
|
|
}
|
|
|
|
function renderToolButton(tool: ToolDefinition): string {
|
|
return ` <button class="tool-btn" data-cmd="${escapeHtml(tool.command)}">
|
|
<span class="tool-title">${escapeHtml(tool.title)}${tool.beta ? ' <span class="beta-badge">Beta</span>' : ''}</span>
|
|
<span class="tool-desc">${escapeHtml(tool.description)}</span>
|
|
</button>`;
|
|
}
|
|
|
|
function escapeHtml(value: string): string {
|
|
return value.replace(/[&<>"']/g, ch => ({
|
|
'&': '&',
|
|
'<': '<',
|
|
'>': '>',
|
|
'"': '"',
|
|
"'": ''',
|
|
}[ch] ?? ch));
|
|
}
|