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: