Add status progress for batch tool operations
This commit is contained in:
@@ -113,6 +113,25 @@ const statusEl = document.getElementById('status');
|
||||
const resultsEl = document.getElementById('results');
|
||||
const sourceSelectionEl = document.getElementById('sourceSelection');
|
||||
|
||||
async function readJSONStream(response, handle) {
|
||||
if (!response.ok || !response.body) throw new Error('Request failed.');
|
||||
const reader = response.body.getReader();
|
||||
const decoder = new TextDecoder();
|
||||
let buffer = '';
|
||||
while (true) {
|
||||
const { value, done } = await reader.read();
|
||||
if (done) break;
|
||||
buffer += decoder.decode(value, { stream: true });
|
||||
let newline;
|
||||
while ((newline = buffer.indexOf('\n')) >= 0) {
|
||||
const line = buffer.slice(0, newline);
|
||||
buffer = buffer.slice(newline + 1);
|
||||
if (line.trim()) handle(JSON.parse(line));
|
||||
}
|
||||
}
|
||||
if (buffer.trim()) handle(JSON.parse(buffer));
|
||||
}
|
||||
|
||||
function updateConvertBtn() {
|
||||
const hasNet = [...document.querySelectorAll('.net-cb')].some(c => c.checked);
|
||||
convertBtn.disabled = !srcEl.value || !outEl.value || !baseNameEl.value.trim() || !hasNet;
|
||||
@@ -215,9 +234,24 @@ document.getElementById('convert').addEventListener('click', async () => {
|
||||
headers:{'Content-Type':'application/json'},
|
||||
body: JSON.stringify({ sourcePath: srcEl.value, outputDir: outEl.value, baseName: baseNameEl.value, networks })
|
||||
});
|
||||
const msg = await res.json();
|
||||
let msg = null;
|
||||
try {
|
||||
await readJSONStream(res, (event) => {
|
||||
if (event.type === 'status') {
|
||||
statusEl.textContent = event.message;
|
||||
statusEl.classList.add('is-busy');
|
||||
} else if (event.type === 'done') {
|
||||
msg = event;
|
||||
} else if (event.type === 'error') {
|
||||
msg = { error: event.message, results: event.results || [] };
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
msg = { error: e.message || e, results: [] };
|
||||
}
|
||||
convertBtn.disabled = false;
|
||||
updateConvertBtn();
|
||||
if (!msg) { msg = { error: 'No response.', results: [] }; }
|
||||
if (msg.error) { statusEl.classList.remove('is-busy'); statusEl.textContent = 'Error: ' + msg.error; return; }
|
||||
const results = msg.results || [];
|
||||
const ok = results.filter(r => r.ok).length;
|
||||
@@ -256,33 +290,37 @@ func PlayworksPickOutput(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func PlayworksConvert(w http.ResponseWriter, r *http.Request) {
|
||||
send := newJSONStream(w)
|
||||
var opts playworksConvertOptions
|
||||
if err := json.NewDecoder(r.Body).Decode(&opts); err != nil {
|
||||
writeJSON(w, map[string]any{"results": []playworksNetworkResult{}, "error": err.Error()})
|
||||
send(map[string]any{"type": "error", "message": err.Error(), "results": []playworksNetworkResult{}})
|
||||
return
|
||||
}
|
||||
if !fileExists(opts.SourcePath) {
|
||||
writeJSON(w, map[string]any{"results": []playworksNetworkResult{}, "error": "Source file not found."})
|
||||
send(map[string]any{"type": "error", "message": "Source file not found.", "results": []playworksNetworkResult{}})
|
||||
return
|
||||
}
|
||||
if err := os.MkdirAll(opts.OutputDir, 0755); err != nil {
|
||||
writeJSON(w, map[string]any{"results": []playworksNetworkResult{}, "error": "Could not create output folder."})
|
||||
send(map[string]any{"type": "error", "message": "Could not create output folder.", "results": []playworksNetworkResult{}})
|
||||
return
|
||||
}
|
||||
send(map[string]any{"type": "status", "message": "Reading source HTML..."})
|
||||
data, err := os.ReadFile(opts.SourcePath)
|
||||
if err != nil {
|
||||
writeJSON(w, map[string]any{"results": []playworksNetworkResult{}, "error": "Could not read source: " + err.Error()})
|
||||
send(map[string]any{"type": "error", "message": "Could not read source: " + err.Error(), "results": []playworksNetworkResult{}})
|
||||
return
|
||||
}
|
||||
|
||||
results := []playworksNetworkResult{}
|
||||
send(map[string]any{"type": "status", "message": "Converting Unity..."})
|
||||
unityPath, err := copyPlayworksUnityInput(data, opts)
|
||||
if err != nil {
|
||||
results = append(results, playworksNetworkResult{Network: "un", OK: false, Error: err.Error()})
|
||||
} else {
|
||||
results = append(results, playworksNetworkResult{Network: "un", File: unityPath, OK: true})
|
||||
}
|
||||
for _, network := range opts.Networks {
|
||||
for i, network := range opts.Networks {
|
||||
send(map[string]any{"type": "status", "message": fmt.Sprintf("Converting %d/%d %s", i+1, len(opts.Networks), network)})
|
||||
filePath, err := convertPlayworksNetwork(string(data), opts, network)
|
||||
if err != nil {
|
||||
results = append(results, playworksNetworkResult{Network: network, OK: false, Error: err.Error()})
|
||||
@@ -290,7 +328,7 @@ func PlayworksConvert(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
results = append(results, playworksNetworkResult{Network: network, File: filePath, OK: true})
|
||||
}
|
||||
writeJSON(w, map[string]any{"results": results})
|
||||
send(map[string]any{"type": "done", "results": results})
|
||||
}
|
||||
|
||||
var playworksSuffixRx = regexp.MustCompile(`_(?:un|al|is|fb|gg|ap|mo|vu|mtg|tt)$`)
|
||||
|
||||
Reference in New Issue
Block a user