aboutsummaryrefslogtreecommitdiff
path: root/source/ui/QueueMenu.mc
diff options
context:
space:
mode:
Diffstat (limited to 'source/ui/QueueMenu.mc')
-rw-r--r--source/ui/QueueMenu.mc78
1 files changed, 65 insertions, 13 deletions
diff --git a/source/ui/QueueMenu.mc b/source/ui/QueueMenu.mc
index 3f9161d..0ec9daf 100644
--- a/source/ui/QueueMenu.mc
+++ b/source/ui/QueueMenu.mc
@@ -5,20 +5,32 @@
// the point is that a person at the watch agrees, not that a key is
// available. (Before any PIN exists only "Require PIN" can wait here, and
// confirming creates the PIN. "Require PIN" items are applied by the PIN
-// screen itself, ChangeQueue.applyLocks, and listed in the results.) The changes are then applied by a
-// ChangeQueueJob on a timer and the results screen shows what happened.
+// screen itself, LockJob, and listed in the results.) The changes are then
+// applied by a ChangeQueueJob on a timer and the results screen shows what
+// happened. The menu is built from DescribeJob's lines, read behind a short
+// "Reading…" screen (opening 16 items in one event trips the watchdog).
import Toybox.Lang;
import Toybox.WatchUi;
module QueueMenu {
- function build() as WatchUi.Menu2 {
+ // The "Reading…" screen while it runs (kept so the runner isn't collected).
+ var screen as QueueMenuScreen? = null;
+
+ // Open the menu (replacing the current view).
+ function open() as Void {
+ var s = new QueueMenuScreen();
+ screen = s;
+ s.start();
+ }
+
+ // The menu for these descriptions (DescribeJob.lines).
+ function build(items as Array<String>) as WatchUi.Menu2 {
var vault = AppState.theVault();
var menu = new WatchUi.Menu2({:title => "Phone changes"});
menu.addItem(new WatchUi.MenuItem("Confirm all", vault.hasPin() ? "Asks for your PIN" : "Sets a PIN first", :confirm, null));
menu.addItem(new WatchUi.MenuItem("Reject all", null, :reject, null));
- var items = ChangeQueue.descriptions(vault);
for (var i = 0; i < items.size(); i++) {
menu.addItem(new WatchUi.MenuItem(items[i], null, i, null));
}
@@ -26,10 +38,44 @@ module QueueMenu {
}
}
-class QueueMenuDelegate extends WatchUi.Menu2InputDelegate {
+// Shows "Reading…", runs DescribeJob, then replaces that screen with the
+// menu, unless the user left it meanwhile.
+class QueueMenuScreen {
+
+ var runner as Jobs.JobRunner? = null;
+ private var _job as DescribeJob = new DescribeJob(AppState.theVault());
+ private var _reading as InfoView = new InfoView("Phone changes", ["Reading…"] as Array<String>, "queue_reading");
function initialize() {
+ }
+
+ function start() as Void {
+ WatchUi.switchToView(_reading, new InfoDelegate(), WatchUi.SLIDE_LEFT);
+ var r = new Jobs.JobRunner(_job, 1, method(:done));
+ runner = r;
+ r.start();
+ }
+
+ function done() as Void {
+ runner = null;
+ QueueMenu.screen = null;
+ if (WatchUi.getCurrentView()[0] == _reading) {
+ WatchUi.switchToView(QueueMenu.build(_job.lines), new QueueMenuDelegate(_job.lines, _job.keys), WatchUi.SLIDE_IMMEDIATE);
+ }
+ }
+}
+
+class QueueMenuDelegate extends WatchUi.Menu2InputDelegate {
+
+ // The descriptions the menu shows, and the keys of the items read
+ // (DescribeJob): confirming or rejecting acts on exactly those.
+ private var _items as Array<String>;
+ private var _keys as Array<String>;
+
+ function initialize(items as Array<String>, keys as Array<String>) {
Menu2InputDelegate.initialize();
+ _items = items;
+ _keys = keys;
}
function onSelect(item as WatchUi.MenuItem) as Void {
@@ -37,22 +83,25 @@ class QueueMenuDelegate extends WatchUi.Menu2InputDelegate {
var id = item.getId();
var vault = AppState.theVault();
if (id == :confirm) {
- var then = new ApplyQueueAfterPin();
+ var then = new ApplyQueueAfterPin(_keys);
var mode = vault.hasPin() ? PinView.MODE_UNLOCK : PinView.MODE_CREATE;
WatchUi.switchToView(new PinView(mode, then.method(:run)), new PinDelegate(), WatchUi.SLIDE_LEFT);
} else if (id == :reject) {
var lines = ["Rejected these changes from the phone:"] as Array<String>;
- lines.addAll(ChangeQueue.descriptions(vault));
- ChangeQueue.clear(vault);
+ lines.addAll(_items);
+ var late = ChangeQueue.remove(vault, _keys);
+ if (late > 0) {
+ lines.add(late + (late == 1 ? " change" : " changes") + " arrived meanwhile and still "
+ + (late == 1 ? "waits" : "wait") + " (menu, Phone changes)");
+ }
Results.save(lines);
WatchUi.switchToView(new InfoView("Results", lines, "results"), new InfoDelegate(), WatchUi.SLIDE_LEFT);
Results.markSeen();
AppState.processSettings(); // the About fields mention waiting changes
} else if (id instanceof Number) {
// The full text of one change (menu labels are cut short).
- var items = ChangeQueue.descriptions(vault);
- if (id < items.size()) {
- WatchUi.pushView(new InfoView("Change", [items[id]] as Array<String>, "change"), new InfoDelegate(),
+ if (id < _items.size()) {
+ WatchUi.pushView(new InfoView("Change", [_items[id]] as Array<String>, "change"), new InfoDelegate(),
WatchUi.SLIDE_LEFT);
}
}
@@ -65,12 +114,15 @@ class ApplyQueueAfterPin {
// The job's timer driver (kept so it isn't collected while it runs).
var runner as Jobs.JobRunner? = null;
private var _job as ChangeQueueJob? = null;
+ private var _keys as Array<String>;
- function initialize() {
+ // keys: the items the menu showed (DescribeJob.keys).
+ function initialize(keys as Array<String>) {
+ _keys = keys;
}
function run() as Void {
- var job = new ChangeQueueJob(AppState.theVault());
+ var job = new ChangeQueueJob(AppState.theVault(), _keys);
_job = job;
WatchUi.switchToView(new InfoView("Results", ["Applying the changes…"] as Array<String>, "applying"), new InfoDelegate(),
WatchUi.SLIDE_LEFT);