Aggiunge tabellone punteggio in app senza link regia.

Controlli +1/− e chiudi set in camera e dopo test rete, sync via WebSocket.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-02 23:19:17 +02:00
parent 8882e7854f
commit 1bd81d84af
4 changed files with 249 additions and 74 deletions

View File

@@ -16,6 +16,8 @@ import '../../shared/models/stream_session.dart';
import '../../shared/websocket_service.dart';
import '../../shared/regia_share.dart';
import '../../shared/watch_share.dart';
import '../../providers/match_rules_provider.dart';
import '../../shared/widgets/live_score_controls.dart';
import '../../shared/widgets/metric_card.dart';
import '../../shared/widgets/primary_cta.dart';
import '../../shared/widgets/screen_insets.dart';
@@ -44,6 +46,17 @@ class _StepNetworkTestState extends ConsumerState<StepNetworkTest> {
String _networkType = '';
bool _starting = false;
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
final session = ref.read(sessionProvider).session;
if (session?.score != null) {
ref.read(scoreProvider.notifier).reset(session!.score!);
}
});
}
Future<void> _runTest() async {
setState(() {
_testing = true;
@@ -87,6 +100,23 @@ class _StepNetworkTestState extends ConsumerState<StepNetworkTest> {
_networkType = networkLabel;
_ready = testResult?.ready ?? upload >= 2.0;
});
await _ensureScoreboardLink();
}
}
Future<void> _ensureScoreboardLink() async {
final session = ref.read(sessionProvider).session;
if (session == null) return;
if (session.score != null) {
ref.read(scoreProvider.notifier).reset(session.score!);
}
try {
await ref.read(websocketServiceProvider).connect(
sessionId: session.id,
deviceRole: 'controller',
);
} catch (_) {
// Tabellone locale; sync quando la camera si connette.
}
}
@@ -144,6 +174,8 @@ class _StepNetworkTestState extends ConsumerState<StepNetworkTest> {
final session = ref.watch(sessionProvider).session;
final shareUrl = session != null ? watchShareUrl(session) : null;
final shareTitle = 'Diretta — ${widget.match.teamName} vs ${widget.match.opponentName}';
final score = ref.watch(scoreProvider);
final pointsTarget = ref.watch(matchScoringRulesProvider).pointsTarget(score.currentSet);
return SingleChildScrollView(
padding: ScreenInsets.contentPadding(context, horizontal: 20, vertical: 12),
@@ -268,6 +300,14 @@ class _StepNetworkTestState extends ConsumerState<StepNetworkTest> {
icon: const Icon(Icons.scoreboard),
label: const Text('Condividi link regia (punteggio)'),
),
const SizedBox(height: 16),
Text('Tabellone', style: theme.textTheme.titleMedium),
const SizedBox(height: 8),
LiveScoreControls(
homeName: widget.match.teamName,
awayName: widget.match.opponentName,
pointsTarget: pointsTarget,
),
],
if (_testCompleted) ...[
const SizedBox(height: 16),