Introduce checkmate screen
Show checkmate screen, once the server sends the 'gameEnded' message. Additionally, show an icon that lets users copy the passphrase to the clipboard.
This commit is contained in:
parent
7d55a0e123
commit
dfdae284ff
@ -4,7 +4,8 @@ enum MessageType {
|
|||||||
boardState,
|
boardState,
|
||||||
move,
|
move,
|
||||||
invalidMove,
|
invalidMove,
|
||||||
colorDetermined;
|
colorDetermined,
|
||||||
|
gameEnded;
|
||||||
|
|
||||||
String toJson() => name;
|
String toJson() => name;
|
||||||
static MessageType fromJson(String json) => values.byName(json);
|
static MessageType fromJson(String json) => values.byName(json);
|
||||||
@ -82,6 +83,16 @@ class ApiWebsocketMessage {
|
|||||||
squareInCheck: json['squareInCheck'],
|
squareInCheck: json['squareInCheck'],
|
||||||
playerColor: null,
|
playerColor: null,
|
||||||
);
|
);
|
||||||
|
case MessageType.gameEnded:
|
||||||
|
ret = ApiWebsocketMessage(
|
||||||
|
type: type,
|
||||||
|
move: null,
|
||||||
|
turnColor: null,
|
||||||
|
reason: json['reason'],
|
||||||
|
position: null,
|
||||||
|
squareInCheck: null,
|
||||||
|
playerColor: null,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:developer';
|
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/move.dart';
|
||||||
import 'package:mchess/api/websocket_message.dart';
|
import 'package:mchess/api/websocket_message.dart';
|
||||||
import 'package:mchess/chess_bloc/chess_bloc.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/api/register.dart';
|
||||||
import 'package:mchess/chess_bloc/chess_position.dart';
|
import 'package:mchess/chess_bloc/chess_position.dart';
|
||||||
import 'package:mchess/connection_cubit/connection_cubit.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/chess_utils.dart';
|
||||||
|
import 'package:mchess/utils/config.dart' as config;
|
||||||
import 'package:web_socket_channel/web_socket_channel.dart';
|
import 'package:web_socket_channel/web_socket_channel.dart';
|
||||||
|
|
||||||
class ServerConnection {
|
class ServerConnection {
|
||||||
@ -38,9 +42,7 @@ class ServerConnection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void connect(String playerID, lobbyID, String? passphrase) {
|
void connect(String playerID, lobbyID, String? passphrase) {
|
||||||
String url;
|
channel = WebSocketChannel.connect(Uri.parse(config.getWebsocketURL()));
|
||||||
url = 'wss://chess.sw-gross.de:9999/api/ws';
|
|
||||||
channel = WebSocketChannel.connect(Uri.parse(url));
|
|
||||||
|
|
||||||
send(
|
send(
|
||||||
jsonEncode(
|
jsonEncode(
|
||||||
@ -82,6 +84,8 @@ class ServerConnection {
|
|||||||
|
|
||||||
case MessageType.invalidMove:
|
case MessageType.invalidMove:
|
||||||
handleInvalidMoveMessage(apiMessage);
|
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');
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import 'dart:developer';
|
import 'dart:developer';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:http/http.dart';
|
import 'package:http/http.dart';
|
||||||
@ -10,6 +11,7 @@ import 'package:http/http.dart' as http;
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:mchess/pages/chess_game.dart';
|
import 'package:mchess/pages/chess_game.dart';
|
||||||
|
import 'package:mchess/utils/config.dart' as config;
|
||||||
|
|
||||||
class HostGameWidget extends StatefulWidget {
|
class HostGameWidget extends StatefulWidget {
|
||||||
const HostGameWidget({super.key});
|
const HostGameWidget({super.key});
|
||||||
@ -80,9 +82,21 @@ class _HostGameWidgetState extends State<HostGameWidget> {
|
|||||||
color: Theme.of(context).colorScheme.primary),
|
color: Theme.of(context).colorScheme.primary),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 25),
|
const SizedBox(height: 25),
|
||||||
SelectableText(
|
Row(
|
||||||
passphrase,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
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 SizedBox(height: 25),
|
||||||
const CircularProgressIndicator()
|
const CircularProgressIndicator()
|
||||||
@ -97,14 +111,11 @@ class _HostGameWidgetState extends State<HostGameWidget> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<PlayerInfo?> hostPrivateGame() async {
|
Future<PlayerInfo?> hostPrivateGame() async {
|
||||||
String addr;
|
|
||||||
Response response;
|
Response response;
|
||||||
|
|
||||||
addr = 'https://chess.sw-gross.de:9999/api/hostPrivate';
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
response = await http
|
response = await http.get(Uri.parse(config.getHostURL()),
|
||||||
.get(Uri.parse(addr), headers: {"Accept": "application/json"});
|
headers: {"Accept": "application/json"});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log(e.toString());
|
log(e.toString());
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ import 'package:http/http.dart' as http;
|
|||||||
import 'package:mchess/api/register.dart';
|
import 'package:mchess/api/register.dart';
|
||||||
import 'package:mchess/connection_cubit/connection_cubit.dart';
|
import 'package:mchess/connection_cubit/connection_cubit.dart';
|
||||||
import 'package:mchess/pages/chess_game.dart';
|
import 'package:mchess/pages/chess_game.dart';
|
||||||
|
import 'package:mchess/utils/config.dart' as config;
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
class LobbySelector extends StatefulWidget {
|
class LobbySelector extends StatefulWidget {
|
||||||
@ -149,17 +150,14 @@ class _LobbySelectorState extends State<LobbySelector> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<PlayerInfo?> joinPrivateGame() async {
|
Future<PlayerInfo?> joinPrivateGame() async {
|
||||||
String addr;
|
|
||||||
http.Response response;
|
http.Response response;
|
||||||
|
|
||||||
// server expects us to send the passphrase
|
// server expects us to send the passphrase
|
||||||
var info = PlayerInfo(
|
var info = PlayerInfo(
|
||||||
playerID: null, lobbyID: null, passphrase: phraseController.text);
|
playerID: null, lobbyID: null, passphrase: phraseController.text);
|
||||||
|
|
||||||
addr = 'https://chess.sw-gross.de:9999/api/joinPrivate';
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
response = await http.post(Uri.parse(addr),
|
response = await http.post(Uri.parse(config.getJoinURL()),
|
||||||
body: jsonEncode(info), headers: {"Accept": "application/json"});
|
body: jsonEncode(info), headers: {"Accept": "application/json"});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log(e.toString());
|
log(e.toString());
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:mchess/pages/chess_game.dart';
|
import 'package:mchess/pages/chess_game.dart';
|
||||||
import 'package:mchess/pages/lobby_selector.dart';
|
import 'package:mchess/pages/lobby_selector.dart';
|
||||||
import 'package:mchess/pages/host_game.dart';
|
import 'package:mchess/pages/host_game.dart';
|
||||||
|
|
||||||
|
final navigatorKey = GlobalKey<NavigatorState>();
|
||||||
|
|
||||||
class ChessAppRouter {
|
class ChessAppRouter {
|
||||||
static final ChessAppRouter _instance = ChessAppRouter._internal();
|
static final ChessAppRouter _instance = ChessAppRouter._internal();
|
||||||
|
|
||||||
@ -13,6 +16,7 @@ class ChessAppRouter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final router = GoRouter(
|
final router = GoRouter(
|
||||||
|
navigatorKey: navigatorKey,
|
||||||
debugLogDiagnostics: true,
|
debugLogDiagnostics: true,
|
||||||
routes: [
|
routes: [
|
||||||
GoRoute(
|
GoRoute(
|
||||||
|
34
lib/utils/config.dart
Normal file
34
lib/utils/config.dart
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
const prodURL = 'chess.sw-gross.de:9999';
|
||||||
|
const debugURL = 'localhost:8080';
|
||||||
|
|
||||||
|
const dbgUrl = true;
|
||||||
|
|
||||||
|
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';
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user