2023-12-23 15:44:23 +00:00
|
|
|
import 'dart:convert';
|
|
|
|
import 'dart:developer';
|
|
|
|
|
2022-12-25 15:16:23 +00:00
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
import 'package:go_router/go_router.dart';
|
2023-12-23 15:44:23 +00:00
|
|
|
import 'package:http/http.dart' as http;
|
|
|
|
import 'package:mchess/api/register.dart';
|
|
|
|
import 'package:mchess/connection_cubit/connection_cubit.dart';
|
|
|
|
import 'package:mchess/pages/chess_game.dart';
|
2024-01-17 21:50:02 +00:00
|
|
|
import 'package:mchess/utils/config.dart' as config;
|
2023-12-23 15:44:23 +00:00
|
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
2022-12-25 15:16:23 +00:00
|
|
|
|
2023-12-23 15:44:23 +00:00
|
|
|
class LobbySelector extends StatefulWidget {
|
2022-12-25 15:16:23 +00:00
|
|
|
const LobbySelector({super.key});
|
|
|
|
|
2023-12-23 15:44:23 +00:00
|
|
|
@override
|
|
|
|
State<LobbySelector> createState() => _LobbySelectorState();
|
|
|
|
}
|
|
|
|
|
|
|
|
class _LobbySelectorState extends State<LobbySelector> {
|
2023-06-29 23:49:18 +00:00
|
|
|
final buttonStyle = const ButtonStyle();
|
2023-12-27 14:46:15 +00:00
|
|
|
final phraseController = TextEditingController();
|
2023-12-23 15:44:23 +00:00
|
|
|
late Future<PlayerInfo?> joinGameFuture;
|
2023-06-29 23:49:18 +00:00
|
|
|
|
2022-12-25 15:16:23 +00:00
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
2023-12-23 15:44:23 +00:00
|
|
|
SharedPreferences.getInstance().then((prefs) {
|
|
|
|
final playerID = prefs.getString("playerID");
|
|
|
|
final lobbyID = prefs.getString("lobbyID");
|
|
|
|
final passphrase = prefs.getString("passphrase");
|
|
|
|
log("lobbyID: $lobbyID and playerID: $playerID and passphrase: $passphrase");
|
|
|
|
});
|
|
|
|
|
2022-12-25 19:18:50 +00:00
|
|
|
return Scaffold(
|
2023-06-08 15:10:48 +00:00
|
|
|
body: Center(
|
2023-06-29 23:49:18 +00:00
|
|
|
child: Column(
|
|
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
|
|
children: [
|
|
|
|
ElevatedButton(
|
2023-12-27 14:46:15 +00:00
|
|
|
onPressed: () => buildJoinOrHostDialog(context),
|
2023-06-29 23:49:18 +00:00
|
|
|
child: const Row(
|
|
|
|
mainAxisSize: MainAxisSize.min,
|
|
|
|
children: [
|
|
|
|
Icon(Icons.lock),
|
|
|
|
SizedBox(
|
|
|
|
width: 10,
|
|
|
|
),
|
2023-08-14 15:04:25 +00:00
|
|
|
Text('Private game')
|
2023-06-29 23:49:18 +00:00
|
|
|
],
|
|
|
|
),
|
|
|
|
),
|
|
|
|
],
|
2023-06-08 15:10:48 +00:00
|
|
|
),
|
2022-12-25 19:18:50 +00:00
|
|
|
),
|
2022-12-25 15:16:23 +00:00
|
|
|
);
|
|
|
|
}
|
2023-06-29 23:49:18 +00:00
|
|
|
|
2023-12-23 15:44:23 +00:00
|
|
|
Future<void> buildJoinOrHostDialog(BuildContext context) {
|
|
|
|
return showDialog<void>(
|
|
|
|
context: context,
|
|
|
|
builder: (BuildContext context) {
|
|
|
|
return Scaffold(
|
|
|
|
body: AlertDialog(
|
|
|
|
title: const Text('Host or join?'),
|
|
|
|
actions: <Widget>[
|
|
|
|
TextButton(
|
|
|
|
child: const Text('Cancel'),
|
2023-12-27 14:46:15 +00:00
|
|
|
onPressed: () => context.pop(),
|
2023-12-23 15:44:23 +00:00
|
|
|
),
|
|
|
|
TextButton(
|
2023-12-27 14:46:15 +00:00
|
|
|
child: const Text('Host'),
|
|
|
|
onPressed: () {
|
|
|
|
context.pop(); //close dialog before going to host
|
|
|
|
context.goNamed('host');
|
|
|
|
}),
|
2023-12-23 15:44:23 +00:00
|
|
|
TextButton(
|
|
|
|
child: const Text('Join'),
|
|
|
|
onPressed: () {
|
2023-12-27 14:46:15 +00:00
|
|
|
context.pop(); //close dialog before going to next dialog
|
2023-12-23 15:44:23 +00:00
|
|
|
buildEnterPassphraseDialog(context);
|
|
|
|
},
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
);
|
|
|
|
},
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<void> buildEnterPassphraseDialog(BuildContext context) {
|
2023-06-29 23:49:18 +00:00
|
|
|
return showDialog<void>(
|
|
|
|
context: context,
|
|
|
|
builder: (BuildContext context) {
|
|
|
|
return AlertDialog(
|
2023-12-23 15:44:23 +00:00
|
|
|
title: const Text('Enter the passphrase here:'),
|
|
|
|
content: TextField(
|
2023-12-27 14:46:15 +00:00
|
|
|
controller: phraseController,
|
2023-12-23 15:44:23 +00:00
|
|
|
decoration: InputDecoration(
|
|
|
|
hintText: 'Enter passphrase here',
|
|
|
|
suffixIcon: IconButton(
|
|
|
|
onPressed: () {
|
|
|
|
joinGameFuture = joinPrivateGame();
|
|
|
|
joinGameFuture.then((value) {
|
2023-12-27 14:46:15 +00:00
|
|
|
if (value != null) {
|
|
|
|
phraseController.clear();
|
|
|
|
context.pop();
|
|
|
|
switchToGame(value);
|
|
|
|
}
|
2023-12-23 15:44:23 +00:00
|
|
|
});
|
|
|
|
},
|
|
|
|
icon: const Icon(Icons.check),
|
|
|
|
)),
|
|
|
|
),
|
2023-06-29 23:49:18 +00:00
|
|
|
actions: <Widget>[
|
|
|
|
TextButton(
|
2023-12-23 15:44:23 +00:00
|
|
|
child: const Text('Cancel'),
|
2023-06-29 23:49:18 +00:00
|
|
|
onPressed: () {
|
2023-12-23 15:44:23 +00:00
|
|
|
context.pop();
|
2023-06-29 23:49:18 +00:00
|
|
|
},
|
|
|
|
),
|
|
|
|
],
|
|
|
|
);
|
|
|
|
},
|
|
|
|
);
|
|
|
|
}
|
2023-12-23 15:44:23 +00:00
|
|
|
|
|
|
|
void switchToGame(PlayerInfo 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()) {
|
2023-12-25 16:50:58 +00:00
|
|
|
context.goNamed('lobbySelector');
|
2023-12-23 15:44:23 +00:00
|
|
|
const snackBar = SnackBar(
|
|
|
|
backgroundColor: Colors.amberAccent,
|
|
|
|
content: Text("Game information is corrupted"),
|
|
|
|
);
|
|
|
|
ScaffoldMessenger.of(context).clearSnackBars();
|
|
|
|
ScaffoldMessenger.of(context).showSnackBar(snackBar);
|
|
|
|
}
|
|
|
|
|
2023-12-27 14:46:15 +00:00
|
|
|
context.goNamed('game', extra: chessGameArgs);
|
2023-12-23 15:44:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Future<PlayerInfo?> joinPrivateGame() async {
|
|
|
|
http.Response response;
|
|
|
|
|
|
|
|
// server expects us to send the passphrase
|
|
|
|
var info = PlayerInfo(
|
2023-12-27 14:46:15 +00:00
|
|
|
playerID: null, lobbyID: null, passphrase: phraseController.text);
|
2023-12-23 15:44:23 +00:00
|
|
|
|
|
|
|
try {
|
2024-01-17 21:50:02 +00:00
|
|
|
response = await http.post(Uri.parse(config.getJoinURL()),
|
2023-12-23 15:44:23 +00:00
|
|
|
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"),
|
|
|
|
);
|
2024-02-01 10:37:00 +00:00
|
|
|
if (mounted) {
|
|
|
|
ScaffoldMessenger.of(context).clearSnackBars();
|
|
|
|
ScaffoldMessenger.of(context).showSnackBar(snackBar);
|
|
|
|
}
|
2023-12-23 15:44:23 +00:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (response.statusCode == 200) {
|
|
|
|
var info = PlayerInfo.fromJson(jsonDecode(response.body));
|
|
|
|
log('Player info received from server: ');
|
|
|
|
log('lobbyID: ${info.lobbyID}');
|
|
|
|
log('playerID: ${info.playerID}');
|
|
|
|
log('passphrase: ${info.passphrase}');
|
|
|
|
|
|
|
|
return info;
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
2022-12-25 15:16:23 +00:00
|
|
|
}
|