early version of OCR viewer now integrated
This commit is contained in:
207
prompts/ocr-viewer-redesign.md
Normal file
207
prompts/ocr-viewer-redesign.md
Normal file
@@ -0,0 +1,207 @@
|
||||
P44 OCR Viewer — Pass 1 Flag System Redesign
|
||||
Scope: p44-ocr-viewer.js, p44-ocr-viewer.css, p44-ocr-viewer.html. Make all three changes in sequence. Do not touch PDF rendering, zoom, sync scroll, Pass 2 logic, or the corrections storage model.
|
||||
|
||||
PART 1 — HTML (p44-ocr-viewer.html)
|
||||
In the right panel header, replace the five buttons:
|
||||
html<button id="btn-flag-verified" ...>✓ Verified</button>
|
||||
<button id="btn-flag-review" ...>⚑ Review</button>
|
||||
<button id="btn-flag-error" ...>✗ Error</button>
|
||||
<button id="btn-flag-clear" ...>Clear</button>
|
||||
<button id="btn-edit" ...>Edit</button>
|
||||
With these three buttons:
|
||||
html<button id="btn-flag-done" class="tb-btn flag-btn" title="Mark page as done — sends to Pass 2 queue. Cannot be undone.">✓ Done</button>
|
||||
<button id="btn-flag-problem" class="tb-btn flag-btn" title="Flag page as a problem — OCR too bad to fix. Still goes to Pass 2.">⚠ Problem</button>
|
||||
<button id="btn-edit" class="tb-btn" title="Toggle edit mode">Edit</button>
|
||||
Add a new read-only banner element inside #text-panel-body, immediately before #pass2-revert-bar:
|
||||
html<div id="done-banner" style="display:none;"></div>
|
||||
|
||||
PART 2 — CSS (p44-ocr-viewer.css)
|
||||
Remove the CSS rules for #btn-flag-verified, #btn-flag-review, #btn-flag-error if any exist by those IDs. The .flag-btn and .flag-btn.active rules stay — they apply to the new buttons too.
|
||||
Add these new rules at the end of the file:
|
||||
css/* ── Done-page read-only banner (Pass 1) ─────────────────────── */
|
||||
#done-banner {
|
||||
display: none;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 7px 16px;
|
||||
background: #0f2a0f;
|
||||
border-bottom: 1px solid #2e6e2e;
|
||||
font-size: 10px;
|
||||
color: #5cb85c;
|
||||
letter-spacing: 0.05em;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* ── Problem flag indicator on page nav input ─────────────────── */
|
||||
#page-input.problem { border-color: #c08020; }
|
||||
|
||||
/* ── Greyed-out done state on the OCR text panel ─────────────── */
|
||||
#text-output.done-readonly {
|
||||
opacity: 0.55;
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
PART 3 — JS (p44-ocr-viewer.js)
|
||||
Make the following changes in order. Each change is isolated — do not touch any other function.
|
||||
3a — DOM refs
|
||||
Replace:
|
||||
javascriptconst btnFlagVerified = document.getElementById('btn-flag-verified');
|
||||
const btnFlagReview = document.getElementById('btn-flag-review');
|
||||
const btnFlagError = document.getElementById('btn-flag-error');
|
||||
const btnFlagClear = document.getElementById('btn-flag-clear');
|
||||
With:
|
||||
javascriptconst btnFlagDone = document.getElementById('btn-flag-done');
|
||||
const btnFlagProblem = document.getElementById('btn-flag-problem');
|
||||
3b — Flag label constants
|
||||
Replace the PASS2_BTN_LABELS and PASS1_BTN_LABELS constants with:
|
||||
javascriptconst PASS2_BTN_LABELS = { done: '✓ Pass 2 approved', problem: '⚠ Needs work' };
|
||||
const PASS1_BTN_LABELS = { done: '✓ Done', problem: '⚠ Problem' };
|
||||
3c — updateFlagButtons(pageNum)
|
||||
Replace the entire function body with:
|
||||
javascriptfunction updateFlagButtons(pageNum) {
|
||||
const flagSrc = currentRole === 'pass2' ? pass2Flags : state.flags;
|
||||
const flag = flagSrc[pageNum] || null;
|
||||
btnFlagDone.classList.toggle('active', flag === 'done');
|
||||
btnFlagProblem.classList.toggle('active', flag === 'problem');
|
||||
|
||||
// Done pages are read-only in Pass 1 — disable both flag buttons and Edit
|
||||
const isDone = currentRole === 'pass1' && flag === 'done';
|
||||
btnFlagDone.disabled = isDone;
|
||||
btnFlagProblem.disabled = isDone;
|
||||
btnEdit.disabled = isDone;
|
||||
btnEdit.style.opacity = isDone ? '0.35' : '';
|
||||
}
|
||||
3d — setFlag(type)
|
||||
Replace the entire function body with:
|
||||
javascriptfunction setFlag(type) {
|
||||
const p = state.currentPage;
|
||||
|
||||
if (currentRole === 'pass2') {
|
||||
if (type === null) { delete pass2Flags[p]; } else { pass2Flags[p] = type; }
|
||||
updateFlagButtons(p);
|
||||
savePass2Flags();
|
||||
return;
|
||||
}
|
||||
|
||||
// Pass 1 — Done is one-way: once set it cannot be cleared by the volunteer
|
||||
if (state.flags[p] === 'done') return;
|
||||
|
||||
// Problem is toggleable — clicking it again removes it
|
||||
if (type === 'problem' && state.flags[p] === 'problem') {
|
||||
delete state.flags[p];
|
||||
} else if (type === null) {
|
||||
delete state.flags[p];
|
||||
} else {
|
||||
state.flags[p] = type;
|
||||
}
|
||||
|
||||
updateFlagButtons(p);
|
||||
updateFlagsSummary();
|
||||
saveFlags();
|
||||
}
|
||||
3e — showOCRPage(pageNum)
|
||||
At the end of showOCRPage(), after the existing block that calls updateFlagButtons() and updateCorrectionIndicator(), add the following. Do not change any existing lines in showOCRPage() — only add this block at the end (before the closing brace), replacing the existing Pass 2 auto-edit-mode call:
|
||||
javascript // Pass 1 done-page read-only state
|
||||
const doneBanner = document.getElementById('done-banner');
|
||||
const isDonePage = currentRole === 'pass1' && state.flags[pageNum] === 'done';
|
||||
|
||||
if (isDonePage) {
|
||||
// Show the final corrected text (same display logic as normal, already rendered above)
|
||||
// Lock the panel visually
|
||||
textOutput.classList.add('done-readonly');
|
||||
doneBanner.innerHTML =
|
||||
'✓ <strong>Done</strong> — submitted to Pass 2 queue. This page is locked.';
|
||||
doneBanner.style.display = 'flex';
|
||||
// Ensure editor is closed and stays closed
|
||||
if (state.editMode) exitEditMode();
|
||||
} else {
|
||||
textOutput.classList.remove('done-readonly');
|
||||
doneBanner.style.display = 'none';
|
||||
}
|
||||
|
||||
// Pass 2 auto-edit mode (unchanged behaviour)
|
||||
if (currentRole === 'pass2') {
|
||||
if (!state.editMode) enterEditMode();
|
||||
updatePass2NavButtons();
|
||||
}
|
||||
Note: this block replaces the existing two lines at the bottom of showOCRPage() that read:
|
||||
javascript if (currentRole === 'pass2') {
|
||||
if (!state.editMode) enterEditMode();
|
||||
updatePass2NavButtons();
|
||||
}
|
||||
3f — applyRole()
|
||||
In applyRole(), replace the two label-setting lines for pass2 branch:
|
||||
javascript btnFlagVerified.textContent = PASS2_BTN_LABELS.verified;
|
||||
btnFlagReview.textContent = PASS2_BTN_LABELS.review;
|
||||
btnFlagError.textContent = PASS2_BTN_LABELS.error;
|
||||
With:
|
||||
javascript btnFlagDone.textContent = PASS2_BTN_LABELS.done;
|
||||
btnFlagProblem.textContent = PASS2_BTN_LABELS.problem;
|
||||
And replace the three label-setting lines for the pass1 branch:
|
||||
javascript btnFlagVerified.textContent = PASS1_BTN_LABELS.verified;
|
||||
btnFlagReview.textContent = PASS1_BTN_LABELS.review;
|
||||
btnFlagError.textContent = PASS1_BTN_LABELS.error;
|
||||
With:
|
||||
javascript btnFlagDone.textContent = PASS1_BTN_LABELS.done;
|
||||
btnFlagProblem.textContent = PASS1_BTN_LABELS.problem;
|
||||
3g — Event listeners
|
||||
Replace:
|
||||
javascriptbtnFlagVerified.addEventListener('click', () => setFlag('verified'));
|
||||
btnFlagReview.addEventListener('click', () => setFlag('review'));
|
||||
btnFlagError.addEventListener('click', () => setFlag('error'));
|
||||
btnFlagClear.addEventListener('click', () => setFlag(null));
|
||||
With:
|
||||
javascriptbtnFlagDone.addEventListener('click', () => setFlag('done'));
|
||||
btnFlagProblem.addEventListener('click', () => setFlag('problem'));
|
||||
3h — updateFlagsSummary()
|
||||
Replace the counting logic inside updateFlagsSummary():
|
||||
javascript Object.values(state.flags).forEach(f => {
|
||||
if (f === 'verified') v++;
|
||||
else if (f === 'review') r++;
|
||||
else if (f === 'error') er++;
|
||||
});
|
||||
flagsSummary.textContent = v || r || er
|
||||
? '✓ ' + v + ' ⚑ ' + r + ' ✗ ' + er
|
||||
: '';
|
||||
With:
|
||||
javascript let done = 0, problem = 0;
|
||||
Object.values(state.flags).forEach(f => {
|
||||
if (f === 'done') done++;
|
||||
else if (f === 'problem') problem++;
|
||||
});
|
||||
flagsSummary.textContent = done || problem
|
||||
? '✓ ' + done + (problem ? ' ⚠ ' + problem : '')
|
||||
: '';
|
||||
3i — Keyboard shortcut
|
||||
In the keydown handler, replace:
|
||||
javascript case 'v':
|
||||
setFlag('verified'); break;
|
||||
case 'r':
|
||||
setFlag('review'); break;
|
||||
case 'e':
|
||||
setFlag('error'); break;
|
||||
With:
|
||||
javascript case 'v':
|
||||
setFlag('done'); break;
|
||||
case 'p':
|
||||
setFlag('problem'); break;
|
||||
Update the footer kbd hint in p44-ocr-viewer.html from:
|
||||
html<span id="kbd-hint">← → navigate v/r/e flag esc close</span>
|
||||
To:
|
||||
html<span id="kbd-hint">← → navigate v done p problem esc close</span>
|
||||
3j — getVerifiedPages()
|
||||
Replace:
|
||||
javascript .filter(k => state.flags[k] === 'verified')
|
||||
With:
|
||||
javascript .filter(k => state.flags[k] === 'done')
|
||||
|
||||
VERIFICATION CHECKLIST — confirm each before closing the prompt:
|
||||
|
||||
Clicking ✓ Done on an unreviewed page: button highlights gold, page text goes grey, green Done banner appears, Edit button is disabled, cannot click Done or Problem again
|
||||
Clicking ⚠ Problem on an unreviewed page: button highlights gold, page remains editable
|
||||
Clicking ⚠ Problem again on a problem page: flag clears, button returns to inactive
|
||||
Navigating to a Done page while in Pass 1 role: banner shows, editor locked, text visible as final corrected version
|
||||
Switching to Pass 2 role: Done banner hidden, flag buttons show Pass 2 labels, auto-edit mode activates as before
|
||||
Footer summary shows correct counts using ✓ and ⚠ symbols
|
||||
Keyboard v sets Done, p sets/toggles Problem, no reference to old r or e keys anywhere
|
||||
Reference in New Issue
Block a user