import 'dart:developer'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:go_router/go_router.dart'; import 'package:http/http.dart'; import 'package:mchess/api/game_info.dart'; import 'package:mchess/connection_cubit/connection_cubit.dart'; import 'package:http/http.dart' as http; import 'dart:convert'; import 'package:mchess/pages/chess_game.dart'; import 'package:mchess/utils/config.dart' as config; import 'package:mchess/utils/passphrase.dart'; import 'package:universal_platform/universal_platform.dart'; class CreateGameWidget extends StatefulWidget { const CreateGameWidget({super.key}); @override State createState() => _CreateGameWidgetState(); } class _CreateGameWidgetState extends State { late Future registerResponse; late Future disconnectFuture; late ChessGameArguments chessGameArgs; @override void initState() { super.initState(); disconnectFuture = ConnectionCubit().disonnect(); disconnectFuture.then((val) { registerResponse = createPrivateGame(); }); } @override Widget build(BuildContext context) { FloatingActionButton? fltnBtn; if (UniversalPlatform.isLinux || UniversalPlatform.isMacOS || UniversalPlatform.isWindows) { fltnBtn = FloatingActionButton( child: const Icon(Icons.cancel), onPressed: () { context.pop(); }, ); } return Scaffold( floatingActionButton: fltnBtn, body: Center( child: FutureBuilder( future: disconnectFuture, builder: (context, snapshot) { if (snapshot.connectionState != ConnectionState.done) { return Container(); } else { return FutureBuilder( future: registerResponse, builder: (context, snapshot) { if (snapshot.connectionState != ConnectionState.done) { return const SizedBox( height: 100, width: 100, child: CircularProgressIndicator(), ); } else { var passphrase = snapshot.data?.passphrase ?? "no passphrase"; ConnectionCubit().connect( snapshot.data!.playerID.toString(), snapshot.data!.passphrase, ); return BlocListener( listener: (context, state) { // We wait for our opponent to connect if (state.opponentConnected) { //TODO: is goNamed the correct way to navigate? context.goNamed('game', pathParameters: { 'phrase': passphrase.toURL(), }); } }, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( 'Give this phrase to your friend and sit tight:', style: TextStyle( color: Theme.of(context).colorScheme.primary), ), const SizedBox(height: 25), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ SelectableText( passphrase, style: const TextStyle( fontWeight: FontWeight.bold), ), IconButton( icon: const Icon(Icons.copy), onPressed: () async { await Clipboard.setData( ClipboardData(text: passphrase)); }, ) ], ), const SizedBox(height: 25), const CircularProgressIndicator() ], ), ); } }, ); } }), ), ); } Future createPrivateGame() async { Response response; try { response = await http.get(Uri.parse(config.getCreateGameURL()), headers: {"Accept": "application/json"}); } catch (e) { log('Exception: ${e.toString()}'); const snackBar = SnackBar( backgroundColor: Colors.amberAccent, content: Text("mChess server is not responding. Try again or give up"), ); Future.delayed(const Duration(seconds: 2), () { if (!context.mounted) return null; ScaffoldMessenger.of(context).clearSnackBars(); ScaffoldMessenger.of(context).showSnackBar(snackBar); context.goNamed('lobbySelector'); // We go back to the lobby selector }); return null; } if (response.statusCode == 200) { var info = GameInfo.fromJson(jsonDecode(response.body)); info.store(); return info; } return null; } }