This commit is contained in:
2026-05-23 16:57:24 +08:00
parent 9d6ed4b0a5
commit 6be55255b2
10 changed files with 44 additions and 12 deletions

View File

@@ -112,7 +112,7 @@ if ($Standalone) {
$exeName = "hpl-toolbox-$version.exe"
$exeOut = Join-Path $distDir $exeName
go build -ldflags="-s -w -H windowsgui" -trimpath -o $exeOut .
go build -ldflags="-s -w -H windowsgui -X main.AppVersion=$version" -trimpath -o $exeOut .
if ($LASTEXITCODE -ne 0) { Write-Error "go build failed"; exit 1 }
$summary += [pscustomobject]@{

View File

@@ -2,7 +2,7 @@
"name": "hpl-toolbox",
"displayName": "HPL Toolbox",
"description": "Bundled tools: PLEC Upload, AppLovin Demo Upload, Base64 Asset Scanner, Daily Update. Local HTML Host.",
"version": "0.1.4",
"version": "0.1.5",
"publisher": "hesukastro",
"license": "UNLICENSED",
"repository": {

View File

@@ -13,7 +13,7 @@ export function activate(context: vscode.ExtensionContext) {
vscode.commands.registerCommand('hplToolbox.openBase64Scanner', () => openBase64Scanner(context)),
vscode.commands.registerCommand('hplToolbox.openDailyUpdate', () => openDailyUpdate(context)),
vscode.commands.registerCommand('hplToolbox.openSendToMobile', () => openSendToMobile(context)),
vscode.window.registerWebviewViewProvider('hplToolbox.launcher', new LauncherViewProvider())
vscode.window.registerWebviewViewProvider('hplToolbox.launcher', new LauncherViewProvider(context))
);
}

View File

@@ -1,9 +1,12 @@
import * as vscode from 'vscode';
export class LauncherViewProvider implements vscode.WebviewViewProvider {
constructor(private readonly context: vscode.ExtensionContext) {}
resolveWebviewView(view: vscode.WebviewView) {
view.webview.options = { enableScripts: true };
view.webview.html = getHtml();
const version = this.context.extension.packageJSON.version as string;
view.webview.html = getHtml(version);
view.webview.onDidReceiveMessage((msg) => {
if (msg?.type === 'open' && typeof msg.command === 'string') {
vscode.commands.executeCommand(msg.command);
@@ -12,7 +15,7 @@ export class LauncherViewProvider implements vscode.WebviewViewProvider {
}
}
function getHtml(): string {
function getHtml(version: string): string {
return `<!DOCTYPE html>
<html>
<head>
@@ -35,7 +38,7 @@ function getHtml(): string {
</style>
</head>
<body>
<h3>HPL Toolbox</h3>
<h3>HPL Toolbox ${version}</h3>
<button class="tool-btn" data-cmd="hplToolbox.openPlecUpload">
PLEC Upload
<span class="tool-desc">Upload HTML to internal PLEC server</span>

View File

@@ -234,8 +234,11 @@ function getHtml(): string {
function parseIterationName(filename) {
const base = filename.replace(/\\.html?$/i, '');
const match = base.match(/\\b(full|\\d+clk|\\d+s(?:ec)?)\\b/i);
return match ? match[1].toLowerCase() : base;
const tokens = base.split('_');
for (const t of tokens) {
if (/^(full|\\d+clk|\\d+s(?:ec)?)$/i.test(t)) return t.toLowerCase();
}
return base;
}
const statusEl = document.getElementById('status');
const resultsEl = document.getElementById('results');
@@ -292,6 +295,7 @@ function getHtml(): string {
const m = e.data;
if (m.type === 'filesSelected') {
const firstTr = tbody.querySelector('tr[data-id="' + m.rowId + '"]');
const affected = [];
m.files.forEach(function(f, i) {
let tr;
if (i === 0) {
@@ -305,7 +309,16 @@ function getHtml(): string {
tr.querySelector('[data-name]').textContent = f.name;
const iter = tr.querySelector('[data-iter]');
if (!iter.value) iter.value = parseIterationName(f.name);
affected.push(tr);
});
if (affected.length > 1) {
const iters = affected.map(r => r.querySelector('[data-iter]').value);
if (iters[0] !== '' && iters.every(n => n === iters[0])) {
affected.forEach((r, i) => {
r.querySelector('[data-iter]').value = String(i + 1).padStart(2, '0') + '_' + iters[0];
});
}
}
} else if (m.type === 'status') {
statusEl.textContent = m.message;
statusEl.className = '';

View File

@@ -17,6 +17,7 @@ const SharedCSS = `
.topbar a { color: #9cdcfe; text-decoration: none; padding: 4px 10px; border-radius: 3px; }
.topbar a:hover { background: #2a2d2e; }
.topbar a.active { background: #094771; color: #fff; }
.topbar-version { margin-left: auto; font-size: 11px; opacity: 0.45; letter-spacing: 0.4px; }
.content { padding: 16px; max-width: 980px; margin: 0 auto; }
h2 { margin-top: 0; font-weight: 500; }
input[type=text], input[type=date], select, textarea {
@@ -67,7 +68,7 @@ func Page(activePath, title, body string) string {
<title>` + title + ` — HPL Toolbox</title>
<style>` + SharedCSS + `</style>
</head><body>
<div class="topbar">` + tabs.String() + `</div>
<div class="topbar">` + tabs.String() + `<span class="topbar-version">v` + AppVersion + `</span></div>
<div class="content">` + body + `</div>
</body></html>`
}

View File

@@ -16,6 +16,8 @@ import (
webview "github.com/jchv/go-webview2"
)
var AppVersion = "dev"
var currentHwnd atomic.Uintptr
func setupFileLogging() {
@@ -68,7 +70,7 @@ func main() {
AutoFocus: true,
DataPath: webviewTmp,
WindowOptions: webview.WindowOptions{
Title: "HPL Toolbox",
Title: "HPL Toolbox " + AppVersion,
Width: 1100,
Height: 720,
IconId: 1,

View File

@@ -56,8 +56,11 @@ const resultsEl = document.getElementById('results');
function parseIterationName(filename) {
const base = filename.replace(/\.html?$/i, '');
const match = base.match(/\b(full|\d+clk|\d+s(?:ec)?)\b/i);
return match ? match[1].toLowerCase() : base;
const tokens = base.split('_');
for (const t of tokens) {
if (/^(full|\d+clk|\d+s(?:ec)?)$/i.test(t)) return t.toLowerCase();
}
return base;
}
function addRow() {
@@ -80,13 +83,23 @@ function addRow() {
const res = await fetch('/api/plec/pick', { method: 'POST' });
const j = await res.json();
if (j.files && j.files.length) {
const affected = [];
j.files.forEach(function(f, i) {
const target = i === 0 ? tr : (addRow(), tbody.lastElementChild);
target.querySelector('[data-path]').value = f.path;
target.querySelector('[data-name]').textContent = f.name;
const iter = target.querySelector('[data-iter]');
if (!iter.value) iter.value = parseIterationName(f.name);
affected.push(target);
});
if (affected.length > 1) {
const iters = affected.map(r => r.querySelector('[data-iter]').value);
if (iters[0] !== '' && iters.every(n => n === iters[0])) {
affected.forEach((r, i) => {
r.querySelector('[data-iter]').value = String(i + 1).padStart(2, '0') + '_' + iters[0];
});
}
}
}
});
tr.querySelector('.remove-btn').addEventListener('click', () => {