Handle board status message
This is another step to allow reconnecting after connection loss or browser closing. When the game is left with the X button on the bottom right, we will close the websocket connection, to let the server know, that we are gone. The server still has issues that prevent this from working flawlessly.
This commit is contained in:
parent
e441aaec1e
commit
1cb5ffb82b
@ -12,8 +12,8 @@ class PlayerInfo {
|
|||||||
});
|
});
|
||||||
|
|
||||||
factory PlayerInfo.fromJson(Map<String, dynamic> json) {
|
factory PlayerInfo.fromJson(Map<String, dynamic> json) {
|
||||||
final playerid = UuidValue(json['playerID']);
|
final playerid = UuidValue.fromString(json['playerID']);
|
||||||
final lobbyid = UuidValue(json['lobbyID']);
|
final lobbyid = UuidValue.fromString(json['lobbyID']);
|
||||||
final passphrase = json['passphrase'];
|
final passphrase = json['passphrase'];
|
||||||
|
|
||||||
return PlayerInfo(
|
return PlayerInfo(
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import 'package:mchess/api/move.dart';
|
import 'package:mchess/api/move.dart';
|
||||||
|
|
||||||
enum MessageType {
|
enum MessageType {
|
||||||
|
boardState,
|
||||||
move,
|
move,
|
||||||
invalidMove,
|
invalidMove,
|
||||||
colorDetermined;
|
colorDetermined;
|
||||||
@ -20,7 +21,8 @@ enum ApiColor {
|
|||||||
class ApiWebsocketMessage {
|
class ApiWebsocketMessage {
|
||||||
final MessageType type;
|
final MessageType type;
|
||||||
final ApiMove? move;
|
final ApiMove? move;
|
||||||
final ApiColor? color;
|
final ApiColor? turnColor;
|
||||||
|
final ApiColor? playerColor;
|
||||||
final String? reason;
|
final String? reason;
|
||||||
final String? position;
|
final String? position;
|
||||||
final ApiCoordinate? squareInCheck;
|
final ApiCoordinate? squareInCheck;
|
||||||
@ -28,7 +30,8 @@ class ApiWebsocketMessage {
|
|||||||
ApiWebsocketMessage({
|
ApiWebsocketMessage({
|
||||||
required this.type,
|
required this.type,
|
||||||
required this.move,
|
required this.move,
|
||||||
required this.color,
|
required this.turnColor,
|
||||||
|
required this.playerColor,
|
||||||
required this.reason,
|
required this.reason,
|
||||||
required this.position,
|
required this.position,
|
||||||
required this.squareInCheck,
|
required this.squareInCheck,
|
||||||
@ -38,34 +41,46 @@ class ApiWebsocketMessage {
|
|||||||
final type = MessageType.fromJson(json['messageType']);
|
final type = MessageType.fromJson(json['messageType']);
|
||||||
ApiWebsocketMessage ret;
|
ApiWebsocketMessage ret;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case MessageType.boardState:
|
||||||
|
ret = ApiWebsocketMessage(
|
||||||
|
type: type,
|
||||||
|
move: null,
|
||||||
|
turnColor: ApiColor.fromJson(json['turnColor']),
|
||||||
|
reason: null,
|
||||||
|
position: json['position'],
|
||||||
|
squareInCheck: null,
|
||||||
|
playerColor: ApiColor.fromJson(json['playerColor']),
|
||||||
|
);
|
||||||
case MessageType.colorDetermined:
|
case MessageType.colorDetermined:
|
||||||
ret = ApiWebsocketMessage(
|
ret = ApiWebsocketMessage(
|
||||||
type: type,
|
type: type,
|
||||||
move: null,
|
move: null,
|
||||||
color: ApiColor.fromJson(json['color']),
|
turnColor: null,
|
||||||
reason: null,
|
reason: null,
|
||||||
position: null,
|
position: null,
|
||||||
squareInCheck: null,
|
squareInCheck: null,
|
||||||
|
playerColor: ApiColor.fromJson(json['playerColor']),
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case MessageType.move:
|
case MessageType.move:
|
||||||
ret = ApiWebsocketMessage(
|
ret = ApiWebsocketMessage(
|
||||||
type: type,
|
type: type,
|
||||||
move: ApiMove.fromJson(json['move']),
|
move: ApiMove.fromJson(json['move']),
|
||||||
color: null,
|
turnColor: null,
|
||||||
reason: null,
|
reason: null,
|
||||||
position: json['position'],
|
position: json['position'],
|
||||||
squareInCheck: json['squareInCheck']
|
squareInCheck: json['squareInCheck'],
|
||||||
);
|
playerColor: null);
|
||||||
break;
|
break;
|
||||||
case MessageType.invalidMove:
|
case MessageType.invalidMove:
|
||||||
ret = ApiWebsocketMessage(
|
ret = ApiWebsocketMessage(
|
||||||
type: type,
|
type: type,
|
||||||
move: ApiMove.fromJson(json['move']),
|
move: ApiMove.fromJson(json['move']),
|
||||||
color: null,
|
turnColor: null,
|
||||||
reason: json['reason'],
|
reason: json['reason'],
|
||||||
position: null,
|
position: null,
|
||||||
squareInCheck: json['squareInCheck'],
|
squareInCheck: json['squareInCheck'],
|
||||||
|
playerColor: null,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -74,6 +89,6 @@ class ApiWebsocketMessage {
|
|||||||
Map<String, dynamic> toJson() => {
|
Map<String, dynamic> toJson() => {
|
||||||
'messageType': type,
|
'messageType': type,
|
||||||
'move': move,
|
'move': move,
|
||||||
'color': color,
|
'color': turnColor,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,8 @@ class _ChessSquareState extends State<ChessSquare> {
|
|||||||
listener: (context, state) {
|
listener: (context, state) {
|
||||||
setState(() {
|
setState(() {
|
||||||
squareColor = Colors.red;
|
squareColor = Colors.red;
|
||||||
});},
|
});
|
||||||
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
color: widget.color,
|
color: widget.color,
|
||||||
child: ChessSquareOuterDragTarget(
|
child: ChessSquareOuterDragTarget(
|
||||||
|
@ -20,10 +20,11 @@ class ChessBloc extends Bloc<ChessEvent, ChessBoardState> {
|
|||||||
ChessBloc._internal() : super(ChessBoardState.init()) {
|
ChessBloc._internal() : super(ChessBoardState.init()) {
|
||||||
on<InitBoard>(initBoard);
|
on<InitBoard>(initBoard);
|
||||||
on<ColorDetermined>(flipBoard);
|
on<ColorDetermined>(flipBoard);
|
||||||
on<ReceivedMove>(moveAndPositionHandler);
|
on<ReceivedBoardState>(moveAndPositionHandler);
|
||||||
on<OwnPieceMoved>(ownMoveHandler);
|
on<OwnPieceMoved>(ownMoveHandler);
|
||||||
on<OwnPromotionPlayed>(ownPromotionHandler);
|
on<OwnPromotionPlayed>(ownPromotionHandler);
|
||||||
on<InvalidMovePlayed>(invalidMoveHandler);
|
on<InvalidMovePlayed>(invalidMoveHandler);
|
||||||
|
on<BoardStatusReceived>(boardStatusHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
factory ChessBloc.getInstance() {
|
factory ChessBloc.getInstance() {
|
||||||
@ -65,21 +66,24 @@ class ChessBloc extends Bloc<ChessEvent, ChessBoardState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void moveAndPositionHandler(
|
void moveAndPositionHandler(
|
||||||
ReceivedMove event,
|
ReceivedBoardState event, Emitter<ChessBoardState> emit) {
|
||||||
Emitter<ChessBoardState> emit,
|
|
||||||
) {
|
|
||||||
ChessPositionManager.getInstance()
|
|
||||||
.recordMove(event.startSquare, event.endSquare, event.position);
|
|
||||||
turnColor = state.newTurnColor == ChessColor.white
|
turnColor = state.newTurnColor == ChessColor.white
|
||||||
? ChessColor.black
|
? ChessColor.black
|
||||||
: ChessColor.white;
|
: ChessColor.white;
|
||||||
|
|
||||||
|
ChessMove? move;
|
||||||
|
if (event.startSquare != null && event.endSquare != null) {
|
||||||
|
move = ChessMove(from: event.startSquare!, to: event.endSquare!);
|
||||||
|
ChessPositionManager.getInstance()
|
||||||
|
.recordMove(event.startSquare, event.endSquare, event.position);
|
||||||
|
}
|
||||||
|
|
||||||
emit(
|
emit(
|
||||||
ChessBoardState(
|
ChessBoardState(
|
||||||
state.bottomColor,
|
state.bottomColor,
|
||||||
turnColor,
|
turnColor,
|
||||||
event.position,
|
event.position,
|
||||||
ChessMove(from: event.startSquare, to: event.endSquare),
|
move,
|
||||||
true,
|
true,
|
||||||
event.squareInCheck,
|
event.squareInCheck,
|
||||||
),
|
),
|
||||||
@ -93,10 +97,11 @@ class ChessBloc extends Bloc<ChessEvent, ChessBoardState> {
|
|||||||
var apiMessage = ApiWebsocketMessage(
|
var apiMessage = ApiWebsocketMessage(
|
||||||
type: MessageType.move,
|
type: MessageType.move,
|
||||||
move: apiMove,
|
move: apiMove,
|
||||||
color: null,
|
turnColor: null,
|
||||||
reason: null,
|
reason: null,
|
||||||
position: null,
|
position: null,
|
||||||
squareInCheck: null,
|
squareInCheck: null,
|
||||||
|
playerColor: null,
|
||||||
);
|
);
|
||||||
|
|
||||||
ServerConnection.getInstance().send(jsonEncode(apiMessage));
|
ServerConnection.getInstance().send(jsonEncode(apiMessage));
|
||||||
@ -122,10 +127,11 @@ class ChessBloc extends Bloc<ChessEvent, ChessBoardState> {
|
|||||||
var message = ApiWebsocketMessage(
|
var message = ApiWebsocketMessage(
|
||||||
type: MessageType.move,
|
type: MessageType.move,
|
||||||
move: apiMove,
|
move: apiMove,
|
||||||
color: null,
|
turnColor: null,
|
||||||
reason: null,
|
reason: null,
|
||||||
position: null,
|
position: null,
|
||||||
squareInCheck: null,
|
squareInCheck: null,
|
||||||
|
playerColor: null,
|
||||||
);
|
);
|
||||||
log(jsonEncode(message));
|
log(jsonEncode(message));
|
||||||
ServerConnection.getInstance().send(jsonEncode(message));
|
ServerConnection.getInstance().send(jsonEncode(message));
|
||||||
@ -144,6 +150,20 @@ class ChessBloc extends Bloc<ChessEvent, ChessBoardState> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void boardStatusHandler(
|
||||||
|
BoardStatusReceived event, Emitter<ChessBoardState> emit) {
|
||||||
|
emit(
|
||||||
|
ChessBoardState(
|
||||||
|
event.myColor,
|
||||||
|
event.whoseTurn,
|
||||||
|
event.pos,
|
||||||
|
ChessMove.none(),
|
||||||
|
false,
|
||||||
|
ChessCoordinate.none(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ChessBoardState {
|
class ChessBoardState {
|
||||||
@ -167,12 +187,12 @@ class ChessBoardState {
|
|||||||
ChessColor bottomColor,
|
ChessColor bottomColor,
|
||||||
ChessColor turnColor,
|
ChessColor turnColor,
|
||||||
ChessPosition position,
|
ChessPosition position,
|
||||||
ChessMove lastMove,
|
ChessMove? lastMove,
|
||||||
bool positionAckd,
|
bool positionAckd,
|
||||||
ChessCoordinate squareInCheck,
|
ChessCoordinate squareInCheck,
|
||||||
) {
|
) {
|
||||||
return ChessBoardState._(bottomColor, turnColor, position, lastMove,
|
return ChessBoardState._(bottomColor, turnColor, position,
|
||||||
positionAckd, squareInCheck);
|
lastMove ?? ChessMove.none(), positionAckd, squareInCheck);
|
||||||
}
|
}
|
||||||
|
|
||||||
factory ChessBoardState.init() {
|
factory ChessBoardState.init() {
|
||||||
|
@ -3,13 +3,13 @@ import 'package:mchess/utils/chess_utils.dart';
|
|||||||
|
|
||||||
abstract class ChessEvent {}
|
abstract class ChessEvent {}
|
||||||
|
|
||||||
class ReceivedMove extends ChessEvent {
|
class ReceivedBoardState extends ChessEvent {
|
||||||
final ChessCoordinate startSquare;
|
final ChessCoordinate? startSquare;
|
||||||
final ChessCoordinate endSquare;
|
final ChessCoordinate? endSquare;
|
||||||
final ChessPosition position;
|
final ChessPosition position;
|
||||||
final ChessCoordinate squareInCheck;
|
final ChessCoordinate squareInCheck;
|
||||||
|
|
||||||
ReceivedMove({
|
ReceivedBoardState({
|
||||||
required this.startSquare,
|
required this.startSquare,
|
||||||
required this.endSquare,
|
required this.endSquare,
|
||||||
required this.position,
|
required this.position,
|
||||||
@ -54,3 +54,15 @@ class InvalidMovePlayed extends ChessEvent {
|
|||||||
required this.squareInCheck,
|
required this.squareInCheck,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class BoardStatusReceived extends ChessEvent {
|
||||||
|
final ChessPosition pos;
|
||||||
|
final ChessColor myColor;
|
||||||
|
final ChessColor whoseTurn;
|
||||||
|
|
||||||
|
BoardStatusReceived({
|
||||||
|
required this.pos,
|
||||||
|
required this.myColor,
|
||||||
|
required this.whoseTurn,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
@ -71,10 +71,16 @@ class ChessPositionManager {
|
|||||||
log(logString);
|
log(logString);
|
||||||
}
|
}
|
||||||
|
|
||||||
void recordMove(ChessCoordinate from, ChessCoordinate to, ChessPosition pos) {
|
void recordMove(
|
||||||
|
ChessCoordinate? from, ChessCoordinate? to, ChessPosition pos) {
|
||||||
position = pos;
|
position = pos;
|
||||||
|
|
||||||
history.add(ChessMove(from: from, to: to));
|
history.add(
|
||||||
|
ChessMove(
|
||||||
|
from: from ?? ChessCoordinate.none(),
|
||||||
|
to: to ?? ChessCoordinate.none(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
logPosition(position);
|
logPosition(position);
|
||||||
logHistory(history);
|
logHistory(history);
|
||||||
|
@ -12,9 +12,8 @@ import 'package:mchess/utils/chess_utils.dart';
|
|||||||
import 'package:web_socket_channel/web_socket_channel.dart';
|
import 'package:web_socket_channel/web_socket_channel.dart';
|
||||||
|
|
||||||
class ServerConnection {
|
class ServerConnection {
|
||||||
late WebSocketChannel channel;
|
WebSocketChannel? channel;
|
||||||
late bool wasConnected = false;
|
late bool wasConnected = false;
|
||||||
late int counter = 0;
|
|
||||||
Stream broadcast = const Stream.empty();
|
Stream broadcast = const Stream.empty();
|
||||||
|
|
||||||
static final ServerConnection _instance = ServerConnection._internal();
|
static final ServerConnection _instance = ServerConnection._internal();
|
||||||
@ -32,18 +31,22 @@ class ServerConnection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void send(String message) {
|
void send(String message) {
|
||||||
channel.sink.add(message);
|
if (channel == null) {
|
||||||
counter++;
|
log("Sending on channel without initializing");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
channel!.sink.add(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
void connect(String playerID, lobbyID, String? passphrase) {
|
void connect(String playerID, lobbyID, String? passphrase) {
|
||||||
|
String url;
|
||||||
if (kDebugMode) {
|
if (kDebugMode) {
|
||||||
channel =
|
url = 'ws://localhost:8080/api/ws';
|
||||||
WebSocketChannel.connect(Uri.parse('ws://localhost:8080/api/ws'));
|
|
||||||
} else {
|
} else {
|
||||||
channel = WebSocketChannel.connect(
|
url = 'wss://chess.sw-gross.de:9999/api/ws';
|
||||||
Uri.parse('wss://chess.sw-gross.de:9999/api/ws'));
|
|
||||||
}
|
}
|
||||||
|
channel = WebSocketChannel.connect(Uri.parse(url));
|
||||||
|
|
||||||
send(
|
send(
|
||||||
jsonEncode(
|
jsonEncode(
|
||||||
WebsocketMessageIdentifyPlayer(
|
WebsocketMessageIdentifyPlayer(
|
||||||
@ -54,17 +57,26 @@ class ServerConnection {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
log(channel.closeCode.toString());
|
log(channel!.closeCode.toString());
|
||||||
broadcast = channel.stream.asBroadcastStream();
|
broadcast = channel!.stream.asBroadcastStream();
|
||||||
broadcast.listen(handleIncomingData);
|
broadcast.listen(handleIncomingData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void disconnectExistingConnection() {
|
||||||
|
if (channel == null) return;
|
||||||
|
channel!.sink.close();
|
||||||
|
}
|
||||||
|
|
||||||
void handleIncomingData(dynamic data) {
|
void handleIncomingData(dynamic data) {
|
||||||
log("Data received:");
|
log("Data received:");
|
||||||
log(data);
|
log(data);
|
||||||
var apiMessage = ApiWebsocketMessage.fromJson(jsonDecode(data));
|
var apiMessage = ApiWebsocketMessage.fromJson(jsonDecode(data));
|
||||||
|
|
||||||
switch (apiMessage.type) {
|
switch (apiMessage.type) {
|
||||||
|
case MessageType.boardState:
|
||||||
|
handleBoardStateMessage(apiMessage);
|
||||||
|
break;
|
||||||
|
|
||||||
case MessageType.colorDetermined:
|
case MessageType.colorDetermined:
|
||||||
handleIncomingColorDeterminedMessage(apiMessage);
|
handleIncomingColorDeterminedMessage(apiMessage);
|
||||||
break;
|
break;
|
||||||
@ -78,25 +90,46 @@ class ServerConnection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleIncomingColorDeterminedMessage(ApiWebsocketMessage apiMessage) {
|
void handleBoardStateMessage(ApiWebsocketMessage apiMessage) {
|
||||||
ConnectionCubit.getInstance().opponentConnected();
|
ChessMove? move;
|
||||||
ChessBloc.getInstance().add(InitBoard());
|
if (apiMessage.move != null) {
|
||||||
ChessBloc.getInstance().add(
|
move = ChessMove.fromApiMove(apiMessage.move!);
|
||||||
ColorDetermined(myColor: ChessColor.fromApiColor(apiMessage.color!)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleIncomingMoveMessage(ApiWebsocketMessage apiMessage) {
|
|
||||||
var move = ChessMove.fromApiMove(apiMessage.move!);
|
|
||||||
|
|
||||||
if (apiMessage.position != null) {
|
if (apiMessage.position != null) {
|
||||||
ChessBloc.getInstance().add(
|
ChessBloc.getInstance().add(
|
||||||
ReceivedMove(
|
ReceivedBoardState(
|
||||||
|
startSquare: move?.from,
|
||||||
|
endSquare: move?.to,
|
||||||
|
position: ChessPositionManager.getInstance()
|
||||||
|
.fromPGNString(apiMessage.position!),
|
||||||
|
squareInCheck: ChessCoordinate.fromApiCoordinate(
|
||||||
|
apiMessage.squareInCheck ?? const ApiCoordinate(col: 0, row: 0)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
log('Error: no position received');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleIncomingColorDeterminedMessage(ApiWebsocketMessage apiMessage) {
|
||||||
|
ConnectionCubit.getInstance().opponentConnected();
|
||||||
|
ChessBloc.getInstance().add(InitBoard());
|
||||||
|
ChessBloc.getInstance().add(ColorDetermined(
|
||||||
|
myColor: ChessColor.fromApiColor(apiMessage.playerColor!)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleIncomingMoveMessage(ApiWebsocketMessage apiMessage) {
|
||||||
|
if (apiMessage.position != null) {
|
||||||
|
var move = ChessMove.fromApiMove(apiMessage.move!);
|
||||||
|
ChessBloc.getInstance().add(
|
||||||
|
ReceivedBoardState(
|
||||||
startSquare: move.from,
|
startSquare: move.from,
|
||||||
endSquare: move.to,
|
endSquare: move.to,
|
||||||
position: ChessPositionManager.getInstance()
|
position: ChessPositionManager.getInstance()
|
||||||
.fromPGNString(apiMessage.position!),
|
.fromPGNString(apiMessage.position!),
|
||||||
squareInCheck:
|
squareInCheck: ChessCoordinate.fromApiCoordinate(
|
||||||
ChessCoordinate.fromApiCoordinate(apiMessage.squareInCheck ?? const ApiCoordinate(col: 0, row: 0)),
|
apiMessage.squareInCheck ?? const ApiCoordinate(col: 0, row: 0)),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
@ -109,8 +142,8 @@ class ServerConnection {
|
|||||||
ChessBloc.getInstance().add(
|
ChessBloc.getInstance().add(
|
||||||
InvalidMovePlayed(
|
InvalidMovePlayed(
|
||||||
move: ChessMove.fromApiMove(apiMessage.move!),
|
move: ChessMove.fromApiMove(apiMessage.move!),
|
||||||
squareInCheck:
|
squareInCheck: ChessCoordinate.fromApiCoordinate(
|
||||||
ChessCoordinate.fromApiCoordinate(apiMessage.squareInCheck!),
|
apiMessage.squareInCheck ?? const ApiCoordinate(col: 0, row: 0)),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import 'package:mchess/chess_bloc/chess_bloc.dart';
|
|||||||
|
|
||||||
import 'package:mchess/chess/chess_board.dart';
|
import 'package:mchess/chess/chess_board.dart';
|
||||||
import 'package:mchess/chess_bloc/promotion_bloc.dart';
|
import 'package:mchess/chess_bloc/promotion_bloc.dart';
|
||||||
|
import 'package:mchess/connection/ws_connection.dart';
|
||||||
import 'package:mchess/utils/chess_utils.dart';
|
import 'package:mchess/utils/chess_utils.dart';
|
||||||
import 'package:mchess/utils/widgets/promotion_dialog.dart';
|
import 'package:mchess/utils/widgets/promotion_dialog.dart';
|
||||||
import 'package:uuid/uuid.dart';
|
import 'package:uuid/uuid.dart';
|
||||||
@ -53,6 +54,7 @@ class _ChessGameState extends State<ChessGame> {
|
|||||||
),
|
),
|
||||||
floatingActionButton: FloatingActionButton(
|
floatingActionButton: FloatingActionButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
|
ServerConnection.getInstance().disconnectExistingConnection();
|
||||||
context.push('/');
|
context.push('/');
|
||||||
},
|
},
|
||||||
child: const Icon(Icons.cancel),
|
child: const Icon(Icons.cancel),
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
|
import 'package:mchess/connection/ws_connection.dart';
|
||||||
import 'package:mchess/pages/chess_game.dart';
|
import 'package:mchess/pages/chess_game.dart';
|
||||||
import 'package:mchess/pages/join_game.dart';
|
import 'package:mchess/pages/join_game.dart';
|
||||||
import 'package:mchess/pages/lobby_selector.dart';
|
import 'package:mchess/pages/lobby_selector.dart';
|
||||||
@ -19,7 +20,9 @@ class ChessAppRouter {
|
|||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/',
|
path: '/',
|
||||||
name: 'lobbySelector',
|
name: 'lobbySelector',
|
||||||
builder: (context, state) => const LobbySelector(),
|
builder: (context, state) {
|
||||||
|
return const LobbySelector();
|
||||||
|
},
|
||||||
),
|
),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/prepareRandom',
|
path: '/prepareRandom',
|
||||||
|
@ -1,53 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
||||||
import 'package:mchess/chess_bloc/chess_bloc.dart';
|
|
||||||
import 'package:mchess/chess_bloc/chess_position.dart';
|
|
||||||
import 'package:mchess/utils/chess_utils.dart';
|
|
||||||
|
|
||||||
class MoveHistory extends StatefulWidget {
|
|
||||||
const MoveHistory({super.key});
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<MoveHistory> createState() => _MoveHistoryState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _MoveHistoryState extends State<MoveHistory> {
|
|
||||||
late List<String> entries;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
entries = [];
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return BlocListener<ChessBloc, ChessBoardState>(
|
|
||||||
listener: (context, state) {
|
|
||||||
List<String> newEntries = [];
|
|
||||||
var positionManager = ChessPositionManager.getInstance();
|
|
||||||
var allMoves = positionManager.allMoves;
|
|
||||||
|
|
||||||
for (ChessMove move in allMoves) {
|
|
||||||
var movedPiece = positionManager.getPieceAt(move.to);
|
|
||||||
var char = pieceCharacter[ChessPieceAssetKey(
|
|
||||||
pieceClass: movedPiece!.pieceClass,
|
|
||||||
color: movedPiece.color.getOpposite())];
|
|
||||||
|
|
||||||
if (movedPiece.color == ChessColor.white) {
|
|
||||||
newEntries.add("$char ${move.to.toAlphabetical()}");
|
|
||||||
} else {
|
|
||||||
newEntries.last =
|
|
||||||
"${newEntries.last}\t\t$char${move.to.toAlphabetical()}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setState(() {
|
|
||||||
entries = newEntries;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
child: ListView(children: [
|
|
||||||
for (var entry in entries) Text(entry),
|
|
||||||
]),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
20
pubspec.lock
20
pubspec.lock
@ -124,18 +124,18 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: go_router
|
name: go_router
|
||||||
sha256: c247a4f76071c3b97bb5ae8912968870d5565644801c5e09f3bc961b4d874895
|
sha256: c5fa45fa502ee880839e3b2152d987c44abae26d064a2376d4aad434cf0f7b15
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "12.1.1"
|
version: "12.1.3"
|
||||||
http:
|
http:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: http
|
name: http
|
||||||
sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525"
|
sha256: d4872660c46d929f6b8a9ef4e7a7eff7e49bbf0c4ec3f385ee32df5119175139
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "1.1.2"
|
||||||
http_parser:
|
http_parser:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -212,10 +212,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: petitparser
|
name: petitparser
|
||||||
sha256: eeb2d1428ee7f4170e2bd498827296a18d4e7fc462b71727d111c0ac7707cfa6
|
sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.0.1"
|
version: "6.0.2"
|
||||||
provider:
|
provider:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -361,10 +361,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: xml
|
name: xml
|
||||||
sha256: af5e77e9b83f2f4adc5d3f0a4ece1c7f45a2467b695c2540381bac793e34e556
|
sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.4.2"
|
version: "6.5.0"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=3.2.0-194.0.dev <4.0.0"
|
dart: ">=3.2.0 <4.0.0"
|
||||||
flutter: ">=3.7.0"
|
flutter: ">=3.10.0"
|
||||||
|
@ -13,9 +13,9 @@ import 'package:uuid/uuid.dart';
|
|||||||
void main() {
|
void main() {
|
||||||
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
|
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
|
||||||
// Build our app and trigger a frame.
|
// Build our app and trigger a frame.
|
||||||
await tester.pumpWidget(const ChessGame(
|
await tester.pumpWidget(ChessGame(
|
||||||
playerID: UuidValue("test"),
|
playerID: UuidValue.fromString("test"),
|
||||||
lobbyID: UuidValue("testLobbyId"),
|
lobbyID: UuidValue.fromString("testLobbyId"),
|
||||||
passphrase: 'test',
|
passphrase: 'test',
|
||||||
));
|
));
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user