import 'dart:convert'; import 'dart:developer'; import 'dart:io'; import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:http/http.dart' as http; import 'package:mchess/api/game_info.dart'; import 'package:mchess/connection_cubit/connection_cubit.dart'; import 'package:mchess/pages/chess_game.dart'; import 'package:mchess/utils/config.dart' as config; class JoinGameHandleWidget extends StatefulWidget { final String passphrase; const JoinGameHandleWidget({required this.passphrase, super.key}); @override State createState() => _JoinGameHandleWidgetState(); } class _JoinGameHandleWidgetState extends State { late Future joinGameFuture; @override void initState() { joinGameFuture = joinPrivateGame(widget.passphrase); joinGameFuture.then( (value) { if (value != null) { switchToGame(value); } }, ); super.initState(); } @override Widget build(BuildContext context) { return const ChessGame(); } void switchToGame(GameInfo info) { var chessGameArgs = ChessGameArguments( lobbyID: info.lobbyID!, playerID: info.playerID!, passphrase: info.passphrase); ConnectionCubit.getInstance().connect( info.playerID!.uuid, info.lobbyID!.uuid, info.passphrase, ); if (!chessGameArgs.isValid()) { context.goNamed('lobbySelector'); const snackBar = SnackBar( backgroundColor: Colors.amberAccent, content: Text("Game information is corrupted"), ); ScaffoldMessenger.of(context).clearSnackBars(); ScaffoldMessenger.of(context).showSnackBar(snackBar); return; } } Future joinPrivateGame(String phrase) async { http.Response response; var existingInfo = await GameInfo.get(); log('lobbyID: ${existingInfo?.lobbyID} and playerID: ${existingInfo?.playerID} and passphrase: "${existingInfo?.passphrase}"'); GameInfo info; if (existingInfo?.passphrase == phrase) { // We have player info for this exact passphrase info = GameInfo( playerID: existingInfo?.playerID, lobbyID: existingInfo?.lobbyID, passphrase: phrase); } else { info = GameInfo(playerID: null, lobbyID: null, passphrase: phrase); } try { response = await http.post(Uri.parse(config.getJoinURL()), body: jsonEncode(info), headers: {"Accept": "application/json"}); } catch (e) { log(e.toString()); if (!context.mounted) return null; const snackBar = SnackBar( backgroundColor: Colors.amberAccent, content: Text("mChess server is not responding. Try again or give up"), ); ScaffoldMessenger.of(context).clearSnackBars(); ScaffoldMessenger.of(context).showSnackBar(snackBar); return null; } if (response.statusCode == HttpStatus.notFound) { const snackBar = SnackBar( backgroundColor: Colors.amberAccent, content: Text("Passphrase could not be found."), ); if (!context.mounted) return null; ScaffoldMessenger.of(context).clearSnackBars(); ScaffoldMessenger.of(context).showSnackBar(snackBar); return null; } if (response.statusCode == HttpStatus.ok) { var info = GameInfo.fromJson(jsonDecode(response.body)); info.store(); log('Player info received from server: '); log('lobbyID: ${info.lobbyID}'); log('playerID: ${info.playerID}'); log('passphrase: ${info.passphrase}'); return info; } return null; } }