import 'dart:convert'; import 'dart:developer'; import 'dart:io'; import 'package:flutter/material.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; late Future disconnectFuture; @override void initState() { super.initState(); disconnectFuture = ConnectionCubit().disonnect(); disconnectFuture.then((val) { joinGameFuture = joinPrivateGame(widget.passphrase); }); } @override Widget build(BuildContext context) { return FutureBuilder( future: disconnectFuture, builder: (context, snapshot) { if (snapshot.connectionState != ConnectionState.done) { return Container(); } else { return FutureBuilder( future: joinGameFuture, builder: (context, snapshot) { if (snapshot.connectionState != ConnectionState.done) { return const SizedBox( height: 100, width: 100, child: CircularProgressIndicator(), ); } else { ConnectionCubit.getInstance().connect( snapshot.data!.playerID!.uuid, snapshot.data!.passphrase, ); return const ChessGame(); } }); } }); } Future joinPrivateGame(String phrase) async { http.Response response; var existingInfo = await GameInfo.get(phrase); log('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, passphrase: phrase); } else { info = GameInfo(playerID: null, passphrase: phrase); } try { response = await http.post(Uri.parse(config.getJoinGameURL()), 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('playerID: ${info.playerID}'); log('passphrase: ${info.passphrase}'); return info; } return null; } }