Stage 2: Library search, filters and Exercise detail with Flip Animation
- LibraryFilter: word search on names; muscle (primary), equipment and level choices that widen within a filter and narrow across filters - ExerciseBrowser (reusable for the Plan picker) with search field, filter sheets showing live result counts, a clear button and an empty state - Exercise detail: start/end Flip Animation at each Mode's pace (still with reduced motion), facts, main/secondary muscles, numbered steps Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
1289fadb98
commit
786dd52e30
16 files changed
+1272
-32
No files matched your search
@@ -1,3 +1,4 @@
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
@@ -7,25 +8,51 @@ import 'package:zenxercise/src/exercises/exercise_library.dart';
|
||||
import 'package:zenxercise/src/modes/mode.dart';
|
||||
import 'package:zenxercise/src/settings/settings_controller.dart';
|
||||
|
||||
Exercise exercise(String id, Mode mode, {String? name, int imageCount = 0}) => Exercise(
|
||||
Exercise exercise(
|
||||
String id,
|
||||
Mode mode, {
|
||||
String? name,
|
||||
List<String> primary = const ['hamstrings'],
|
||||
List<String> secondary = const [],
|
||||
String? equipment = 'body only',
|
||||
String level = 'beginner',
|
||||
List<String> instructions = const ['Breathe.'],
|
||||
int imageCount = 0,
|
||||
}) => Exercise(
|
||||
id: id,
|
||||
name: name ?? id.replaceAll('_', ' '),
|
||||
mode: mode,
|
||||
category: mode == Mode.stretching ? 'stretching' : 'strength',
|
||||
level: 'beginner',
|
||||
equipment: 'body only',
|
||||
primaryMuscles: const ['hamstrings'],
|
||||
secondaryMuscles: const [],
|
||||
instructions: const ['Breathe.'],
|
||||
level: level,
|
||||
equipment: equipment,
|
||||
primaryMuscles: primary,
|
||||
secondaryMuscles: secondary,
|
||||
instructions: instructions,
|
||||
imageCount: imageCount,
|
||||
);
|
||||
|
||||
/// Two stretches and a squat. The 90/90 Hamstring's images exist in the real assets.
|
||||
final sampleLibrary = ExerciseLibrary([
|
||||
exercise('Hamstring_Stretch', Mode.stretching),
|
||||
exercise('Calf_Stretch', Mode.stretching),
|
||||
exercise('Barbell_Squat', Mode.workout),
|
||||
exercise(
|
||||
'90_90_Hamstring',
|
||||
Mode.stretching,
|
||||
name: '90/90 Hamstring',
|
||||
secondary: const ['calves'],
|
||||
instructions: const ['Lie on your back.', 'Straighten one leg.'],
|
||||
imageCount: 2,
|
||||
),
|
||||
exercise('Calf_Stretch', Mode.stretching, primary: const ['calves'], equipment: 'other', level: 'intermediate'),
|
||||
exercise('Barbell_Squat', Mode.workout, primary: const ['quadriceps'], equipment: 'barbell'),
|
||||
]);
|
||||
|
||||
/// A Pixel-sized screen instead of the default 800×600, so the floating
|
||||
/// navigation bar does not cover what a test taps.
|
||||
void usePhoneScreen(WidgetTester tester) {
|
||||
tester.view.physicalSize = const Size(1080, 2400);
|
||||
tester.view.devicePixelRatio = 2.75;
|
||||
addTearDown(tester.view.reset);
|
||||
}
|
||||
|
||||
/// The whole app over [library], with preferences starting from [prefs].
|
||||
Future<SettingsController> pumpApp(
|
||||
WidgetTester tester, {
|
||||
|
||||
Reference in new issue
Block a user