feat(plantare): UI — propose from chat, review & sign on the ledger
The viral loop, made usable end-to-end: - Propose sheet (plantare_propose_sheet.dart): from a chat with a peer (their key already in hand), pick your side, name the seed, choose what comes back (similar · non-GMO organic / work hours / other) and an optional return-by, then sign and send. Reached from the chat overflow menu; confirms "waiting for them to sign". - Plantares screen: incoming proposals show Accept & sign / Decline right on the tile; every bilateral row wears a handshake badge — awaiting signature, signed by both, or declined. Accept falls back to a gentle "offline" nudge if the proposal isn't in hand yet. - i18n: full en + es for the bilateral flow; other locales fall back to base per slang config. Wire-up only touches human copy (no jargon) and stays behind the optional PlantareService, so inventory-only builds are unaffected. Tests: propose sheet drives a real sign+send; the ledger renders the signed/awaiting badges. Fake SocialSession in your_people test gains the new transport getter. Widget tests targeted + timed. All green.
This commit is contained in:
parent
b607ddde41
commit
e78656bc07
11 changed files with 2223 additions and 1459 deletions
|
|
@ -12,6 +12,7 @@ import '../domain/message_rules.dart';
|
|||
import '../i18n/strings.g.dart';
|
||||
import '../services/message_store.dart';
|
||||
import '../services/onboarding_store.dart';
|
||||
import '../services/plantare_service.dart';
|
||||
import '../services/profile_cache.dart';
|
||||
import '../services/profile_store.dart';
|
||||
import '../services/social_connection.dart';
|
||||
|
|
@ -23,6 +24,7 @@ import '../state/peer_rating_cubit.dart';
|
|||
import '../state/trust_cubit.dart';
|
||||
import 'market_gate.dart';
|
||||
import 'peer_avatar.dart';
|
||||
import 'plantare_propose_sheet.dart';
|
||||
import 'rating_sheet.dart';
|
||||
import 'report_sheet.dart';
|
||||
import 'theme.dart';
|
||||
|
|
@ -205,6 +207,23 @@ class _ChatScreenState extends State<ChatScreen> {
|
|||
|
||||
/// Reports this peer (a standard report event to the community servers);
|
||||
/// when they were also blocked from the sheet, leaves the chat too.
|
||||
/// Opens the "propose a signed Plantaré" sheet against this peer (their key is
|
||||
/// in hand from the conversation), and confirms when a proposal is sent.
|
||||
Future<void> _proposePlantare() async {
|
||||
if (!getIt.isRegistered<PlantareService>()) return;
|
||||
final sent = await showProposePlantareSheet(
|
||||
context,
|
||||
service: getIt<PlantareService>(),
|
||||
peerPubkey: widget.peerPubkey,
|
||||
peerName: _peerName,
|
||||
);
|
||||
if (sent == true && mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text(context.t.plantare.sent)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _reportPeer() async {
|
||||
final outcome = await showReportSheet(
|
||||
context,
|
||||
|
|
@ -305,10 +324,16 @@ class _ChatScreenState extends State<ChatScreen> {
|
|||
PopupMenuButton<String>(
|
||||
key: const Key('chat.menu'),
|
||||
onSelected: (value) {
|
||||
if (value == 'plantare') _proposePlantare();
|
||||
if (value == 'report') _reportPeer();
|
||||
if (value == 'block') _blockPeer();
|
||||
},
|
||||
itemBuilder: (context) => [
|
||||
if (getIt.isRegistered<PlantareService>())
|
||||
PopupMenuItem(
|
||||
value: 'plantare',
|
||||
child: Text(t.plantare.propose),
|
||||
),
|
||||
PopupMenuItem(
|
||||
value: 'report',
|
||||
child: Text(t.report.person),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue