WIP: claude works hard

This commit is contained in:
Gérald Colangelo
2026-03-19 16:42:37 +01:00
parent 5b18fadb60
commit 54b8cc991e
38 changed files with 3492 additions and 317 deletions

View File

@@ -8,7 +8,14 @@
<a href="{{ url_for('sessions.detail', session_id=session.id) }}">{{ session.label }}</a> &rsaquo;
Annotate
</div>
<h1 style="margin:0;">{{ photo.caption or 'Photo annotation' }}</h1>
<div style="display:flex;align-items:center;justify-content:space-between;gap:1rem;">
<h1 style="margin:0;">{{ photo.caption or 'Photo annotation' }}</h1>
<a href="{{ url_for('sessions.detail', session_id=session.id) }}"
style="background:#f0f4ff;color:#1a1a2e;border:1px solid #c8d4f0;border-radius:4px;
padding:.45rem 1rem;font-size:0.88rem;text-decoration:none;white-space:nowrap;">
✕ Close
</a>
</div>
</div>
<div style="display:flex;gap:1.5rem;align-items:flex-start;">
@@ -49,8 +56,8 @@
<hr style="border:none;border-top:1px solid #e8e8e8;margin-bottom:1rem;">
{# Shooting distance (always visible) #}
<div style="margin-bottom:1rem;">
{# Shooting distance (always visible, pre-filled from session) #}
<div style="margin-bottom:.75rem;">
<label style="display:block;font-size:.82rem;font-weight:600;color:#444;margin-bottom:.3rem;">Shooting distance</label>
<div style="display:flex;gap:.4rem;">
<input type="number" id="shoot-dist" min="1" step="1" placeholder="100"
@@ -63,6 +70,14 @@
</div>
</div>
{# Clean barrel checkbox #}
<div style="margin-bottom:1rem;">
<label style="display:flex;align-items:center;gap:.5rem;cursor:pointer;font-size:0.88rem;color:#444;">
<input type="checkbox" id="clean-barrel" style="width:1rem;height:1rem;">
Clean barrel (first shot)
</label>
</div>
<hr style="border:none;border-top:1px solid #e8e8e8;margin-bottom:1rem;">
{# Step 0: Reference line #}
@@ -117,7 +132,7 @@
<div id="panel-3" class="step-panel" style="display:none;">
<div id="results-box" style="margin-bottom:1rem;"></div>
<div style="display:flex;gap:.5rem;flex-wrap:wrap;">
<button class="btn-primary" id="btn-save" onclick="saveAnnotations()">Save</button>
<button class="btn-primary" id="btn-save" onclick="saveAnnotations()">Save &amp; close</button>
<button class="btn-ghost" onclick="goStep(2)">← Edit</button>
</div>
<div id="save-status" style="font-size:0.82rem;margin-top:.5rem;"></div>
@@ -145,9 +160,11 @@
</style>
<script>
const PHOTO_URL = {{ photo.photo_url | tojson }};
const SAVE_URL = {{ url_for('sessions.annotate_photo', session_id=session.id, photo_id=photo.id) | tojson }};
const EXISTING = {{ (photo.annotations or {}) | tojson }};
const PHOTO_URL = {{ photo.photo_url | tojson }};
const SAVE_URL = {{ url_for('sessions.annotate_photo', session_id=session.id, photo_id=photo.id) | tojson }};
const SESSION_URL = {{ url_for('sessions.detail', session_id=session.id) | tojson }};
const SESSION_DIST_M = {{ (session.distance_m or 'null') }};
const EXISTING = {{ (photo.annotations or {}) | tojson }};
// ── State ──────────────────────────────────────────────────────────────────
let step = 0;
@@ -408,6 +425,8 @@ function renderResults() {
<span class="stat-val">${stats.shot_count}</span></div>
<div class="stat-row"><span class="stat-label">@ distance</span>
<span class="stat-val">${stats.shooting_distance_m.toFixed(0)} m</span></div>
<div class="stat-row"><span class="stat-label">Clean barrel</span>
<span class="stat-val">${document.getElementById('clean-barrel').checked ? 'Yes' : 'No'}</span></div>
`;
}
@@ -554,6 +573,7 @@ async function saveAnnotations() {
poa: toFrac(poa),
pois: pois.map(toFrac),
shooting_distance_m: stats.shooting_distance_m,
clean_barrel: document.getElementById('clean-barrel').checked,
stats: stats,
};
@@ -564,8 +584,7 @@ async function saveAnnotations() {
body: JSON.stringify(payload),
});
if (resp.ok) {
status.style.color = '#27ae60';
status.textContent = 'Saved!';
window.location.href = SESSION_URL;
} else {
throw new Error('Server error');
}
@@ -578,6 +597,12 @@ async function saveAnnotations() {
// ── Load existing annotations ──────────────────────────────────────────────
function loadExisting() {
// Always pre-fill shooting distance from session if available
if (SESSION_DIST_M) {
document.getElementById('shoot-dist').value = SESSION_DIST_M;
document.getElementById('shoot-unit').value = 'm';
}
if (!EXISTING || !EXISTING.ref) return;
const W = img.naturalWidth, H = img.naturalHeight;
function fromFrac(f) { return { x: f.x * W, y: f.y * H }; }
@@ -597,6 +622,9 @@ function loadExisting() {
document.getElementById('shoot-dist').value = EXISTING.shooting_distance_m.toFixed(0);
document.getElementById('shoot-unit').value = 'm';
}
if (EXISTING.clean_barrel) {
document.getElementById('clean-barrel').checked = true;
}
if (EXISTING.stats) {
stats = EXISTING.stats;
renderResults();