This commit is contained in:
2026-05-27 18:37:52 +08:00
parent 9e82656eeb
commit 698223234d
14 changed files with 931 additions and 301 deletions

View File

@@ -4,7 +4,6 @@ import { openPlecUpload } from './tools/plecUpload';
import { openApplovinUpload } from './tools/applovinUpload';
import { openBase64Scanner } from './tools/base64Scanner';
import { openMraidChecker } from './tools/mraidChecker';
import { openDailyUpdate } from './tools/dailyUpdate';
import { openSendToMobile } from './tools/sendToMobile';
import { openPlayworksConverter } from './tools/playworksConverter';
@@ -14,7 +13,6 @@ export function activate(context: vscode.ExtensionContext) {
vscode.commands.registerCommand('hplToolbox.openApplovinUpload', () => openApplovinUpload(context)),
vscode.commands.registerCommand('hplToolbox.openBase64Scanner', () => openBase64Scanner(context)),
vscode.commands.registerCommand('hplToolbox.openMraidChecker', () => openMraidChecker(context)),
vscode.commands.registerCommand('hplToolbox.openDailyUpdate', () => openDailyUpdate(context)),
vscode.commands.registerCommand('hplToolbox.openSendToMobile', () => openSendToMobile(context)),
vscode.commands.registerCommand('hplToolbox.openPlayworksConverter', () => openPlayworksConverter(context)),
vscode.window.registerWebviewViewProvider('hplToolbox.launcher', new LauncherViewProvider(context))

View File

@@ -31,11 +31,6 @@ const TOOLS: ToolDefinition[] = [
description: 'Check MRAID requirements and best practices',
beta: true,
},
{
command: 'hplToolbox.openDailyUpdate',
title: 'Daily Update',
description: 'Compose & copy a daily status',
},
{
command: 'hplToolbox.openSendToMobile',
title: 'Send To Mobile',
@@ -45,11 +40,12 @@ const TOOLS: ToolDefinition[] = [
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) {}
constructor(private readonly context: vscode.ExtensionContext) { }
resolveWebviewView(view: vscode.WebviewView) {
view.webview.options = { enableScripts: true };
@@ -68,7 +64,7 @@ export class LauncherViewProvider implements vscode.WebviewViewProvider {
}
function getHtml(version: string, betaToolsEnabled: boolean): string {
const visibleTools = TOOLS.filter(tool => betaToolsEnabled || !tool.beta);
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>
@@ -155,6 +151,10 @@ ${toolButtons}
</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>

View File

@@ -1,122 +0,0 @@
import * as vscode from 'vscode';
import { singletonPanel } from './shared';
const PROJECT_KEY = 'hplToolbox.dailyUpdate.lastProject';
const store: { panel: vscode.WebviewPanel | null } = { panel: null };
export function openDailyUpdate(context: vscode.ExtensionContext) {
const { panel, isNew } = singletonPanel(store, 'hplToolbox.dailyUpdate', 'Daily Update');
if (!isNew) return;
const lastProject = context.globalState.get<string>(PROJECT_KEY, '');
panel.webview.html = getHtml(lastProject);
panel.webview.onDidReceiveMessage(async (msg) => {
if (msg.type === 'submit') {
const text = formatMessage(msg.payload);
await vscode.env.clipboard.writeText(text);
await context.globalState.update(PROJECT_KEY, msg.payload.project);
vscode.window.showInformationMessage('Daily update copied to clipboard.');
panel.dispose();
}
});
}
function formatMessage(p: { date: string; status: string; project: string; remarks: string }): string {
const bullets = p.remarks
.split(/\r?\n/)
.map((l) => l.replace(/^\s*[-*]\s*/, '').trim())
.filter((l) => l.length > 0)
.map((l) => `- ${l}`)
.join('\n');
const lines = [
`Date: ${formatDate(p.date)}`,
`Status: ${p.status}`,
`Project: ${p.project}`,
`Remarks:`,
bullets,
];
if (p.status === 'For OT') {
lines.push('@Joyce Lanot , @Reland Pigte, @Anthony Castor, @Angela Grace');
}
return lines.join('\n');
}
function formatDate(iso: string): string {
const m = /^(\d{4})-(\d{2})-(\d{2})$/.exec(iso);
if (!m) return iso;
return `${m[2]}/${m[3]}/${m[1]}`;
}
function escapeAttr(s: string): string {
return s.replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
}
function getHtml(lastProject: string): string {
const today = new Date().toISOString().slice(0, 10);
return `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src 'unsafe-inline'; script-src 'unsafe-inline';" />
<style>
body { font-family: var(--vscode-font-family); color: var(--vscode-foreground); padding: 16px; max-width: 520px; }
label { display: block; margin-top: 12px; font-size: 12px; opacity: 0.85; }
input, select, textarea {
width: 100%; box-sizing: border-box; margin-top: 4px; padding: 6px 8px;
background: var(--vscode-input-background); color: var(--vscode-input-foreground);
border: 1px solid var(--vscode-input-border, transparent); font-family: inherit; font-size: 13px;
}
textarea { min-height: 96px; resize: vertical; }
button {
margin-top: 16px; padding: 8px 16px; cursor: pointer;
background: var(--vscode-button-background); color: var(--vscode-button-foreground);
border: none; font-size: 13px;
}
button:hover { background: var(--vscode-button-hoverBackground); }
</style>
</head>
<body>
<h2 style="margin:0 0 4px 0;">Daily Update</h2>
<div style="font-size:12px;opacity:0.7;">Submit copies the formatted text to your clipboard.</div>
<label for="date">Date</label>
<input type="date" id="date" value="${today}" />
<label for="status">Status</label>
<select id="status">
<option>Started</option>
<option>Progress</option>
<option>Finished</option>
<option>Client Feedback</option>
<option>For OT</option>
</select>
<label for="project">Project</label>
<input type="text" id="project" placeholder="Project name" value="${escapeAttr(lastProject)}" />
<label for="remarks">Remarks</label>
<textarea id="remarks" placeholder="What did you do?"></textarea>
<button id="submit">Submit</button>
<script>
const vscode = acquireVsCodeApi();
document.getElementById('submit').addEventListener('click', () => {
vscode.postMessage({
type: 'submit',
payload: {
date: document.getElementById('date').value,
status: document.getElementById('status').value,
project: document.getElementById('project').value.trim(),
remarks: document.getElementById('remarks').value.trim(),
},
});
});
</script>
</body>
</html>`;
}