Billing Stripe, link regia mobile e staff solo trasmissione.

Aggiunge fatturazione club, pagina regia condivisibile senza account, roster squadre e rimuove la modalità controller dall'app (v1.1.0).

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-05-29 07:23:13 +02:00
parent 4083bc5dee
commit f4b7be0f80
156 changed files with 5033 additions and 2033 deletions

View File

@@ -14,8 +14,8 @@ import '../../platform/streaming_channel.dart';
import '../../platform/streaming_preview.dart';
import '../../providers/match_rules_provider.dart';
import '../../providers/score_provider.dart';
import '../shared/live_score_actions.dart';
import '../../shared/api_client.dart';
import '../../shared/regia_share.dart';
import '../../shared/models/score_state.dart';
import '../../providers/session_provider.dart';
import '../../shared/websocket_service.dart';
@@ -120,8 +120,6 @@ class _CameraScreenState extends ConsumerState<CameraScreen> {
final match = await client.fetchMatch(session.matchId);
ref.read(sessionProvider.notifier).setSession(session, match: match);
ref.read(sessionProvider.notifier).setDeviceRole(DeviceRole.camera);
if (session.score != null) {
ref.read(scoreProvider.notifier).reset(session.score!);
}
@@ -223,60 +221,14 @@ class _CameraScreenState extends ConsumerState<CameraScreen> {
await SystemChrome.setPreferredOrientations(DeviceOrientation.values);
}
void _syncScore() {
ref.read(websocketServiceProvider).sendScoreUpdate(ref.read(scoreProvider));
}
Future<void> _homePoint() async {
ref.read(scoreProvider.notifier).incrementHome();
_syncScore();
Future<void> _shareRegia() async {
final match = ref.read(sessionProvider).match;
await LiveScoreActions(ref).afterPointChange(
await shareRegiaLink(
context,
homeName: match?.teamName ?? 'Casa',
awayName: match?.opponentName ?? 'Ospiti',
onCloseSetConfirmed: () => _closeSetConfirmed(),
);
}
Future<void> _awayPoint() async {
ref.read(scoreProvider.notifier).incrementAway();
_syncScore();
final match = ref.read(sessionProvider).match;
await LiveScoreActions(ref).afterPointChange(
context,
homeName: match?.teamName ?? 'Casa',
awayName: match?.opponentName ?? 'Ospiti',
onCloseSetConfirmed: () => _closeSetConfirmed(),
);
}
void _homeMinus() {
ref.read(scoreProvider.notifier).decrementHome();
_syncScore();
}
void _awayMinus() {
ref.read(scoreProvider.notifier).decrementAway();
_syncScore();
}
Future<void> _closeSet() async {
await LiveScoreActions(ref).requestCloseSet(
context,
onCloseSetConfirmed: () => _closeSetConfirmed(),
);
}
Future<void> _closeSetConfirmed() async {
ref.read(scoreProvider.notifier).closeSet();
_syncScore();
final match = ref.read(sessionProvider).match;
await LiveScoreActions(ref).afterCloseSet(
context,
homeName: match?.teamName ?? 'Casa',
awayName: match?.opponentName ?? 'Ospiti',
onStopStream: _closeStreamPermanently,
ref,
sessionId: widget.sessionId,
shareSubject:
'Regia — ${match?.teamName ?? 'Casa'} vs ${match?.opponentName ?? 'Ospiti'}',
);
}
@@ -390,11 +342,7 @@ class _CameraScreenState extends ConsumerState<CameraScreen> {
bitrateMbps: _bitrateMbps,
fps: _fps,
viewerCount: _viewerCount,
onHomePoint: () => _homePoint(),
onAwayPoint: () => _awayPoint(),
onHomeMinus: _homeMinus,
onAwayMinus: _awayMinus,
onCloseSet: () => _closeSet(),
onShareRegia: _shareRegia,
onInterrupt: _interruptStream,
onCloseStream: _closeStreamPermanently,
pointsTarget: pointsTarget,
@@ -410,11 +358,7 @@ class _CameraScreenState extends ConsumerState<CameraScreen> {
bitrateMbps: _bitrateMbps,
fps: _fps,
viewerCount: _viewerCount,
onHomePoint: () => _homePoint(),
onAwayPoint: () => _awayPoint(),
onHomeMinus: _homeMinus,
onAwayMinus: _awayMinus,
onCloseSet: () => _closeSet(),
onShareRegia: _shareRegia,
onInterrupt: _interruptStream,
onCloseStream: _closeStreamPermanently,
pointsTarget: pointsTarget,
@@ -436,11 +380,7 @@ class _PortraitOverlay extends StatelessWidget {
required this.bitrateMbps,
required this.fps,
required this.viewerCount,
required this.onHomePoint,
required this.onAwayPoint,
required this.onHomeMinus,
required this.onAwayMinus,
required this.onCloseSet,
required this.onShareRegia,
required this.onInterrupt,
required this.onCloseStream,
required this.pointsTarget,
@@ -455,11 +395,7 @@ class _PortraitOverlay extends StatelessWidget {
final double bitrateMbps;
final int fps;
final int viewerCount;
final VoidCallback onHomePoint;
final VoidCallback onAwayPoint;
final VoidCallback onHomeMinus;
final VoidCallback onAwayMinus;
final VoidCallback onCloseSet;
final VoidCallback onShareRegia;
final VoidCallback onInterrupt;
final Future<void> Function() onCloseStream;
final int pointsTarget;
@@ -476,6 +412,11 @@ class _PortraitOverlay extends StatelessWidget {
children: [
LiveBadge(elapsed: elapsed),
const Spacer(),
IconButton(
onPressed: onShareRegia,
icon: const Icon(Icons.share),
tooltip: 'Condividi link regia',
),
CameraCompactMetrics(
networkType: networkType,
bitrateMbps: bitrateMbps,
@@ -507,13 +448,14 @@ class _PortraitOverlay extends StatelessWidget {
homeSets: score.homeSets,
awaySets: score.awaySets,
pointsTarget: pointsTarget,
onHomePoint: onHomePoint,
onAwayPoint: onAwayPoint,
onHomeMinus: onHomeMinus,
onAwayMinus: onAwayMinus,
onCloseSet: onCloseSet,
),
const SizedBox(height: 10),
OutlinedButton.icon(
onPressed: onShareRegia,
icon: const Icon(Icons.share, size: 18),
label: const Text('Condividi link regia'),
),
const SizedBox(height: 8),
OutlinedButton(
onPressed: onInterrupt,
child: const Text('Interrompi (riprendibile)'),
@@ -543,11 +485,7 @@ class _LandscapeOverlay extends StatelessWidget {
required this.bitrateMbps,
required this.fps,
required this.viewerCount,
required this.onHomePoint,
required this.onAwayPoint,
required this.onHomeMinus,
required this.onAwayMinus,
required this.onCloseSet,
required this.onShareRegia,
required this.onInterrupt,
required this.onCloseStream,
required this.pointsTarget,
@@ -563,11 +501,7 @@ class _LandscapeOverlay extends StatelessWidget {
final double bitrateMbps;
final int fps;
final int viewerCount;
final VoidCallback onHomePoint;
final VoidCallback onAwayPoint;
final VoidCallback onHomeMinus;
final VoidCallback onAwayMinus;
final VoidCallback onCloseSet;
final VoidCallback onShareRegia;
final VoidCallback onInterrupt;
final Future<void> Function() onCloseStream;
final int pointsTarget;
@@ -618,15 +552,15 @@ class _LandscapeOverlay extends StatelessWidget {
awaySets: score.awaySets,
lastDelta: lastDelta,
pointsTarget: pointsTarget,
onHomePoint: onHomePoint,
onAwayPoint: onAwayPoint,
onHomeMinus: onHomeMinus,
onAwayMinus: onAwayMinus,
onCloseSet: onCloseSet,
),
const SizedBox(height: 8),
Row(
children: [
IconButton(
onPressed: onShareRegia,
icon: const Icon(Icons.share, color: Colors.white),
tooltip: 'Condividi link regia',
),
Expanded(
child: OutlinedButton(
onPressed: onInterrupt,