fix(map): a region is picked on a screen of its own, and a country's map offered once it is picked
The composer showed the map inside its scrolling page, so zooming and scrolling fought over the wheel. A map question's answer is now a field that opens the map in the whole window, as a studyset's description is written, with Save in the app bar; nothing scrolls there, so the wheel alone zooms. The Prefectures chip stood beside East Asia's countries before Japan was picked; it now shows once Japan, or a prefecture, is. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MMm7usAo6q9ZZRoPkWjoxi Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
43bf1d2987
commit
3181223940
2 changed files with 327 additions and 110 deletions
|
|
@ -6,6 +6,7 @@ import 'package:halkyon_learn_flutter/src/core/content/content_blocks.dart';
|
|||
import 'package:halkyon_learn_flutter/src/core/content/rich_content.dart';
|
||||
import 'package:halkyon_learn_flutter/src/core/editor/rich_content_editor.dart';
|
||||
import 'package:halkyon_learn_flutter/src/core/router/route_paths.dart';
|
||||
import 'package:halkyon_learn_flutter/src/core/widget/chevron_field.dart';
|
||||
import 'package:halkyon_learn_flutter/src/feature/card/data/card_payload.dart';
|
||||
import 'package:halkyon_learn_flutter/src/feature/card/data/card_repository.dart';
|
||||
import 'package:halkyon_learn_flutter/src/feature/card/model/card_content.dart';
|
||||
|
|
@ -122,6 +123,12 @@ void main() {
|
|||
await settle(tester);
|
||||
}
|
||||
|
||||
/// Opens the map from a map question's answer.
|
||||
Future<void> pickOnMap(WidgetTester tester) async {
|
||||
await tester.tap(find.byType(ChevronField));
|
||||
await settle(tester);
|
||||
}
|
||||
|
||||
/// Chooses [item] of the card's ⋮ menu.
|
||||
Future<void> action(WidgetTester tester, String item) async {
|
||||
await tester.tap(find.byTooltip('More actions'));
|
||||
|
|
@ -637,19 +644,32 @@ void main() {
|
|||
expect(saved.back, RichContent.empty());
|
||||
});
|
||||
|
||||
testWidgets('a map question takes the region tapped as its answer', (
|
||||
tester,
|
||||
) async {
|
||||
testWidgets('a map question takes the region tapped on a screen of its '
|
||||
'own, where nothing scrolls, as its answer once saved', (tester) async {
|
||||
await cards.create('japanese', card('Where is Tokyo?', 'east'));
|
||||
await showStudyset(tester, maps: await loadedMaps(tester));
|
||||
await open(tester, 'Where is Tokyo?');
|
||||
|
||||
await tester.tap(find.text('Map'));
|
||||
await settle(tester);
|
||||
expect(find.byType(RegionMap), findsNothing);
|
||||
await pickOnMap(tester);
|
||||
expect(find.text('No region picked yet'), findsOneWidget);
|
||||
expect(
|
||||
find.ancestor(
|
||||
of: find.byType(RegionMap),
|
||||
matching: find.byType(Scrollable),
|
||||
),
|
||||
findsNothing,
|
||||
);
|
||||
expect(tester.widget<RegionMap>(find.byType(RegionMap)).wheelZooms, true);
|
||||
tester.widget<RegionMap>(find.byType(RegionMap)).onRegionTapped!('JP-13');
|
||||
await settle(tester);
|
||||
expect(find.text('Tokyo · 東京都'), findsOneWidget);
|
||||
await tester.tap(find.widgetWithText(FilledButton, 'Save'));
|
||||
await settle(tester);
|
||||
expect(find.byType(RegionMap), findsNothing);
|
||||
expect(find.text('Tokyo · 東京都'), findsOneWidget);
|
||||
await tester.tap(find.byType(BackButton));
|
||||
await settle(tester);
|
||||
|
||||
|
|
@ -676,10 +696,13 @@ void main() {
|
|||
await tester.tap(find.text('Map'));
|
||||
await settle(tester);
|
||||
expect(find.text('Countries of the world'), findsNothing);
|
||||
await pickOnMap(tester);
|
||||
tester.widget<RegionMap>(find.byType(RegionMap)).onRegionTapped!('JP-13');
|
||||
await settle(tester);
|
||||
tester.widget<RegionMap>(find.byType(RegionMap)).onRegionTapped!('CY');
|
||||
await settle(tester);
|
||||
await tester.tap(find.widgetWithText(FilledButton, 'Save'));
|
||||
await settle(tester);
|
||||
// Beside the app's language, the studyset's: Japanese.
|
||||
expect(find.text('Cyprus · キプロス'), findsOneWidget);
|
||||
await tester.tap(find.byType(BackButton));
|
||||
|
|
@ -720,6 +743,7 @@ void main() {
|
|||
|
||||
await tester.tap(find.text('Map'));
|
||||
await settle(tester);
|
||||
await pickOnMap(tester);
|
||||
|
||||
expect(tester.widget<RegionMap>(find.byType(RegionMap)).around, {
|
||||
'JP-13',
|
||||
|
|
@ -731,4 +755,23 @@ void main() {
|
|||
findsOneWidget,
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('leaving the map without saving keeps the answer', (
|
||||
tester,
|
||||
) async {
|
||||
await cards.create('japanese', card('Where is Tokyo?', 'east'));
|
||||
await showStudyset(tester, maps: await loadedMaps(tester));
|
||||
await open(tester, 'Where is Tokyo?');
|
||||
await tester.tap(find.text('Map'));
|
||||
await settle(tester);
|
||||
|
||||
await pickOnMap(tester);
|
||||
tester.widget<RegionMap>(find.byType(RegionMap)).onRegionTapped!('JP-13');
|
||||
await settle(tester);
|
||||
await tester.tap(find.byType(CloseButton));
|
||||
await settle(tester);
|
||||
|
||||
expect(find.byType(RegionMap), findsNothing);
|
||||
expect(find.text('Tap to pick the region on the map'), findsOneWidget);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ void main() {
|
|||
});
|
||||
|
||||
/// Shows the maps at a phone's size, anew unless [key] is the one shown;
|
||||
/// what is picked lands in the list.
|
||||
/// what is picked lands in the list, and shows as picked.
|
||||
Future<List<String>> show(
|
||||
WidgetTester tester, {
|
||||
Key? key,
|
||||
|
|
@ -34,6 +34,7 @@ void main() {
|
|||
..devicePixelRatio = 1;
|
||||
addTearDown(tester.view.reset);
|
||||
final picked = <String>[];
|
||||
final shown = key ?? UniqueKey();
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: appTheme(Brightness.light),
|
||||
|
|
@ -42,14 +43,19 @@ void main() {
|
|||
home: Scaffold(
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: RegionMap(
|
||||
key: key ?? UniqueKey(),
|
||||
atlas: atlas,
|
||||
countryTaps: countryTaps,
|
||||
around: around,
|
||||
right: right,
|
||||
wrong: wrong,
|
||||
onRegionTapped: readOnly ? null : picked.add,
|
||||
child: StatefulBuilder(
|
||||
builder: (context, setState) => RegionMap(
|
||||
key: shown,
|
||||
atlas: atlas,
|
||||
countryTaps: countryTaps,
|
||||
around: around,
|
||||
selected: picked.lastOrNull,
|
||||
right: right,
|
||||
wrong: wrong,
|
||||
onRegionTapped: readOnly
|
||||
? null
|
||||
: (code) => setState(() => picked.add(code)),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
@ -96,11 +102,12 @@ void main() {
|
|||
|
||||
const tokyo = (139.69, 35.69);
|
||||
|
||||
testWidgets('Japan is picked in East Asia, and a chip opens its '
|
||||
'prefectures in layers; Back goes up one', (tester) async {
|
||||
testWidgets('Japan is picked in East Asia, and once it is, a chip opens '
|
||||
'its prefectures in layers; Back goes up one', (tester) async {
|
||||
final picked = await show(tester);
|
||||
|
||||
await choose(tester, 'East Asia');
|
||||
expect(chip('Prefectures'), findsNothing);
|
||||
await tapAt(tester, tokyo);
|
||||
expect(picked, ['JP']);
|
||||
|
||||
|
|
@ -130,6 +137,11 @@ void main() {
|
|||
await tester.tap(back('East Asia'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text('East Asia'), findsOneWidget);
|
||||
// Osaka is within Japan; Seoul isn't.
|
||||
expect(chip('Prefectures'), findsOneWidget);
|
||||
await tapAt(tester, (126.98, 37.57));
|
||||
expect(picked.last, 'KR');
|
||||
expect(chip('Prefectures'), findsNothing);
|
||||
await tester.tap(back('World'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(chip('Europe'), findsOneWidget);
|
||||
|
|
|
|||
Loading…
Reference in a new issue