You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
154 lines
6.6 KiB
HTML
154 lines
6.6 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
<title>Result — Diagram → TikZ</title>
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" />
|
|
<link rel="stylesheet" href="{{ base_path }}/public/styles.css" />
|
|
</head>
|
|
<body class="page page-result">
|
|
<div class="topbar">
|
|
<a class="no-wrap" href="{{ base_path }}/">← New upload</a>
|
|
<div class="label run-id" title="{{ run_id }}">Run: {{ run_id }}</div>
|
|
<div class="label no-wrap">Model: {{ convert_model }}</div>
|
|
</div>
|
|
|
|
<div class="container">
|
|
<div class="pane left">
|
|
<div class="label">Standalone LaTeX/TikZ</div>
|
|
<form action="{{ base_path }}/{{ run_id }}" method="post" class="edit-form">
|
|
<div class="field">
|
|
<label for="instructions">Edit instructions</label>
|
|
<div class="prompt-row">
|
|
<input
|
|
id="instructions"
|
|
name="instructions"
|
|
autocomplete="off"
|
|
type="text"
|
|
placeholder="e.g. move labels closer, align boxes, add arrows"
|
|
/>
|
|
<button class="btn" type="submit">Apply edits</button>
|
|
</div>
|
|
<div class="hint">
|
|
Applies edits to the LaTeX only, then compiles. {% if last_edit_model %}Last edit model: {{
|
|
last_edit_model }}.{% endif %}
|
|
<br />Edit quota: {{ edit_remaining }}/{{ edit_limit }} left today.
|
|
</div>
|
|
</div>
|
|
|
|
<div class="field">
|
|
<label for="history-select">History</label>
|
|
<select id="history-select">
|
|
<option value="current" selected>Current</option>
|
|
</select>
|
|
<div class="hint">Most recent first. Selecting an entry loads its LaTeX into the editor.</div>
|
|
</div>
|
|
|
|
<div class="field">
|
|
<label for="latex-source">LaTeX Source</label>
|
|
<textarea id="latex-source" name="latex" spellcheck="false" wrap="off">{{ tex }}</textarea>
|
|
</div>
|
|
<div class="actions">
|
|
<button class="btn" type="submit" formaction="{{ base_path }}/{{ run_id }}/compile">
|
|
<i class="fa-solid fa-play icon" aria-hidden="true"></i>
|
|
<span>Compile</span>
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<div class="pane right">
|
|
<div class="label">Rendered preview</div>
|
|
<div class="preview">
|
|
{% if png_url %}
|
|
<img src="{{ png_url }}" alt="Rendered TikZ preview" />
|
|
{% else %}
|
|
<div class="label">No preview available.</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<div class="downloads">
|
|
<a class="button" href="{{ download_original_url }}">Download original image</a>
|
|
<a class="button" href="{{ download_tex_url }}">Download .tex</a>
|
|
<a class="button" href="{{ download_pdf_url }}">Download .pdf</a>
|
|
<a class="button" href="{{ download_svg_url }}">Download .svg</a>
|
|
<a class="button" href="{{ download_png_url }}">Download .png</a>
|
|
</div>
|
|
|
|
{% if error %}
|
|
<div class="error">{{ error }}</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</body>
|
|
|
|
<script>
|
|
;(() => {
|
|
const basePath = "{{ base_path }}"
|
|
const runId = "{{ run_id }}"
|
|
const historySelect = document.getElementById("history-select")
|
|
const latexArea = document.getElementById("latex-source")
|
|
const currentTex = latexArea ? latexArea.value : ""
|
|
let historyEntries = []
|
|
|
|
const formatTs = ts => {
|
|
if (!ts) return "unknown time"
|
|
const d = new Date(ts * 1000)
|
|
return d.toISOString().replace("T", " ").slice(0, 19)
|
|
}
|
|
|
|
const renderOptions = () => {
|
|
if (!historySelect) return
|
|
const frag = document.createDocumentFragment()
|
|
const current = document.createElement("option")
|
|
current.value = "current"
|
|
current.textContent = "Current"
|
|
frag.appendChild(current)
|
|
|
|
historyEntries.forEach((entry, idx) => {
|
|
const opt = document.createElement("option")
|
|
opt.value = String(idx)
|
|
const statusLabel = entry.status === "error" ? " (error)" : ""
|
|
opt.textContent = `${entry.action || "edit"} @ ${formatTs(entry.ts)}${statusLabel}`
|
|
frag.appendChild(opt)
|
|
})
|
|
|
|
historySelect.innerHTML = ""
|
|
historySelect.appendChild(frag)
|
|
}
|
|
|
|
const loadHistory = async () => {
|
|
if (!historySelect) return
|
|
try {
|
|
const resp = await fetch(`${basePath}/${runId}/history`)
|
|
if (!resp.ok) return
|
|
const data = await resp.json()
|
|
historyEntries = Array.isArray(data.entries) ? data.entries : []
|
|
renderOptions()
|
|
} catch (err) {
|
|
console.error("history.load.failed", err)
|
|
}
|
|
}
|
|
|
|
if (historySelect && latexArea) {
|
|
historySelect.addEventListener("change", () => {
|
|
const value = historySelect.value
|
|
if (value === "current") {
|
|
latexArea.value = currentTex
|
|
return
|
|
}
|
|
const idx = Number(value)
|
|
if (Number.isNaN(idx) || idx < 0 || idx >= historyEntries.length) {
|
|
return
|
|
}
|
|
const entry = historyEntries[idx]
|
|
latexArea.value = entry?.latex || ""
|
|
})
|
|
|
|
loadHistory()
|
|
}
|
|
})()
|
|
</script>
|
|
</html>
|