diff --git a/.idea/Bowl_in.iml b/.idea/Bowl_in.iml
index f1b2d07..01dd66f 100644
--- a/.idea/Bowl_in.iml
+++ b/.idea/Bowl_in.iml
@@ -10,6 +10,5 @@
-
\ No newline at end of file
diff --git a/Sources/bowlin_project/lib/database/fields/FriendFields.dart b/Sources/bowlin_project/lib/database/fields/FriendFields.dart
new file mode 100644
index 0000000..327d16a
--- /dev/null
+++ b/Sources/bowlin_project/lib/database/fields/FriendFields.dart
@@ -0,0 +1,10 @@
+class GameFields {
+ static final List values = [
+ id, date, pointsCurrentUser, userId
+ ];
+
+ static final String id = '_id';
+ static final String date = '_date';
+ static final String pointsCurrentUser = '_points_current_user';
+ static final String userId = '_user_id';
+}
\ No newline at end of file
diff --git a/Sources/bowlin_project/lib/database/fields/GameDetailFields.dart b/Sources/bowlin_project/lib/database/fields/GameDetailFields.dart
new file mode 100644
index 0000000..8d30c01
--- /dev/null
+++ b/Sources/bowlin_project/lib/database/fields/GameDetailFields.dart
@@ -0,0 +1,10 @@
+class GameDetailFields {
+ static final List values = [
+ id, date, nameWinner, host
+ ];
+
+ static final String id = '_id';
+ static final String date = '_date';
+ static final String nameWinner = '_winner_id';
+ static final String host = '_host';
+}
\ No newline at end of file
diff --git a/Sources/bowlin_project/lib/database/fields/GameFields.dart b/Sources/bowlin_project/lib/database/fields/GameFields.dart
new file mode 100644
index 0000000..327d16a
--- /dev/null
+++ b/Sources/bowlin_project/lib/database/fields/GameFields.dart
@@ -0,0 +1,10 @@
+class GameFields {
+ static final List values = [
+ id, date, pointsCurrentUser, userId
+ ];
+
+ static final String id = '_id';
+ static final String date = '_date';
+ static final String pointsCurrentUser = '_points_current_user';
+ static final String userId = '_user_id';
+}
\ No newline at end of file
diff --git a/Sources/bowlin_project/lib/database/fields/PlayerFields.dart b/Sources/bowlin_project/lib/database/fields/PlayerFields.dart
new file mode 100644
index 0000000..b927bef
--- /dev/null
+++ b/Sources/bowlin_project/lib/database/fields/PlayerFields.dart
@@ -0,0 +1,10 @@
+class PlayerFields {
+ static final List values = [
+ idGame, name, image
+ ];
+
+ static final String idGame = '_idGame';
+ static final String name = '_name';
+ static final String image = '_image';
+}
+
diff --git a/Sources/bowlin_project/lib/database/fields/StatFields.dart b/Sources/bowlin_project/lib/database/fields/StatFields.dart
new file mode 100644
index 0000000..e6bed82
--- /dev/null
+++ b/Sources/bowlin_project/lib/database/fields/StatFields.dart
@@ -0,0 +1,16 @@
+class StatFields {
+ static final List values = [
+ idUser, nbVictory, nbGames, highscore, nbStrikes, nbSpares, nbScore, avgScore, avgPinsPerRound
+ ];
+
+ static final String nbVictory = '_nbVictory';
+ static final String nbGames = '_nbGames';
+ static final String highscore = '_highscore';
+ static final String nbStrikes = '_nbStrikes';
+ static final String nbSpares = '_nbSpares';
+ static final String nbScore = '_nbScore';
+ static final String avgScore = '_avgScore';
+ static final String avgPinsPerRound = '_avgPinsPerRound';
+ static final String idUser = '_idUser';
+
+}
\ No newline at end of file
diff --git a/Sources/bowlin_project/lib/database/fields/UserFields.dart b/Sources/bowlin_project/lib/database/fields/UserFields.dart
new file mode 100644
index 0000000..5999827
--- /dev/null
+++ b/Sources/bowlin_project/lib/database/fields/UserFields.dart
@@ -0,0 +1,12 @@
+class UserFields {
+ static final List values = [
+ id, name, image, mail
+ ];
+
+ static final String id = '_id';
+ static final String name = '_name';
+ static final String image = '_image';
+ static final String mail = '_mail';
+
+}
+
diff --git a/Sources/bowlin_project/lib/database/mappers/GameDetailMapper.dart b/Sources/bowlin_project/lib/database/mappers/GameDetailMapper.dart
new file mode 100644
index 0000000..abeaa3b
--- /dev/null
+++ b/Sources/bowlin_project/lib/database/mappers/GameDetailMapper.dart
@@ -0,0 +1,26 @@
+import 'package:bowl_in/model/GameDetail.dart';
+
+import '../../model/Player.dart';
+import '../fields/GameDetailFields.dart';
+
+class GameDetailMapper {
+ static Map toJson(GameDetail gameDetail) {
+ return {
+ GameDetailFields.id: gameDetail.id,
+ GameDetailFields.date: gameDetail.time.toIso8601String(),
+ GameDetailFields.nameWinner: gameDetail.winner?.name,
+ GameDetailFields.host: gameDetail.host
+ };
+ }
+
+ static GameDetail toModel(
+ Map json, Player? winner, List players) {
+ String dateString = json[GameDetailFields.date];
+ return GameDetail(
+ json[GameDetailFields.id],
+ DateTime.parse(dateString),
+ winner,
+ json[GameDetailFields.host],
+ players);
+ }
+}
diff --git a/Sources/bowlin_project/lib/database/mappers/GameMapper.dart b/Sources/bowlin_project/lib/database/mappers/GameMapper.dart
new file mode 100644
index 0000000..1191460
--- /dev/null
+++ b/Sources/bowlin_project/lib/database/mappers/GameMapper.dart
@@ -0,0 +1,24 @@
+import 'package:bowl_in/model/Game.dart';
+import '../../model/Player.dart';
+import '../../model/User.dart';
+import '../fields/GameFields.dart';
+
+class GameMapper {
+ static Map toJson(Game game, User user) {
+ return {
+ GameFields.id: game.id,
+ GameFields.date: game.date.toIso8601String(),
+ GameFields.pointsCurrentUser: game.pointsCurrentUser,
+ GameFields.userId: user.id,
+ };
+ }
+
+ static Game toModel(Map json, List players) {
+ return Game(
+ json[GameFields.id],
+ DateTime.parse(json[GameFields.date]),
+ json[GameFields.pointsCurrentUser],
+ players
+ );
+ }
+}
diff --git a/Sources/bowlin_project/lib/database/mappers/PlayerMapper.dart b/Sources/bowlin_project/lib/database/mappers/PlayerMapper.dart
new file mode 100644
index 0000000..d6ca2f2
--- /dev/null
+++ b/Sources/bowlin_project/lib/database/mappers/PlayerMapper.dart
@@ -0,0 +1,21 @@
+import 'package:bowl_in/database/fields/PlayerFields.dart';
+
+import '../../model/Game.dart';
+import '../../model/Player.dart';
+
+class PlayerMapper {
+ static Map toJson(Player player, Game game) {
+ return {
+ PlayerFields.idGame: game.id,
+ PlayerFields.name: player.name,
+ PlayerFields.image: player.image,
+ };
+ }
+
+ static Player toModel(Map json) {
+ return Player(
+ json[PlayerFields.name],
+ json[PlayerFields.image]
+ );
+ }
+}
diff --git a/Sources/bowlin_project/lib/database/mappers/StatMapper.dart b/Sources/bowlin_project/lib/database/mappers/StatMapper.dart
new file mode 100644
index 0000000..d668541
--- /dev/null
+++ b/Sources/bowlin_project/lib/database/mappers/StatMapper.dart
@@ -0,0 +1,32 @@
+import 'package:bowl_in/database/fields/StatFields.dart';
+import '../../model/Stat.dart';
+import '../../model/User.dart';
+
+class StatMapper {
+ static Map toJson(Stat stat, User user) {
+ return {
+ StatFields.idUser: user.id,
+ StatFields.nbVictory: stat.nbVictory,
+ StatFields.nbGames: stat.nbGames,
+ StatFields.highscore: stat.highscore,
+ StatFields.nbStrikes: stat.nbStrikes,
+ StatFields.nbSpares: stat.nbSpares,
+ StatFields.nbScore: stat.nbScore,
+ StatFields.avgScore: stat.avgScore,
+ StatFields.avgPinsPerRound: stat.avgPinsPerRound
+ };
+ }
+
+ static Stat toModel(Map json) {
+ return Stat(
+ json[StatFields.nbVictory],
+ json[StatFields.nbGames],
+ json[StatFields.highscore],
+ json[StatFields.nbStrikes],
+ json[StatFields.nbSpares],
+ json[StatFields.nbScore],
+ json[StatFields.avgScore],
+ json[StatFields.avgPinsPerRound]
+ );
+ }
+}
diff --git a/Sources/bowlin_project/lib/database/mappers/UserMapper.dart b/Sources/bowlin_project/lib/database/mappers/UserMapper.dart
new file mode 100644
index 0000000..7aa14a8
--- /dev/null
+++ b/Sources/bowlin_project/lib/database/mappers/UserMapper.dart
@@ -0,0 +1,26 @@
+import '../../model/Stat.dart';
+import '../../model/User.dart';
+import '../fields/UserFields.dart';
+
+class UserMapper {
+ static Map toJson(User user) {
+ return {
+ UserFields.id: user.id,
+ UserFields.name: user.name,
+ UserFields.image: user.image,
+ UserFields.mail: user.mail,
+ };
+ }
+
+ static User toModel(Map json, Stat stat) {
+ return User.withStat(
+ json[UserFields.id],
+ json[UserFields.name],
+ json[UserFields.image],
+ json[UserFields.mail],
+ [],
+ [],
+ stat
+ );
+ }
+}
diff --git a/Sources/bowlin_project/lib/database/sqlflite/BowlInDatabase.dart b/Sources/bowlin_project/lib/database/sqlflite/BowlInDatabase.dart
new file mode 100644
index 0000000..817b5d0
--- /dev/null
+++ b/Sources/bowlin_project/lib/database/sqlflite/BowlInDatabase.dart
@@ -0,0 +1,336 @@
+import 'package:bowl_in/database/fields/PlayerFields.dart';
+import 'package:bowl_in/database/mappers/GameMapper.dart';
+import 'package:bowl_in/database/mappers/PlayerMapper.dart';
+import 'package:bowl_in/database/mappers/StatMapper.dart';
+import 'package:bowl_in/model/Game.dart';
+import 'package:bowl_in/model/GameDetail.dart';
+import 'package:bowl_in/model/User.dart';
+import 'package:path/path.dart';
+import 'package:sqflite/sqflite.dart';
+
+import '../../model/Player.dart';
+import '../../model/Stat.dart';
+import '../fields/GameDetailFields.dart';
+import '../fields/GameFields.dart';
+import '../fields/StatFields.dart';
+import '../fields/UserFields.dart';
+import '../mappers/GameDetailMapper.dart';
+import '../mappers/UserMapper.dart';
+
+class BowlInDatabase {
+ BowlInDatabase();
+
+ static final BowlInDatabase instance = BowlInDatabase._init();
+
+ static Database? _database;
+
+ BowlInDatabase._init();
+
+ static const String tableUser = 'users';
+ static const String tableGame = 'games';
+ static const String tableGameDetail = 'gameDetails';
+ static const String tableStat = 'stats';
+ static const String tablePlayer = 'players';
+
+ Future get database async {
+ if (_database != null) return _database!;
+
+ _database = await _initDB('user.db');
+ return _database!;
+ }
+
+ Future _initDB(String filePath) async {
+ final dbPath = await getDatabasesPath();
+ final path = join(dbPath, filePath);
+
+ return await openDatabase(path,
+ version: 6, onCreate: _createDB, onUpgrade: _upgradeDB);
+ }
+
+ Future _createDB(Database db, int version) async {
+ const idType = 'INTEGER PRIMARY KEY AUTOINCREMENT';
+ const textType = 'TEXT NOT NULL';
+ const boolType = 'BOOLEAN NOT NULL';
+ const integerType = 'INTEGER NOT NULL';
+ const realType = 'REAL NOT NULL';
+
+ await db.execute('''
+CREATE TABLE $tableUser (
+ ${UserFields.id} $idType,
+ ${UserFields.name} $boolType,
+ ${UserFields.image} $textType,
+ ${UserFields.mail} $textType
+ )
+''');
+
+ await db.execute('''
+CREATE TABLE $tableGame (
+ ${GameFields.id} $idType,
+ ${GameFields.date} $textType,
+ ${GameFields.pointsCurrentUser} $integerType,
+ ${GameFields.userId} $integerType,
+ FOREIGN KEY(${GameFields.userId}) REFERENCES $tableUser(${UserFields.id})
+)
+''');
+
+ await db.execute('''
+CREATE TABLE $tableGameDetail (
+ ${GameDetailFields.id} $idType,
+ ${GameDetailFields.date} $textType,
+ ${GameDetailFields.nameWinner} $textType,
+ ${GameDetailFields.host} $integerType
+)
+''');
+
+ await db.execute('''
+CREATE TABLE $tableStat (
+ ${StatFields.idUser} $integerType,
+ ${StatFields.nbVictory} $integerType,
+ ${StatFields.nbGames} $integerType,
+ ${StatFields.highscore} $integerType,
+ ${StatFields.nbStrikes} $integerType,
+ ${StatFields.nbSpares} $integerType,
+ ${StatFields.nbScore} $integerType,
+ ${StatFields.avgScore} $realType,
+ ${StatFields.avgPinsPerRound} $realType,
+ FOREIGN KEY(${StatFields.idUser}) REFERENCES $tableUser(${UserFields.id})
+)
+''');
+
+ await db.execute('''
+CREATE TABLE $tablePlayer (
+ id $idType,
+ ${PlayerFields.name} $textType,
+ ${PlayerFields.image} $textType,
+ ${PlayerFields.idGame} $integerType,
+ FOREIGN KEY(${PlayerFields.idGame}) REFERENCES $tableGame(${GameFields.id})
+)
+''');
+ }
+
+ Future _upgradeDB(Database db, int oldVersion, int newVersion) async {
+ if (oldVersion < 6 ) {
+ await db.execute('DROP TABLE IF EXISTS $tableUser');
+ await db.execute('DROP TABLE IF EXISTS $tableGame');
+ await db.execute('DROP TABLE IF EXISTS $tableGameDetail');
+ await db.execute('DROP TABLE IF EXISTS $tableStat');
+ await db.execute('DROP TABLE IF EXISTS $tablePlayer');
+ await _createDB(db, newVersion);
+ }
+ }
+
+ // User
+
+ Future createUser(User user) async {
+ final db = await instance.database;
+ await db.insert(tableUser, UserMapper.toJson(user));
+ await createStat(user);
+ }
+
+ Future readUser(int id) async {
+ final db = await instance.database;
+ final result = await db
+ .query(tableUser, where: '${UserFields.id} = ?', whereArgs: [id]);
+
+ if (result.isNotEmpty) {
+ final stat = await readStat(id);
+
+ User user;
+ if (stat != null) {
+ user = UserMapper.toModel(result.first, stat);
+ } else {
+ user = UserMapper.toModel(result.first, Stat.empty());
+ }
+ final games = await readGame(id);
+ for (var game in games) {
+ user.games.add(game);
+ }
+ return user;
+ } else {
+ return null;
+ }
+ }
+
+ Future updateUser(User user) async {
+ final db = await instance.database;
+
+ await db.transaction((txn) async {
+ await txn.update(tableUser, UserMapper.toJson(user),
+ where: '${UserFields.id} = ?', whereArgs: [user.id]);
+
+ await txn.update(tableStat, StatMapper.toJson(user.stat, user),
+ where: '${StatFields.idUser} = ?', whereArgs: [user.id]);
+
+ // Insert new games for the user
+ for (var game in user.games) {
+ var result = await txn.query(tableGame,
+ where: '${GameFields.id} = ? AND ${GameFields.userId} = ?',
+ whereArgs: [game.id, user.id]);
+ if (result.isNotEmpty) {
+ await txn.update(tableGame, GameMapper.toJson(game, user),
+ where: '${GameFields.id} = ? AND ${GameFields.userId} = ?',
+ whereArgs: [game.id, user.id]);
+ } else {
+ await txn.insert(tableGame, GameMapper.toJson(game, user));
+ for (var player in game.players) {
+ await txn.insert(tablePlayer, PlayerMapper.toJson(player, game));
+ }
+ }
+ }
+ });
+ }
+
+ Future deleteUser(int id) async {
+ final db = await instance.database;
+
+ await deleteGame(id);
+
+ await deleteStat(id);
+
+ return await db.delete(
+ tableUser,
+ where: '${UserFields.id} = ?',
+ whereArgs: [id],
+ );
+ }
+
+ // GameDetail
+
+ Future createGameDetail(GameDetail gameDetail) async {
+ final db = await instance.database;
+
+ await db.transaction((txn) async {
+ await txn.insert(tableGameDetail, GameDetailMapper.toJson(gameDetail));
+ });
+ }
+
+ Future> readGameDetail() async {
+ final db = await instance.database;
+ final result = await db.query(tableGameDetail);
+
+ if (result.isNotEmpty) {
+ List gameDetails = [];
+ for (var gameDetail in result) {
+ List players = [];
+ Player? winner = null;
+ final resultPlayer = await db.query(tablePlayer,
+ where: '${PlayerFields.idGame} = ?',
+ whereArgs: [gameDetail[GameDetailFields.id]]);
+ for (var player in resultPlayer) {
+ var rPlayer = PlayerMapper.toModel(player);
+ players.add(rPlayer);
+ if (rPlayer.name == gameDetail[GameDetailFields.nameWinner]) {
+ winner = rPlayer;
+ }
+ }
+ gameDetails.add(GameDetailMapper.toModel(gameDetail, winner, players));
+ }
+ return gameDetails;
+ } else {
+ return [];
+ }
+ }
+
+ Future deleteGameDetail() async {
+ final db = await instance.database;
+
+ return await db.delete(tableGameDetail);
+ }
+
+ // Game
+
+ Future createGame(User user) async {
+ final db = await instance.database;
+
+ await db.transaction((txn) async {
+ for (var game in user.games) {
+ await txn.insert(tableGame, GameMapper.toJson(game, user));
+ }
+ });
+ }
+
+ Future> readGame(int id) async {
+ final db = await instance.database;
+ final result = await db
+ .query(tableGame, where: '${GameFields.userId} = ?', whereArgs: [id]);
+
+ if (result.isNotEmpty) {
+ List games = [];
+ for (var game in result) {
+ List players = [];
+ final resultPlayer = await db.query(tablePlayer,
+ where: '${PlayerFields.idGame} = ?', whereArgs: [game[GameFields.id]]);
+ for (var player in resultPlayer) {
+ players.add(PlayerMapper.toModel(player));
+ }
+ games.add(GameMapper.toModel(game, players));
+ players = [];
+ }
+ return games;
+ } else {
+ return [];
+ }
+ }
+
+ Future deleteGame(int id) async {
+ final db = await instance.database;
+
+ return await db.transaction((txn) async {
+ await txn.delete(
+ tablePlayer,
+ where: '${PlayerFields.idGame} IN (SELECT ${GameFields.id} FROM $tableGame WHERE ${GameFields.userId} = ?)',
+ whereArgs: [id],
+ );
+
+ return await txn.delete(
+ tableGame,
+ where: '${GameFields.userId} = ?',
+ whereArgs: [id],
+ );
+ });
+ }
+
+ // Stat
+
+ Future createStat(User user) async {
+ final db = await instance.database;
+ await db.insert(tableStat, StatMapper.toJson(Stat.empty(), user));
+ }
+
+ Future readStat(int id) async {
+ final db = await instance.database;
+ final result = await db
+ .query(tableStat, where: '${StatFields.idUser} = ?', whereArgs: [id]);
+
+ if (result.isNotEmpty) {
+ Stat stat = StatMapper.toModel(result.first);
+ return stat;
+ } else {
+ return null;
+ }
+ }
+
+ Future updateStat(User user) async {
+ final db = await instance.database;
+ await db.transaction((txn) async {
+ await txn.update(tableStat, StatMapper.toJson(user.stat, user),
+ where: '${StatFields.idUser} = ?', whereArgs: [user.id]);
+ });
+ }
+
+ Future deleteStat(int id) async {
+ final db = await instance.database;
+
+ return await db.delete(
+ tableStat,
+ where: '${StatFields.idUser} = ?',
+ whereArgs: [id],
+ );
+ }
+
+ Future close() async {
+ final db = await instance.database;
+
+ db.close();
+ }
+}
diff --git a/Sources/bowlin_project/lib/main.dart b/Sources/bowlin_project/lib/main.dart
index 5346fbe..d6faae1 100644
--- a/Sources/bowlin_project/lib/main.dart
+++ b/Sources/bowlin_project/lib/main.dart
@@ -1,16 +1,16 @@
+import 'package:bowl_in/model/LocalManager/LocalData.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:bowl_in/config/app_router.dart';
import 'model/IManager.dart';
-import 'model/StubManager/StubData.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
- static IManager controller = StubData();
+ static IManager controller = LocalData();
const MyApp({super.key});
diff --git a/Sources/bowlin_project/lib/model/GamePlayer.dart b/Sources/bowlin_project/lib/model/GamePlayer.dart
index 61af1ad..ec4d40e 100644
--- a/Sources/bowlin_project/lib/model/GamePlayer.dart
+++ b/Sources/bowlin_project/lib/model/GamePlayer.dart
@@ -40,6 +40,8 @@ class GamePlayer {
_parent.gameMgr.addGame(game);
game.computeScores();
+ _parent.userMgr.saveUser(_parent.userCurrent);
+ _parent.gameMgr.saveGame(_game);
context?.go("/scoreboard", extra: game);
} else {
print("IN GAME : " + currentRoundIndex.toString());
diff --git a/Sources/bowlin_project/lib/model/IGameManager.dart b/Sources/bowlin_project/lib/model/IGameManager.dart
index 2b4eff8..c0ee256 100644
--- a/Sources/bowlin_project/lib/model/IGameManager.dart
+++ b/Sources/bowlin_project/lib/model/IGameManager.dart
@@ -3,6 +3,7 @@ import 'Player.dart';
abstract class IGameManager {
GameDetail getGameById(int id);
+ saveGame(GameDetail gameDetail);
List getGamesByPlayerId(int id);
List getGamesByPlayer(Player user);
List getGamesByPlayers(List users);
diff --git a/Sources/bowlin_project/lib/model/IUserManager.dart b/Sources/bowlin_project/lib/model/IUserManager.dart
index b9d5ed6..e5a7e89 100644
--- a/Sources/bowlin_project/lib/model/IUserManager.dart
+++ b/Sources/bowlin_project/lib/model/IUserManager.dart
@@ -12,5 +12,6 @@ abstract class IUserManager {
IAuthManager get authMgr => _authMgr;
List getUsersByName(String name);
Player getUserById(int id);
+ saveUser(User user);
List getRankingWithFriends();
}
diff --git a/Sources/bowlin_project/lib/model/LocalManager/AuthManager.dart b/Sources/bowlin_project/lib/model/LocalManager/AuthManager.dart
new file mode 100644
index 0000000..e97923f
--- /dev/null
+++ b/Sources/bowlin_project/lib/model/LocalManager/AuthManager.dart
@@ -0,0 +1,16 @@
+import 'package:bowl_in/model/IAuthManager.dart';
+import 'package:bowl_in/model/LocalManager/LocalData.dart';
+
+class AuthManager extends IAuthManager {
+ final LocalData parent;
+
+ // Constructor
+ AuthManager(this.parent);
+
+ @override
+ bool verifiedUser(String mail, String password) {
+ // TODO: implement verifiedUser
+ throw UnimplementedError();
+ }
+
+}
\ No newline at end of file
diff --git a/Sources/bowlin_project/lib/model/LocalManager/GameManager.dart b/Sources/bowlin_project/lib/model/LocalManager/GameManager.dart
new file mode 100644
index 0000000..e2f7b70
--- /dev/null
+++ b/Sources/bowlin_project/lib/model/LocalManager/GameManager.dart
@@ -0,0 +1,101 @@
+import 'package:bowl_in/model/GameDetail.dart';
+import 'package:bowl_in/model/IGameManager.dart';
+import 'package:bowl_in/model/LocalManager/LocalData.dart';
+import 'package:bowl_in/model/Player.dart';
+
+import '../User.dart';
+
+class GameManager extends IGameManager {
+ final LocalData parent;
+
+ // Constructor
+ GameManager(this.parent){
+ _initGame();
+ }
+
+ // Methods
+ _initGame() async {
+ parent.gameDetails = await parent.database.readGameDetail();
+ }
+
+ GameDetail getGameById(int id) {
+ for (var element in parent.gameDetails) {
+ if (element.id == id) {
+ return element;
+ }
+ }
+ throw Exception("Game not found.");
+ }
+
+ saveGame(GameDetail gameDetail) async {
+ await parent.database.createGameDetail(gameDetail);
+ }
+
+ List getGamesByPlayerId(int id) {
+ List games = [];
+ for (var element in parent.gameDetails) {
+ for (Player player in element.players) {
+ if (player is User && player.id == id) {
+ games.add(element);
+ break;
+ }
+ }
+ }
+ return games;
+ }
+
+ List getGamesByPlayer(Player user) {
+ List games = [];
+ for (var element in parent.gameDetails) {
+ for (Player player in element.players) {
+ if (player is User && user is User && player.id == user.id) {
+ games.add(element);
+ break;
+ }
+ }
+ }
+ return games;
+ }
+
+ List getGamesByPlayers(List users) {
+ List games = [];
+ for (var element in parent.gameDetails) {
+ if (element.players.toSet().containsAll(users.toSet())) {
+ games.add(element);
+ }
+ }
+ return games;
+ }
+
+ List getPlayersByIdGame(int id) {
+ List players = [];
+ for (var element in parent.gameDetails) {
+ if (element.id == id) {
+ for (var player in element.players) {
+ players.add(player);
+ }
+ return players;
+ }
+ }
+ throw Exception("Game not found.");
+ }
+
+ Map getRankByIdGame(int id) {
+ for (var game in parent.gameDetails) {
+ if (game.id == id) {
+ return game.getRank();
+ }
+ }
+ throw Exception("Game not found.");
+ }
+
+ @override
+ addGame(GameDetail gd) {
+ parent.gameDetails.add(gd);
+ }
+
+ @override
+ int getNextId() {
+ return parent.gameDetails.length;
+ }
+}
diff --git a/Sources/bowlin_project/lib/model/LocalManager/LocalData.dart b/Sources/bowlin_project/lib/model/LocalManager/LocalData.dart
new file mode 100644
index 0000000..b548dd9
--- /dev/null
+++ b/Sources/bowlin_project/lib/model/LocalManager/LocalData.dart
@@ -0,0 +1,23 @@
+import 'package:bowl_in/database/sqlflite/BowlInDatabase.dart';
+import 'package:bowl_in/model/IManager.dart';
+import '../GameDetail.dart';
+import 'GameManager.dart';
+import 'UserManager.dart';
+
+class LocalData extends IManager {
+ final BowlInDatabase database = BowlInDatabase();
+
+ LocalData() {
+ userMgr = UserManager(this);
+ gameMgr = GameManager(this);
+ }
+
+ List _gameDetails = [];
+
+ List get gameDetails => _gameDetails;
+
+ set gameDetails(List gameDetails) {
+ _gameDetails = gameDetails;
+ }
+
+}
diff --git a/Sources/bowlin_project/lib/model/LocalManager/UserManager.dart b/Sources/bowlin_project/lib/model/LocalManager/UserManager.dart
new file mode 100644
index 0000000..acb8d37
--- /dev/null
+++ b/Sources/bowlin_project/lib/model/LocalManager/UserManager.dart
@@ -0,0 +1,66 @@
+import 'package:bowl_in/model/IUserManager.dart';
+import 'package:bowl_in/model/LocalManager/LocalData.dart';
+import 'package:bowl_in/model/Player.dart';
+import 'package:bowl_in/model/User.dart';
+import 'AuthManager.dart';
+
+class UserManager extends IUserManager {
+ final LocalData parent;
+
+ // Constructor
+ UserManager(this.parent) : super(AuthManager(parent)) {
+ _initUser();
+ }
+
+ _initUser() async {
+ //await parent.database.deleteGameDetail();
+ //await parent.database.deleteUser(0);
+ //User crUser = User(0, "Lucas", "./assets/images/image_user_red.png", "", [], []);
+ //await saveUser(crUser);
+ var user = await parent.database.readUser(0);
+ if (user == null) {
+ User user2 =
+ User(0, "Unknown", "./assets/images/image_user_pink.png", "", [], []);
+ parent.userCurrent = user2;
+ } else {
+ parent.userCurrent = user;
+ }
+ }
+
+ saveUser(User user) async {
+ var result = await parent.database.readUser(0);
+ if (result == null) {
+ await parent.database.createUser(user);
+ } else {
+ await parent.database.updateUser(user);
+ }
+ }
+
+ Map userToMap(User user) {
+ return {
+ '_id': user.id,
+ 'name': user.name,
+ 'image': user.image,
+ '_mail': user.mail,
+ };
+ }
+
+ @override
+ List getRankingWithFriends() {
+ List sortedPlayers = List.from(parent.userCurrent.friends);
+ sortedPlayers.sort((a, b) => b.stat.highscore.compareTo(a.stat.highscore));
+ return sortedPlayers;
+ }
+
+ @override
+ Player getUserById(int id) {
+ // TODO: implement getUserById
+ throw UnimplementedError();
+ }
+
+ @override
+ List getUsersByName(String name) {
+ // TODO: implement getUsersByName
+ throw UnimplementedError();
+ }
+}
diff --git a/Sources/bowlin_project/lib/model/Stat.dart b/Sources/bowlin_project/lib/model/Stat.dart
index 434b0ff..e2e3d91 100644
--- a/Sources/bowlin_project/lib/model/Stat.dart
+++ b/Sources/bowlin_project/lib/model/Stat.dart
@@ -96,4 +96,5 @@ class Stat {
avgPinsPerRound =
((avgPinsPerRound * (nbGames - 1)) + (totalpins / 10)) / nbGames;
}
+
}
diff --git a/Sources/bowlin_project/lib/model/StubManager/AuthManager.dart b/Sources/bowlin_project/lib/model/StubManager/AuthManager.dart
index 2b581dd..cee989e 100644
--- a/Sources/bowlin_project/lib/model/StubManager/AuthManager.dart
+++ b/Sources/bowlin_project/lib/model/StubManager/AuthManager.dart
@@ -9,6 +9,7 @@ class AuthManager extends IAuthManager {
// Constructor
AuthManager(this.parent);
+
// Methods
bool verifiedUser(String mail, String password) {
for (var user in parent.players) {
diff --git a/Sources/bowlin_project/lib/model/StubManager/GameManager.dart b/Sources/bowlin_project/lib/model/StubManager/GameManager.dart
index 63c878e..96aacaf 100644
--- a/Sources/bowlin_project/lib/model/StubManager/GameManager.dart
+++ b/Sources/bowlin_project/lib/model/StubManager/GameManager.dart
@@ -22,6 +22,10 @@ class GameManager extends IGameManager {
throw Exception("Game not found.");
}
+ saveGame(GameDetail gameDetail) {
+ return ;
+ }
+
List getGamesByPlayerId(int id) {
List games = [];
for (var element in parent.gameDetails) {
diff --git a/Sources/bowlin_project/lib/model/StubManager/StubData.dart b/Sources/bowlin_project/lib/model/StubManager/StubData.dart
index b6da634..8499b82 100644
--- a/Sources/bowlin_project/lib/model/StubManager/StubData.dart
+++ b/Sources/bowlin_project/lib/model/StubManager/StubData.dart
@@ -11,6 +11,7 @@ import 'UserManager.dart';
import 'GameManager.dart';
class StubData extends IManager {
+
StubData() {
userMgr = UserManager(this);
gameMgr = GameManager(this);
@@ -18,7 +19,6 @@ class StubData extends IManager {
_initGameDetails();
_initGame();
userCurrent = players[8] as User;
- userCurrent.games = [];
}
List players = [
diff --git a/Sources/bowlin_project/lib/model/StubManager/UserManager.dart b/Sources/bowlin_project/lib/model/StubManager/UserManager.dart
index fd8d9e9..e016c60 100644
--- a/Sources/bowlin_project/lib/model/StubManager/UserManager.dart
+++ b/Sources/bowlin_project/lib/model/StubManager/UserManager.dart
@@ -38,4 +38,9 @@ class UserManager extends IUserManager {
sortedPlayers.sort((a, b) => b.stat.highscore.compareTo(a.stat.highscore));
return sortedPlayers;
}
+
+ @override
+ saveUser(User user) {
+ return ;
+ }
}
diff --git a/Sources/bowlin_project/lib/model/User.dart b/Sources/bowlin_project/lib/model/User.dart
index b5b1bd7..582785c 100644
--- a/Sources/bowlin_project/lib/model/User.dart
+++ b/Sources/bowlin_project/lib/model/User.dart
@@ -8,12 +8,18 @@ class User extends Player {
String _mail;
List _achievements = [];
List _friends = [];
- final Stat _stat = Stat.empty();
+ late final Stat _stat;
List games = [];
// Constructor
User(this._id, String name, String image, this._mail, this._achievements,
this._friends)
+ : super(name, image){
+ _stat = Stat.empty();
+ }
+
+ User.withStat(this._id, String name, String image, this._mail, this._achievements,
+ this._friends, this._stat)
: super(name, image);
int get id => _id;
@@ -38,4 +44,5 @@ class User extends Player {
}
Stat get stat => _stat;
+
}
diff --git a/Sources/bowlin_project/pubspec.lock b/Sources/bowlin_project/pubspec.lock
index 6ba6aa5..e04bffe 100644
--- a/Sources/bowlin_project/pubspec.lock
+++ b/Sources/bowlin_project/pubspec.lock
@@ -156,10 +156,10 @@ packages:
dependency: "direct main"
description:
name: go_router
- sha256: b90b9aaa7723ca7159a81c0cd3be8108c74c986c3fbc41d413fd82ea164733ea
+ sha256: e2a90e1d4eed378ea12e0771be9e32766a2f8d2de3064e42f3a55f1b04fb8af8
url: "https://pub.dev"
source: hosted
- version: "6.4.0"
+ version: "6.4.1"
google_fonts:
dependency: "direct main"
description:
@@ -373,6 +373,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.9.1"
+ sqflite:
+ dependency: "direct main"
+ description:
+ name: sqflite
+ sha256: "500d6fec583d2c021f2d25a056d96654f910662c64f836cd2063167b8f1fa758"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.2.6"
+ sqflite_common:
+ dependency: transitive
+ description:
+ name: sqflite_common
+ sha256: "963dad8c4aa2f814ce7d2d5b1da2f36f31bd1a439d8f27e3dc189bb9d26bc684"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.4.3"
stack_trace:
dependency: transitive
description:
@@ -397,6 +413,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.2.0"
+ synchronized:
+ dependency: transitive
+ description:
+ name: synchronized
+ sha256: "33b31b6beb98100bf9add464a36a8dd03eb10c7a8cf15aeec535e9b054aaf04b"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.0.1"
term_glyph:
dependency: transitive
description:
@@ -457,10 +481,10 @@ packages:
dependency: transitive
description:
name: xml
- sha256: ac0e3f4bf00ba2708c33fbabbbe766300e509f8c82dbd4ab6525039813f7e2fb
+ sha256: "979ee37d622dec6365e2efa4d906c37470995871fe9ae080d967e192d88286b5"
url: "https://pub.dev"
source: hosted
- version: "6.1.0"
+ version: "6.2.2"
yaml:
dependency: transitive
description:
diff --git a/Sources/bowlin_project/pubspec.yaml b/Sources/bowlin_project/pubspec.yaml
index d4df740..a2e33e3 100644
--- a/Sources/bowlin_project/pubspec.yaml
+++ b/Sources/bowlin_project/pubspec.yaml
@@ -41,6 +41,7 @@ dependencies:
go_router: ^6.0.1
uuid: ^3.0.7
intl: ^0.18.0
+ sqflite: ^2.0.0+3
dev_dependencies: