feat(market): one-time community-rules gate before joining the market, publishing or messaging

This commit is contained in:
vjrj 2026-07-13 00:52:39 +02:00
parent a7e10eba7a
commit 5d25f65f76
7 changed files with 311 additions and 1 deletions

View file

@ -11,6 +11,7 @@ import '../domain/chat_timeline.dart';
import '../domain/message_rules.dart';
import '../i18n/strings.g.dart';
import '../services/message_store.dart';
import '../services/onboarding_store.dart';
import '../services/profile_cache.dart';
import '../services/profile_store.dart';
import '../services/social_connection.dart';
@ -19,6 +20,7 @@ import '../services/unread_service.dart';
import '../state/messages_cubit.dart';
import '../state/peer_rating_cubit.dart';
import '../state/trust_cubit.dart';
import 'market_gate.dart';
import 'peer_avatar.dart';
import 'rating_sheet.dart';
import 'theme.dart';
@ -33,6 +35,7 @@ class ChatScreen extends StatefulWidget {
required this.peerPubkey,
this.messageStore,
this.profileCache,
this.onboarding,
super.key,
});
@ -49,6 +52,11 @@ class ChatScreen extends StatefulWidget {
/// Optional cache of peer display names; null in tests.
final ProfileCache? profileCache;
/// When set, the first message requires the one-time community-rules
/// acceptance (a chat can be reached from an incoming message without ever
/// entering the market). Null in tests no gate.
final OnboardingStore? onboarding;
@override
State<ChatScreen> createState() => _ChatScreenState();
}
@ -186,6 +194,13 @@ class _ChatScreenState extends State<ChatScreen> {
Future<void> _send() async {
final cubit = _messages;
if (cubit == null || _input.text.trim().isEmpty) return;
// Writing to someone is creating content: the community-rules acceptance
// must exist even when this chat was reached without entering the market.
final store = widget.onboarding;
if (store != null) {
final ok = await ensureMarketRulesAccepted(context, store);
if (!ok || !mounted) return;
}
final text = _input.text;
// Links aren't allowed — warn and keep the text so it can be edited.
if (containsUrl(text)) {