Your avatar is your photo, picked from the device by tapping it on Home or from a new Profile photo row in Settings, shrunk to 256 px and kept on the phone (there is no upload endpoint yet). Group members show the photo the server sends in a new `photo` field, everywhere avatars appear. Without a photo, an initial on a neutral disc. Mock mode bundles free Unsplash portraits for the sample people. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KhQh614DMeYoQEH9SoMRUw
108 lines
3.6 KiB
Dart
108 lines
3.6 KiB
Dart
// MOCK DATA — TEMPORARY. See MockSwitch.dart.
|
|
|
|
import 'dart:math';
|
|
|
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
|
|
|
import '../about/internal/application/MeDescription.dart';
|
|
import '../about/internal/application/RoutineRunRecord.dart';
|
|
import '../about/internal/application/TodoItem.dart';
|
|
import '../about/internal/application/UserDetails.dart';
|
|
import '../memory/InternalMemory.dart';
|
|
import 'MockStorage.dart';
|
|
|
|
/// The real [InternalMemory], pointed at in-memory storage and pre-seeded
|
|
/// with a signed-in user so the app opens straight onto Home.
|
|
class MockMemory extends InternalMemory {
|
|
static bool _seeded = false;
|
|
|
|
MockMemory() {
|
|
if (!_seeded) {
|
|
_seeded = true;
|
|
setMyDescription(
|
|
MeDescription(id: "mock-user", name: "Alex", token: "mock-token"));
|
|
setUserDetails(UserDetails(
|
|
pic: "asset:assets/images/person_alex.jpg", name: "Alex"));
|
|
setTodos(<TodoItem>[
|
|
TodoItem(id: "t1", title: "Pick up gym kit"),
|
|
TodoItem(id: "t2", title: "Book physio for Thursday"),
|
|
TodoItem(id: "t3", title: "Reply to Sam about Saturday", done: true),
|
|
]);
|
|
setRunLog(_history());
|
|
}
|
|
}
|
|
|
|
/// Six weeks of runs against the seeded routines, mostly held, with the
|
|
/// odd broken chain and skipped day, so Progress has a shape to draw.
|
|
static List<RoutineRunRecord> _history() {
|
|
final Random random = Random(11);
|
|
final DateTime now = DateTime.now();
|
|
final DateTime today = DateTime(now.year, now.month, now.day);
|
|
final List<RoutineRunRecord> records = <RoutineRunRecord>[];
|
|
|
|
void add(DateTime day, String id, String title, String kind, int minute,
|
|
int seconds, int steps, double holdRate) {
|
|
final DateTime at = day.add(Duration(minutes: minute));
|
|
if (at.isAfter(now)) {
|
|
return;
|
|
}
|
|
final bool held = random.nextDouble() < holdRate;
|
|
records.add(RoutineRunRecord(
|
|
routineId: id,
|
|
title: title,
|
|
kind: kind,
|
|
startedAt: at,
|
|
seconds:
|
|
(seconds * (held ? 1 : 0.5) * (0.85 + random.nextDouble() * 0.3))
|
|
.round(),
|
|
completedSteps: held ? steps : 1 + random.nextInt(steps - 1),
|
|
totalSteps: steps,
|
|
));
|
|
}
|
|
|
|
for (int ago = 42; ago >= 1; ago--) {
|
|
final DateTime day = today.subtract(Duration(days: ago));
|
|
final int weekday = day.weekday;
|
|
|
|
// A quiet day now and then: nothing run at all.
|
|
if (random.nextDouble() < 0.12) {
|
|
continue;
|
|
}
|
|
if (weekday <= 5) {
|
|
add(day, "routine-morning", "Morning non-negotiables", "MustDo",
|
|
7 * 60 + 15, 14 * 60, 4, 0.85);
|
|
add(day, "routine-shutdown", "Evening shutdown", "MustDo", 18 * 60,
|
|
9 * 60, 4, 0.6);
|
|
}
|
|
if (weekday == 1 || weekday == 3 || weekday == 5) {
|
|
add(day, "routine-strength", "Full body strength", "Workout",
|
|
17 * 60 + 30, 44 * 60, 6, 0.75);
|
|
}
|
|
if (weekday >= 6) {
|
|
add(day, "routine-mobility", "Mobility flow", "Workout", 10 * 60,
|
|
22 * 60, 5, 0.8);
|
|
}
|
|
if (random.nextDouble() < 0.35) {
|
|
add(day, "routine-breathing", "Box breathing", "Meditation", 21 * 60,
|
|
8 * 60, 3, 0.95);
|
|
}
|
|
}
|
|
|
|
// Today: the morning chain is already held in the seeded routines.
|
|
records.add(RoutineRunRecord(
|
|
routineId: "routine-morning",
|
|
title: "Morning non-negotiables",
|
|
kind: "MustDo",
|
|
startedAt: today.add(const Duration(minutes: 7 * 60 + 10)),
|
|
seconds: 13 * 60 + 40,
|
|
completedSteps: 4,
|
|
totalSteps: 4,
|
|
));
|
|
|
|
return records;
|
|
}
|
|
|
|
@override
|
|
FlutterSecureStorage get groundedStorage => const MockStorage();
|
|
}
|