A lot of changes again?!?
This commit is contained in:
parent
43fca47dae
commit
52540ec96c
@ -1,30 +1,43 @@
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
class ResponseFromRegisteringGame {
|
||||
final UuidValue playerID;
|
||||
final UuidValue lobbyID;
|
||||
class PlayerInfo {
|
||||
final UuidValue? playerID;
|
||||
final UuidValue? lobbyID;
|
||||
final String? passphrase;
|
||||
|
||||
const ResponseFromRegisteringGame({
|
||||
const PlayerInfo({
|
||||
required this.playerID,
|
||||
required this.lobbyID,
|
||||
required this.passphrase,
|
||||
});
|
||||
|
||||
factory ResponseFromRegisteringGame.fromJson(Map<String, dynamic> json) {
|
||||
factory PlayerInfo.fromJson(Map<String, dynamic> json) {
|
||||
final playerid = UuidValue(json['playerID']);
|
||||
final lobbyid = UuidValue(json['lobbyID']);
|
||||
final passphrase = json['passphrase'];
|
||||
|
||||
return ResponseFromRegisteringGame(playerID: playerid, lobbyID: lobbyid);
|
||||
return PlayerInfo(
|
||||
playerID: playerid, lobbyID: lobbyid, passphrase: passphrase);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
'playerID': playerID,
|
||||
'lobbyID': lobbyID,
|
||||
'passphrase': passphrase,
|
||||
};
|
||||
}
|
||||
|
||||
class WebsocketMessageIdentifyPlayer {
|
||||
final String playerID;
|
||||
final String lobbyID;
|
||||
final String? passphrase;
|
||||
|
||||
const WebsocketMessageIdentifyPlayer({
|
||||
required this.playerID,
|
||||
required this.lobbyID,
|
||||
required this.passphrase,
|
||||
});
|
||||
|
||||
Map<String, dynamic> toJson() => {'lobbyID': lobbyID, 'playerID': playerID};
|
||||
Map<String, dynamic> toJson() =>
|
||||
{'lobbyID': lobbyID, 'playerID': playerID, 'passphrase': passphrase};
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ class ChessBloc extends Bloc<ChessEvent, ChessBoardState> {
|
||||
|
||||
ServerConnection.getInstance().send(jsonEncode(apiMessage));
|
||||
|
||||
//Temporary chess position until server responds with acknoledgement
|
||||
//Temporary chess position until server responds with acknowledgement
|
||||
var move = ChessMove.fromApiMove(apiMove);
|
||||
var tempPosition = ChessPosition.getInstance().copyOfCurrentPosition;
|
||||
tempPosition[move.to] = tempPosition[move.from] ?? const ChessPiece.none();
|
||||
|
@ -104,7 +104,7 @@ class ChessPosition {
|
||||
logString = '$logString\n';
|
||||
}
|
||||
|
||||
print(logString);
|
||||
log(logString);
|
||||
}
|
||||
|
||||
void logHistory(ChessMoveHistory hist) {
|
||||
|
@ -4,8 +4,8 @@ import 'package:flutter/foundation.dart';
|
||||
import 'package:mchess/api/websocket_message.dart';
|
||||
import 'package:mchess/chess_bloc/chess_bloc.dart';
|
||||
import 'package:mchess/chess_bloc/chess_events.dart';
|
||||
import 'package:mchess/chess_bloc/chess_position.dart';
|
||||
import 'package:mchess/api/register.dart';
|
||||
import 'package:mchess/connection_cubit/connection_cubit.dart';
|
||||
import 'package:mchess/utils/chess_utils.dart';
|
||||
import 'package:web_socket_channel/web_socket_channel.dart';
|
||||
|
||||
@ -34,9 +34,7 @@ class ServerConnection {
|
||||
counter++;
|
||||
}
|
||||
|
||||
void connect(String playerID, lobbyID) {
|
||||
if (wasConnected) channel.sink.close();
|
||||
|
||||
void connect(String playerID, lobbyID, String? passphrase) {
|
||||
if (kDebugMode) {
|
||||
channel =
|
||||
WebSocketChannel.connect(Uri.parse('ws://localhost:8080/api/ws'));
|
||||
@ -44,15 +42,18 @@ class ServerConnection {
|
||||
channel = WebSocketChannel.connect(
|
||||
Uri.parse('wss://chess.sw-gross.de:9999/api/ws'));
|
||||
}
|
||||
send(jsonEncode(WebsocketMessageIdentifyPlayer(
|
||||
playerID: (playerID), lobbyID: (lobbyID))));
|
||||
send(
|
||||
jsonEncode(
|
||||
WebsocketMessageIdentifyPlayer(
|
||||
playerID: (playerID),
|
||||
lobbyID: (lobbyID),
|
||||
passphrase: (passphrase),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
log(channel.closeCode.toString());
|
||||
|
||||
wasConnected = true;
|
||||
|
||||
broadcast = channel.stream.asBroadcastStream();
|
||||
|
||||
broadcast.listen(handleIncomingData);
|
||||
}
|
||||
|
||||
@ -78,6 +79,7 @@ class ServerConnection {
|
||||
void handleIncomingColorDeterminedMessage(ApiWebsocketMessage apiMessage) {
|
||||
ChessBloc.getInstance().add(
|
||||
ColorDetermined(myColor: ChessColor.fromApiColor(apiMessage.color!)));
|
||||
ConnectionCubit.getInstance().opponentConnected();
|
||||
}
|
||||
|
||||
void handleIncomingMoveMessage(ApiWebsocketMessage apiMessage) {
|
||||
|
@ -15,16 +15,19 @@ class ConnectionCubit extends Cubit<ConnectionCubitState> {
|
||||
return _instance;
|
||||
}
|
||||
|
||||
void connect(String playerID, lobbyID) {
|
||||
ServerConnection.getInstance().connect(playerID, lobbyID);
|
||||
void connect(String playerID, lobbyID, String? passphrase) {
|
||||
ServerConnection.getInstance().connect(playerID, lobbyID, passphrase);
|
||||
}
|
||||
|
||||
void opponentConnected() {
|
||||
emit(ConnectionCubitState(true));
|
||||
}
|
||||
}
|
||||
|
||||
class ConnectionCubitState {
|
||||
final bool reconnecting;
|
||||
final bool opponentConnected;
|
||||
|
||||
ConnectionCubitState(this.reconnecting);
|
||||
ConnectionCubitState(this.opponentConnected);
|
||||
|
||||
factory ConnectionCubitState.init() {
|
||||
return ConnectionCubitState(false);
|
||||
|
@ -6,16 +6,18 @@ import 'package:mchess/chess_bloc/chess_bloc.dart';
|
||||
|
||||
import 'package:mchess/chess/chess_board.dart';
|
||||
import 'package:mchess/chess/turn_indicator_widget.dart';
|
||||
import 'package:mchess/connection_cubit/connection_cubit.dart';
|
||||
|
||||
import 'package:mchess/connection/ws_connection.dart';
|
||||
import 'package:mchess/utils/widgets/server_log_widget.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
class ChessGame extends StatefulWidget {
|
||||
final UuidValue playerID;
|
||||
final UuidValue lobbyID;
|
||||
const ChessGame({required this.playerID, required this.lobbyID, super.key});
|
||||
final String? passphrase;
|
||||
const ChessGame(
|
||||
{required this.playerID,
|
||||
required this.lobbyID,
|
||||
required this.passphrase,
|
||||
super.key});
|
||||
|
||||
@override
|
||||
State<ChessGame> createState() => _ChessGameState();
|
||||
@ -25,28 +27,16 @@ class _ChessGameState extends State<ChessGame> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
ConnectionCubit.getInstance()
|
||||
.connect(widget.playerID.uuid, widget.lobbyID.uuid);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Center(
|
||||
child: FittedBox(
|
||||
body: FittedBox(
|
||||
fit: BoxFit.contain,
|
||||
child: Column(
|
||||
children: [
|
||||
if (kDebugMode)
|
||||
StreamBuilder(
|
||||
stream: ServerConnection.getInstance().broadcast,
|
||||
builder: (context, snapshot) {
|
||||
return ServerLogWidget(
|
||||
snapshot.data ?? "<snapshot empty>",
|
||||
textColor: Colors.white,
|
||||
);
|
||||
},
|
||||
),
|
||||
if (kDebugMode) const ServerLogWidget(textColor: Colors.white),
|
||||
Container(
|
||||
margin: const EdgeInsets.all(20),
|
||||
child: BlocBuilder<ChessBloc, ChessBoardState>(
|
||||
@ -61,13 +51,24 @@ class _ChessGameState extends State<ChessGame> {
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
onPressed: () {
|
||||
context.goNamed('lobbySelector');
|
||||
context.push('/');
|
||||
},
|
||||
child: const Icon(Icons.arrow_back),
|
||||
child: const Icon(Icons.cancel),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ChessGameArguments {
|
||||
final UuidValue lobbyID;
|
||||
final UuidValue playerID;
|
||||
final String? passphrase;
|
||||
|
||||
ChessGameArguments({
|
||||
required this.lobbyID,
|
||||
required this.playerID,
|
||||
required this.passphrase,
|
||||
});
|
||||
}
|
||||
|
144
lib/pages/host_game.dart
Normal file
144
lib/pages/host_game.dart
Normal file
@ -0,0 +1,144 @@
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:http/http.dart';
|
||||
import 'package:mchess/api/register.dart';
|
||||
import 'package:mchess/chess_bloc/chess_bloc.dart';
|
||||
import 'package:mchess/chess_bloc/chess_events.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';
|
||||
|
||||
class HostGameWidget extends StatefulWidget {
|
||||
const HostGameWidget({super.key});
|
||||
|
||||
@override
|
||||
State<HostGameWidget> createState() => _HostGameWidgetState();
|
||||
}
|
||||
|
||||
class _HostGameWidgetState extends State<HostGameWidget> {
|
||||
late Future<PlayerInfo?> registerResponse;
|
||||
late ChessGameArguments chessGameArgs;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
ChessBloc.getInstance().add(InitBoard());
|
||||
|
||||
registerResponse = hostPrivateGame();
|
||||
connectToWebsocket(registerResponse);
|
||||
|
||||
super.initState();
|
||||
}
|
||||
|
||||
void connectToWebsocket(Future<PlayerInfo?> resp) {
|
||||
resp.then((value) {
|
||||
if (value == null) return;
|
||||
|
||||
chessGameArgs = ChessGameArguments(
|
||||
lobbyID: value.lobbyID!,
|
||||
playerID: value.playerID!,
|
||||
passphrase: value.passphrase);
|
||||
|
||||
ConnectionCubit.getInstance().connect(
|
||||
value.playerID!.uuid,
|
||||
value.lobbyID!.uuid,
|
||||
value.passphrase,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Center(
|
||||
child: FutureBuilder<PlayerInfo?>(
|
||||
future: registerResponse,
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.connectionState != ConnectionState.done) {
|
||||
return const SizedBox(
|
||||
height: 100,
|
||||
width: 100,
|
||||
child: CircularProgressIndicator(),
|
||||
);
|
||||
} else {
|
||||
String passphrase = snapshot.data?.passphrase ?? "no passphrase";
|
||||
return BlocListener<ConnectionCubit, ConnectionCubitState>(
|
||||
listener: (context, state) {
|
||||
// We wait for our opponent to connect
|
||||
if (state.opponentConnected) {
|
||||
context.push('/game', extra: chessGameArgs);
|
||||
}
|
||||
},
|
||||
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),
|
||||
Text(
|
||||
passphrase,
|
||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
const SizedBox(height: 25),
|
||||
const CircularProgressIndicator()
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
child: const Icon(Icons.cancel),
|
||||
onPressed: () {
|
||||
context.push('/');
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<PlayerInfo?> hostPrivateGame() async {
|
||||
String addr;
|
||||
Response response;
|
||||
|
||||
if (kDebugMode) {
|
||||
addr = 'http://localhost:8080/api/hostPrivate';
|
||||
} else {
|
||||
addr = 'https://chess.sw-gross.de:9999/api/hostPrivate';
|
||||
}
|
||||
|
||||
try {
|
||||
response = await http
|
||||
.get(Uri.parse(addr), 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"),
|
||||
);
|
||||
Future.delayed(const Duration(seconds: 2), () {
|
||||
ScaffoldMessenger.of(context).clearSnackBars();
|
||||
ScaffoldMessenger.of(context).showSnackBar(snackBar);
|
||||
context.pop();
|
||||
});
|
||||
return null;
|
||||
}
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
log(response.body);
|
||||
return PlayerInfo.fromJson(jsonDecode(response.body));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
118
lib/pages/join_game.dart
Normal file
118
lib/pages/join_game.dart
Normal file
@ -0,0 +1,118 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:http/http.dart';
|
||||
import 'package:mchess/api/register.dart';
|
||||
import 'package:mchess/connection_cubit/connection_cubit.dart';
|
||||
import 'package:mchess/pages/chess_game.dart';
|
||||
|
||||
class JoinGameWidget extends StatefulWidget {
|
||||
const JoinGameWidget({
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
State<JoinGameWidget> createState() => _JoinGameWidgetState();
|
||||
}
|
||||
|
||||
class _JoinGameWidgetState extends State<JoinGameWidget> {
|
||||
final myController = TextEditingController();
|
||||
late Future<PlayerInfo?> joinGameFuture;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: TextField(
|
||||
controller: myController,
|
||||
decoration: InputDecoration(
|
||||
hintText: 'Enter passphrase here',
|
||||
suffixIcon: IconButton(
|
||||
onPressed: () {
|
||||
joinGameFuture = joinPrivateGame();
|
||||
switchToGame(joinGameFuture);
|
||||
},
|
||||
icon: const Icon(Icons.check),
|
||||
)),
|
||||
),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
onPressed: () {
|
||||
context.push('/');
|
||||
},
|
||||
child: const Icon(Icons.cancel),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void switchToGame(Future<PlayerInfo?> resp) {
|
||||
resp.then((value) {
|
||||
if (value == null) return;
|
||||
|
||||
var chessGameArgs = ChessGameArguments(
|
||||
lobbyID: value.lobbyID!,
|
||||
playerID: value.playerID!,
|
||||
passphrase: value.passphrase);
|
||||
|
||||
ConnectionCubit.getInstance().connect(
|
||||
value.playerID!.uuid,
|
||||
value.lobbyID!.uuid,
|
||||
value.passphrase,
|
||||
);
|
||||
|
||||
context.push('/game', extra: chessGameArgs);
|
||||
});
|
||||
}
|
||||
|
||||
Future<PlayerInfo?> joinPrivateGame() async {
|
||||
String addr;
|
||||
Response response;
|
||||
|
||||
// server expects us to send the passphrase
|
||||
var info = PlayerInfo(
|
||||
playerID: null, lobbyID: null, passphrase: myController.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"),
|
||||
);
|
||||
Future.delayed(const Duration(seconds: 2), () {
|
||||
ScaffoldMessenger.of(context).clearSnackBars();
|
||||
ScaffoldMessenger.of(context).showSnackBar(snackBar);
|
||||
context.pop();
|
||||
});
|
||||
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;
|
||||
}
|
||||
}
|
@ -4,17 +4,76 @@ import 'package:go_router/go_router.dart';
|
||||
class LobbySelector extends StatelessWidget {
|
||||
const LobbySelector({super.key});
|
||||
|
||||
final buttonStyle = const ButtonStyle();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Center(
|
||||
child: TextButton(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
context.goNamed('prepareChessGame');
|
||||
context.push('/prepareRandom');
|
||||
},
|
||||
child: const Text('Random lobby'),
|
||||
child: const Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(Icons.question_mark),
|
||||
SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Text('Random')
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 25,
|
||||
),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
_dialogBuilder(context);
|
||||
},
|
||||
child: const Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(Icons.lock),
|
||||
SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Text('Private')
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _dialogBuilder(BuildContext context) {
|
||||
return showDialog<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
title: const Text('Host or join?'),
|
||||
actions: <Widget>[
|
||||
TextButton(
|
||||
child: const Text('Host'),
|
||||
onPressed: () {
|
||||
context.push('/host');
|
||||
},
|
||||
),
|
||||
TextButton(
|
||||
child: const Text('Join'),
|
||||
onPressed: () {
|
||||
context.push('/join');
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,96 +0,0 @@
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:http/http.dart';
|
||||
import 'package:mchess/api/register.dart';
|
||||
import 'package:mchess/chess_bloc/chess_bloc.dart';
|
||||
import 'package:mchess/chess_bloc/chess_events.dart';
|
||||
import 'package:mchess/pages/chess_game.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'dart:convert';
|
||||
|
||||
class PrepareChessGameWidget extends StatefulWidget {
|
||||
const PrepareChessGameWidget({super.key});
|
||||
|
||||
@override
|
||||
State<PrepareChessGameWidget> createState() => _PrepareChessGameWidgetState();
|
||||
}
|
||||
|
||||
class _PrepareChessGameWidgetState extends State<PrepareChessGameWidget> {
|
||||
late Future randomGameResponse;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
ChessBloc.getInstance().add(InitBoard());
|
||||
randomGameResponse = registerForRandomGame();
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: FutureBuilder(
|
||||
future: randomGameResponse,
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.connectionState == ConnectionState.done) {
|
||||
log('Response from registering to random game ${snapshot.data}');
|
||||
|
||||
if (snapshot.data != null) {
|
||||
return ChessGame(
|
||||
playerID: snapshot.data!.playerID,
|
||||
lobbyID: snapshot.data!.lobbyID,
|
||||
);
|
||||
}
|
||||
}
|
||||
return const Center(
|
||||
child: SizedBox(
|
||||
height: 100,
|
||||
width: 100,
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<ResponseFromRegisteringGame?> registerForRandomGame() async {
|
||||
String addr;
|
||||
if (kDebugMode) {
|
||||
addr = 'http://localhost:8080/api/random';
|
||||
} else {
|
||||
addr = 'https://chess.sw-gross.de:9999/api/random';
|
||||
}
|
||||
|
||||
Response response;
|
||||
|
||||
try {
|
||||
response = await http
|
||||
.get(Uri.parse(addr), headers: {"Accept": "application/json"});
|
||||
} catch (e) {
|
||||
const snackBar = SnackBar(
|
||||
backgroundColor: Colors.amberAccent,
|
||||
content:
|
||||
Text("mChess server is not responding. Try again or give up"));
|
||||
|
||||
if (!context.mounted) return null;
|
||||
|
||||
ScaffoldMessenger.of(context).clearSnackBars();
|
||||
ScaffoldMessenger.of(context).showSnackBar(snackBar);
|
||||
|
||||
Future.delayed(const Duration(seconds: 2), () {
|
||||
context.goNamed('lobbySelector');
|
||||
});
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
log(response.body);
|
||||
return ResponseFromRegisteringGame.fromJson(jsonDecode(response.body));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
97
lib/pages/prepare_random_game.dart
Normal file
97
lib/pages/prepare_random_game.dart
Normal file
@ -0,0 +1,97 @@
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:http/http.dart';
|
||||
import 'package:mchess/api/register.dart';
|
||||
import 'package:mchess/chess_bloc/chess_bloc.dart';
|
||||
import 'package:mchess/chess_bloc/chess_events.dart';
|
||||
import 'package:mchess/pages/chess_game.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'dart:convert';
|
||||
|
||||
class PrepareRandomGameWidget extends StatefulWidget {
|
||||
const PrepareRandomGameWidget({super.key});
|
||||
|
||||
@override
|
||||
State<PrepareRandomGameWidget> createState() =>
|
||||
_PrepareRandomGameWidgetState();
|
||||
}
|
||||
|
||||
class _PrepareRandomGameWidgetState extends State<PrepareRandomGameWidget> {
|
||||
late Future randomGameResponse;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
ChessBloc.getInstance().add(InitBoard());
|
||||
|
||||
randomGameResponse = registerForRandomGame();
|
||||
|
||||
goToGameWhenResponseIsHere(randomGameResponse as Future<PlayerInfo?>);
|
||||
|
||||
super.initState();
|
||||
}
|
||||
|
||||
void goToGameWhenResponseIsHere(Future<PlayerInfo?> resp) {
|
||||
resp.then((value) {
|
||||
if (value == null) return;
|
||||
context.push(
|
||||
'/game',
|
||||
extra: ChessGameArguments(
|
||||
lobbyID: value.lobbyID!,
|
||||
playerID: value.playerID!,
|
||||
passphrase: value.passphrase),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const Scaffold(
|
||||
body: Center(
|
||||
child: SizedBox(
|
||||
height: 100,
|
||||
width: 100,
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<PlayerInfo?> registerForRandomGame() async {
|
||||
String addr;
|
||||
Response response;
|
||||
|
||||
if (kDebugMode) {
|
||||
addr = 'http://localhost:8080/api/random';
|
||||
} else {
|
||||
addr = 'https://chess.sw-gross.de:9999/api/random';
|
||||
}
|
||||
|
||||
try {
|
||||
response = await http
|
||||
.get(Uri.parse(addr), headers: {"Accept": "application/json"});
|
||||
} catch (e) {
|
||||
if (!context.mounted) return null;
|
||||
|
||||
const snackBar = SnackBar(
|
||||
backgroundColor: Colors.amberAccent,
|
||||
content: Text("mChess server is not responding. Try again or give up"),
|
||||
);
|
||||
Future.delayed(const Duration(seconds: 2), () {
|
||||
ScaffoldMessenger.of(context).clearSnackBars();
|
||||
ScaffoldMessenger.of(context).showSnackBar(snackBar);
|
||||
context.pop();
|
||||
});
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
log(response.body);
|
||||
return PlayerInfo.fromJson(jsonDecode(response.body));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -1,6 +1,9 @@
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:mchess/pages/chess_game.dart';
|
||||
import 'package:mchess/pages/join_game.dart';
|
||||
import 'package:mchess/pages/lobby_selector.dart';
|
||||
import 'package:mchess/pages/prepare_chess_game.dart';
|
||||
import 'package:mchess/pages/host_game.dart';
|
||||
import 'package:mchess/pages/prepare_random_game.dart';
|
||||
|
||||
class ChessAppRouter {
|
||||
static final ChessAppRouter _instance = ChessAppRouter._internal();
|
||||
@ -19,11 +22,36 @@ class ChessAppRouter {
|
||||
builder: (context, state) => const LobbySelector(),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/play',
|
||||
name: 'prepareChessGame',
|
||||
path: '/prepareRandom',
|
||||
name: 'prepareRandom',
|
||||
builder: (context, state) {
|
||||
return const PrepareChessGameWidget();
|
||||
})
|
||||
return const PrepareRandomGameWidget();
|
||||
}),
|
||||
GoRoute(
|
||||
path: '/host',
|
||||
name: 'host',
|
||||
builder: (context, state) {
|
||||
return const HostGameWidget();
|
||||
}),
|
||||
GoRoute(
|
||||
path: '/join',
|
||||
name: 'join',
|
||||
builder: (context, state) {
|
||||
return const JoinGameWidget();
|
||||
}),
|
||||
GoRoute(
|
||||
path: '/game',
|
||||
name: 'game',
|
||||
builder: (context, state) {
|
||||
var args = state.extra as ChessGameArguments;
|
||||
|
||||
return ChessGame(
|
||||
lobbyID: args.lobbyID,
|
||||
playerID: args.playerID,
|
||||
passphrase: args.passphrase,
|
||||
);
|
||||
},
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:mchess/connection/ws_connection.dart';
|
||||
|
||||
class ServerLogWidget extends StatefulWidget {
|
||||
final Color textColor;
|
||||
final String addString;
|
||||
|
||||
const ServerLogWidget(this.addString, {required this.textColor, super.key});
|
||||
const ServerLogWidget({required this.textColor, super.key});
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => ServerLogWidgetState();
|
||||
@ -17,17 +17,11 @@ class ServerLogWidgetState extends State<ServerLogWidget> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
log.add(widget.addString);
|
||||
return SizedBox(
|
||||
height: 200,
|
||||
width: 200,
|
||||
child: ListView(
|
||||
children: [
|
||||
for (int i = 0; i < log.length; i++)
|
||||
Text(
|
||||
style: TextStyle(color: widget.textColor, fontSize: 20), log[i])
|
||||
],
|
||||
),
|
||||
);
|
||||
// return Container();
|
||||
return StreamBuilder(
|
||||
stream: ServerConnection.getInstance().broadcast,
|
||||
builder: (context, snapshot) {
|
||||
return Container();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,8 @@ void main() {
|
||||
// Build our app and trigger a frame.
|
||||
await tester.pumpWidget(ChessGame(
|
||||
playerID: UuidValue("test"),
|
||||
lobbyID: UuidValue("testLobbyId"),
|
||||
passphrase: 'test',
|
||||
));
|
||||
|
||||
// Verify that our counter starts at 0.
|
||||
|
Loading…
Reference in New Issue
Block a user