mchess-client/lib/pages/lobby_selector.dart

196 lines
5.7 KiB
Dart
Raw Permalink Normal View History

import 'dart:convert';
import 'dart:developer';
import 'package:flutter/foundation.dart';
2022-12-25 15:16:23 +00:00
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
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';
import 'package:shared_preferences/shared_preferences.dart';
2022-12-25 15:16:23 +00:00
class LobbySelector extends StatefulWidget {
2022-12-25 15:16:23 +00:00
const LobbySelector({super.key});
@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();
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) {
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,
),
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
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(),
),
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');
}),
TextButton(
child: const Text('Join'),
onPressed: () {
2023-12-27 14:46:15 +00:00
context.pop(); //close dialog before going to next dialog
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(
title: const Text('Enter the passphrase here:'),
content: TextField(
2023-12-27 14:46:15 +00:00
controller: phraseController,
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);
}
});
},
icon: const Icon(Icons.check),
)),
),
2023-06-29 23:49:18 +00:00
actions: <Widget>[
TextButton(
child: const Text('Cancel'),
2023-06-29 23:49:18 +00:00
onPressed: () {
context.pop();
2023-06-29 23:49:18 +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');
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);
}
Future<PlayerInfo?> joinPrivateGame() async {
String addr;
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);
if (kDebugMode) {
addr = 'http://localhost:8080/api/joinPrivate';
} else {
addr = 'https://chess.sw-gross.de:9999/api/joinPrivate';
}
try {
response = await http.post(Uri.parse(addr),
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 == 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
}