fix(market): zone prompt before connection error; keep Save above the nav bar

- A new user's first step (set your area) works offline, so that empty state
  now wins over 'can't reach the servers'
- The sharing-setup sheet wraps in SafeArea(top: false) so the Save button
  isn't clipped by the system navigation bar on edge-to-edge devices
This commit is contained in:
vjrj 2026-07-22 13:03:25 +02:00
parent 49e9a45a7d
commit 3a87e112f9
2 changed files with 318 additions and 214 deletions

View file

@ -84,8 +84,9 @@ void main() {
findsOneWidget);
});
testWidgets('MarketScreen with no relays configured degrades to offline',
(tester) async {
testWidgets(
'a fresh install (no area, unreachable) asks for the area first, '
'not the connection', (tester) async {
final social = await SocialService.fromRootSeedHex('00' * 32);
final settings = SocialSettings(InMemorySecretStore());
await settings.setRelayUrls(const []); // offline: don't hit the network
@ -94,7 +95,23 @@ void main() {
await tester.pumpAndSettle();
expect(find.text('Seeds near you'), findsOneWidget); // app bar title
expect(find.text('Retry'), findsOneWidget); // can't-reach state offers retry
// Setting a zone works offline and is the first step the connection
// error must not bury it.
expect(find.text('Set your area'), findsOneWidget);
expect(find.text('Retry'), findsNothing);
});
testWidgets('with an area set, unreachable servers degrade to retry',
(tester) async {
final social = await SocialService.fromRootSeedHex('00' * 32);
final settings = SocialSettings(InMemorySecretStore());
await settings.setRelayUrls(const []); // offline: don't hit the network
await settings.setAreaGeohash('ezsn9');
await tester.pumpWidget(_wrapMarket(social, settings));
await tester.pumpAndSettle();
expect(find.text('Retry'), findsOneWidget);
});
testWidgets('the range selector persists the chosen search precision',
@ -148,6 +165,36 @@ void main() {
expect(tester.widget<CheckboxListTile>(find.byKey(firstKey)).value, isTrue);
});
testWidgets('the config sheet Save button stays above the system nav bar',
(tester) async {
// Edge-to-edge Android: a 50-logical-px gesture/nav bar at the bottom.
tester.view.padding = const FakeViewPadding(bottom: 150); // physical px
tester.view.viewPadding = const FakeViewPadding(bottom: 150);
addTearDown(tester.view.reset);
final social = await SocialService.fromRootSeedHex('00' * 32);
final settings = SocialSettings(InMemorySecretStore());
await settings.setRelayUrls(const []); // offline: don't hit the network
await tester.pumpWidget(_wrapMarket(social, settings));
await tester.pumpAndSettle();
await tester.tap(find.byKey(const Key('market.config')));
await tester.pumpAndSettle();
final save = find.byKey(const Key('market.save'));
await tester.ensureVisible(save);
await tester.pumpAndSettle();
final screenHeight = tester.view.physicalSize.height /
tester.view.devicePixelRatio; // 600 on the default test surface
const navBarLogical = 150 / 3.0; // FakeViewPadding is physical px
expect(
tester.getRect(save).bottom,
lessThanOrEqualTo(screenHeight - navBarLogical + 0.1),
reason: 'Save must not sit under the system navigation bar',
);
});
testWidgets('"use my location" fills the area with a coarse geohash',
(tester) async {
final social = await SocialService.fromRootSeedHex('00' * 32);