feat(block2): publish my seeds to the network (completes publish->discover)
The other half of the market: share your marked lots as offers. - VarietyRepository.shareableLots(): non-private lots WITH their id (stable, updatable offer id) + the variety label. Private lots never leave the device. - OffersCubit.publishLots(): maps each via OfferMapper and publishes, tagged with the coarse area + signed by the derived key; counts acceptances; no-op offline or with no area. - Market screen: a 'share my seeds' action (online only) — publishes, then re-discovers to show them; 'mark some seeds first' when nothing's shared. - i18n en/es/pt. 14 tests green (repo query, cubit publish, market UI); analyzer clean for new code.
This commit is contained in:
parent
cb5f55e146
commit
f8f73c4153
12 changed files with 284 additions and 5 deletions
|
|
@ -2,6 +2,7 @@ import 'package:commons_core/commons_core.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
import '../data/variety_repository.dart';
|
||||
import '../i18n/strings.g.dart';
|
||||
import '../services/social_service.dart';
|
||||
import '../services/social_settings.dart';
|
||||
|
|
@ -57,6 +58,36 @@ class _MarketScreenState extends State<MarketScreen> {
|
|||
if (changed == true) await _init();
|
||||
}
|
||||
|
||||
/// Publishes the user's shared lots as offers to the network, tagged with the
|
||||
/// coarse area. Prompts for setup when the area isn't set.
|
||||
Future<void> _shareMine() async {
|
||||
final cubit = _cubit;
|
||||
if (cubit == null || !cubit.isOnline) return;
|
||||
final repo = context.read<VarietyRepository>();
|
||||
final messenger = ScaffoldMessenger.of(context);
|
||||
final t = context.t;
|
||||
final area = await widget.settings.areaGeohash();
|
||||
if (!mounted) return;
|
||||
if (area.isEmpty) {
|
||||
await _openConfig();
|
||||
return;
|
||||
}
|
||||
final lots = await repo.shareableLots();
|
||||
if (!mounted) return;
|
||||
if (lots.isEmpty) {
|
||||
messenger.showSnackBar(SnackBar(content: Text(t.market.nothingToShare)));
|
||||
return;
|
||||
}
|
||||
final count = await cubit.publishLots(
|
||||
lots,
|
||||
authorPubkeyHex: widget.social.publicKeyHex,
|
||||
areaGeohash: area,
|
||||
);
|
||||
if (!mounted) return;
|
||||
messenger.showSnackBar(SnackBar(content: Text(t.market.sharedCount(n: count))));
|
||||
await cubit.discover(area); // refresh — now including the just-shared lots
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_cubit?.close();
|
||||
|
|
@ -71,6 +102,13 @@ class _MarketScreenState extends State<MarketScreen> {
|
|||
appBar: AppBar(
|
||||
title: Text(t.market.title),
|
||||
actions: [
|
||||
if (cubit != null && cubit.isOnline)
|
||||
IconButton(
|
||||
key: const Key('market.shareMine'),
|
||||
icon: const Icon(Icons.ios_share_outlined),
|
||||
tooltip: t.market.shareMine,
|
||||
onPressed: _shareMine,
|
||||
),
|
||||
IconButton(
|
||||
key: const Key('market.config'),
|
||||
icon: const Icon(Icons.tune),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue