Add Coach, take the reference's colours and copy its nav and motion
Coach is the centre tab: questions about routines, slips, streak, today, active time and debt, answered on the device from the user's own data, with a target bar chart and buttons that start routines or open the right screen. The palette moves to neutral grey, near-black and one orange accent, and Home's header becomes a light panel. The nav is now overlapping frosted circles whose active disc pops forward, and tabs fade and rise in on switch. Goals leaves the nav for Coach and stays one tap away in Home's category row. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KhQh614DMeYoQEH9SoMRUw
This commit is contained in:
107
frontend/lib/Grounded/see/coach/ViewCoach.dart
Normal file
107
frontend/lib/Grounded/see/coach/ViewCoach.dart
Normal file
@@ -0,0 +1,107 @@
|
||||
import '../../about/external/data/Commitment.dart';
|
||||
import '../../about/external/data/RoutineChain.dart';
|
||||
import '../../about/external/data/pages/request/CommitmentsRequest.dart';
|
||||
import '../../about/external/data/pages/request/HistoryRequest.dart';
|
||||
import '../../about/external/data/pages/request/PageAndSort.dart';
|
||||
import '../../about/external/data/pages/request/Pageable.dart';
|
||||
import '../../about/external/data/pages/request/Sort.dart';
|
||||
import '../../about/external/data/pages/response/CommitmentPage.dart';
|
||||
import '../../about/internal/application/CoachContext.dart';
|
||||
import '../../about/internal/application/CoachMessage.dart';
|
||||
import '../../utils/CoachEngine.dart';
|
||||
import '../../utils/ObjectConvertors.dart';
|
||||
import '../parent/ParentViewModel.dart';
|
||||
import 'ConnectCoach.dart';
|
||||
|
||||
class ViewCoach extends ParentViewModel {
|
||||
ConnectCoach connection;
|
||||
|
||||
ViewCoach(super.context, this.connection);
|
||||
|
||||
/// The coach reads fresh data for every question, so an answer never
|
||||
/// lags behind a routine just logged. Network parts fail quietly: the run
|
||||
/// log on the device still answers most questions.
|
||||
void ask(String question) async {
|
||||
final CoachContext data = await _gather();
|
||||
|
||||
// A short beat so the answer reads as considered, not instant.
|
||||
await Future<void>.delayed(const Duration(milliseconds: 700));
|
||||
|
||||
connection.onAnswered(CoachEngine.answer(question, data, DateTime.now()));
|
||||
}
|
||||
|
||||
Future<CoachContext> _gather() async {
|
||||
final PageAndSort page = PageAndSort(
|
||||
sort: Sort('asc', 'startMinute'),
|
||||
page: Pageable(0, 0, 50, 0),
|
||||
);
|
||||
|
||||
List<RoutineChain> routines = <RoutineChain>[];
|
||||
try {
|
||||
final response =
|
||||
await getDataManager().getMyRoutines(HistoryRequest(query: page));
|
||||
routines = getRoutineChainList(response.data);
|
||||
} catch (e) {
|
||||
routines = <RoutineChain>[];
|
||||
}
|
||||
|
||||
List<Commitment> plan = <Commitment>[];
|
||||
try {
|
||||
final response = await getDataManager().getTodayPlan(CommitmentsRequest(
|
||||
query: PageAndSort(
|
||||
sort: Sort('asc', 'dueStart'),
|
||||
page: Pageable(0, 0, 50, 0),
|
||||
),
|
||||
));
|
||||
plan = CommitmentPage.fromJson(response.data).content;
|
||||
} catch (e) {
|
||||
plan = <Commitment>[];
|
||||
}
|
||||
|
||||
List<Commitment> overdue = <Commitment>[];
|
||||
try {
|
||||
final response = await getDataManager().getOverdueQueue(HistoryRequest(
|
||||
query: PageAndSort(
|
||||
sort: Sort('desc', 'dueEnd'),
|
||||
page: Pageable(0, 0, 50, 0),
|
||||
),
|
||||
));
|
||||
overdue = CommitmentPage.fromJson(response.data).content;
|
||||
} catch (e) {
|
||||
overdue = <Commitment>[];
|
||||
}
|
||||
|
||||
return CoachContext(
|
||||
runs: await getDataManager().getRunLog(),
|
||||
routines: routines,
|
||||
targets: await getDataManager().getProgressTargets(),
|
||||
plan: plan,
|
||||
overdue: overdue,
|
||||
debtScore: await getDataManager().getCachedDebtScore(),
|
||||
);
|
||||
}
|
||||
|
||||
/// The routine a "Start" button names, fetched fresh so it runs current
|
||||
/// steps.
|
||||
Future<RoutineChain?> findRoutine(String id) async {
|
||||
try {
|
||||
final response = await getDataManager().getMyRoutines(HistoryRequest(
|
||||
query: PageAndSort(
|
||||
sort: Sort('asc', 'startMinute'),
|
||||
page: Pageable(0, 0, 50, 0),
|
||||
),
|
||||
));
|
||||
for (RoutineChain routine in getRoutineChainList(response.data)) {
|
||||
if (routine.id == id) {
|
||||
return routine;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static CoachMessage question(String text) =>
|
||||
CoachMessage(mine: true, body: text);
|
||||
}
|
||||
Reference in New Issue
Block a user