Switch to Inter, round the corners softly and make the nav switch tabs
Inter replaces General Sans (Inter Display for titles and big numbers). Corners come back from before the squaring commit, scaled to a soft set (16 cards, 14 buttons, 12 rows, 8 chips) and applied to the screens built since. The nav is now a cluster of round frosted buttons that switches Today, Routines, Goals, Groups and Progress in place inside Home: no pushed pages, no back arrows, and Android back returns to Today. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KhQh614DMeYoQEH9SoMRUw
This commit is contained in:
@@ -3,7 +3,11 @@ import 'package:flutter/material.dart';
|
||||
import 'ProgressState.dart';
|
||||
|
||||
class Progress extends StatefulWidget {
|
||||
const Progress({super.key});
|
||||
/// Shown as a tab inside Home: no back arrow, and room at the bottom
|
||||
/// for the nav.
|
||||
final bool tab;
|
||||
|
||||
const Progress({super.key, this.tab = false});
|
||||
|
||||
@override
|
||||
State<Progress> createState() => ProgressState();
|
||||
|
||||
@@ -33,7 +33,13 @@ class ProgressState extends State<Progress> implements ConnectProgress {
|
||||
bool _loaded = false;
|
||||
|
||||
static const List<String> _weekLetters = <String>[
|
||||
"M", "T", "W", "T", "F", "S", "S"
|
||||
"M",
|
||||
"T",
|
||||
"W",
|
||||
"T",
|
||||
"F",
|
||||
"S",
|
||||
"S"
|
||||
];
|
||||
|
||||
@override
|
||||
@@ -130,7 +136,8 @@ class ProgressState extends State<Progress> implements ConnectProgress {
|
||||
return Sheet(
|
||||
eyebrow: "Over time",
|
||||
title: "Progress",
|
||||
onBack: _onBack,
|
||||
onBack: widget.tab ? null : _onBack,
|
||||
bottomSpace: widget.tab ? 130 : 40,
|
||||
action: chromeAction(CupertinoIcons.slider_horizontal_3, _onOpenTargets),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
@@ -175,7 +182,6 @@ class ProgressState extends State<Progress> implements ConnectProgress {
|
||||
"Weekly report card",
|
||||
_onOpenReportCard,
|
||||
icon: CupertinoIcons.doc_text,
|
||||
radius: 0,
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
],
|
||||
@@ -190,7 +196,10 @@ class ProgressState extends State<Progress> implements ConnectProgress {
|
||||
onTap: _onOpenTargets,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.fromLTRB(18, 16, 14, 16),
|
||||
color: colorNight,
|
||||
decoration: BoxDecoration(
|
||||
color: colorNight,
|
||||
borderRadius: const BorderRadius.all(Radius.circular(12)),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(CupertinoIcons.scope, size: 22, color: colorLime),
|
||||
@@ -226,8 +235,7 @@ class ProgressState extends State<Progress> implements ConnectProgress {
|
||||
/// and the bars underneath.
|
||||
Widget _headline() {
|
||||
final int held = ProgressEngine.held(_current);
|
||||
final int target =
|
||||
ProgressEngine.routineTarget(_targets, _period, _start);
|
||||
final int target = ProgressEngine.routineTarget(_targets, _period, _start);
|
||||
final int delta = held - ProgressEngine.held(_previous);
|
||||
|
||||
return card(
|
||||
@@ -270,14 +278,16 @@ class ProgressState extends State<Progress> implements ConnectProgress {
|
||||
}
|
||||
|
||||
Widget _deltaChip(int delta) {
|
||||
final Color tone = delta > 0
|
||||
? colorPositive
|
||||
: (delta < 0 ? colorNegative : colorInkSoft);
|
||||
final Color tone =
|
||||
delta > 0 ? colorPositive : (delta < 0 ? colorNegative : colorInkSoft);
|
||||
final String sign = delta > 0 ? "+" : "";
|
||||
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 9, vertical: 5),
|
||||
color: tone.withValues(alpha: 0.12),
|
||||
decoration: BoxDecoration(
|
||||
color: tone.withValues(alpha: 0.12),
|
||||
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
||||
),
|
||||
child: text("$sign$delta vs $_previousNoun", 11, TextType.Medium,
|
||||
color: tone),
|
||||
);
|
||||
@@ -319,9 +329,12 @@ class ProgressState extends State<Progress> implements ConnectProgress {
|
||||
const SizedBox(height: 4),
|
||||
Container(
|
||||
height: future ? 4 : 6 + 84 * fraction,
|
||||
color: isCurrent
|
||||
? colorNight
|
||||
: (future ? colorMuted : colorChartGrid),
|
||||
decoration: BoxDecoration(
|
||||
color: isCurrent
|
||||
? colorNight
|
||||
: (future ? colorMuted : colorChartGrid),
|
||||
borderRadius: const BorderRadius.all(Radius.circular(4)),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
text(
|
||||
@@ -343,8 +356,7 @@ class ProgressState extends State<Progress> implements ConnectProgress {
|
||||
|
||||
Widget _activeTile() {
|
||||
final int minutes = ProgressEngine.minutes(_current);
|
||||
final int target =
|
||||
ProgressEngine.minuteTarget(_targets, _period, _start);
|
||||
final int target = ProgressEngine.minuteTarget(_targets, _period, _start);
|
||||
|
||||
return _tile(
|
||||
CupertinoIcons.clock,
|
||||
@@ -396,14 +408,20 @@ class ProgressState extends State<Progress> implements ConnectProgress {
|
||||
return Container(
|
||||
margin: const EdgeInsets.only(bottom: 10),
|
||||
padding: const EdgeInsets.fromLTRB(14, 12, 16, 12),
|
||||
color: colorCard,
|
||||
decoration: BoxDecoration(
|
||||
color: colorCard,
|
||||
borderRadius: const BorderRadius.all(Radius.circular(12)),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
width: 42,
|
||||
height: 42,
|
||||
alignment: Alignment.center,
|
||||
color: kindColor(kind).withValues(alpha: 0.14),
|
||||
decoration: BoxDecoration(
|
||||
color: kindColor(kind).withValues(alpha: 0.14),
|
||||
borderRadius: const BorderRadius.all(Radius.circular(12)),
|
||||
),
|
||||
child: Icon(kindIcon(kind), size: 20, color: kindColor(kind)),
|
||||
),
|
||||
const SizedBox(width: 14),
|
||||
|
||||
@@ -166,7 +166,6 @@ class TargetSetupState extends State<TargetSetup>
|
||||
"Save targets",
|
||||
_onSave,
|
||||
icon: CupertinoIcons.checkmark,
|
||||
radius: 0,
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
],
|
||||
@@ -225,8 +224,8 @@ class TargetSetupState extends State<TargetSetup>
|
||||
if (_scheduled != _targets.routinesPerWeek)
|
||||
GestureDetector(
|
||||
onTap: _onMatchSchedule,
|
||||
child: text("Match it", 12, TextType.Medium,
|
||||
color: colorInk),
|
||||
child:
|
||||
text("Match it", 12, TextType.Medium, color: colorInk),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -243,7 +242,10 @@ class TargetSetupState extends State<TargetSetup>
|
||||
width: 48,
|
||||
height: 48,
|
||||
alignment: Alignment.center,
|
||||
color: enabled ? colorNight : colorMuted,
|
||||
decoration: BoxDecoration(
|
||||
color: enabled ? colorNight : colorMuted,
|
||||
borderRadius: const BorderRadius.all(Radius.circular(12)),
|
||||
),
|
||||
child: Icon(icon, size: 20, color: enabled ? colorLime : colorGrey),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -17,11 +17,9 @@ class ViewProgress extends ParentViewModel {
|
||||
/// The runs and targets are on the device, so there is no network guard
|
||||
/// or spinner. Until a target is saved, the schedule stands in for it.
|
||||
void initialise() async {
|
||||
final List<RoutineRunRecord> records =
|
||||
await getDataManager().getRunLog();
|
||||
final List<RoutineRunRecord> records = await getDataManager().getRunLog();
|
||||
|
||||
final ProgressTargets targets =
|
||||
await getDataManager().getProgressTargets();
|
||||
final ProgressTargets targets = await getDataManager().getProgressTargets();
|
||||
|
||||
if (!targets.set) {
|
||||
try {
|
||||
@@ -31,8 +29,8 @@ class ViewProgress extends ParentViewModel {
|
||||
page: Pageable(0, 0, 50, 0),
|
||||
),
|
||||
));
|
||||
final int scheduled = ProgressEngine.scheduledPerWeek(
|
||||
getRoutineChainList(response.data));
|
||||
final int scheduled =
|
||||
ProgressEngine.scheduledPerWeek(getRoutineChainList(response.data));
|
||||
if (scheduled > 0) {
|
||||
targets.routinesPerWeek = scheduled;
|
||||
}
|
||||
|
||||
@@ -20,8 +20,7 @@ class ViewTargetSetup extends ParentViewModel {
|
||||
/// Targets are on the device; the routines are only needed to count the
|
||||
/// schedule and to place reminders, so their failure is quiet.
|
||||
void initialise() async {
|
||||
final ProgressTargets targets =
|
||||
await getDataManager().getProgressTargets();
|
||||
final ProgressTargets targets = await getDataManager().getProgressTargets();
|
||||
|
||||
try {
|
||||
final response = await getDataManager().getMyRoutines(HistoryRequest(
|
||||
|
||||
Reference in New Issue
Block a user