1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
use crateTone;
// Names this module's prose links to, resolved for rustdoc.
use crate::;
/// What is in a region right now.
///
/// The state, not the shimmer. Whether pending paints a skeleton, a spinner or
/// nothing at all is renderer policy, the same class of decision that got
/// `Fill::fallback` deleted from this crate. goingson and Balanced Breakfast
/// each grew a skeleton with differently-named parts; both keep them, as the
/// webview renderer's expression of [`Readiness::Pending`]. audiofiles has none
/// and needs none, because an immediate-mode renderer simply repaints.
///
/// # Four states and not two
///
/// Naming only `Ready` and `Pending` leaves a screen whose list came back empty
/// with nothing to say about it, so it renders an empty region or invents its
/// own placeholder text and neither says what it is. Left to the apps, the
/// class family drifts: `empty-state`, `empty-state--error`, `error-state` and
/// six more.
///
/// The four are one axis because they are mutually exclusive: a region shows its
/// content, or a sign that it is coming, or a sign that there is none, or a sign
/// that it broke. Never two. That is the test for one enum against several
/// fields, and it is why this grew rather than a new member arriving beside it.
///
/// # What is not here
///
/// **The message.** "No projects yet" is content, and this names a state. It
/// lives with whatever holds the region — in quasi's case a `Slot` — alongside
/// the action that leads out of the emptiness, since an address is the one thing
/// this crate never names.
///
/// **How much room it gets.** goingson's `--compact`, `--dashboard` and
/// `--padded` are the same state at three sizes, and a size is
/// `makeover-geometry`'s question. Naming them here would be this crate stating
/// values again.
///
/// **The icon.** Presentation, and each host has its own answer or none.
/// An action is waiting on something that resolves once, in expected finite
/// time.
///
/// The control-side sibling of [`Readiness`]. That enum names four states for a
/// region and named nothing at all for the button that is currently doing what
/// it was clicked for, so the in-flight treatment is hand-written wherever it
/// exists: the MNW server carries 57 in-flight indicators against 2 guards
/// against a second press, which is the spinner mostly present and the guard
/// mostly absent, on a codebase whose money path is a purchase button.
///
/// # What is described here, and what is not
///
/// The fact is that there is an outstanding thing which will complete. Not that
/// the address is remote: a heavy local query waits too, and a server calling a
/// payment provider is not the browser leaving the app. Not that the call is
/// slow either, which is a judgement about a call rather than a property of one.
///
/// Resolving **once** is the boundary, and it is what separates this from a
/// screen that keeps changing. A live screen never resolves and has no name in
/// this crate yet.
///
/// # One mark, two renderings
///
/// | what reads it | what it does |
/// |---|---|
/// | a control that was pressed | goes busy and refuses a second press until it resolves |
/// | a region fed by it | stands in as [`Readiness::Pending`], then fills |
///
/// The two were on the table separately and both were taken. Controls alone
/// leaves a slow region hand-split into its own route, which is what MNW's user
/// dashboard does with its payout summary; regions alone leaves the purchase
/// button unguarded.
///
/// # A quantity when it is measured, never a duration
///
/// [`amount`](Self::amount) is stated only when it is a measured fact about the
/// payload. An upload's file length, yes; a round trip to a payment provider,
/// [`None`]. A duration is described nowhere, and a renderer may not manufacture
/// one from the amount either: a determinate bar shows what is done over what
/// there is, plus the time it has taken so far, and never a remaining time, an
/// arrival time or a rate extrapolated forwards. A prediction is wrong the
/// moment the transfer stalls, and being confidently wrong is worse than being
/// honestly indeterminate.
///
/// This is why the crate refuses to say how long an undo stays offered and
/// accepts a byte count here. The refusal is about naming a decision that
/// belongs to the renderer; a file's length is not a decision, nobody chose it.
///
/// # Not [`Meter`]
///
/// [`Meter`] is how much of a set is done, and its own docs refuse the progress
/// of an operation on the grounds that a description is built once and dropped
/// while an operation runs between renders. That refusal stands. This names the
/// operation and its size, which is all that is known before it starts; how much
/// of it has gone through is the renderer's to observe live, and nothing round
/// trips through a description to say so.
/// When a picture is needed.
///
/// A claim about *importance and position* rather than a fetch mechanism, which
/// is why it is the description's to make: only the app knows whether a picture
/// is the first thing on the screen or the fortieth thing down a list.
///
/// # Eager is the default, and that is a correctness choice
///
/// Emitting the webview's `loading="lazy"` for every picture reads one
/// consumer's habit as a rule. Deferring a picture that is on screen at first paint does not
/// save anything -- it is needed immediately either way -- and it delays the
/// arrival, so the space it eventually takes is claimed later and the shift is
/// more visible, not less.
///
/// So the safe answer is the default and the optimisation is opted into. A
/// carousel is the case that proves the two cannot be one setting for the
/// renderer to choose: its first frame is on screen and its other frames are
/// not, in the same widget, at the same moment.