Compare commits
No commits in common. "master" and "drag-starts-tap" have entirely different histories.
master
...
drag-start
@ -1,65 +0,0 @@
|
|||||||
import 'package:shared_preferences/shared_preferences.dart';
|
|
||||||
import 'package:uuid/uuid.dart';
|
|
||||||
|
|
||||||
class GameInfo {
|
|
||||||
final UuidValue? playerID;
|
|
||||||
final String? passphrase;
|
|
||||||
|
|
||||||
const GameInfo({
|
|
||||||
required this.playerID,
|
|
||||||
required this.passphrase,
|
|
||||||
});
|
|
||||||
|
|
||||||
factory GameInfo.empty() {
|
|
||||||
return const GameInfo(playerID: null, passphrase: null);
|
|
||||||
}
|
|
||||||
|
|
||||||
factory GameInfo.fromJson(Map<String, dynamic> json) {
|
|
||||||
final playerid = UuidValue.fromString(json['playerID']);
|
|
||||||
final passphrase = json['passphrase'];
|
|
||||||
|
|
||||||
return GameInfo(playerID: playerid, passphrase: passphrase);
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
|
||||||
String? pid;
|
|
||||||
|
|
||||||
if (playerID != null) {
|
|
||||||
pid = playerID.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
'playerID': pid,
|
|
||||||
'passphrase': passphrase,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
void store() async {
|
|
||||||
final SharedPreferences prefs = await SharedPreferences.getInstance();
|
|
||||||
|
|
||||||
await prefs.setString(passphrase!, playerID.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
static Future<GameInfo?> get(String phrase) async {
|
|
||||||
final SharedPreferences prefs = await SharedPreferences.getInstance();
|
|
||||||
var playerID = prefs.getString(phrase);
|
|
||||||
|
|
||||||
if (playerID == null) return null;
|
|
||||||
|
|
||||||
return GameInfo(
|
|
||||||
playerID: UuidValue.fromString(playerID), passphrase: phrase);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class WebsocketMessageIdentifyPlayer {
|
|
||||||
final String playerID;
|
|
||||||
final String? passphrase;
|
|
||||||
|
|
||||||
const WebsocketMessageIdentifyPlayer({
|
|
||||||
required this.playerID,
|
|
||||||
required this.passphrase,
|
|
||||||
});
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() =>
|
|
||||||
{'playerID': playerID, 'passphrase': passphrase};
|
|
||||||
}
|
|
80
lib/api/register.dart
Normal file
80
lib/api/register.dart
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
import 'package:uuid/uuid.dart';
|
||||||
|
|
||||||
|
class PlayerInfo {
|
||||||
|
final UuidValue? playerID;
|
||||||
|
final UuidValue? lobbyID;
|
||||||
|
final String? passphrase;
|
||||||
|
|
||||||
|
const PlayerInfo({
|
||||||
|
required this.playerID,
|
||||||
|
required this.lobbyID,
|
||||||
|
required this.passphrase,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory PlayerInfo.fromJson(Map<String, dynamic> json) {
|
||||||
|
final playerid = UuidValue.fromString(json['playerID']);
|
||||||
|
final lobbyid = UuidValue.fromString(json['lobbyID']);
|
||||||
|
final passphrase = json['passphrase'];
|
||||||
|
|
||||||
|
return PlayerInfo(
|
||||||
|
playerID: playerid, lobbyID: lobbyid, passphrase: passphrase);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => {
|
||||||
|
'playerID': playerID,
|
||||||
|
'lobbyID': lobbyID,
|
||||||
|
'passphrase': passphrase,
|
||||||
|
};
|
||||||
|
|
||||||
|
void store() async {
|
||||||
|
final SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
|
|
||||||
|
await prefs.setBool("contains", true);
|
||||||
|
await prefs.setString("playerID", playerID.toString());
|
||||||
|
await prefs.setString("lobbyID", lobbyID.toString());
|
||||||
|
await prefs.setString("passphrase", passphrase.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
void delete() async {
|
||||||
|
final SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
|
|
||||||
|
await prefs.setBool("contains", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<PlayerInfo?> get() async {
|
||||||
|
final SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
|
var contains = prefs.getBool("contains");
|
||||||
|
var playerID = prefs.getString("playerID");
|
||||||
|
var lobbyID = prefs.getString("lobbyID");
|
||||||
|
var passphrase = prefs.getString("passphrase");
|
||||||
|
|
||||||
|
if (contains == null ||
|
||||||
|
!contains ||
|
||||||
|
playerID == null ||
|
||||||
|
lobbyID == null ||
|
||||||
|
passphrase == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PlayerInfo(
|
||||||
|
playerID: UuidValue.fromString(playerID),
|
||||||
|
lobbyID: UuidValue.fromString(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, 'passphrase': passphrase};
|
||||||
|
}
|
@ -7,8 +7,7 @@ import 'package:mchess/connection_cubit/connection_cubit.dart';
|
|||||||
import 'package:mchess/utils/chess_router.dart';
|
import 'package:mchess/utils/chess_router.dart';
|
||||||
|
|
||||||
class ChessApp extends StatelessWidget {
|
class ChessApp extends StatelessWidget {
|
||||||
final String? version;
|
const ChessApp({super.key});
|
||||||
const ChessApp({super.key, this.version});
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -32,7 +31,7 @@ class ChessApp extends StatelessWidget {
|
|||||||
useMaterial3: true,
|
useMaterial3: true,
|
||||||
),
|
),
|
||||||
routerConfig: ChessAppRouter.getInstance().router,
|
routerConfig: ChessAppRouter.getInstance().router,
|
||||||
title: 'mChess $version',
|
title: 'mChess 0.9.115',
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:mchess/chess/chess_square_outer_dragtarget.dart';
|
import 'package:mchess/chess/chess_square_outer_dragtarget.dart';
|
||||||
import 'package:mchess/chess_bloc/chess_bloc.dart';
|
|
||||||
import 'package:mchess/chess_bloc/tap_bloc.dart';
|
import 'package:mchess/chess_bloc/tap_bloc.dart';
|
||||||
import '../utils/chess_utils.dart';
|
import '../utils/chess_utils.dart';
|
||||||
|
|
||||||
@ -67,8 +66,7 @@ class _ChessSquareState extends State<ChessSquare> {
|
|||||||
containedPiece: widget.containedPiece ?? const ChessPiece.none()),
|
containedPiece: widget.containedPiece ?? const ChessPiece.none()),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (widget.containedPiece == null ||
|
if (widget.containedPiece == null) {
|
||||||
widget.containedPiece!.color != ChessBloc.getMyColor()) {
|
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
child: dragTarget,
|
child: dragTarget,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
@ -30,13 +30,13 @@ class ChessSquareOuterDragTarget extends StatelessWidget {
|
|||||||
|
|
||||||
if (isPromotionMove(
|
if (isPromotionMove(
|
||||||
details.data.movedPiece!.pieceClass,
|
details.data.movedPiece!.pieceClass,
|
||||||
ChessBloc.getMyColor(),
|
ChessBloc.myColor!,
|
||||||
details.data.toSquare,
|
details.data.toSquare,
|
||||||
)) {
|
)) {
|
||||||
var move = ChessMove(
|
var move = ChessMove(
|
||||||
from: details.data.fromSquare, to: details.data.toSquare);
|
from: details.data.fromSquare, to: details.data.toSquare);
|
||||||
PromotionBloc().add(PawnMovedToPromotionField(
|
PromotionBloc().add(PawnMovedToPromotionField(
|
||||||
move: move, colorMoved: ChessBloc.myColor));
|
move: move, colorMoved: ChessBloc.myColor!));
|
||||||
} else if (coordinate != details.data.fromSquare) {
|
} else if (coordinate != details.data.fromSquare) {
|
||||||
ChessBloc().add(OwnPieceMoved(
|
ChessBloc().add(OwnPieceMoved(
|
||||||
startSquare: details.data.fromSquare,
|
startSquare: details.data.fromSquare,
|
||||||
|
@ -11,9 +11,9 @@ import 'package:mchess/utils/chess_utils.dart';
|
|||||||
class ChessBloc extends Bloc<ChessEvent, ChessBoardState> {
|
class ChessBloc extends Bloc<ChessEvent, ChessBoardState> {
|
||||||
static final ChessBloc _instance = ChessBloc._internal();
|
static final ChessBloc _instance = ChessBloc._internal();
|
||||||
static ChessColor turnColor = ChessColor.white;
|
static ChessColor turnColor = ChessColor.white;
|
||||||
static ChessColor myColor = ChessColor.white;
|
static ChessColor? myColor = ChessColor.white;
|
||||||
|
|
||||||
static ChessColor getMyColor() {
|
static ChessColor? getSidesColor() {
|
||||||
return myColor;
|
return myColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,12 +51,10 @@ class ChessBloc extends Bloc<ChessEvent, ChessBoardState> {
|
|||||||
|
|
||||||
void flipBoard(ColorDetermined event, Emitter<ChessBoardState> emit) {
|
void flipBoard(ColorDetermined event, Emitter<ChessBoardState> emit) {
|
||||||
log("My Color is $myColor");
|
log("My Color is $myColor");
|
||||||
|
myColor = event.myColor;
|
||||||
myColor = event.playerColor;
|
|
||||||
|
|
||||||
emit(
|
emit(
|
||||||
ChessBoardState(
|
ChessBoardState(
|
||||||
event.playerColor,
|
event.myColor,
|
||||||
state.newTurnColor,
|
state.newTurnColor,
|
||||||
state.position,
|
state.position,
|
||||||
ChessMove.none(),
|
ChessMove.none(),
|
||||||
@ -76,13 +74,12 @@ class ChessBloc extends Bloc<ChessEvent, ChessBoardState> {
|
|||||||
.recordMove(event.startSquare, event.endSquare, event.position);
|
.recordMove(event.startSquare, event.endSquare, event.position);
|
||||||
}
|
}
|
||||||
|
|
||||||
myColor = event.playerColor;
|
|
||||||
turnColor = event.turnColor;
|
turnColor = event.turnColor;
|
||||||
|
|
||||||
emit(
|
emit(
|
||||||
ChessBoardState(
|
ChessBoardState(
|
||||||
myColor,
|
state.bottomColor,
|
||||||
event.turnColor,
|
turnColor,
|
||||||
event.position,
|
event.position,
|
||||||
move,
|
move,
|
||||||
true,
|
true,
|
||||||
@ -129,7 +126,7 @@ class ChessBloc extends Bloc<ChessEvent, ChessBoardState> {
|
|||||||
OwnPromotionPlayed event, Emitter<ChessBoardState> emit) {
|
OwnPromotionPlayed event, Emitter<ChessBoardState> emit) {
|
||||||
var apiMove = event.move.toApiMove();
|
var apiMove = event.move.toApiMove();
|
||||||
var shorNameForPiece = chessPiecesShortName[
|
var shorNameForPiece = chessPiecesShortName[
|
||||||
ChessPieceAssetKey(pieceClass: event.pieceClass, color: myColor)]!;
|
ChessPieceAssetKey(pieceClass: event.pieceClass, color: myColor!)]!;
|
||||||
apiMove.promotionToPiece = shorNameForPiece;
|
apiMove.promotionToPiece = shorNameForPiece;
|
||||||
var message = ApiWebsocketMessage(
|
var message = ApiWebsocketMessage(
|
||||||
type: MessageType.move,
|
type: MessageType.move,
|
||||||
|
@ -9,7 +9,6 @@ class ReceivedBoardState extends ChessEvent {
|
|||||||
final ChessPosition position;
|
final ChessPosition position;
|
||||||
final ChessCoordinate squareInCheck;
|
final ChessCoordinate squareInCheck;
|
||||||
final ChessColor turnColor;
|
final ChessColor turnColor;
|
||||||
final ChessColor playerColor;
|
|
||||||
|
|
||||||
ReceivedBoardState({
|
ReceivedBoardState({
|
||||||
required this.startSquare,
|
required this.startSquare,
|
||||||
@ -17,7 +16,6 @@ class ReceivedBoardState extends ChessEvent {
|
|||||||
required this.position,
|
required this.position,
|
||||||
required this.squareInCheck,
|
required this.squareInCheck,
|
||||||
required this.turnColor,
|
required this.turnColor,
|
||||||
required this.playerColor,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,9 +38,9 @@ class InitBoard extends ChessEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class ColorDetermined extends ChessEvent {
|
class ColorDetermined extends ChessEvent {
|
||||||
final ChessColor playerColor;
|
final ChessColor myColor;
|
||||||
|
|
||||||
ColorDetermined({required this.playerColor});
|
ColorDetermined({required this.myColor});
|
||||||
}
|
}
|
||||||
|
|
||||||
class InvalidMovePlayed extends ChessEvent {
|
class InvalidMovePlayed extends ChessEvent {
|
||||||
|
@ -51,12 +51,12 @@ class TapBloc extends Bloc<TapEvent, TapState> {
|
|||||||
state.firstSquareTapped != event.tapped) {
|
state.firstSquareTapped != event.tapped) {
|
||||||
if (isPromotionMove(
|
if (isPromotionMove(
|
||||||
state.pieceOnFirstTappedSquare!.pieceClass,
|
state.pieceOnFirstTappedSquare!.pieceClass,
|
||||||
ChessBloc.myColor,
|
ChessBloc.myColor!,
|
||||||
event.tapped,
|
event.tapped,
|
||||||
)) {
|
)) {
|
||||||
PromotionBloc().add(PawnMovedToPromotionField(
|
PromotionBloc().add(PawnMovedToPromotionField(
|
||||||
move: ChessMove(from: state.firstSquareTapped!, to: event.tapped),
|
move: ChessMove(from: state.firstSquareTapped!, to: event.tapped),
|
||||||
colorMoved: ChessBloc.myColor));
|
colorMoved: ChessBloc.myColor!));
|
||||||
emit(TapState.init());
|
emit(TapState.init());
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
|
@ -6,7 +6,7 @@ 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';
|
||||||
import 'package:mchess/chess_bloc/chess_events.dart';
|
import 'package:mchess/chess_bloc/chess_events.dart';
|
||||||
import 'package:mchess/api/game_info.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_router.dart';
|
||||||
@ -16,6 +16,7 @@ import 'package:web_socket_channel/web_socket_channel.dart';
|
|||||||
|
|
||||||
class ServerConnection {
|
class ServerConnection {
|
||||||
WebSocketChannel? channel;
|
WebSocketChannel? channel;
|
||||||
|
late bool wasConnected = false;
|
||||||
Stream broadcast = const Stream.empty();
|
Stream broadcast = const Stream.empty();
|
||||||
|
|
||||||
static final ServerConnection _instance = ServerConnection._internal();
|
static final ServerConnection _instance = ServerConnection._internal();
|
||||||
@ -40,36 +41,27 @@ class ServerConnection {
|
|||||||
channel!.sink.add(message);
|
channel!.sink.add(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future? connect(String playerID, String? passphrase) {
|
void connect(String playerID, lobbyID, String? passphrase) {
|
||||||
if (channel != null) return null;
|
|
||||||
|
|
||||||
channel = WebSocketChannel.connect(Uri.parse(config.getWebsocketURL()));
|
channel = WebSocketChannel.connect(Uri.parse(config.getWebsocketURL()));
|
||||||
|
|
||||||
channel!.ready.then((val) {
|
send(
|
||||||
send(
|
jsonEncode(
|
||||||
jsonEncode(
|
WebsocketMessageIdentifyPlayer(
|
||||||
WebsocketMessageIdentifyPlayer(
|
playerID: (playerID),
|
||||||
playerID: (playerID),
|
lobbyID: (lobbyID),
|
||||||
passphrase: (passphrase),
|
passphrase: (passphrase),
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
),
|
||||||
|
);
|
||||||
|
|
||||||
log(channel!.closeCode.toString());
|
log(channel!.closeCode.toString());
|
||||||
broadcast = channel!.stream.asBroadcastStream();
|
broadcast = channel!.stream.asBroadcastStream();
|
||||||
broadcast.listen(handleIncomingData);
|
broadcast.listen(handleIncomingData);
|
||||||
});
|
|
||||||
|
|
||||||
return channel!.ready;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future disconnectExistingConnection() async {
|
void disconnectExistingConnection() {
|
||||||
if (channel == null) return;
|
if (channel == null) return;
|
||||||
|
channel!.sink.close();
|
||||||
await channel!.sink.close();
|
|
||||||
|
|
||||||
channel = null;
|
|
||||||
broadcast = const Stream.empty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleIncomingData(dynamic data) {
|
void handleIncomingData(dynamic data) {
|
||||||
@ -106,15 +98,14 @@ class ServerConnection {
|
|||||||
if (apiMessage.position != null) {
|
if (apiMessage.position != null) {
|
||||||
ChessBloc.getInstance().add(
|
ChessBloc.getInstance().add(
|
||||||
ReceivedBoardState(
|
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: ChessCoordinate.fromApiCoordinate(
|
squareInCheck: ChessCoordinate.fromApiCoordinate(
|
||||||
apiMessage.squareInCheck ?? const ApiCoordinate(col: 0, row: 0)),
|
apiMessage.squareInCheck ??
|
||||||
turnColor: ChessColor.fromApiColor(apiMessage.turnColor!),
|
const ApiCoordinate(col: 0, row: 0)),
|
||||||
playerColor: ChessColor.fromApiColor(apiMessage.playerColor!),
|
turnColor: ChessColor.fromApiColor(apiMessage.turnColor!)),
|
||||||
),
|
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
log('Error: no position received');
|
log('Error: no position received');
|
||||||
@ -125,7 +116,7 @@ class ServerConnection {
|
|||||||
ConnectionCubit.getInstance().opponentConnected();
|
ConnectionCubit.getInstance().opponentConnected();
|
||||||
ChessBloc.getInstance().add(InitBoard());
|
ChessBloc.getInstance().add(InitBoard());
|
||||||
ChessBloc.getInstance().add(ColorDetermined(
|
ChessBloc.getInstance().add(ColorDetermined(
|
||||||
playerColor: ChessColor.fromApiColor(apiMessage.playerColor!)));
|
myColor: ChessColor.fromApiColor(apiMessage.playerColor!)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleInvalidMoveMessage(ApiWebsocketMessage apiMessage) {
|
void handleInvalidMoveMessage(ApiWebsocketMessage apiMessage) {
|
||||||
|
@ -15,64 +15,21 @@ class ConnectionCubit extends Cubit<ConnectionCubitState> {
|
|||||||
return _instance;
|
return _instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
void connect(String playerID, String? passphrase) {
|
void connect(String playerID, lobbyID, String? passphrase) {
|
||||||
var connectedFuture =
|
ServerConnection.getInstance().connect(playerID, lobbyID, passphrase);
|
||||||
ServerConnection.getInstance().connect(playerID, passphrase);
|
|
||||||
|
|
||||||
connectedFuture?.then((val) {
|
|
||||||
emit(ConnectionCubitState(
|
|
||||||
iAmConnected: true,
|
|
||||||
connectedToPhrase: passphrase,
|
|
||||||
opponentConnected: false));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void connectIfNotConnected(String playerID, String? passphrase) {
|
|
||||||
if (state.iAmConnected && state.connectedToPhrase == passphrase) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (state.iAmConnected && state.connectedToPhrase != passphrase) {
|
|
||||||
disonnect().then((val) {
|
|
||||||
connect(playerID, passphrase);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
connect(playerID, passphrase);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future disonnect() async {
|
|
||||||
var disconnectFuture =
|
|
||||||
ServerConnection.getInstance().disconnectExistingConnection();
|
|
||||||
|
|
||||||
disconnectFuture.then(
|
|
||||||
(val) {
|
|
||||||
emit(ConnectionCubitState.init());
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
return disconnectFuture;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void opponentConnected() {
|
void opponentConnected() {
|
||||||
emit(ConnectionCubitState(
|
emit(ConnectionCubitState(true));
|
||||||
iAmConnected: state.iAmConnected,
|
|
||||||
connectedToPhrase: state.connectedToPhrase,
|
|
||||||
opponentConnected: true));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ConnectionCubitState {
|
class ConnectionCubitState {
|
||||||
final bool iAmConnected;
|
|
||||||
final String? connectedToPhrase;
|
|
||||||
final bool opponentConnected;
|
final bool opponentConnected;
|
||||||
|
|
||||||
ConnectionCubitState(
|
ConnectionCubitState(this.opponentConnected);
|
||||||
{required this.iAmConnected,
|
|
||||||
required this.connectedToPhrase,
|
|
||||||
required this.opponentConnected});
|
|
||||||
|
|
||||||
factory ConnectionCubitState.init() {
|
factory ConnectionCubitState.init() {
|
||||||
return ConnectionCubitState(
|
return ConnectionCubitState(false);
|
||||||
iAmConnected: false, connectedToPhrase: null, opponentConnected: false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:mchess/chess/chess_app.dart';
|
import 'package:mchess/chess/chess_app.dart';
|
||||||
import 'package:package_info_plus/package_info_plus.dart';
|
|
||||||
|
|
||||||
void main() async {
|
void main() {
|
||||||
final info = await PackageInfo.fromPlatform();
|
GoRouter.optionURLReflectsImperativeAPIs = true;
|
||||||
|
runApp(const ChessApp());
|
||||||
runApp(ChessApp(version: info.version));
|
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,14 @@ import 'package:universal_platform/universal_platform.dart';
|
|||||||
import 'package:uuid/uuid.dart';
|
import 'package:uuid/uuid.dart';
|
||||||
|
|
||||||
class ChessGame extends StatefulWidget {
|
class ChessGame extends StatefulWidget {
|
||||||
const ChessGame({super.key});
|
final UuidValue playerID;
|
||||||
|
final UuidValue lobbyID;
|
||||||
|
final String? passphrase;
|
||||||
|
const ChessGame(
|
||||||
|
{required this.playerID,
|
||||||
|
required this.lobbyID,
|
||||||
|
required this.passphrase,
|
||||||
|
super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<ChessGame> createState() => _ChessGameState();
|
State<ChessGame> createState() => _ChessGameState();
|
||||||
|
@ -1,161 +0,0 @@
|
|||||||
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';
|
|
||||||
import 'package:mchess/api/game_info.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';
|
|
||||||
import 'package:mchess/utils/config.dart' as config;
|
|
||||||
import 'package:mchess/utils/passphrase.dart';
|
|
||||||
import 'package:universal_platform/universal_platform.dart';
|
|
||||||
|
|
||||||
class CreateGameWidget extends StatefulWidget {
|
|
||||||
const CreateGameWidget({super.key});
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<CreateGameWidget> createState() => _CreateGameWidgetState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _CreateGameWidgetState extends State<CreateGameWidget> {
|
|
||||||
late Future<GameInfo?> registerResponse;
|
|
||||||
late Future disconnectFuture;
|
|
||||||
late ChessGameArguments chessGameArgs;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
disconnectFuture = ConnectionCubit().disonnect();
|
|
||||||
disconnectFuture.then((val) {
|
|
||||||
registerResponse = createPrivateGame();
|
|
||||||
registerResponse.then((val) {
|
|
||||||
ConnectionCubit().connectIfNotConnected(
|
|
||||||
val!.playerID.toString(),
|
|
||||||
val.passphrase,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
FloatingActionButton? fltnBtn;
|
|
||||||
if (UniversalPlatform.isLinux ||
|
|
||||||
UniversalPlatform.isMacOS ||
|
|
||||||
UniversalPlatform.isWindows) {
|
|
||||||
fltnBtn = FloatingActionButton(
|
|
||||||
child: const Icon(Icons.cancel),
|
|
||||||
onPressed: () {
|
|
||||||
context.pop();
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Scaffold(
|
|
||||||
floatingActionButton: fltnBtn,
|
|
||||||
body: Center(
|
|
||||||
child: FutureBuilder(
|
|
||||||
future: disconnectFuture,
|
|
||||||
builder: (context, snapshot) {
|
|
||||||
if (snapshot.connectionState != ConnectionState.done) {
|
|
||||||
return Container();
|
|
||||||
} else {
|
|
||||||
return FutureBuilder<GameInfo?>(
|
|
||||||
future: registerResponse,
|
|
||||||
builder: (context, snapshot) {
|
|
||||||
if (snapshot.connectionState != ConnectionState.done) {
|
|
||||||
return const SizedBox(
|
|
||||||
height: 100,
|
|
||||||
width: 100,
|
|
||||||
child: CircularProgressIndicator(),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
var passphrase =
|
|
||||||
snapshot.data?.passphrase ?? "no passphrase";
|
|
||||||
return BlocListener<ConnectionCubit,
|
|
||||||
ConnectionCubitState>(
|
|
||||||
listener: (context, state) {
|
|
||||||
// We wait for our opponent to connect
|
|
||||||
if (state.opponentConnected) {
|
|
||||||
//TODO: is goNamed the correct way to navigate?
|
|
||||||
context.goNamed('game', pathParameters: {
|
|
||||||
'phrase': passphrase.toURL(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
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),
|
|
||||||
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()
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<GameInfo?> createPrivateGame() async {
|
|
||||||
Response response;
|
|
||||||
|
|
||||||
try {
|
|
||||||
response = await http.get(Uri.parse(config.getCreateGameURL()),
|
|
||||||
headers: {"Accept": "application/json"});
|
|
||||||
} catch (e) {
|
|
||||||
log('Exception: ${e.toString()}');
|
|
||||||
|
|
||||||
const snackBar = SnackBar(
|
|
||||||
backgroundColor: Colors.amberAccent,
|
|
||||||
content: Text("mChess server is not responding. Try again or give up"),
|
|
||||||
);
|
|
||||||
Future.delayed(const Duration(seconds: 1), () {
|
|
||||||
if (!mounted) return null;
|
|
||||||
|
|
||||||
ScaffoldMessenger.of(context).clearSnackBars();
|
|
||||||
ScaffoldMessenger.of(context).showSnackBar(snackBar);
|
|
||||||
context.goNamed('lobbySelector'); // We go back to the lobby selector
|
|
||||||
});
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (response.statusCode == 200) {
|
|
||||||
var info = GameInfo.fromJson(jsonDecode(response.body));
|
|
||||||
info.store();
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
142
lib/pages/host_game.dart
Normal file
142
lib/pages/host_game.dart
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
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';
|
||||||
|
import 'package:mchess/api/register.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';
|
||||||
|
import 'package:mchess/utils/config.dart' as config;
|
||||||
|
|
||||||
|
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() {
|
||||||
|
registerResponse = hostPrivateGame();
|
||||||
|
registerResponse.then((value) {
|
||||||
|
value?.store();
|
||||||
|
});
|
||||||
|
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.pushReplacement('/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),
|
||||||
|
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()
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<PlayerInfo?> hostPrivateGame() async {
|
||||||
|
Response response;
|
||||||
|
|
||||||
|
try {
|
||||||
|
response = await http.get(Uri.parse(config.getHostURL()),
|
||||||
|
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.goNamed('lobbySelector'); // We go back to the lobby selector
|
||||||
|
});
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.statusCode == 200) {
|
||||||
|
log(response.body);
|
||||||
|
return PlayerInfo.fromJson(jsonDecode(response.body));
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -1,146 +0,0 @@
|
|||||||
import 'dart:convert';
|
|
||||||
import 'dart:developer';
|
|
||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
||||||
import 'package:go_router/go_router.dart';
|
|
||||||
import 'package:http/http.dart' as http;
|
|
||||||
import 'package:mchess/api/game_info.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:universal_platform/universal_platform.dart';
|
|
||||||
|
|
||||||
class JoinGameHandleWidget extends StatefulWidget {
|
|
||||||
final String passphrase;
|
|
||||||
const JoinGameHandleWidget({required this.passphrase, super.key});
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<JoinGameHandleWidget> createState() => _JoinGameHandleWidgetState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _JoinGameHandleWidgetState extends State<JoinGameHandleWidget> {
|
|
||||||
late Future<GameInfo?> joinGameFuture;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
joinGameFuture = joinPrivateGame(widget.passphrase);
|
|
||||||
joinGameFuture.then((val) {
|
|
||||||
if (val == null) return;
|
|
||||||
|
|
||||||
ConnectionCubit.getInstance().connectIfNotConnected(
|
|
||||||
val.playerID!.uuid,
|
|
||||||
val.passphrase,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
FloatingActionButton? fltnBtn;
|
|
||||||
if (UniversalPlatform.isLinux ||
|
|
||||||
UniversalPlatform.isMacOS ||
|
|
||||||
UniversalPlatform.isWindows) {
|
|
||||||
fltnBtn = FloatingActionButton(
|
|
||||||
child: const Icon(Icons.cancel),
|
|
||||||
onPressed: () {
|
|
||||||
context.pop();
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
var loadingIndicator = const SizedBox(
|
|
||||||
height: 100,
|
|
||||||
width: 100,
|
|
||||||
child: CircularProgressIndicator(),
|
|
||||||
);
|
|
||||||
|
|
||||||
return Scaffold(
|
|
||||||
floatingActionButton: fltnBtn,
|
|
||||||
body: Center(
|
|
||||||
child: FutureBuilder(
|
|
||||||
future: joinGameFuture,
|
|
||||||
builder: (context, snapshot) {
|
|
||||||
if (snapshot.connectionState != ConnectionState.done) {
|
|
||||||
return loadingIndicator;
|
|
||||||
} else {
|
|
||||||
return BlocBuilder<ConnectionCubit, ConnectionCubitState>(
|
|
||||||
builder: (context, state) {
|
|
||||||
if (state.iAmConnected) {
|
|
||||||
return const ChessGame();
|
|
||||||
} else {
|
|
||||||
return loadingIndicator;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<GameInfo?> joinPrivateGame(String phrase) async {
|
|
||||||
http.Response response;
|
|
||||||
|
|
||||||
var existingInfo = await GameInfo.get(phrase);
|
|
||||||
log('playerID: ${existingInfo?.playerID} and passphrase: "${existingInfo?.passphrase}"');
|
|
||||||
|
|
||||||
GameInfo info;
|
|
||||||
if (existingInfo?.passphrase == phrase) {
|
|
||||||
// We have player info for this exact passphrase
|
|
||||||
info = GameInfo(playerID: existingInfo?.playerID, passphrase: phrase);
|
|
||||||
} else {
|
|
||||||
info = GameInfo(playerID: null, passphrase: phrase);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
response = await http.post(Uri.parse(config.getJoinGameURL()),
|
|
||||||
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: 1), () {
|
|
||||||
if (!mounted) return null;
|
|
||||||
ScaffoldMessenger.of(context).clearSnackBars();
|
|
||||||
ScaffoldMessenger.of(context).showSnackBar(snackBar);
|
|
||||||
context.goNamed('lobbySelector'); // We go back to the lobby selector
|
|
||||||
});
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (response.statusCode == HttpStatus.notFound) {
|
|
||||||
const snackBar = SnackBar(
|
|
||||||
backgroundColor: Colors.amberAccent,
|
|
||||||
content: Text("Passphrase could not be found."),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!mounted) return null;
|
|
||||||
|
|
||||||
ScaffoldMessenger.of(context).clearSnackBars();
|
|
||||||
ScaffoldMessenger.of(context).showSnackBar(snackBar);
|
|
||||||
context.goNamed('lobbySelector');
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (response.statusCode == HttpStatus.ok) {
|
|
||||||
var info = GameInfo.fromJson(jsonDecode(response.body));
|
|
||||||
info.store();
|
|
||||||
log('Player info received from server: ');
|
|
||||||
log('playerID: ${info.playerID}');
|
|
||||||
log('passphrase: ${info.passphrase}');
|
|
||||||
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +1,14 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:developer';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:mchess/utils/passphrase.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:mchess/utils/config.dart' as config;
|
||||||
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
class LobbySelector extends StatefulWidget {
|
class LobbySelector extends StatefulWidget {
|
||||||
const LobbySelector({super.key});
|
const LobbySelector({super.key});
|
||||||
@ -10,19 +18,26 @@ class LobbySelector extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _LobbySelectorState extends State<LobbySelector> {
|
class _LobbySelectorState extends State<LobbySelector> {
|
||||||
|
final buttonStyle = const ButtonStyle();
|
||||||
final phraseController = TextEditingController();
|
final phraseController = TextEditingController();
|
||||||
|
late Future<PlayerInfo?> joinGameFuture;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
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");
|
||||||
|
});
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
body: Center(
|
body: Center(
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: () {
|
onPressed: () => buildJoinOrHostDialog(context),
|
||||||
context.goNamed('createGame');
|
|
||||||
},
|
|
||||||
child: const Row(
|
child: const Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
@ -30,23 +45,7 @@ class _LobbySelectorState extends State<LobbySelector> {
|
|||||||
SizedBox(
|
SizedBox(
|
||||||
width: 10,
|
width: 10,
|
||||||
),
|
),
|
||||||
Text('Create private game')
|
Text('Private game')
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 20),
|
|
||||||
ElevatedButton(
|
|
||||||
onPressed: () {
|
|
||||||
buildEnterPassphraseDialog(context);
|
|
||||||
},
|
|
||||||
child: const Row(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
Icon(Icons.mail),
|
|
||||||
SizedBox(
|
|
||||||
width: 10,
|
|
||||||
),
|
|
||||||
Text('Join private game')
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -56,45 +55,134 @@ class _LobbySelectorState extends State<LobbySelector> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> buildEnterPassphraseDialog(BuildContext context) {
|
Future<void> buildJoinOrHostDialog(BuildContext context) {
|
||||||
return showDialog<void>(
|
return showDialog<void>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return ScaffoldMessenger(
|
return Scaffold(
|
||||||
child: Builder(builder: (builderContext) {
|
body: AlertDialog(
|
||||||
return Scaffold(
|
title: const Text('Host or join?'),
|
||||||
backgroundColor: Colors.transparent,
|
actions: <Widget>[
|
||||||
body: AlertDialog(
|
TextButton(
|
||||||
title: const Text('Enter the passphrase here:'),
|
child: const Text('Cancel'),
|
||||||
content: TextField(
|
onPressed: () => context.pop(),
|
||||||
controller: phraseController,
|
|
||||||
onSubmitted: (val) => submitAction(val),
|
|
||||||
decoration: InputDecoration(
|
|
||||||
hintText: 'Enter passphrase here',
|
|
||||||
suffixIcon: IconButton(
|
|
||||||
onPressed: () => submitAction(phraseController.text),
|
|
||||||
icon: const Icon(Icons.check),
|
|
||||||
)),
|
|
||||||
),
|
|
||||||
actions: <Widget>[
|
|
||||||
TextButton(
|
|
||||||
child: const Text('Cancel'),
|
|
||||||
onPressed: () {
|
|
||||||
builderContext.pop();
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
);
|
TextButton(
|
||||||
}),
|
child: const Text('Host'),
|
||||||
|
onPressed: () {
|
||||||
|
context.pop(); //close dialog before going to host
|
||||||
|
context.goNamed('host');
|
||||||
|
}),
|
||||||
|
TextButton(
|
||||||
|
child: const Text('Join'),
|
||||||
|
onPressed: () {
|
||||||
|
context.pop(); //close dialog before going to next dialog
|
||||||
|
buildEnterPassphraseDialog(context);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void submitAction(String phrase) {
|
Future<void> buildEnterPassphraseDialog(BuildContext context) {
|
||||||
context.pop();
|
return showDialog<void>(
|
||||||
context.goNamed('game', pathParameters: {'phrase': phrase.toURL()});
|
context: context,
|
||||||
phraseController.clear();
|
builder: (BuildContext context) {
|
||||||
|
return AlertDialog(
|
||||||
|
title: const Text('Enter the passphrase here:'),
|
||||||
|
content: TextField(
|
||||||
|
controller: phraseController,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
hintText: 'Enter passphrase here',
|
||||||
|
suffixIcon: IconButton(
|
||||||
|
onPressed: () {
|
||||||
|
joinGameFuture = joinPrivateGame();
|
||||||
|
joinGameFuture.then((value) {
|
||||||
|
if (value != null) {
|
||||||
|
phraseController.clear();
|
||||||
|
context.pop();
|
||||||
|
switchToGame(value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
icon: const Icon(Icons.check),
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
actions: <Widget>[
|
||||||
|
TextButton(
|
||||||
|
child: const Text('Cancel'),
|
||||||
|
onPressed: () {
|
||||||
|
context.pop();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
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()) {
|
||||||
|
context.goNamed('lobbySelector');
|
||||||
|
const snackBar = SnackBar(
|
||||||
|
backgroundColor: Colors.amberAccent,
|
||||||
|
content: Text("Game information is corrupted"),
|
||||||
|
);
|
||||||
|
ScaffoldMessenger.of(context).clearSnackBars();
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(snackBar);
|
||||||
|
}
|
||||||
|
|
||||||
|
context.goNamed('game', extra: chessGameArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<PlayerInfo?> joinPrivateGame() async {
|
||||||
|
http.Response response;
|
||||||
|
|
||||||
|
// server expects us to send the passphrase
|
||||||
|
var info = PlayerInfo(
|
||||||
|
playerID: null, lobbyID: null, passphrase: phraseController.text);
|
||||||
|
|
||||||
|
try {
|
||||||
|
response = await http.post(Uri.parse(config.getJoinURL()),
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,8 @@
|
|||||||
import 'dart:developer';
|
|
||||||
|
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:mchess/pages/join_game_handle_widget.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/create_game_widget.dart';
|
import 'package:mchess/pages/host_game.dart';
|
||||||
import 'package:mchess/utils/passphrase.dart';
|
|
||||||
|
|
||||||
final navigatorKey = GlobalKey<NavigatorState>();
|
final navigatorKey = GlobalKey<NavigatorState>();
|
||||||
|
|
||||||
@ -30,23 +27,22 @@ class ChessAppRouter {
|
|||||||
},
|
},
|
||||||
routes: [
|
routes: [
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: 'createGame',
|
path: 'host',
|
||||||
name: 'createGame',
|
name: 'host',
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
return const CreateGameWidget();
|
return const HostGameWidget();
|
||||||
}),
|
}),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: 'game/:phrase',
|
path: 'game',
|
||||||
name: 'game',
|
name: 'game',
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
var urlPhrase = state.pathParameters['phrase'];
|
var args = state.extra as ChessGameArguments;
|
||||||
if (urlPhrase == null) {
|
|
||||||
log('in /game route builder: url phrase null');
|
|
||||||
return const LobbySelector();
|
|
||||||
}
|
|
||||||
|
|
||||||
return JoinGameHandleWidget(
|
return ChessGame(
|
||||||
passphrase: urlPhrase.toPhraseWithSpaces());
|
lobbyID: args.lobbyID,
|
||||||
|
playerID: args.playerID,
|
||||||
|
passphrase: args.passphrase,
|
||||||
|
);
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
@ -1,22 +1,22 @@
|
|||||||
const prodURL = 'chess.sw-gross.de:9999';
|
const prodURL = 'chess.sw-gross.de:9999';
|
||||||
const debugURL = 'localhost';
|
const debugURL = 'localhost:8080';
|
||||||
|
|
||||||
const useDbgUrl = false;
|
const dbgUrl = false;
|
||||||
|
|
||||||
String getCreateGameURL() {
|
String getHostURL() {
|
||||||
var prot = 'https';
|
var prot = 'https';
|
||||||
var domain = prodURL;
|
var domain = prodURL;
|
||||||
if (useDbgUrl) {
|
if (dbgUrl) {
|
||||||
prot = 'http';
|
prot = 'http';
|
||||||
domain = debugURL;
|
domain = debugURL;
|
||||||
}
|
}
|
||||||
return '$prot://$domain/api/hostPrivate';
|
return '$prot://$domain/api/hostPrivate';
|
||||||
}
|
}
|
||||||
|
|
||||||
String getJoinGameURL() {
|
String getJoinURL() {
|
||||||
var prot = 'https';
|
var prot = 'https';
|
||||||
var domain = prodURL;
|
var domain = prodURL;
|
||||||
if (useDbgUrl) {
|
if (dbgUrl) {
|
||||||
prot = 'http';
|
prot = 'http';
|
||||||
domain = debugURL;
|
domain = debugURL;
|
||||||
}
|
}
|
||||||
@ -26,7 +26,7 @@ String getJoinGameURL() {
|
|||||||
String getWebsocketURL() {
|
String getWebsocketURL() {
|
||||||
var prot = 'wss';
|
var prot = 'wss';
|
||||||
var domain = prodURL;
|
var domain = prodURL;
|
||||||
if (useDbgUrl) {
|
if (dbgUrl) {
|
||||||
prot = 'ws';
|
prot = 'ws';
|
||||||
domain = debugURL;
|
domain = debugURL;
|
||||||
}
|
}
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
extension PassphaseURL on String {
|
|
||||||
String capitalize() {
|
|
||||||
return "${this[0].toUpperCase()}${substring(1).toLowerCase()}";
|
|
||||||
}
|
|
||||||
|
|
||||||
String toURL() {
|
|
||||||
var words = split(' ');
|
|
||||||
|
|
||||||
for (var i = 0; i < words.length; i++) {
|
|
||||||
words[i] = words[i].capitalize();
|
|
||||||
}
|
|
||||||
|
|
||||||
return words.join();
|
|
||||||
}
|
|
||||||
|
|
||||||
String toPhraseWithSpaces() {
|
|
||||||
var phrase = '';
|
|
||||||
|
|
||||||
for (var i = 0; i < length; i++) {
|
|
||||||
if (this[i] == this[i].toUpperCase()) {
|
|
||||||
phrase += ' ';
|
|
||||||
}
|
|
||||||
phrase += this[i].toLowerCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
phrase = phrase.trim();
|
|
||||||
|
|
||||||
return phrase.toLowerCase();
|
|
||||||
}
|
|
||||||
}
|
|
@ -5,10 +5,8 @@
|
|||||||
import FlutterMacOS
|
import FlutterMacOS
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
import package_info_plus
|
|
||||||
import shared_preferences_foundation
|
import shared_preferences_foundation
|
||||||
|
|
||||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||||
FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin"))
|
|
||||||
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||||
}
|
}
|
||||||
|
218
pubspec.lock
218
pubspec.lock
@ -5,10 +5,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: args
|
name: args
|
||||||
sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6
|
sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.6.0"
|
version: "2.4.2"
|
||||||
async:
|
async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -21,10 +21,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: bloc
|
name: bloc
|
||||||
sha256: "106842ad6569f0b60297619e9e0b1885c2fb9bf84812935490e6c5275777804e"
|
sha256: "3820f15f502372d979121de1f6b97bfcf1630ebff8fe1d52fb2b0bfa49be5b49"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "8.1.4"
|
version: "8.1.2"
|
||||||
boolean_selector:
|
boolean_selector:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -53,26 +53,26 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: collection
|
name: collection
|
||||||
sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf
|
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.19.0"
|
version: "1.18.0"
|
||||||
crypto:
|
crypto:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: crypto
|
name: crypto
|
||||||
sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855"
|
sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.6"
|
version: "3.0.3"
|
||||||
cupertino_icons:
|
cupertino_icons:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: cupertino_icons
|
name: cupertino_icons
|
||||||
sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6
|
sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.8"
|
version: "1.0.6"
|
||||||
fake_async:
|
fake_async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -85,26 +85,26 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: ffi
|
name: ffi
|
||||||
sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6"
|
sha256: "493f37e7df1804778ff3a53bd691d8692ddf69702cf4c1c1096a2e41b4779e21"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.3"
|
version: "2.1.2"
|
||||||
file:
|
file:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: file
|
name: file
|
||||||
sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4
|
sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.0.1"
|
version: "7.0.0"
|
||||||
fixnum:
|
fixnum:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: fixnum
|
name: fixnum
|
||||||
sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be
|
sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.1"
|
version: "1.1.0"
|
||||||
flutter:
|
flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description: flutter
|
description: flutter
|
||||||
@ -114,26 +114,26 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: flutter_bloc
|
name: flutter_bloc
|
||||||
sha256: b594505eac31a0518bdcb4b5b79573b8d9117b193cc80cc12e17d639b10aa27a
|
sha256: e74efb89ee6945bcbce74a5b3a5a3376b088e5f21f55c263fc38cbdc6237faae
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "8.1.6"
|
version: "8.1.3"
|
||||||
flutter_lints:
|
flutter_lints:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
name: flutter_lints
|
name: flutter_lints
|
||||||
sha256: "5398f14efa795ffb7a33e9b6a08798b26a180edac4ad7db3f231e40f82ce11e1"
|
sha256: e2a421b7e59244faef694ba7b30562e489c2b489866e505074eb005cd7060db7
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.0.0"
|
version: "3.0.1"
|
||||||
flutter_svg:
|
flutter_svg:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: flutter_svg
|
name: flutter_svg
|
||||||
sha256: "54900a1a1243f3c4a5506d853a2b5c2dbc38d5f27e52a52618a8054401431123"
|
sha256: d39e7f95621fc84376bc0f7d504f05c3a41488c562f4a8ad410569127507402c
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.16"
|
version: "2.0.9"
|
||||||
flutter_test:
|
flutter_test:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description: flutter
|
description: flutter
|
||||||
@ -148,66 +148,66 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: go_router
|
name: go_router
|
||||||
sha256: "2fd11229f59e23e967b0775df8d5948a519cd7e1e8b6e849729e010587b46539"
|
sha256: "07ee2436909f749d606f53521dc1725dd738dc5196e5ff815bc254253c594075"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "14.6.2"
|
version: "13.1.0"
|
||||||
http:
|
http:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: http
|
name: http
|
||||||
sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010
|
sha256: a2bbf9d017fcced29139daa8ed2bba4ece450ab222871df93ca9eec6f80c34ba
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.2"
|
version: "1.2.0"
|
||||||
http_parser:
|
http_parser:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: http_parser
|
name: http_parser
|
||||||
sha256: "76d306a1c3afb33fe82e2bbacad62a61f409b5634c915fceb0d799de1a913360"
|
sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.1.1"
|
version: "4.0.2"
|
||||||
leak_tracker:
|
leak_tracker:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: leak_tracker
|
name: leak_tracker
|
||||||
sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06"
|
sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "10.0.7"
|
version: "10.0.0"
|
||||||
leak_tracker_flutter_testing:
|
leak_tracker_flutter_testing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: leak_tracker_flutter_testing
|
name: leak_tracker_flutter_testing
|
||||||
sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379"
|
sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.8"
|
version: "2.0.1"
|
||||||
leak_tracker_testing:
|
leak_tracker_testing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: leak_tracker_testing
|
name: leak_tracker_testing
|
||||||
sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
|
sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.1"
|
version: "2.0.1"
|
||||||
lints:
|
lints:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: lints
|
name: lints
|
||||||
sha256: c35bb79562d980e9a453fc715854e1ed39e24e7d0297a880ef54e17f9874a9d7
|
sha256: cbf8d4b858bb0134ef3ef87841abdf8d63bfc255c266b7bf6b39daa1085c4290
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.1.1"
|
version: "3.0.0"
|
||||||
logging:
|
logging:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: logging
|
name: logging
|
||||||
sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61
|
sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.0"
|
version: "1.2.0"
|
||||||
matcher:
|
matcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -220,18 +220,18 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: material_color_utilities
|
name: material_color_utilities
|
||||||
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
|
sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.11.1"
|
version: "0.8.0"
|
||||||
meta:
|
meta:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: meta
|
name: meta
|
||||||
sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7
|
sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.15.0"
|
version: "1.11.0"
|
||||||
nested:
|
nested:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -240,22 +240,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.0"
|
version: "1.0.0"
|
||||||
package_info_plus:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: package_info_plus
|
|
||||||
sha256: "70c421fe9d9cc1a9a7f3b05ae56befd469fe4f8daa3b484823141a55442d858d"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "8.1.2"
|
|
||||||
package_info_plus_platform_interface:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: package_info_plus_platform_interface
|
|
||||||
sha256: a5ef9986efc7bf772f2696183a3992615baa76c1ffb1189318dd8803778fb05b
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "3.0.2"
|
|
||||||
path:
|
path:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -268,10 +252,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_parsing
|
name: path_parsing
|
||||||
sha256: "883402936929eac138ee0a45da5b0f2c80f89913e6dc3bf77eb65b84b409c6ca"
|
sha256: e3e67b1629e6f7e8100b367d3db6ba6af4b1f0bb80f64db18ef1fbabd2fa9ccf
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "1.0.1"
|
||||||
path_provider_linux:
|
path_provider_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -292,10 +276,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_windows
|
name: path_provider_windows
|
||||||
sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7
|
sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.0"
|
version: "2.2.1"
|
||||||
petitparser:
|
petitparser:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -308,10 +292,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: platform
|
name: platform
|
||||||
sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984"
|
sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.6"
|
version: "3.1.4"
|
||||||
plugin_platform_interface:
|
plugin_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -324,79 +308,79 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: provider
|
name: provider
|
||||||
sha256: c8a055ee5ce3fd98d6fc872478b03823ffdb448699c6ebdbbc71d59b596fd48c
|
sha256: "9a96a0a19b594dbc5bf0f1f27d2bc67d5f95957359b461cd9feb44ed6ae75096"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.1.2"
|
version: "6.1.1"
|
||||||
quiver:
|
quiver:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: quiver
|
name: quiver
|
||||||
sha256: ea0b925899e64ecdfbf9c7becb60d5b50e706ade44a85b2363be2a22d88117d2
|
sha256: b1c1ac5ce6688d77f65f3375a9abb9319b3cb32486bdc7a1e0fdf004d7ba4e47
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.2.2"
|
version: "3.2.1"
|
||||||
shared_preferences:
|
shared_preferences:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: shared_preferences
|
name: shared_preferences
|
||||||
sha256: "3c7e73920c694a436afaf65ab60ce3453d91f84208d761fbd83fc21182134d93"
|
sha256: "81429e4481e1ccfb51ede496e916348668fd0921627779233bd24cc3ff6abd02"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.4"
|
version: "2.2.2"
|
||||||
shared_preferences_android:
|
shared_preferences_android:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shared_preferences_android
|
name: shared_preferences_android
|
||||||
sha256: "02a7d8a9ef346c9af715811b01fbd8e27845ad2c41148eefd31321471b41863d"
|
sha256: "8568a389334b6e83415b6aae55378e158fbc2314e074983362d20c562780fb06"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.0"
|
version: "2.2.1"
|
||||||
shared_preferences_foundation:
|
shared_preferences_foundation:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shared_preferences_foundation
|
name: shared_preferences_foundation
|
||||||
sha256: "6a52cfcdaeac77cad8c97b539ff688ccfc458c007b4db12be584fbe5c0e49e03"
|
sha256: "7708d83064f38060c7b39db12aefe449cb8cdc031d6062280087bc4cdb988f5c"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.5.4"
|
version: "2.3.5"
|
||||||
shared_preferences_linux:
|
shared_preferences_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shared_preferences_linux
|
name: shared_preferences_linux
|
||||||
sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f"
|
sha256: "9f2cbcf46d4270ea8be39fa156d86379077c8a5228d9dfdb1164ae0bb93f1faa"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.1"
|
version: "2.3.2"
|
||||||
shared_preferences_platform_interface:
|
shared_preferences_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shared_preferences_platform_interface
|
name: shared_preferences_platform_interface
|
||||||
sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80"
|
sha256: "22e2ecac9419b4246d7c22bfbbda589e3acf5c0351137d87dd2939d984d37c3b"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.1"
|
version: "2.3.2"
|
||||||
shared_preferences_web:
|
shared_preferences_web:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shared_preferences_web
|
name: shared_preferences_web
|
||||||
sha256: d2ca4132d3946fec2184261726b355836a82c33d7d5b67af32692aff18a4684e
|
sha256: "7b15ffb9387ea3e237bb7a66b8a23d2147663d391cafc5c8f37b2e7b4bde5d21"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.2"
|
version: "2.2.2"
|
||||||
shared_preferences_windows:
|
shared_preferences_windows:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shared_preferences_windows
|
name: shared_preferences_windows
|
||||||
sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1"
|
sha256: "841ad54f3c8381c480d0c9b508b89a34036f512482c407e6df7a9c4aa2ef8f59"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.1"
|
version: "2.3.2"
|
||||||
sky_engine:
|
sky_engine:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
version: "0.0.99"
|
||||||
source_span:
|
source_span:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -417,10 +401,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: stack_trace
|
name: stack_trace
|
||||||
sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377"
|
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.12.0"
|
version: "1.11.1"
|
||||||
stream_channel:
|
stream_channel:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -433,10 +417,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: string_scanner
|
name: string_scanner
|
||||||
sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3"
|
sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.0"
|
version: "1.2.0"
|
||||||
term_glyph:
|
term_glyph:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -449,58 +433,58 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: test_api
|
name: test_api
|
||||||
sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c"
|
sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.7.3"
|
version: "0.6.1"
|
||||||
typed_data:
|
typed_data:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: typed_data
|
name: typed_data
|
||||||
sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
|
sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.4.0"
|
version: "1.3.2"
|
||||||
universal_platform:
|
universal_platform:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: universal_platform
|
name: universal_platform
|
||||||
sha256: "64e16458a0ea9b99260ceb5467a214c1f298d647c659af1bff6d3bf82536b1ec"
|
sha256: d315be0f6641898b280ffa34e2ddb14f3d12b1a37882557869646e0cc363d0cc
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "1.0.0+1"
|
||||||
uuid:
|
uuid:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: uuid
|
name: uuid
|
||||||
sha256: a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff
|
sha256: cd210a09f7c18cbe5a02511718e0334de6559871052c90a90c0cca46a4aa81c8
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.5.1"
|
version: "4.3.3"
|
||||||
vector_graphics:
|
vector_graphics:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: vector_graphics
|
name: vector_graphics
|
||||||
sha256: "27d5fefe86fb9aace4a9f8375b56b3c292b64d8c04510df230f849850d912cb7"
|
sha256: "18f6690295af52d081f6808f2f7c69f0eed6d7e23a71539d75f4aeb8f0062172"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.15"
|
version: "1.1.9+2"
|
||||||
vector_graphics_codec:
|
vector_graphics_codec:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: vector_graphics_codec
|
name: vector_graphics_codec
|
||||||
sha256: "2430b973a4ca3c4dbc9999b62b8c719a160100dcbae5c819bae0cacce32c9cdb"
|
sha256: "531d20465c10dfac7f5cd90b60bbe4dd9921f1ec4ca54c83ebb176dbacb7bb2d"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.12"
|
version: "1.1.9+2"
|
||||||
vector_graphics_compiler:
|
vector_graphics_compiler:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: vector_graphics_compiler
|
name: vector_graphics_compiler
|
||||||
sha256: "1b4b9e706a10294258727674a340ae0d6e64a7231980f9f9a3d12e4b42407aad"
|
sha256: "03012b0a33775c5530576b70240308080e1d5050f0faf000118c20e6463bc0ad"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.16"
|
version: "1.1.9+2"
|
||||||
vector_math:
|
vector_math:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -513,50 +497,42 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: vm_service
|
name: vm_service
|
||||||
sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b
|
sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "14.3.0"
|
version: "13.0.0"
|
||||||
web:
|
web:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: web
|
name: web
|
||||||
sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb
|
sha256: "4188706108906f002b3a293509234588823c8c979dc83304e229ff400c996b05"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "0.4.2"
|
||||||
web_socket:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: web_socket
|
|
||||||
sha256: "3c12d96c0c9a4eec095246debcea7b86c0324f22df69893d538fcc6f1b8cce83"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "0.1.6"
|
|
||||||
web_socket_channel:
|
web_socket_channel:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: web_socket_channel
|
name: web_socket_channel
|
||||||
sha256: "9f187088ed104edd8662ca07af4b124465893caf063ba29758f97af57e61da8f"
|
sha256: "939ab60734a4f8fa95feacb55804fa278de28bdeef38e616dc08e44a84adea23"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.1"
|
version: "2.4.3"
|
||||||
win32:
|
win32:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: win32
|
name: win32
|
||||||
sha256: "8b338d4486ab3fbc0ba0db9f9b4f5239b6697fcee427939a40e720cbb9ee0a69"
|
sha256: "464f5674532865248444b4c3daca12bd9bf2d7c47f759ce2617986e7229494a8"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.9.0"
|
version: "5.2.0"
|
||||||
xdg_directories:
|
xdg_directories:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: xdg_directories
|
name: xdg_directories
|
||||||
sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15"
|
sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "1.0.4"
|
||||||
xml:
|
xml:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -566,5 +542,5 @@ packages:
|
|||||||
source: hosted
|
source: hosted
|
||||||
version: "6.5.0"
|
version: "6.5.0"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=3.6.0 <4.0.0"
|
dart: ">=3.3.0-279.1.beta <4.0.0"
|
||||||
flutter: ">=3.24.0"
|
flutter: ">=3.16.0"
|
||||||
|
13
pubspec.yaml
13
pubspec.yaml
@ -16,10 +16,10 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
|||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
# In Windows, build-name is used as the major, minor, and patch parts
|
# In Windows, build-name is used as the major, minor, and patch parts
|
||||||
# of the product and file versions while build-number is used as the build suffix.
|
# of the product and file versions while build-number is used as the build suffix.
|
||||||
version: 0.9.11
|
version: 1.0.1
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ^3.6.0
|
sdk: ^3.1.0
|
||||||
|
|
||||||
# Dependencies specify other packages that your package needs in order to work.
|
# Dependencies specify other packages that your package needs in order to work.
|
||||||
# To automatically upgrade your package dependencies to the latest versions
|
# To automatically upgrade your package dependencies to the latest versions
|
||||||
@ -40,13 +40,12 @@ dependencies:
|
|||||||
cupertino_icons: ^1.0.2
|
cupertino_icons: ^1.0.2
|
||||||
flutter_bloc: ^8.1.3
|
flutter_bloc: ^8.1.3
|
||||||
quiver: ^3.1.0
|
quiver: ^3.1.0
|
||||||
web_socket_channel: ^3.0.0
|
web_socket_channel: ^2.4.3
|
||||||
go_router: ^14.0.2
|
go_router: ^13.0.0
|
||||||
http: ^1.0.0
|
http: ^1.0.0
|
||||||
uuid: ^4.0.0
|
uuid: ^4.0.0
|
||||||
shared_preferences: ^2.2.2
|
shared_preferences: ^2.2.2
|
||||||
universal_platform: ^1.0.0
|
universal_platform: ^1.0.0+1
|
||||||
package_info_plus: ^8.1.0
|
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
@ -57,7 +56,7 @@ dev_dependencies:
|
|||||||
# activated in the `analysis_options.yaml` file located at the root of your
|
# activated in the `analysis_options.yaml` file located at the root of your
|
||||||
# package. See that file for information about deactivating specific lint
|
# package. See that file for information about deactivating specific lint
|
||||||
# rules and activating additional ones.
|
# rules and activating additional ones.
|
||||||
flutter_lints: ^5.0.0
|
flutter_lints: ^3.0.0
|
||||||
|
|
||||||
# For information on the generic Dart part of this file, see the
|
# For information on the generic Dart part of this file, see the
|
||||||
# following page: https://dart.dev/tools/pub/pubspec
|
# following page: https://dart.dev/tools/pub/pubspec
|
||||||
|
@ -8,11 +8,16 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:mchess/pages/chess_game.dart';
|
import 'package:mchess/pages/chess_game.dart';
|
||||||
|
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.fromString("test"),
|
||||||
|
lobbyID: UuidValue.fromString("testLobbyId"),
|
||||||
|
passphrase: 'test',
|
||||||
|
));
|
||||||
|
|
||||||
// Verify that our counter starts at 0.
|
// Verify that our counter starts at 0.
|
||||||
expect(find.text('0'), findsOneWidget);
|
expect(find.text('0'), findsOneWidget);
|
||||||
|
Loading…
Reference in New Issue
Block a user