fix(block2): clearer market states — 'can't reach servers' (retry) vs 'set your area'
Feedback: the market sometimes looked 'disabled'. Now the offline/empty states are distinct and honest: - No working relay (defaults exist, so it's a reachability issue) → 'Can't reach the community servers right now' + a Retry. - Online but no area set → 'Set your area' prompt (you'd otherwise see a bare 'nothing nearby'). - Area set + nothing found → the existing empty state. i18n en/es/pt; offline tests updated; analyzer clean.
This commit is contained in:
parent
5f87ad2d56
commit
cfba85b9d9
9 changed files with 86 additions and 8 deletions
|
|
@ -339,6 +339,11 @@
|
||||||
"notSetUp": "Sharing isn't set up yet",
|
"notSetUp": "Sharing isn't set up yet",
|
||||||
"notSetUpBody": "Turn on sharing to see and give seeds to people near you. It stays rough — your zone, never your exact address.",
|
"notSetUpBody": "Turn on sharing to see and give seeds to people near you. It stays rough — your zone, never your exact address.",
|
||||||
"setUp": "Set up sharing",
|
"setUp": "Set up sharing",
|
||||||
|
"cantReach": "Can't reach the community servers right now",
|
||||||
|
"cantReachBody": "Try again, or check the servers under Advanced setup.",
|
||||||
|
"retry": "Retry",
|
||||||
|
"setArea": "Set your area",
|
||||||
|
"setAreaBody": "Tell the market roughly where you are to see seeds nearby.",
|
||||||
"searching": "Looking around your area…",
|
"searching": "Looking around your area…",
|
||||||
"empty": "No seeds shared near you yet",
|
"empty": "No seeds shared near you yet",
|
||||||
"near": "Near you",
|
"near": "Near you",
|
||||||
|
|
|
||||||
|
|
@ -339,6 +339,11 @@
|
||||||
"notSetUp": "Aún no has configurado el compartir",
|
"notSetUp": "Aún no has configurado el compartir",
|
||||||
"notSetUpBody": "Activa el compartir para ver y dar semillas a gente cercana. Se mantiene aproximado — tu zona, nunca tu dirección exacta.",
|
"notSetUpBody": "Activa el compartir para ver y dar semillas a gente cercana. Se mantiene aproximado — tu zona, nunca tu dirección exacta.",
|
||||||
"setUp": "Configurar el compartir",
|
"setUp": "Configurar el compartir",
|
||||||
|
"cantReach": "No se puede conectar con los servidores ahora mismo",
|
||||||
|
"cantReachBody": "Inténtalo de nuevo, o revisa los servidores en la configuración avanzada.",
|
||||||
|
"retry": "Reintentar",
|
||||||
|
"setArea": "Indica tu zona",
|
||||||
|
"setAreaBody": "Dile al mercado tu zona aproximada para ver semillas cerca.",
|
||||||
"searching": "Buscando por tu zona…",
|
"searching": "Buscando por tu zona…",
|
||||||
"empty": "Aún no hay semillas compartidas cerca de ti",
|
"empty": "Aún no hay semillas compartidas cerca de ti",
|
||||||
"near": "Cerca de ti",
|
"near": "Cerca de ti",
|
||||||
|
|
|
||||||
|
|
@ -335,6 +335,11 @@
|
||||||
"notSetUp": "Ainda não configuraste a partilha",
|
"notSetUp": "Ainda não configuraste a partilha",
|
||||||
"notSetUpBody": "Ativa a partilha para ver e dar sementes a pessoas por perto. Mantém-se aproximado — a tua zona, nunca a tua morada exata.",
|
"notSetUpBody": "Ativa a partilha para ver e dar sementes a pessoas por perto. Mantém-se aproximado — a tua zona, nunca a tua morada exata.",
|
||||||
"setUp": "Configurar a partilha",
|
"setUp": "Configurar a partilha",
|
||||||
|
"cantReach": "Não é possível ligar aos servidores neste momento",
|
||||||
|
"cantReachBody": "Tenta de novo, ou verifica os servidores na configuração avançada.",
|
||||||
|
"retry": "Tentar de novo",
|
||||||
|
"setArea": "Indica a tua zona",
|
||||||
|
"setAreaBody": "Diz ao mercado a tua zona aproximada para ver sementes por perto.",
|
||||||
"searching": "A procurar pela tua zona…",
|
"searching": "A procurar pela tua zona…",
|
||||||
"empty": "Ainda não há sementes partilhadas perto de ti",
|
"empty": "Ainda não há sementes partilhadas perto de ti",
|
||||||
"near": "Perto de ti",
|
"near": "Perto de ti",
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,9 @@
|
||||||
/// To regenerate, run: `dart run slang`
|
/// To regenerate, run: `dart run slang`
|
||||||
///
|
///
|
||||||
/// Locales: 3
|
/// Locales: 3
|
||||||
/// Strings: 1058 (352 per locale)
|
/// Strings: 1073 (357 per locale)
|
||||||
///
|
///
|
||||||
/// Built on 2026-07-10 at 11:31 UTC
|
/// Built on 2026-07-10 at 11:35 UTC
|
||||||
|
|
||||||
// coverage:ignore-file
|
// coverage:ignore-file
|
||||||
// ignore_for_file: type=lint, unused_import
|
// ignore_for_file: type=lint, unused_import
|
||||||
|
|
|
||||||
|
|
@ -1080,6 +1080,21 @@ class Translations$market$en {
|
||||||
/// en: 'Set up sharing'
|
/// en: 'Set up sharing'
|
||||||
String get setUp => 'Set up sharing';
|
String get setUp => 'Set up sharing';
|
||||||
|
|
||||||
|
/// en: 'Can't reach the community servers right now'
|
||||||
|
String get cantReach => 'Can\'t reach the community servers right now';
|
||||||
|
|
||||||
|
/// en: 'Try again, or check the servers under Advanced setup.'
|
||||||
|
String get cantReachBody => 'Try again, or check the servers under Advanced setup.';
|
||||||
|
|
||||||
|
/// en: 'Retry'
|
||||||
|
String get retry => 'Retry';
|
||||||
|
|
||||||
|
/// en: 'Set your area'
|
||||||
|
String get setArea => 'Set your area';
|
||||||
|
|
||||||
|
/// en: 'Tell the market roughly where you are to see seeds nearby.'
|
||||||
|
String get setAreaBody => 'Tell the market roughly where you are to see seeds nearby.';
|
||||||
|
|
||||||
/// en: 'Looking around your area…'
|
/// en: 'Looking around your area…'
|
||||||
String get searching => 'Looking around your area…';
|
String get searching => 'Looking around your area…';
|
||||||
|
|
||||||
|
|
@ -2034,6 +2049,11 @@ extension on Translations {
|
||||||
'market.notSetUp' => 'Sharing isn\'t set up yet',
|
'market.notSetUp' => 'Sharing isn\'t set up yet',
|
||||||
'market.notSetUpBody' => 'Turn on sharing to see and give seeds to people near you. It stays rough — your zone, never your exact address.',
|
'market.notSetUpBody' => 'Turn on sharing to see and give seeds to people near you. It stays rough — your zone, never your exact address.',
|
||||||
'market.setUp' => 'Set up sharing',
|
'market.setUp' => 'Set up sharing',
|
||||||
|
'market.cantReach' => 'Can\'t reach the community servers right now',
|
||||||
|
'market.cantReachBody' => 'Try again, or check the servers under Advanced setup.',
|
||||||
|
'market.retry' => 'Retry',
|
||||||
|
'market.setArea' => 'Set your area',
|
||||||
|
'market.setAreaBody' => 'Tell the market roughly where you are to see seeds nearby.',
|
||||||
'market.searching' => 'Looking around your area…',
|
'market.searching' => 'Looking around your area…',
|
||||||
'market.empty' => 'No seeds shared near you yet',
|
'market.empty' => 'No seeds shared near you yet',
|
||||||
'market.near' => 'Near you',
|
'market.near' => 'Near you',
|
||||||
|
|
|
||||||
|
|
@ -613,6 +613,11 @@ class _Translations$market$es extends Translations$market$en {
|
||||||
@override String get notSetUp => 'Aún no has configurado el compartir';
|
@override String get notSetUp => 'Aún no has configurado el compartir';
|
||||||
@override String get notSetUpBody => 'Activa el compartir para ver y dar semillas a gente cercana. Se mantiene aproximado — tu zona, nunca tu dirección exacta.';
|
@override String get notSetUpBody => 'Activa el compartir para ver y dar semillas a gente cercana. Se mantiene aproximado — tu zona, nunca tu dirección exacta.';
|
||||||
@override String get setUp => 'Configurar el compartir';
|
@override String get setUp => 'Configurar el compartir';
|
||||||
|
@override String get cantReach => 'No se puede conectar con los servidores ahora mismo';
|
||||||
|
@override String get cantReachBody => 'Inténtalo de nuevo, o revisa los servidores en la configuración avanzada.';
|
||||||
|
@override String get retry => 'Reintentar';
|
||||||
|
@override String get setArea => 'Indica tu zona';
|
||||||
|
@override String get setAreaBody => 'Dile al mercado tu zona aproximada para ver semillas cerca.';
|
||||||
@override String get searching => 'Buscando por tu zona…';
|
@override String get searching => 'Buscando por tu zona…';
|
||||||
@override String get empty => 'Aún no hay semillas compartidas cerca de ti';
|
@override String get empty => 'Aún no hay semillas compartidas cerca de ti';
|
||||||
@override String get near => 'Cerca de ti';
|
@override String get near => 'Cerca de ti';
|
||||||
|
|
@ -1346,6 +1351,11 @@ extension on TranslationsEs {
|
||||||
'market.notSetUp' => 'Aún no has configurado el compartir',
|
'market.notSetUp' => 'Aún no has configurado el compartir',
|
||||||
'market.notSetUpBody' => 'Activa el compartir para ver y dar semillas a gente cercana. Se mantiene aproximado — tu zona, nunca tu dirección exacta.',
|
'market.notSetUpBody' => 'Activa el compartir para ver y dar semillas a gente cercana. Se mantiene aproximado — tu zona, nunca tu dirección exacta.',
|
||||||
'market.setUp' => 'Configurar el compartir',
|
'market.setUp' => 'Configurar el compartir',
|
||||||
|
'market.cantReach' => 'No se puede conectar con los servidores ahora mismo',
|
||||||
|
'market.cantReachBody' => 'Inténtalo de nuevo, o revisa los servidores en la configuración avanzada.',
|
||||||
|
'market.retry' => 'Reintentar',
|
||||||
|
'market.setArea' => 'Indica tu zona',
|
||||||
|
'market.setAreaBody' => 'Dile al mercado tu zona aproximada para ver semillas cerca.',
|
||||||
'market.searching' => 'Buscando por tu zona…',
|
'market.searching' => 'Buscando por tu zona…',
|
||||||
'market.empty' => 'Aún no hay semillas compartidas cerca de ti',
|
'market.empty' => 'Aún no hay semillas compartidas cerca de ti',
|
||||||
'market.near' => 'Cerca de ti',
|
'market.near' => 'Cerca de ti',
|
||||||
|
|
|
||||||
|
|
@ -609,6 +609,11 @@ class _Translations$market$pt extends Translations$market$en {
|
||||||
@override String get notSetUp => 'Ainda não configuraste a partilha';
|
@override String get notSetUp => 'Ainda não configuraste a partilha';
|
||||||
@override String get notSetUpBody => 'Ativa a partilha para ver e dar sementes a pessoas por perto. Mantém-se aproximado — a tua zona, nunca a tua morada exata.';
|
@override String get notSetUpBody => 'Ativa a partilha para ver e dar sementes a pessoas por perto. Mantém-se aproximado — a tua zona, nunca a tua morada exata.';
|
||||||
@override String get setUp => 'Configurar a partilha';
|
@override String get setUp => 'Configurar a partilha';
|
||||||
|
@override String get cantReach => 'Não é possível ligar aos servidores neste momento';
|
||||||
|
@override String get cantReachBody => 'Tenta de novo, ou verifica os servidores na configuração avançada.';
|
||||||
|
@override String get retry => 'Tentar de novo';
|
||||||
|
@override String get setArea => 'Indica a tua zona';
|
||||||
|
@override String get setAreaBody => 'Diz ao mercado a tua zona aproximada para ver sementes por perto.';
|
||||||
@override String get searching => 'A procurar pela tua zona…';
|
@override String get searching => 'A procurar pela tua zona…';
|
||||||
@override String get empty => 'Ainda não há sementes partilhadas perto de ti';
|
@override String get empty => 'Ainda não há sementes partilhadas perto de ti';
|
||||||
@override String get near => 'Perto de ti';
|
@override String get near => 'Perto de ti';
|
||||||
|
|
@ -1338,6 +1343,11 @@ extension on TranslationsPt {
|
||||||
'market.notSetUp' => 'Ainda não configuraste a partilha',
|
'market.notSetUp' => 'Ainda não configuraste a partilha',
|
||||||
'market.notSetUpBody' => 'Ativa a partilha para ver e dar sementes a pessoas por perto. Mantém-se aproximado — a tua zona, nunca a tua morada exata.',
|
'market.notSetUpBody' => 'Ativa a partilha para ver e dar sementes a pessoas por perto. Mantém-se aproximado — a tua zona, nunca a tua morada exata.',
|
||||||
'market.setUp' => 'Configurar a partilha',
|
'market.setUp' => 'Configurar a partilha',
|
||||||
|
'market.cantReach' => 'Não é possível ligar aos servidores neste momento',
|
||||||
|
'market.cantReachBody' => 'Tenta de novo, ou verifica os servidores na configuração avançada.',
|
||||||
|
'market.retry' => 'Tentar de novo',
|
||||||
|
'market.setArea' => 'Indica a tua zona',
|
||||||
|
'market.setAreaBody' => 'Diz ao mercado a tua zona aproximada para ver sementes por perto.',
|
||||||
'market.searching' => 'A procurar pela tua zona…',
|
'market.searching' => 'A procurar pela tua zona…',
|
||||||
'market.empty' => 'Ainda não há sementes partilhadas perto de ti',
|
'market.empty' => 'Ainda não há sementes partilhadas perto de ti',
|
||||||
'market.near' => 'Perto de ti',
|
'market.near' => 'Perto de ti',
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ class MarketScreen extends StatefulWidget {
|
||||||
class _MarketScreenState extends State<MarketScreen> {
|
class _MarketScreenState extends State<MarketScreen> {
|
||||||
OffersCubit? _cubit;
|
OffersCubit? _cubit;
|
||||||
bool _loading = true;
|
bool _loading = true;
|
||||||
|
bool _hasArea = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
|
@ -64,6 +65,7 @@ class _MarketScreenState extends State<MarketScreen> {
|
||||||
final previous = _cubit;
|
final previous = _cubit;
|
||||||
setState(() {
|
setState(() {
|
||||||
_cubit = cubit;
|
_cubit = cubit;
|
||||||
|
_hasArea = area.isNotEmpty;
|
||||||
_loading = false;
|
_loading = false;
|
||||||
});
|
});
|
||||||
await previous?.close();
|
await previous?.close();
|
||||||
|
|
@ -171,6 +173,8 @@ class _MarketScreenState extends State<MarketScreen> {
|
||||||
value: cubit,
|
value: cubit,
|
||||||
child: MarketBody(
|
child: MarketBody(
|
||||||
onConfigure: _openConfig,
|
onConfigure: _openConfig,
|
||||||
|
onRetry: _init,
|
||||||
|
hasArea: _hasArea,
|
||||||
selfPubkey: widget.social.publicKeyHex,
|
selfPubkey: widget.social.publicKeyHex,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -181,12 +185,20 @@ class _MarketScreenState extends State<MarketScreen> {
|
||||||
class MarketBody extends StatelessWidget {
|
class MarketBody extends StatelessWidget {
|
||||||
const MarketBody({
|
const MarketBody({
|
||||||
required this.onConfigure,
|
required this.onConfigure,
|
||||||
|
this.onRetry,
|
||||||
|
this.hasArea = true,
|
||||||
this.selfPubkey,
|
this.selfPubkey,
|
||||||
super.key,
|
super.key,
|
||||||
});
|
});
|
||||||
|
|
||||||
final VoidCallback onConfigure;
|
final VoidCallback onConfigure;
|
||||||
|
|
||||||
|
/// Re-opens the connection (for the "can't reach servers" retry).
|
||||||
|
final VoidCallback? onRetry;
|
||||||
|
|
||||||
|
/// Whether the user has set their coarse area yet.
|
||||||
|
final bool hasArea;
|
||||||
|
|
||||||
/// This user's own pubkey, so we don't offer to message our own listings.
|
/// This user's own pubkey, so we don't offer to message our own listings.
|
||||||
final String? selfPubkey;
|
final String? selfPubkey;
|
||||||
|
|
||||||
|
|
@ -196,10 +208,21 @@ class MarketBody extends StatelessWidget {
|
||||||
return BlocBuilder<OffersCubit, OffersState>(
|
return BlocBuilder<OffersCubit, OffersState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
if (!context.read<OffersCubit>().isOnline) {
|
if (!context.read<OffersCubit>().isOnline) {
|
||||||
|
// Default community servers exist, so "offline" means unreachable —
|
||||||
|
// offer a retry rather than "set up sharing".
|
||||||
return _EmptyState(
|
return _EmptyState(
|
||||||
icon: Icons.wifi_tethering_off_outlined,
|
icon: Icons.wifi_tethering_off_outlined,
|
||||||
title: t.market.notSetUp,
|
title: t.market.cantReach,
|
||||||
body: t.market.notSetUpBody,
|
body: t.market.cantReachBody,
|
||||||
|
actionLabel: onRetry != null ? t.market.retry : null,
|
||||||
|
onAction: onRetry,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (!hasArea) {
|
||||||
|
return _EmptyState(
|
||||||
|
icon: Icons.place_outlined,
|
||||||
|
title: t.market.setArea,
|
||||||
|
body: t.market.setAreaBody,
|
||||||
actionLabel: t.market.setUp,
|
actionLabel: t.market.setUp,
|
||||||
onAction: onConfigure,
|
onAction: onConfigure,
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ Widget _wrapMarket(SocialService social, SocialSettings settings,
|
||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
testWidgets('offline (no transport) shows the "set up sharing" prompt',
|
testWidgets('offline (no transport) shows the "can\'t reach servers" state',
|
||||||
(tester) async {
|
(tester) async {
|
||||||
final cubit = OffersCubit(null);
|
final cubit = OffersCubit(null);
|
||||||
addTearDown(cubit.close);
|
addTearDown(cubit.close);
|
||||||
|
|
@ -74,8 +74,8 @@ void main() {
|
||||||
await tester.pumpWidget(_wrapBody(cubit));
|
await tester.pumpWidget(_wrapBody(cubit));
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
expect(find.text("Sharing isn't set up yet"), findsOneWidget);
|
expect(find.textContaining("Can't reach the community servers"),
|
||||||
expect(find.text('Set up sharing'), findsOneWidget);
|
findsOneWidget);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('MarketScreen with no relays configured degrades to offline',
|
testWidgets('MarketScreen with no relays configured degrades to offline',
|
||||||
|
|
@ -88,7 +88,7 @@ void main() {
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
expect(find.text('Seeds near you'), findsOneWidget); // app bar title
|
expect(find.text('Seeds near you'), findsOneWidget); // app bar title
|
||||||
expect(find.text('Set up sharing'), findsOneWidget); // offline prompt
|
expect(find.text('Retry'), findsOneWidget); // can't-reach state offers retry
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('"use my location" fills the area with a coarse geohash',
|
testWidgets('"use my location" fills the area with a coarse geohash',
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue