|
|
… |
142 unchanged lines |
| 143 |
143 |
|
/** |
| 144 |
144 |
|
* A home screen widget (#28): your latest runs, unread notifications and |
| 145 |
145 |
|
* reviews waiting; a tap opens the app. The OxygenHub mark heads it and Your |
| 146 |
|
- |
* sky is drawn behind it, at the widget's own size (#30); a row of counts |
| 147 |
|
- |
* and the phone's runner job runs along its foot (#31). |
|
146 |
+ |
* sky is drawn behind it, at the widget's own size (#30); its counts sit |
|
147 |
+ |
* in its header, and the phone's runner job at its foot (#31, #33). |
| 148 |
148 |
|
*/ |
| 149 |
149 |
|
class HubWidget : GlanceAppWidget() { |
| 150 |
150 |
|
/** Composed for each size the launcher shows it at, so the sky fits exactly. */ |
|
|
… |
89 unchanged lines |
| 240 |
240 |
|
@Composable |
| 241 |
241 |
|
private fun Body(d: WidgetData, title: TextStyle, body: TextStyle, mute: TextStyle) { |
| 242 |
242 |
|
Column(GlanceModifier.fillMaxSize()) { |
| 243 |
|
- |
Row(verticalAlignment = Alignment.CenterVertically) { |
|
243 |
+ |
// The counts sit in the header, right of the title, so the lines below can never push them off (#33). |
|
244 |
+ |
Row(GlanceModifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) { |
| 244 |
245 |
|
Image(ImageProvider(R.drawable.mark), contentDescription = null, modifier = GlanceModifier.size(width = 28.dp, height = 14.dp)) |
| 245 |
246 |
|
Spacer(GlanceModifier.width(6.dp)) |
| 246 |
|
- |
Text("OxygenHub", style = title) |
|
247 |
+ |
Text("OxygenHub", style = title, modifier = GlanceModifier.defaultWeight()) |
|
248 |
+ |
if (d.signedIn) Counts(d) |
| 247 |
249 |
|
} |
| 248 |
250 |
|
Spacer(GlanceModifier.height(6.dp)) |
| 249 |
251 |
|
if (!d.signedIn) { |
|
|
… |
12 unchanged lines |
| 262 |
264 |
|
NeedsYou(d, body) |
| 263 |
265 |
|
Spacer(GlanceModifier.defaultWeight()) |
| 264 |
266 |
|
Health(d, mute) |
| 265 |
|
- |
Spacer(GlanceModifier.height(6.dp)) |
| 266 |
|
- |
Counts(d) |
|
267 |
+ |
Runner(d) |
| 267 |
268 |
|
} |
| 268 |
269 |
|
} |
| 269 |
270 |
|
|
| 270 |
271 |
|
/** |
| 271 |
|
- |
* The row along the bottom (#31): unread messages, proposals to review and |
|
272 |
+ |
* The counts in the header (#31, #33): unread messages, proposals to review and |
| 272 |
273 |
|
* issues assigned, each an icon and its number (dimmed at zero, left out |
| 273 |
|
- |
* when the hub cannot say), then what the phone runs while it serves as a |
| 274 |
|
- |
* runner. Each opens its screen in the app. |
|
274 |
+ |
* when the hub cannot say). Each opens its screen in the app. |
| 275 |
275 |
|
*/ |
| 276 |
276 |
|
@Composable |
| 277 |
277 |
|
private fun Counts(d: WidgetData) { |
| 278 |
|
- |
Row(GlanceModifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) { |
|
278 |
+ |
Row(verticalAlignment = Alignment.CenterVertically) { |
| 279 |
279 |
|
d.unread?.let { Count(R.drawable.widget_inbox, "unread", it, WidgetTaps.action("inbox")) } |
| 280 |
280 |
|
d.reviews?.let { n -> |
| 281 |
281 |
|
val r = d.onlyReview |
|
|
… |
3 unchanged lines |
| 285 |
285 |
|
val i = d.onlyAssigned |
| 286 |
286 |
|
Count(R.drawable.widget_issue, "assigned", n.toLong(), if (i != null) WidgetTaps.action("issue", i.repository, i.number) else WidgetTaps.action("dashboard")) |
| 287 |
287 |
|
} |
| 288 |
|
- |
d.runnerJobs?.let { jobs -> |
| 289 |
|
- |
Row(GlanceModifier.defaultWeight().clickable(WidgetTaps.action("account")), verticalAlignment = Alignment.CenterVertically) { |
| 290 |
|
- |
Image(ImageProvider(R.drawable.widget_runner), contentDescription = "This phone runs", colorFilter = ColorFilter.tint(ok), modifier = GlanceModifier.size(14.dp)) |
| 291 |
|
- |
Spacer(GlanceModifier.width(4.dp)) |
| 292 |
|
- |
Text(runnerLine(jobs), style = TextStyle(color = GlanceTheme.colors.onSurface, fontSize = 12.sp), maxLines = 1) |
| 293 |
|
- |
} |
| 294 |
|
- |
} |
|
288 |
+ |
} |
|
289 |
+ |
} |
|
290 |
+ |
|
|
291 |
+ |
/** While the phone serves as a runner (#31): what it runs, under the health strip. */ |
|
292 |
+ |
@Composable |
|
293 |
+ |
private fun Runner(d: WidgetData) { |
|
294 |
+ |
val jobs = d.runnerJobs ?: return |
|
295 |
+ |
Spacer(GlanceModifier.height(4.dp)) |
|
296 |
+ |
Row(GlanceModifier.fillMaxWidth().clickable(WidgetTaps.action("account")), verticalAlignment = Alignment.CenterVertically) { |
|
297 |
+ |
Image(ImageProvider(R.drawable.widget_runner), contentDescription = "This phone runs", colorFilter = ColorFilter.tint(ok), modifier = GlanceModifier.size(13.dp)) |
|
298 |
+ |
Spacer(GlanceModifier.width(6.dp)) |
|
299 |
+ |
Text(runnerLine(jobs), style = TextStyle(color = GlanceTheme.colors.onSurface, fontSize = 12.sp), maxLines = 1) |
| 295 |
300 |
|
} |
| 296 |
301 |
|
} |
| 297 |
302 |
|
|
|
|
… |
49 unchanged lines |
| 347 |
352 |
|
@Composable |
| 348 |
353 |
|
private fun Count(icon: Int, what: String, n: Long, open: Action) { |
| 349 |
354 |
|
val colour = if (n == 0L) GlanceTheme.colors.onSurfaceVariant else headline |
| 350 |
|
- |
Row(GlanceModifier.padding(end = 14.dp).clickable(open), verticalAlignment = Alignment.CenterVertically) { |
|
355 |
+ |
Row(GlanceModifier.padding(start = 12.dp).clickable(open), verticalAlignment = Alignment.CenterVertically) { |
| 351 |
356 |
|
Image(ImageProvider(icon), contentDescription = "$n $what", colorFilter = ColorFilter.tint(colour), modifier = GlanceModifier.size(14.dp)) |
| 352 |
357 |
|
Spacer(GlanceModifier.width(4.dp)) |
| 353 |
358 |
|
Text("$n", style = TextStyle(color = colour, fontSize = 13.sp, fontWeight = FontWeight.Bold)) |
|
|
… |
9 unchanged lines |