diff options
| author | cirakg <cirakg@cirakg.xyz> | 2026-10-21 03:55:10 +0200 |
|---|---|---|
| committer | cirakg <cirakg@cirakg.xyz> | 2026-10-21 03:55:10 +0200 |
| commit | 5e8ac1e2f5a660e55ea132996e1d5730cfa4fa64 (patch) | |
| tree | 9bb99bdca1ef8f33c93c5100816448681329d810 /source/settings/ManageForm.mc | |
| parent | 88f1cac4fa530fc30fd6ef01970af11c7a959b8e (diff) | |
feat(glance): show the favourite code in the glance (opt-in)
With "Show the favourite code in the glance" on, the glance shows the
code of the first favourite TOTP or Steam entry without the PIN, with a
countdown bar. The glance can't open the vault, so the About scan seals
that entry under "g" (device key, aad OTPW-GL-1) after every change, and
removes it when the option is off or no entry qualifies; the glance also
reads the option itself. HKDF moves to its own module so the glance loads
only the crypto it needs (37 % of its 64 KB). Manage entry gains "Mark as
favourite (glance)" and "Remove favourite", queued for locked entries
like the other changes. Lines are inset on round screens so the
Instinct 3's curved glance corner doesn't cut them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'source/settings/ManageForm.mc')
| -rw-r--r-- | source/settings/ManageForm.mc | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/source/settings/ManageForm.mc b/source/settings/ManageForm.mc index b92c40d..a075880 100644 --- a/source/settings/ManageForm.mc +++ b/source/settings/ManageForm.mc @@ -6,8 +6,8 @@ // * ManageForm.read(): the mg* fields to a ManageAction or a problem. // * ManageRun: a job that checks the action against the entry and then // applies it, or queues it (ChangeQueue) when it touches a locked -// entry: edit, replace, counter, "Don't require PIN" and delete wait -// until the PIN is entered on the watch. "Require PIN" waits too while +// entry: edit, replace, counter, "Don't require PIN", the favourite +// mark and delete wait until the PIN is entered on the watch. "Require PIN" waits too while // the watch is locked (it needs the master key). Moving never waits: // the order isn't protected and a position is absolute, so applying a // move twice can't hit another entry. @@ -28,8 +28,11 @@ class ManageAction { static const REPLACE = 4; static const COUNTER = 5; static const DELETE = 6; + static const FAVORITE = 7; + static const UNFAVORITE = 8; - static const NAMES = ["Edit details", "Move", "Require PIN", "Don't require PIN", "Replace contents", "Set counter", "Delete"]; + static const NAMES = ["Edit details", "Move", "Require PIN", "Don't require PIN", "Replace contents", "Set counter", "Delete", + "Mark as favourite", "Remove favourite"]; // Codec tags of the queued form. static const T_ID = 1; @@ -114,7 +117,7 @@ class ManageAction { if (!(id instanceof String) || !(action instanceof Long) || !(position instanceof Long) || !(counter instanceof Long)) { return null; } - if (action < EDIT || action > DELETE || !Entry.isValidId(id)) { + if (action < EDIT || action > UNFAVORITE || !Entry.isValidId(id)) { return null; } a.id = id; @@ -173,7 +176,7 @@ module ManageForm { return "Entry ID: '" + Text.clip(a.id, 8) + "' is not an ID. IDs have 4 characters, like K7F2"; } var action = Forms.number(store, "mgAction"); - if (action == null || action < ManageAction.EDIT || action > ManageAction.DELETE) { + if (action == null || action < ManageAction.EDIT || action > ManageAction.UNFAVORITE) { return "Action: choose one from the list"; } a.action = action; @@ -334,6 +337,12 @@ class ManageRun extends Jobs.Job { if (a.action == ManageAction.UNLOCK && !header.locked) { return a.id + " doesn't require the PIN"; } + if (a.action == ManageAction.FAVORITE && header.favorite) { + return a.id + " is already a favourite"; + } + if (a.action == ManageAction.UNFAVORITE && !header.favorite) { + return a.id + " is not a favourite"; + } if (a.action == ManageAction.REPLACE && isOtp && !a.decoded) { var raw = a.material as ByteArray; var text = Bytes.toUtf8(raw); @@ -435,7 +444,8 @@ class ManageRun extends Jobs.Job { return true; } - // Edit, lock, unlock or replace: open, change, re-seal. Null or the problem. + // Edit, lock, unlock, (un)favourite or replace: open, change, re-seal. + // Null or the problem. private function changeEntry() as String? { var a = _a; var target = a.id + (a.label.length() > 0 ? " " + a.label : ""); @@ -453,6 +463,9 @@ class ManageRun extends Jobs.Job { } else if (a.action == ManageAction.LOCK || a.action == ManageAction.UNLOCK) { entry.locked = a.action == ManageAction.LOCK; message = target + (entry.locked ? " now requires the PIN" : " no longer requires the PIN"); + } else if (a.action == ManageAction.FAVORITE || a.action == ManageAction.UNFAVORITE) { + entry.favorite = a.action == ManageAction.FAVORITE; + message = target + (entry.favorite ? " is now a favourite" : " is no longer a favourite"); } else { var material = a.material as ByteArray; if (entry.kind == Entry.KIND_OTP) { |
