Merge pull request 'Introduce checkmate screen' (#6) from checkmate-screen into master

Reviewed-on: #6
This commit is contained in:
marco 2024-01-18 17:03:30 +01:00
commit c9381aaa4c
6 changed files with 103 additions and 16 deletions

View File

@ -4,7 +4,8 @@ enum MessageType {
boardState,
move,
invalidMove,
colorDetermined;
colorDetermined,
gameEnded;
String toJson() => name;
static MessageType fromJson(String json) => values.byName(json);
@ -82,6 +83,16 @@ class ApiWebsocketMessage {
squareInCheck: json['squareInCheck'],
playerColor: null,
);
case MessageType.gameEnded:
ret = ApiWebsocketMessage(
type: type,
move: null,
turnColor: null,
reason: json['reason'],
position: null,
squareInCheck: null,
playerColor: null,
);
}
return ret;
}

View File

@ -1,5 +1,7 @@
import 'dart:convert';
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:mchess/api/move.dart';
import 'package:mchess/api/websocket_message.dart';
import 'package:mchess/chess_bloc/chess_bloc.dart';
@ -7,7 +9,9 @@ import 'package:mchess/chess_bloc/chess_events.dart';
import 'package:mchess/api/register.dart';
import 'package:mchess/chess_bloc/chess_position.dart';
import 'package:mchess/connection_cubit/connection_cubit.dart';
import 'package:mchess/utils/chess_router.dart';
import 'package:mchess/utils/chess_utils.dart';
import 'package:mchess/utils/config.dart' as config;
import 'package:web_socket_channel/web_socket_channel.dart';
class ServerConnection {
@ -38,9 +42,7 @@ class ServerConnection {
}
void connect(String playerID, lobbyID, String? passphrase) {
String url;
url = 'wss://chess.sw-gross.de:9999/api/ws';
channel = WebSocketChannel.connect(Uri.parse(url));
channel = WebSocketChannel.connect(Uri.parse(config.getWebsocketURL()));
send(
jsonEncode(
@ -82,6 +84,8 @@ class ServerConnection {
case MessageType.invalidMove:
handleInvalidMoveMessage(apiMessage);
case MessageType.gameEnded:
handleGameEndedMessage(apiMessage);
}
}
@ -125,4 +129,29 @@ class ServerConnection {
),
);
}
void handleGameEndedMessage(ApiWebsocketMessage apiMessage) {
showDialog(
context: navigatorKey.currentContext!,
builder: (context) {
String msg = '';
if (apiMessage.reason == 'whiteIsCheckmated') {
msg = 'Black won! White is checkmated';
} else if (apiMessage.reason == 'blackIsCheckmated') {
msg = 'White won! Black is checkmated';
}
return AlertDialog(
title: const Text('Game ended'),
content: Text(msg),
actions: <Widget>[
TextButton(
child: const Text('Home'),
onPressed: () {
navigatorKey.currentContext!.goNamed('lobbySelector');
},
),
]);
},
);
}
}

View File

@ -1,6 +1,7 @@
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';
@ -10,6 +11,7 @@ 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;
class HostGameWidget extends StatefulWidget {
const HostGameWidget({super.key});
@ -80,9 +82,21 @@ class _HostGameWidgetState extends State<HostGameWidget> {
color: Theme.of(context).colorScheme.primary),
),
const SizedBox(height: 25),
SelectableText(
passphrase,
style: const TextStyle(fontWeight: FontWeight.bold),
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()
@ -97,14 +111,11 @@ class _HostGameWidgetState extends State<HostGameWidget> {
}
Future<PlayerInfo?> hostPrivateGame() async {
String addr;
Response response;
addr = 'https://chess.sw-gross.de:9999/api/hostPrivate';
try {
response = await http
.get(Uri.parse(addr), headers: {"Accept": "application/json"});
response = await http.get(Uri.parse(config.getHostURL()),
headers: {"Accept": "application/json"});
} catch (e) {
log(e.toString());

View File

@ -7,6 +7,7 @@ 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:mchess/utils/config.dart' as config;
import 'package:shared_preferences/shared_preferences.dart';
class LobbySelector extends StatefulWidget {
@ -149,17 +150,14 @@ class _LobbySelectorState extends State<LobbySelector> {
}
Future<PlayerInfo?> joinPrivateGame() async {
String addr;
http.Response response;
// server expects us to send the passphrase
var info = PlayerInfo(
playerID: null, lobbyID: null, passphrase: phraseController.text);
addr = 'https://chess.sw-gross.de:9999/api/joinPrivate';
try {
response = await http.post(Uri.parse(addr),
response = await http.post(Uri.parse(config.getJoinURL()),
body: jsonEncode(info), headers: {"Accept": "application/json"});
} catch (e) {
log(e.toString());

View File

@ -1,8 +1,11 @@
import 'package:flutter/widgets.dart';
import 'package:go_router/go_router.dart';
import 'package:mchess/pages/chess_game.dart';
import 'package:mchess/pages/lobby_selector.dart';
import 'package:mchess/pages/host_game.dart';
final navigatorKey = GlobalKey<NavigatorState>();
class ChessAppRouter {
static final ChessAppRouter _instance = ChessAppRouter._internal();
@ -13,6 +16,7 @@ class ChessAppRouter {
}
final router = GoRouter(
navigatorKey: navigatorKey,
debugLogDiagnostics: true,
routes: [
GoRoute(

34
lib/utils/config.dart Normal file
View File

@ -0,0 +1,34 @@
const prodURL = 'chess.sw-gross.de:9999';
const debugURL = 'localhost:8080';
const dbgUrl = false;
String getHostURL() {
var prot = 'https';
var domain = prodURL;
if (dbgUrl) {
prot = 'http';
domain = debugURL;
}
return '$prot://$domain/api/hostPrivate';
}
String getJoinURL() {
var prot = 'https';
var domain = prodURL;
if (dbgUrl) {
prot = 'http';
domain = debugURL;
}
return '$prot://$domain/api/joinPrivate';
}
String getWebsocketURL() {
var prot = 'wss';
var domain = prodURL;
if (dbgUrl) {
prot = 'ws';
domain = debugURL;
}
return '$prot://$domain/api/ws';
}