|
| 1 | +/* |
| 2 | + * ============================================================================ |
| 3 | + * Name : SetupUiState.java |
| 4 | + * Author : AppDevForAll |
| 5 | + * Copyright : Copyright (c) 2026 AppDevForAll |
| 6 | + * Description : K2GO-434. The setup screen's derived view state as a pure rule: the status dot tone, |
| 7 | + * the status message, whether to animate the waiting ellipsis, the bottom-controls mode |
| 8 | + * and whether "Run in background" shows. Semantic enums only (no Android resource ids), |
| 9 | + * so the mapping to R.color/R.string and to show()/schedule/cancel stays in the Activity |
| 10 | + * and this stays unit-testable on a plain JVM. Slice 3 of |
| 11 | + * controller/docs/ADR-434-setupprogress-decomposition.md. |
| 12 | + * ============================================================================ |
| 13 | + */ |
| 14 | +package org.appdevforall.k2go.setup.domain; |
| 15 | + |
| 16 | +public final class SetupUiState { |
| 17 | + |
| 18 | + /** The status dot tone: a calm run vs a run that is waiting/working. */ |
| 19 | + public enum StatusTone { NEUTRAL, WAITING } |
| 20 | + |
| 21 | + /** The status line message (mapped to a string resource by the Activity). */ |
| 22 | + public enum StatusMessage { STARTING, SLOW, ADDING, INSTALLING } |
| 23 | + |
| 24 | + /** The bottom-controls mode (mapped to show()/scheduleRedirect()/cancelRedirect() by the Activity). */ |
| 25 | + public enum Controls { REDIRECT, FINISH_SUCCESS, FINISH_FAILURE, RUNNING } |
| 26 | + |
| 27 | + public final StatusTone tone; |
| 28 | + public final StatusMessage message; |
| 29 | + public final boolean animate; |
| 30 | + public final Controls controls; |
| 31 | + public final boolean runInBackgroundVisible; |
| 32 | + |
| 33 | + private SetupUiState(StatusTone tone, StatusMessage message, boolean animate, |
| 34 | + Controls controls, boolean runInBackgroundVisible) { |
| 35 | + this.tone = tone; |
| 36 | + this.message = message; |
| 37 | + this.animate = animate; |
| 38 | + this.controls = controls; |
| 39 | + this.runInBackgroundVisible = runInBackgroundVisible; |
| 40 | + } |
| 41 | + |
| 42 | + public static SetupUiState from(Inputs in) { |
| 43 | + // Amber "working" while a module runs, its post-batch restart is pending, or the batch ended |
| 44 | + // with a failed module; never while the server is slow (that is a terminal failure). |
| 45 | + boolean amberWaiting = !in.batchServerSlow |
| 46 | + && (in.moduleFailed || (in.moduleFlow ? !in.batchServerUp : !in.servicesReady)); |
| 47 | + StatusTone tone = (amberWaiting || in.batchServerSlow) ? StatusTone.WAITING : StatusTone.NEUTRAL; |
| 48 | + |
| 49 | + StatusMessage message; |
| 50 | + if (in.batchServerSlow) message = StatusMessage.SLOW; // could not bring services up in time |
| 51 | + else if (in.batchServerSettling) message = StatusMessage.STARTING; // reconciler is (re)starting the server |
| 52 | + else if (in.moduleFlow && !in.batchServerUp) message = StatusMessage.INSTALLING; // runroles in flight |
| 53 | + else if (in.moduleFailed) message = StatusMessage.INSTALLING; // keep the amber install header on a failed batch |
| 54 | + else if (in.moduleFlow) message = StatusMessage.ADDING; // module done + server up |
| 55 | + else if (!in.servicesReady) message = in.slowByPolls ? StatusMessage.SLOW : StatusMessage.STARTING; |
| 56 | + else message = StatusMessage.ADDING; |
| 57 | + |
| 58 | + Controls controls; |
| 59 | + if (in.success && !in.redirectCancelled) controls = Controls.REDIRECT; |
| 60 | + else if (in.success) controls = Controls.FINISH_SUCCESS; // success, countdown cancelled by the user |
| 61 | + else if (in.failure) controls = Controls.FINISH_FAILURE; |
| 62 | + else controls = Controls.RUNNING; |
| 63 | + |
| 64 | + return new SetupUiState(tone, message, amberWaiting, controls, in.runInBackgroundEnabled); |
| 65 | + } |
| 66 | + |
| 67 | + /** The inputs the rule reads, gathered by the Activity from its live sources. */ |
| 68 | + public static final class Inputs { |
| 69 | + boolean batchServerSlow, batchServerSettling, batchServerUp, moduleFlow, moduleFailed; |
| 70 | + boolean servicesReady, slowByPolls, success, failure, redirectCancelled, runInBackgroundEnabled; |
| 71 | + |
| 72 | + public Inputs batchServerSlow(boolean v) { this.batchServerSlow = v; return this; } |
| 73 | + public Inputs batchServerSettling(boolean v) { this.batchServerSettling = v; return this; } |
| 74 | + public Inputs batchServerUp(boolean v) { this.batchServerUp = v; return this; } |
| 75 | + public Inputs moduleFlow(boolean v) { this.moduleFlow = v; return this; } |
| 76 | + public Inputs moduleFailed(boolean v) { this.moduleFailed = v; return this; } |
| 77 | + public Inputs servicesReady(boolean v) { this.servicesReady = v; return this; } |
| 78 | + public Inputs slowByPolls(boolean v) { this.slowByPolls = v; return this; } |
| 79 | + public Inputs success(boolean v) { this.success = v; return this; } |
| 80 | + public Inputs failure(boolean v) { this.failure = v; return this; } |
| 81 | + public Inputs redirectCancelled(boolean v) { this.redirectCancelled = v; return this; } |
| 82 | + public Inputs runInBackgroundEnabled(boolean v) { this.runInBackgroundEnabled = v; return this; } |
| 83 | + public SetupUiState build() { return SetupUiState.from(this); } |
| 84 | + } |
| 85 | +} |
0 commit comments