helwasm: merge Store + Mark correct into one progressive button
The two buttons encoded different facts (catalog membership vs verified hash) but looked alike. Combine into a single button that walks the states, each a real engine command: Store (add) -> Correct (correct) -> Correct ✓ (uncorrect), and Stored ✓ (disabled) when filed but no master is typed. Shorter label: "Correct", not "Mark correct". Help texts updated.
This commit is contained in:
+49
-58
@@ -66,10 +66,10 @@
|
|||||||
<h4>Quick password</h4>
|
<h4>Quick password</h4>
|
||||||
<p>
|
<p>
|
||||||
Type an account name and your master phrase. The password appears instantly,
|
Type an account name and your master phrase. The password appears instantly,
|
||||||
masked; click it (or the master) to reveal. Press <strong>Copy</strong>, or
|
masked; click it (or the master) to reveal, or press <strong>Copy</strong>.
|
||||||
<strong>Store</strong> to remember the <em>name</em> (never the password).
|
The save button steps from <strong>Store</strong> (file the <em>name</em>, never
|
||||||
<strong>Mark correct</strong> remembers this name and master, so that exact
|
the password) to <strong>Correct</strong> (confirm this name + master); once
|
||||||
combination shows in colour; anything unmarked or mistyped stays black.
|
confirmed the result shows in colour, so a typo stays black.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@@ -106,8 +106,8 @@
|
|||||||
<p class="hint">
|
<p class="hint">
|
||||||
The same name and master always make the same password, computed live in your
|
The same name and master always make the same password, computed live in your
|
||||||
browser. Your master is kept in memory for this tab only, never written to
|
browser. Your master is kept in memory for this tab only, never written to
|
||||||
storage, and the app never talks to a server. <strong>Store</strong> saves
|
storage, and the app never talks to a server. The button saves just the entry
|
||||||
just the entry name; <strong>Mark correct</strong> saves only a one-way hash,
|
name (<strong>Store</strong>), then a one-way hash (<strong>Correct</strong>),
|
||||||
both on this device.
|
both on this device.
|
||||||
</p>
|
</p>
|
||||||
<div class="fields">
|
<div class="fields">
|
||||||
@@ -125,9 +125,8 @@
|
|||||||
<span class="secret" id="qsecret" title="click to reveal"></span>
|
<span class="secret" id="qsecret" title="click to reveal"></span>
|
||||||
<span class="len" id="qlen"></span>
|
<span class="len" id="qlen"></span>
|
||||||
<span class="actions">
|
<span class="actions">
|
||||||
<button class="btn ghost small" id="markCorrect" title="Remember this master as correct on this device, so the right master shows in colour." disabled>Mark correct</button>
|
<button class="btn ghost small" id="saveBtn" title="Save this name in your catalog" disabled>Store</button>
|
||||||
<button class="btn small" id="copy">Copy</button>
|
<button class="btn small" id="copy">Copy</button>
|
||||||
<button class="btn ghost small" id="store">Store</button>
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
@@ -265,24 +264,32 @@
|
|||||||
// only the one-way "correct" hash is persisted on the device.
|
// only the one-way "correct" hash is persisted on the device.
|
||||||
let lastSecret = "";
|
let lastSecret = "";
|
||||||
let appliedMaster = null; // last master value pushed to the engine (debounce hint)
|
let appliedMaster = null; // last master value pushed to the engine (debounce hint)
|
||||||
function refreshStoreBtn(name) {
|
// One progressive button. It walks the natural states, each a real engine fact:
|
||||||
const b = $("#store");
|
// not in catalog -> "Store" (click: add the name)
|
||||||
|
// in catalog, master shown -> "Correct" (click: mark this name+master correct)
|
||||||
|
// verified -> "Correct ✓" (click: unmark)
|
||||||
|
// in catalog, no master -> "Stored ✓" (disabled: nothing to verify yet)
|
||||||
|
function refreshSaveBtn(name, hasResult, correct) {
|
||||||
|
const b = $("#saveBtn");
|
||||||
if (!b) return;
|
if (!b) return;
|
||||||
const exists = name ? !!hel_entry(name) : false;
|
const stored = name ? !!hel_entry(name) : false;
|
||||||
b.classList.toggle("is-stored", exists);
|
b.classList.remove("is-correct", "is-stored");
|
||||||
b.disabled = exists || !name;
|
if (!name) {
|
||||||
b.textContent = exists ? "Stored ✓" : "Store";
|
b.disabled = true; b.textContent = "Store";
|
||||||
b.title = exists ? "This name is already in your catalog" : "Save this name in this browser";
|
b.title = "Save this name in your catalog";
|
||||||
}
|
} else if (!stored) {
|
||||||
function refreshCorrectBtn(enabled, isCorrect) {
|
b.disabled = false; b.textContent = "Store";
|
||||||
const b = $("#markCorrect");
|
b.title = "Save this name in your catalog";
|
||||||
if (!b) return;
|
} else if (correct) {
|
||||||
b.disabled = !enabled;
|
b.disabled = false; b.textContent = "Correct ✓"; b.classList.add("is-correct");
|
||||||
b.classList.toggle("is-correct", !!enabled && !!isCorrect);
|
b.title = "This name + master is verified. Click to unmark.";
|
||||||
b.textContent = enabled && isCorrect ? "Correct ✓" : "Mark correct";
|
} else if (hasResult) {
|
||||||
b.title = enabled && isCorrect
|
b.disabled = false; b.textContent = "Correct";
|
||||||
? "This name and master are remembered as correct on this device. Click to forget."
|
b.title = "Mark this name + master correct, so it shows in colour";
|
||||||
: "Remember this name and master as correct on this device, so this combination shows in colour.";
|
} else {
|
||||||
|
b.disabled = true; b.textContent = "Stored ✓"; b.classList.add("is-stored");
|
||||||
|
b.title = "In your catalog. Type the master to mark it correct.";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
function quickGen(silent) {
|
function quickGen(silent) {
|
||||||
const spec = $("#qname").value.trim();
|
const spec = $("#qname").value.trim();
|
||||||
@@ -295,8 +302,7 @@
|
|||||||
if (!name) {
|
if (!name) {
|
||||||
sec.textContent = ""; sec.classList.remove("correct");
|
sec.textContent = ""; sec.classList.remove("correct");
|
||||||
lenEl.textContent = ""; lastSecret = "";
|
lenEl.textContent = ""; lastSecret = "";
|
||||||
refreshCorrectBtn(false, false);
|
refreshSaveBtn("", false, false);
|
||||||
refreshStoreBtn("");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const master = masterEl().value;
|
const master = masterEl().value;
|
||||||
@@ -325,45 +331,31 @@
|
|||||||
sec.textContent = pw;
|
sec.textContent = pw;
|
||||||
sec.classList.toggle("correct", correct);
|
sec.classList.toggle("correct", correct);
|
||||||
lenEl.textContent = pw ? "len " + pw.length : "";
|
lenEl.textContent = pw ? "len " + pw.length : "";
|
||||||
refreshCorrectBtn(!!pw, correct);
|
refreshSaveBtn(name, !!pw, correct);
|
||||||
refreshStoreBtn(name);
|
|
||||||
if (!pw && !silent) toast("No output");
|
if (!pw && !silent) toast("No output");
|
||||||
}
|
}
|
||||||
function toggleCorrect() {
|
// One click advances the progressive button by one step (Store → Correct →
|
||||||
const b = $("#markCorrect");
|
// unmark). Each step is the same command you could type in the console.
|
||||||
|
function saveStep() {
|
||||||
|
const b = $("#saveBtn");
|
||||||
if (!b || b.disabled) return;
|
if (!b || b.disabled) return;
|
||||||
const spec = $("#qname").value.trim();
|
const spec = $("#qname").value.trim();
|
||||||
const name = hel_parse_name(spec);
|
const name = hel_parse_name(spec);
|
||||||
if (!name) return;
|
if (!name) return;
|
||||||
const marking = !b.classList.contains("is-correct");
|
const stored = !!hel_entry(name);
|
||||||
const exists = !!hel_entry(name);
|
if (!stored) {
|
||||||
// Marking correct also STORES the name (you only confirm things you keep), so
|
hel_command("add " + spec); // file the name in the catalog
|
||||||
// the entry stays in the catalog. The hash is SHA1(name‖password) on the device.
|
|
||||||
if (marking) {
|
|
||||||
if (!exists) hel_command("add " + spec); // store it if new
|
|
||||||
hel_command("correct " + name);
|
|
||||||
persist();
|
persist();
|
||||||
} else if (exists) {
|
appendLine('<span class="muted"># stored ' + esc(name) + "</span>");
|
||||||
hel_command("uncorrect " + name); // drop the hash; keep the stored name
|
toast("Stored " + name);
|
||||||
|
} else if (b.classList.contains("is-correct")) {
|
||||||
|
hel_command("uncorrect " + name); // stored entry → removes the hash
|
||||||
|
toast("No longer marked correct");
|
||||||
} else {
|
} else {
|
||||||
// not stored (e.g. a stale hash): wrap add/rm so uncorrect can recompute the
|
hel_command("correct " + name); // stored + master present → verify (colour)
|
||||||
// password to remove the right hash, without leaving the entry behind.
|
toast("Marked correct");
|
||||||
hel_command("add " + spec);
|
|
||||||
hel_command("uncorrect " + name);
|
|
||||||
hel_command("rm " + name);
|
|
||||||
}
|
}
|
||||||
quickGen(true);
|
quickGen(true);
|
||||||
toast(marking ? "Marked correct & stored" : "No longer marked correct");
|
|
||||||
}
|
|
||||||
function quickStore() {
|
|
||||||
const spec = $("#qname").value.trim();
|
|
||||||
if (!spec) return toast("Enter a name");
|
|
||||||
const name = hel_parse_name(spec) || spec.split(/\s+/)[0];
|
|
||||||
const out = hel_command("add " + spec);
|
|
||||||
persist();
|
|
||||||
appendLine('<span class="muted"># stored ' + esc(name) + "</span>");
|
|
||||||
refreshStoreBtn(name);
|
|
||||||
toast(/^(error|warning)/m.test(out) ? out.split("\n")[0] : "Stored " + name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---- console ----
|
// ---- console ----
|
||||||
@@ -495,8 +487,7 @@
|
|||||||
// Click the master field to show what you typed; click again to re-mask.
|
// Click the master field to show what you typed; click again to re-mask.
|
||||||
$("#master").addEventListener("click", () => $("#master").classList.toggle("revealed"));
|
$("#master").addEventListener("click", () => $("#master").classList.toggle("revealed"));
|
||||||
$("#copy").onclick = () => (lastSecret ? copyText(lastSecret) : toast("Nothing to copy"));
|
$("#copy").onclick = () => (lastSecret ? copyText(lastSecret) : toast("Nothing to copy"));
|
||||||
$("#store").onclick = quickStore;
|
$("#saveBtn").onclick = saveStep;
|
||||||
$("#markCorrect").onclick = toggleCorrect;
|
|
||||||
|
|
||||||
// pass overlay wiring
|
// pass overlay wiring
|
||||||
$("#passOk").onclick = submitPass;
|
$("#passOk").onclick = submitPass;
|
||||||
|
|||||||
Reference in New Issue
Block a user