GameHistoryView anpassen #20
57
.gitea/workflows/pull_request.yaml
Normal file
57
.gitea/workflows/pull_request.yaml
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
name: Pull Request Pipeline
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
lint:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install jq
|
||||||
|
run: |
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y jq
|
||||||
|
|
||||||
|
- name: Install Flutter (wget)
|
||||||
|
run: |
|
||||||
|
wget https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_3.38.2-stable.tar.xz
|
||||||
|
tar xf flutter_linux_3.38.2-stable.tar.xz
|
||||||
|
# Set Git safe directory for Flutter path
|
||||||
|
git config --global --add safe.directory "$(pwd)/flutter"
|
||||||
|
# Set Flutter path
|
||||||
|
echo "$(pwd)/flutter/bin" >> $GITHUB_PATH
|
||||||
|
|
||||||
|
- name: Get dependencies
|
||||||
|
run: flutter pub get
|
||||||
|
|
||||||
|
- name: Analyze Formatting
|
||||||
|
run: flutter analyze lib test
|
||||||
|
|
||||||
|
test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y jq
|
||||||
|
|
||||||
|
- name: Install Flutter (wget)
|
||||||
|
run: |
|
||||||
|
wget https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_3.38.2-stable.tar.xz
|
||||||
|
tar xf flutter_linux_3.38.2-stable.tar.xz
|
||||||
|
# Set Git safe directory for Flutter path
|
||||||
|
git config --global --add safe.directory "$(pwd)/flutter"
|
||||||
|
# Set Flutter path
|
||||||
|
echo "$(pwd)/flutter/bin" >> $GITHUB_PATH
|
||||||
|
|
||||||
|
- name: Get dependencies
|
||||||
|
run: flutter pub get
|
||||||
|
|
||||||
|
- name: Run tests
|
||||||
|
run: flutter test
|
||||||
50
.gitea/workflows/push.yaml
Normal file
50
.gitea/workflows/push.yaml
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
name: Push Pipeline
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- "development"
|
||||||
|
- "main"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
format:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: false # Needs bot user
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y jq
|
||||||
|
|
||||||
|
- name: Install Flutter (wget)
|
||||||
|
run: |
|
||||||
|
wget https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_3.38.2-stable.tar.xz
|
||||||
|
tar xf flutter_linux_3.38.2-stable.tar.xz
|
||||||
|
# Set Git safe directory for Flutter path
|
||||||
|
git config --global --add safe.directory "$(pwd)/flutter"
|
||||||
|
# Set Flutter path
|
||||||
|
echo "$(pwd)/flutter/bin" >> $GITHUB_PATH
|
||||||
|
|
||||||
|
- name: Get & upgrade dependencies
|
||||||
|
run: |
|
||||||
|
flutter pub get
|
||||||
|
flutter pub upgrade --major-versions
|
||||||
|
|
||||||
|
- name: Auto-format
|
||||||
|
run: |
|
||||||
|
dart format lib
|
||||||
|
dart fix --apply lib
|
||||||
|
|
||||||
|
# Needs credentials, push access and the right files need to be staged
|
||||||
|
- name: Commit Changes
|
||||||
|
run: |
|
||||||
|
git config --global user.name "Gitea Actions"
|
||||||
|
git config --global user.email "actions@gitea.com"
|
||||||
|
git status
|
||||||
|
git add lib/
|
||||||
|
git status
|
||||||
|
git commit -m "Actions: Auto-formatting [skip ci]"
|
||||||
|
git push
|
||||||
2
lib/core/enums.dart
Normal file
2
lib/core/enums.dart
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
/// Button types used for styling the [CustomWidthButton]
|
||||||
|
enum ButtonType { primary, secondary, tertiary }
|
||||||
@@ -15,7 +15,11 @@ class GameDao extends DatabaseAccessor<AppDatabase> with _$GameDaoMixin {
|
|||||||
Future<List<Game>> getAllGames() async {
|
Future<List<Game>> getAllGames() async {
|
||||||
final query = select(gameTable);
|
final query = select(gameTable);
|
||||||
final result = await query.get();
|
final result = await query.get();
|
||||||
return result.map((row) => Game(id: row.id, name: row.name)).toList();
|
return result
|
||||||
|
.map(
|
||||||
|
(row) => Game(id: row.id, name: row.name, createdAt: row.createdAt),
|
||||||
|
)
|
||||||
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieves a [Game] by its [gameId].
|
/// Retrieves a [Game] by its [gameId].
|
||||||
@@ -38,6 +42,7 @@ class GameDao extends DatabaseAccessor<AppDatabase> with _$GameDaoMixin {
|
|||||||
players: players,
|
players: players,
|
||||||
group: group,
|
group: group,
|
||||||
winner: result.winnerId,
|
winner: result.winnerId,
|
||||||
|
createdAt: result.createdAt,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,6 +63,7 @@ class GameDao extends DatabaseAccessor<AppDatabase> with _$GameDaoMixin {
|
|||||||
id: game.id,
|
id: game.id,
|
||||||
name: game.name,
|
name: game.name,
|
||||||
winnerId: game.winner,
|
winnerId: game.winner,
|
||||||
|
createdAt: game.createdAt,
|
||||||
),
|
),
|
||||||
mode: InsertMode.insertOrReplace,
|
mode: InsertMode.insertOrReplace,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -19,7 +19,12 @@ class GroupDao extends DatabaseAccessor<AppDatabase> with _$GroupDaoMixin {
|
|||||||
final members = await db.playerGroupDao.getPlayersOfGroupById(
|
final members = await db.playerGroupDao.getPlayersOfGroupById(
|
||||||
groupId: groupData.id,
|
groupId: groupData.id,
|
||||||
);
|
);
|
||||||
return Group(id: groupData.id, name: groupData.name, members: members);
|
return Group(
|
||||||
|
id: groupData.id,
|
||||||
|
name: groupData.name,
|
||||||
|
members: members,
|
||||||
|
createdAt: groupData.createdAt,
|
||||||
|
);
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -33,7 +38,12 @@ class GroupDao extends DatabaseAccessor<AppDatabase> with _$GroupDaoMixin {
|
|||||||
groupId: groupId,
|
groupId: groupId,
|
||||||
);
|
);
|
||||||
|
|
||||||
return Group(id: result.id, name: result.name, members: members);
|
return Group(
|
||||||
|
id: result.id,
|
||||||
|
name: result.name,
|
||||||
|
members: members,
|
||||||
|
createdAt: result.createdAt,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds a new group with the given [id] and [name] to the database.
|
/// Adds a new group with the given [id] and [name] to the database.
|
||||||
@@ -41,9 +51,13 @@ class GroupDao extends DatabaseAccessor<AppDatabase> with _$GroupDaoMixin {
|
|||||||
Future<bool> addGroup({required Group group}) async {
|
Future<bool> addGroup({required Group group}) async {
|
||||||
if (!await groupExists(groupId: group.id)) {
|
if (!await groupExists(groupId: group.id)) {
|
||||||
await db.transaction(() async {
|
await db.transaction(() async {
|
||||||
await into(
|
await into(groupTable).insert(
|
||||||
groupTable,
|
GroupTableCompanion.insert(
|
||||||
).insert(GroupTableCompanion.insert(id: group.id, name: group.name));
|
id: group.id,
|
||||||
|
name: group.name,
|
||||||
|
createdAt: group.createdAt,
|
||||||
|
),
|
||||||
|
);
|
||||||
await db.batch(
|
await db.batch(
|
||||||
(b) => b.insertAll(
|
(b) => b.insertAll(
|
||||||
db.playerGroupTable,
|
db.playerGroupTable,
|
||||||
@@ -60,8 +74,8 @@ class GroupDao extends DatabaseAccessor<AppDatabase> with _$GroupDaoMixin {
|
|||||||
await Future.wait(
|
await Future.wait(
|
||||||
group.members.map((player) => db.playerDao.addPlayer(player: player)),
|
group.members.map((player) => db.playerDao.addPlayer(player: player)),
|
||||||
);
|
);
|
||||||
return true;
|
|
||||||
});
|
});
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,14 +13,22 @@ class PlayerDao extends DatabaseAccessor<AppDatabase> with _$PlayerDaoMixin {
|
|||||||
Future<List<Player>> getAllPlayers() async {
|
Future<List<Player>> getAllPlayers() async {
|
||||||
final query = select(playerTable);
|
final query = select(playerTable);
|
||||||
final result = await query.get();
|
final result = await query.get();
|
||||||
return result.map((row) => Player(id: row.id, name: row.name)).toList();
|
return result
|
||||||
|
.map(
|
||||||
|
(row) => Player(id: row.id, name: row.name, createdAt: row.createdAt),
|
||||||
|
)
|
||||||
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieves a [Player] by their [id].
|
/// Retrieves a [Player] by their [id].
|
||||||
Future<Player> getPlayerById({required String playerId}) async {
|
Future<Player> getPlayerById({required String playerId}) async {
|
||||||
final query = select(playerTable)..where((p) => p.id.equals(playerId));
|
final query = select(playerTable)..where((p) => p.id.equals(playerId));
|
||||||
final result = await query.getSingle();
|
final result = await query.getSingle();
|
||||||
return Player(id: result.id, name: result.name);
|
return Player(
|
||||||
|
id: result.id,
|
||||||
|
name: result.name,
|
||||||
|
createdAt: result.createdAt,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds a new [player] to the database.
|
/// Adds a new [player] to the database.
|
||||||
@@ -28,9 +36,13 @@ class PlayerDao extends DatabaseAccessor<AppDatabase> with _$PlayerDaoMixin {
|
|||||||
/// the new one.
|
/// the new one.
|
||||||
Future<bool> addPlayer({required Player player}) async {
|
Future<bool> addPlayer({required Player player}) async {
|
||||||
if (!await playerExists(playerId: player.id)) {
|
if (!await playerExists(playerId: player.id)) {
|
||||||
await into(
|
await into(playerTable).insert(
|
||||||
playerTable,
|
PlayerTableCompanion.insert(
|
||||||
).insert(PlayerTableCompanion.insert(id: player.id, name: player.name));
|
id: player.id,
|
||||||
|
name: player.name,
|
||||||
|
createdAt: player.createdAt,
|
||||||
|
),
|
||||||
|
);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -27,8 +27,19 @@ class $PlayerTableTable extends PlayerTable
|
|||||||
type: DriftSqlType.string,
|
type: DriftSqlType.string,
|
||||||
requiredDuringInsert: true,
|
requiredDuringInsert: true,
|
||||||
);
|
);
|
||||||
|
static const VerificationMeta _createdAtMeta = const VerificationMeta(
|
||||||
|
'createdAt',
|
||||||
|
);
|
||||||
@override
|
@override
|
||||||
List<GeneratedColumn> get $columns => [id, name];
|
late final GeneratedColumn<DateTime> createdAt = GeneratedColumn<DateTime>(
|
||||||
|
'created_at',
|
||||||
|
aliasedName,
|
||||||
|
false,
|
||||||
|
type: DriftSqlType.dateTime,
|
||||||
|
requiredDuringInsert: true,
|
||||||
|
);
|
||||||
|
@override
|
||||||
|
List<GeneratedColumn> get $columns => [id, name, createdAt];
|
||||||
@override
|
@override
|
||||||
String get aliasedName => _alias ?? actualTableName;
|
String get aliasedName => _alias ?? actualTableName;
|
||||||
@override
|
@override
|
||||||
@@ -54,6 +65,14 @@ class $PlayerTableTable extends PlayerTable
|
|||||||
} else if (isInserting) {
|
} else if (isInserting) {
|
||||||
context.missing(_nameMeta);
|
context.missing(_nameMeta);
|
||||||
}
|
}
|
||||||
|
if (data.containsKey('created_at')) {
|
||||||
|
context.handle(
|
||||||
|
_createdAtMeta,
|
||||||
|
createdAt.isAcceptableOrUnknown(data['created_at']!, _createdAtMeta),
|
||||||
|
);
|
||||||
|
} else if (isInserting) {
|
||||||
|
context.missing(_createdAtMeta);
|
||||||
|
}
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,6 +90,10 @@ class $PlayerTableTable extends PlayerTable
|
|||||||
DriftSqlType.string,
|
DriftSqlType.string,
|
||||||
data['${effectivePrefix}name'],
|
data['${effectivePrefix}name'],
|
||||||
)!,
|
)!,
|
||||||
|
createdAt: attachedDatabase.typeMapping.read(
|
||||||
|
DriftSqlType.dateTime,
|
||||||
|
data['${effectivePrefix}created_at'],
|
||||||
|
)!,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,17 +106,27 @@ class $PlayerTableTable extends PlayerTable
|
|||||||
class PlayerTableData extends DataClass implements Insertable<PlayerTableData> {
|
class PlayerTableData extends DataClass implements Insertable<PlayerTableData> {
|
||||||
final String id;
|
final String id;
|
||||||
final String name;
|
final String name;
|
||||||
const PlayerTableData({required this.id, required this.name});
|
final DateTime createdAt;
|
||||||
|
const PlayerTableData({
|
||||||
|
required this.id,
|
||||||
|
required this.name,
|
||||||
|
required this.createdAt,
|
||||||
|
});
|
||||||
@override
|
@override
|
||||||
Map<String, Expression> toColumns(bool nullToAbsent) {
|
Map<String, Expression> toColumns(bool nullToAbsent) {
|
||||||
final map = <String, Expression>{};
|
final map = <String, Expression>{};
|
||||||
map['id'] = Variable<String>(id);
|
map['id'] = Variable<String>(id);
|
||||||
map['name'] = Variable<String>(name);
|
map['name'] = Variable<String>(name);
|
||||||
|
map['created_at'] = Variable<DateTime>(createdAt);
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
PlayerTableCompanion toCompanion(bool nullToAbsent) {
|
PlayerTableCompanion toCompanion(bool nullToAbsent) {
|
||||||
return PlayerTableCompanion(id: Value(id), name: Value(name));
|
return PlayerTableCompanion(
|
||||||
|
id: Value(id),
|
||||||
|
name: Value(name),
|
||||||
|
createdAt: Value(createdAt),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
factory PlayerTableData.fromJson(
|
factory PlayerTableData.fromJson(
|
||||||
@@ -104,6 +137,7 @@ class PlayerTableData extends DataClass implements Insertable<PlayerTableData> {
|
|||||||
return PlayerTableData(
|
return PlayerTableData(
|
||||||
id: serializer.fromJson<String>(json['id']),
|
id: serializer.fromJson<String>(json['id']),
|
||||||
name: serializer.fromJson<String>(json['name']),
|
name: serializer.fromJson<String>(json['name']),
|
||||||
|
createdAt: serializer.fromJson<DateTime>(json['createdAt']),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@override
|
@override
|
||||||
@@ -112,15 +146,21 @@ class PlayerTableData extends DataClass implements Insertable<PlayerTableData> {
|
|||||||
return <String, dynamic>{
|
return <String, dynamic>{
|
||||||
'id': serializer.toJson<String>(id),
|
'id': serializer.toJson<String>(id),
|
||||||
'name': serializer.toJson<String>(name),
|
'name': serializer.toJson<String>(name),
|
||||||
|
'createdAt': serializer.toJson<DateTime>(createdAt),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
PlayerTableData copyWith({String? id, String? name}) =>
|
PlayerTableData copyWith({String? id, String? name, DateTime? createdAt}) =>
|
||||||
PlayerTableData(id: id ?? this.id, name: name ?? this.name);
|
PlayerTableData(
|
||||||
|
id: id ?? this.id,
|
||||||
|
name: name ?? this.name,
|
||||||
|
createdAt: createdAt ?? this.createdAt,
|
||||||
|
);
|
||||||
PlayerTableData copyWithCompanion(PlayerTableCompanion data) {
|
PlayerTableData copyWithCompanion(PlayerTableCompanion data) {
|
||||||
return PlayerTableData(
|
return PlayerTableData(
|
||||||
id: data.id.present ? data.id.value : this.id,
|
id: data.id.present ? data.id.value : this.id,
|
||||||
name: data.name.present ? data.name.value : this.name,
|
name: data.name.present ? data.name.value : this.name,
|
||||||
|
createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,44 +168,52 @@ class PlayerTableData extends DataClass implements Insertable<PlayerTableData> {
|
|||||||
String toString() {
|
String toString() {
|
||||||
return (StringBuffer('PlayerTableData(')
|
return (StringBuffer('PlayerTableData(')
|
||||||
..write('id: $id, ')
|
..write('id: $id, ')
|
||||||
..write('name: $name')
|
..write('name: $name, ')
|
||||||
|
..write('createdAt: $createdAt')
|
||||||
..write(')'))
|
..write(')'))
|
||||||
.toString();
|
.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(id, name);
|
int get hashCode => Object.hash(id, name, createdAt);
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) =>
|
bool operator ==(Object other) =>
|
||||||
identical(this, other) ||
|
identical(this, other) ||
|
||||||
(other is PlayerTableData &&
|
(other is PlayerTableData &&
|
||||||
other.id == this.id &&
|
other.id == this.id &&
|
||||||
other.name == this.name);
|
other.name == this.name &&
|
||||||
|
other.createdAt == this.createdAt);
|
||||||
}
|
}
|
||||||
|
|
||||||
class PlayerTableCompanion extends UpdateCompanion<PlayerTableData> {
|
class PlayerTableCompanion extends UpdateCompanion<PlayerTableData> {
|
||||||
final Value<String> id;
|
final Value<String> id;
|
||||||
final Value<String> name;
|
final Value<String> name;
|
||||||
|
final Value<DateTime> createdAt;
|
||||||
final Value<int> rowid;
|
final Value<int> rowid;
|
||||||
const PlayerTableCompanion({
|
const PlayerTableCompanion({
|
||||||
this.id = const Value.absent(),
|
this.id = const Value.absent(),
|
||||||
this.name = const Value.absent(),
|
this.name = const Value.absent(),
|
||||||
|
this.createdAt = const Value.absent(),
|
||||||
this.rowid = const Value.absent(),
|
this.rowid = const Value.absent(),
|
||||||
});
|
});
|
||||||
PlayerTableCompanion.insert({
|
PlayerTableCompanion.insert({
|
||||||
required String id,
|
required String id,
|
||||||
required String name,
|
required String name,
|
||||||
|
required DateTime createdAt,
|
||||||
this.rowid = const Value.absent(),
|
this.rowid = const Value.absent(),
|
||||||
}) : id = Value(id),
|
}) : id = Value(id),
|
||||||
name = Value(name);
|
name = Value(name),
|
||||||
|
createdAt = Value(createdAt);
|
||||||
static Insertable<PlayerTableData> custom({
|
static Insertable<PlayerTableData> custom({
|
||||||
Expression<String>? id,
|
Expression<String>? id,
|
||||||
Expression<String>? name,
|
Expression<String>? name,
|
||||||
|
Expression<DateTime>? createdAt,
|
||||||
Expression<int>? rowid,
|
Expression<int>? rowid,
|
||||||
}) {
|
}) {
|
||||||
return RawValuesInsertable({
|
return RawValuesInsertable({
|
||||||
if (id != null) 'id': id,
|
if (id != null) 'id': id,
|
||||||
if (name != null) 'name': name,
|
if (name != null) 'name': name,
|
||||||
|
if (createdAt != null) 'created_at': createdAt,
|
||||||
if (rowid != null) 'rowid': rowid,
|
if (rowid != null) 'rowid': rowid,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -173,11 +221,13 @@ class PlayerTableCompanion extends UpdateCompanion<PlayerTableData> {
|
|||||||
PlayerTableCompanion copyWith({
|
PlayerTableCompanion copyWith({
|
||||||
Value<String>? id,
|
Value<String>? id,
|
||||||
Value<String>? name,
|
Value<String>? name,
|
||||||
|
Value<DateTime>? createdAt,
|
||||||
Value<int>? rowid,
|
Value<int>? rowid,
|
||||||
}) {
|
}) {
|
||||||
return PlayerTableCompanion(
|
return PlayerTableCompanion(
|
||||||
id: id ?? this.id,
|
id: id ?? this.id,
|
||||||
name: name ?? this.name,
|
name: name ?? this.name,
|
||||||
|
createdAt: createdAt ?? this.createdAt,
|
||||||
rowid: rowid ?? this.rowid,
|
rowid: rowid ?? this.rowid,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -191,6 +241,9 @@ class PlayerTableCompanion extends UpdateCompanion<PlayerTableData> {
|
|||||||
if (name.present) {
|
if (name.present) {
|
||||||
map['name'] = Variable<String>(name.value);
|
map['name'] = Variable<String>(name.value);
|
||||||
}
|
}
|
||||||
|
if (createdAt.present) {
|
||||||
|
map['created_at'] = Variable<DateTime>(createdAt.value);
|
||||||
|
}
|
||||||
if (rowid.present) {
|
if (rowid.present) {
|
||||||
map['rowid'] = Variable<int>(rowid.value);
|
map['rowid'] = Variable<int>(rowid.value);
|
||||||
}
|
}
|
||||||
@@ -202,6 +255,7 @@ class PlayerTableCompanion extends UpdateCompanion<PlayerTableData> {
|
|||||||
return (StringBuffer('PlayerTableCompanion(')
|
return (StringBuffer('PlayerTableCompanion(')
|
||||||
..write('id: $id, ')
|
..write('id: $id, ')
|
||||||
..write('name: $name, ')
|
..write('name: $name, ')
|
||||||
|
..write('createdAt: $createdAt, ')
|
||||||
..write('rowid: $rowid')
|
..write('rowid: $rowid')
|
||||||
..write(')'))
|
..write(')'))
|
||||||
.toString();
|
.toString();
|
||||||
@@ -232,8 +286,19 @@ class $GroupTableTable extends GroupTable
|
|||||||
type: DriftSqlType.string,
|
type: DriftSqlType.string,
|
||||||
requiredDuringInsert: true,
|
requiredDuringInsert: true,
|
||||||
);
|
);
|
||||||
|
static const VerificationMeta _createdAtMeta = const VerificationMeta(
|
||||||
|
'createdAt',
|
||||||
|
);
|
||||||
@override
|
@override
|
||||||
List<GeneratedColumn> get $columns => [id, name];
|
late final GeneratedColumn<DateTime> createdAt = GeneratedColumn<DateTime>(
|
||||||
|
'created_at',
|
||||||
|
aliasedName,
|
||||||
|
false,
|
||||||
|
type: DriftSqlType.dateTime,
|
||||||
|
requiredDuringInsert: true,
|
||||||
|
);
|
||||||
|
@override
|
||||||
|
List<GeneratedColumn> get $columns => [id, name, createdAt];
|
||||||
@override
|
@override
|
||||||
String get aliasedName => _alias ?? actualTableName;
|
String get aliasedName => _alias ?? actualTableName;
|
||||||
@override
|
@override
|
||||||
@@ -259,6 +324,14 @@ class $GroupTableTable extends GroupTable
|
|||||||
} else if (isInserting) {
|
} else if (isInserting) {
|
||||||
context.missing(_nameMeta);
|
context.missing(_nameMeta);
|
||||||
}
|
}
|
||||||
|
if (data.containsKey('created_at')) {
|
||||||
|
context.handle(
|
||||||
|
_createdAtMeta,
|
||||||
|
createdAt.isAcceptableOrUnknown(data['created_at']!, _createdAtMeta),
|
||||||
|
);
|
||||||
|
} else if (isInserting) {
|
||||||
|
context.missing(_createdAtMeta);
|
||||||
|
}
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -276,6 +349,10 @@ class $GroupTableTable extends GroupTable
|
|||||||
DriftSqlType.string,
|
DriftSqlType.string,
|
||||||
data['${effectivePrefix}name'],
|
data['${effectivePrefix}name'],
|
||||||
)!,
|
)!,
|
||||||
|
createdAt: attachedDatabase.typeMapping.read(
|
||||||
|
DriftSqlType.dateTime,
|
||||||
|
data['${effectivePrefix}created_at'],
|
||||||
|
)!,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -288,17 +365,27 @@ class $GroupTableTable extends GroupTable
|
|||||||
class GroupTableData extends DataClass implements Insertable<GroupTableData> {
|
class GroupTableData extends DataClass implements Insertable<GroupTableData> {
|
||||||
final String id;
|
final String id;
|
||||||
final String name;
|
final String name;
|
||||||
const GroupTableData({required this.id, required this.name});
|
final DateTime createdAt;
|
||||||
|
const GroupTableData({
|
||||||
|
required this.id,
|
||||||
|
required this.name,
|
||||||
|
required this.createdAt,
|
||||||
|
});
|
||||||
@override
|
@override
|
||||||
Map<String, Expression> toColumns(bool nullToAbsent) {
|
Map<String, Expression> toColumns(bool nullToAbsent) {
|
||||||
final map = <String, Expression>{};
|
final map = <String, Expression>{};
|
||||||
map['id'] = Variable<String>(id);
|
map['id'] = Variable<String>(id);
|
||||||
map['name'] = Variable<String>(name);
|
map['name'] = Variable<String>(name);
|
||||||
|
map['created_at'] = Variable<DateTime>(createdAt);
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
GroupTableCompanion toCompanion(bool nullToAbsent) {
|
GroupTableCompanion toCompanion(bool nullToAbsent) {
|
||||||
return GroupTableCompanion(id: Value(id), name: Value(name));
|
return GroupTableCompanion(
|
||||||
|
id: Value(id),
|
||||||
|
name: Value(name),
|
||||||
|
createdAt: Value(createdAt),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
factory GroupTableData.fromJson(
|
factory GroupTableData.fromJson(
|
||||||
@@ -309,6 +396,7 @@ class GroupTableData extends DataClass implements Insertable<GroupTableData> {
|
|||||||
return GroupTableData(
|
return GroupTableData(
|
||||||
id: serializer.fromJson<String>(json['id']),
|
id: serializer.fromJson<String>(json['id']),
|
||||||
name: serializer.fromJson<String>(json['name']),
|
name: serializer.fromJson<String>(json['name']),
|
||||||
|
createdAt: serializer.fromJson<DateTime>(json['createdAt']),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@override
|
@override
|
||||||
@@ -317,15 +405,21 @@ class GroupTableData extends DataClass implements Insertable<GroupTableData> {
|
|||||||
return <String, dynamic>{
|
return <String, dynamic>{
|
||||||
'id': serializer.toJson<String>(id),
|
'id': serializer.toJson<String>(id),
|
||||||
'name': serializer.toJson<String>(name),
|
'name': serializer.toJson<String>(name),
|
||||||
|
'createdAt': serializer.toJson<DateTime>(createdAt),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
GroupTableData copyWith({String? id, String? name}) =>
|
GroupTableData copyWith({String? id, String? name, DateTime? createdAt}) =>
|
||||||
GroupTableData(id: id ?? this.id, name: name ?? this.name);
|
GroupTableData(
|
||||||
|
id: id ?? this.id,
|
||||||
|
name: name ?? this.name,
|
||||||
|
createdAt: createdAt ?? this.createdAt,
|
||||||
|
);
|
||||||
GroupTableData copyWithCompanion(GroupTableCompanion data) {
|
GroupTableData copyWithCompanion(GroupTableCompanion data) {
|
||||||
return GroupTableData(
|
return GroupTableData(
|
||||||
id: data.id.present ? data.id.value : this.id,
|
id: data.id.present ? data.id.value : this.id,
|
||||||
name: data.name.present ? data.name.value : this.name,
|
name: data.name.present ? data.name.value : this.name,
|
||||||
|
createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -333,44 +427,52 @@ class GroupTableData extends DataClass implements Insertable<GroupTableData> {
|
|||||||
String toString() {
|
String toString() {
|
||||||
return (StringBuffer('GroupTableData(')
|
return (StringBuffer('GroupTableData(')
|
||||||
..write('id: $id, ')
|
..write('id: $id, ')
|
||||||
..write('name: $name')
|
..write('name: $name, ')
|
||||||
|
..write('createdAt: $createdAt')
|
||||||
..write(')'))
|
..write(')'))
|
||||||
.toString();
|
.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(id, name);
|
int get hashCode => Object.hash(id, name, createdAt);
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) =>
|
bool operator ==(Object other) =>
|
||||||
identical(this, other) ||
|
identical(this, other) ||
|
||||||
(other is GroupTableData &&
|
(other is GroupTableData &&
|
||||||
other.id == this.id &&
|
other.id == this.id &&
|
||||||
other.name == this.name);
|
other.name == this.name &&
|
||||||
|
other.createdAt == this.createdAt);
|
||||||
}
|
}
|
||||||
|
|
||||||
class GroupTableCompanion extends UpdateCompanion<GroupTableData> {
|
class GroupTableCompanion extends UpdateCompanion<GroupTableData> {
|
||||||
final Value<String> id;
|
final Value<String> id;
|
||||||
final Value<String> name;
|
final Value<String> name;
|
||||||
|
final Value<DateTime> createdAt;
|
||||||
final Value<int> rowid;
|
final Value<int> rowid;
|
||||||
const GroupTableCompanion({
|
const GroupTableCompanion({
|
||||||
this.id = const Value.absent(),
|
this.id = const Value.absent(),
|
||||||
this.name = const Value.absent(),
|
this.name = const Value.absent(),
|
||||||
|
this.createdAt = const Value.absent(),
|
||||||
this.rowid = const Value.absent(),
|
this.rowid = const Value.absent(),
|
||||||
});
|
});
|
||||||
GroupTableCompanion.insert({
|
GroupTableCompanion.insert({
|
||||||
required String id,
|
required String id,
|
||||||
required String name,
|
required String name,
|
||||||
|
required DateTime createdAt,
|
||||||
this.rowid = const Value.absent(),
|
this.rowid = const Value.absent(),
|
||||||
}) : id = Value(id),
|
}) : id = Value(id),
|
||||||
name = Value(name);
|
name = Value(name),
|
||||||
|
createdAt = Value(createdAt);
|
||||||
static Insertable<GroupTableData> custom({
|
static Insertable<GroupTableData> custom({
|
||||||
Expression<String>? id,
|
Expression<String>? id,
|
||||||
Expression<String>? name,
|
Expression<String>? name,
|
||||||
|
Expression<DateTime>? createdAt,
|
||||||
Expression<int>? rowid,
|
Expression<int>? rowid,
|
||||||
}) {
|
}) {
|
||||||
return RawValuesInsertable({
|
return RawValuesInsertable({
|
||||||
if (id != null) 'id': id,
|
if (id != null) 'id': id,
|
||||||
if (name != null) 'name': name,
|
if (name != null) 'name': name,
|
||||||
|
if (createdAt != null) 'created_at': createdAt,
|
||||||
if (rowid != null) 'rowid': rowid,
|
if (rowid != null) 'rowid': rowid,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -378,11 +480,13 @@ class GroupTableCompanion extends UpdateCompanion<GroupTableData> {
|
|||||||
GroupTableCompanion copyWith({
|
GroupTableCompanion copyWith({
|
||||||
Value<String>? id,
|
Value<String>? id,
|
||||||
Value<String>? name,
|
Value<String>? name,
|
||||||
|
Value<DateTime>? createdAt,
|
||||||
Value<int>? rowid,
|
Value<int>? rowid,
|
||||||
}) {
|
}) {
|
||||||
return GroupTableCompanion(
|
return GroupTableCompanion(
|
||||||
id: id ?? this.id,
|
id: id ?? this.id,
|
||||||
name: name ?? this.name,
|
name: name ?? this.name,
|
||||||
|
createdAt: createdAt ?? this.createdAt,
|
||||||
rowid: rowid ?? this.rowid,
|
rowid: rowid ?? this.rowid,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -396,6 +500,9 @@ class GroupTableCompanion extends UpdateCompanion<GroupTableData> {
|
|||||||
if (name.present) {
|
if (name.present) {
|
||||||
map['name'] = Variable<String>(name.value);
|
map['name'] = Variable<String>(name.value);
|
||||||
}
|
}
|
||||||
|
if (createdAt.present) {
|
||||||
|
map['created_at'] = Variable<DateTime>(createdAt.value);
|
||||||
|
}
|
||||||
if (rowid.present) {
|
if (rowid.present) {
|
||||||
map['rowid'] = Variable<int>(rowid.value);
|
map['rowid'] = Variable<int>(rowid.value);
|
||||||
}
|
}
|
||||||
@@ -407,6 +514,7 @@ class GroupTableCompanion extends UpdateCompanion<GroupTableData> {
|
|||||||
return (StringBuffer('GroupTableCompanion(')
|
return (StringBuffer('GroupTableCompanion(')
|
||||||
..write('id: $id, ')
|
..write('id: $id, ')
|
||||||
..write('name: $name, ')
|
..write('name: $name, ')
|
||||||
|
..write('createdAt: $createdAt, ')
|
||||||
..write('rowid: $rowid')
|
..write('rowid: $rowid')
|
||||||
..write(')'))
|
..write(')'))
|
||||||
.toString();
|
.toString();
|
||||||
@@ -451,8 +559,19 @@ class $GameTableTable extends GameTable
|
|||||||
'REFERENCES player_table (id) ON DELETE CASCADE',
|
'REFERENCES player_table (id) ON DELETE CASCADE',
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
static const VerificationMeta _createdAtMeta = const VerificationMeta(
|
||||||
|
'createdAt',
|
||||||
|
);
|
||||||
@override
|
@override
|
||||||
List<GeneratedColumn> get $columns => [id, name, winnerId];
|
late final GeneratedColumn<DateTime> createdAt = GeneratedColumn<DateTime>(
|
||||||
|
'created_at',
|
||||||
|
aliasedName,
|
||||||
|
false,
|
||||||
|
type: DriftSqlType.dateTime,
|
||||||
|
requiredDuringInsert: true,
|
||||||
|
);
|
||||||
|
@override
|
||||||
|
List<GeneratedColumn> get $columns => [id, name, winnerId, createdAt];
|
||||||
@override
|
@override
|
||||||
String get aliasedName => _alias ?? actualTableName;
|
String get aliasedName => _alias ?? actualTableName;
|
||||||
@override
|
@override
|
||||||
@@ -486,6 +605,14 @@ class $GameTableTable extends GameTable
|
|||||||
} else if (isInserting) {
|
} else if (isInserting) {
|
||||||
context.missing(_winnerIdMeta);
|
context.missing(_winnerIdMeta);
|
||||||
}
|
}
|
||||||
|
if (data.containsKey('created_at')) {
|
||||||
|
context.handle(
|
||||||
|
_createdAtMeta,
|
||||||
|
createdAt.isAcceptableOrUnknown(data['created_at']!, _createdAtMeta),
|
||||||
|
);
|
||||||
|
} else if (isInserting) {
|
||||||
|
context.missing(_createdAtMeta);
|
||||||
|
}
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -507,6 +634,10 @@ class $GameTableTable extends GameTable
|
|||||||
DriftSqlType.string,
|
DriftSqlType.string,
|
||||||
data['${effectivePrefix}winner_id'],
|
data['${effectivePrefix}winner_id'],
|
||||||
)!,
|
)!,
|
||||||
|
createdAt: attachedDatabase.typeMapping.read(
|
||||||
|
DriftSqlType.dateTime,
|
||||||
|
data['${effectivePrefix}created_at'],
|
||||||
|
)!,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -520,10 +651,12 @@ class GameTableData extends DataClass implements Insertable<GameTableData> {
|
|||||||
final String id;
|
final String id;
|
||||||
final String name;
|
final String name;
|
||||||
final String winnerId;
|
final String winnerId;
|
||||||
|
final DateTime createdAt;
|
||||||
const GameTableData({
|
const GameTableData({
|
||||||
required this.id,
|
required this.id,
|
||||||
required this.name,
|
required this.name,
|
||||||
required this.winnerId,
|
required this.winnerId,
|
||||||
|
required this.createdAt,
|
||||||
});
|
});
|
||||||
@override
|
@override
|
||||||
Map<String, Expression> toColumns(bool nullToAbsent) {
|
Map<String, Expression> toColumns(bool nullToAbsent) {
|
||||||
@@ -531,6 +664,7 @@ class GameTableData extends DataClass implements Insertable<GameTableData> {
|
|||||||
map['id'] = Variable<String>(id);
|
map['id'] = Variable<String>(id);
|
||||||
map['name'] = Variable<String>(name);
|
map['name'] = Variable<String>(name);
|
||||||
map['winner_id'] = Variable<String>(winnerId);
|
map['winner_id'] = Variable<String>(winnerId);
|
||||||
|
map['created_at'] = Variable<DateTime>(createdAt);
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -539,6 +673,7 @@ class GameTableData extends DataClass implements Insertable<GameTableData> {
|
|||||||
id: Value(id),
|
id: Value(id),
|
||||||
name: Value(name),
|
name: Value(name),
|
||||||
winnerId: Value(winnerId),
|
winnerId: Value(winnerId),
|
||||||
|
createdAt: Value(createdAt),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -551,6 +686,7 @@ class GameTableData extends DataClass implements Insertable<GameTableData> {
|
|||||||
id: serializer.fromJson<String>(json['id']),
|
id: serializer.fromJson<String>(json['id']),
|
||||||
name: serializer.fromJson<String>(json['name']),
|
name: serializer.fromJson<String>(json['name']),
|
||||||
winnerId: serializer.fromJson<String>(json['winnerId']),
|
winnerId: serializer.fromJson<String>(json['winnerId']),
|
||||||
|
createdAt: serializer.fromJson<DateTime>(json['createdAt']),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@override
|
@override
|
||||||
@@ -560,20 +696,27 @@ class GameTableData extends DataClass implements Insertable<GameTableData> {
|
|||||||
'id': serializer.toJson<String>(id),
|
'id': serializer.toJson<String>(id),
|
||||||
'name': serializer.toJson<String>(name),
|
'name': serializer.toJson<String>(name),
|
||||||
'winnerId': serializer.toJson<String>(winnerId),
|
'winnerId': serializer.toJson<String>(winnerId),
|
||||||
|
'createdAt': serializer.toJson<DateTime>(createdAt),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
GameTableData copyWith({String? id, String? name, String? winnerId}) =>
|
GameTableData copyWith({
|
||||||
GameTableData(
|
String? id,
|
||||||
|
String? name,
|
||||||
|
String? winnerId,
|
||||||
|
DateTime? createdAt,
|
||||||
|
}) => GameTableData(
|
||||||
id: id ?? this.id,
|
id: id ?? this.id,
|
||||||
name: name ?? this.name,
|
name: name ?? this.name,
|
||||||
winnerId: winnerId ?? this.winnerId,
|
winnerId: winnerId ?? this.winnerId,
|
||||||
|
createdAt: createdAt ?? this.createdAt,
|
||||||
);
|
);
|
||||||
GameTableData copyWithCompanion(GameTableCompanion data) {
|
GameTableData copyWithCompanion(GameTableCompanion data) {
|
||||||
return GameTableData(
|
return GameTableData(
|
||||||
id: data.id.present ? data.id.value : this.id,
|
id: data.id.present ? data.id.value : this.id,
|
||||||
name: data.name.present ? data.name.value : this.name,
|
name: data.name.present ? data.name.value : this.name,
|
||||||
winnerId: data.winnerId.present ? data.winnerId.value : this.winnerId,
|
winnerId: data.winnerId.present ? data.winnerId.value : this.winnerId,
|
||||||
|
createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -582,51 +725,59 @@ class GameTableData extends DataClass implements Insertable<GameTableData> {
|
|||||||
return (StringBuffer('GameTableData(')
|
return (StringBuffer('GameTableData(')
|
||||||
..write('id: $id, ')
|
..write('id: $id, ')
|
||||||
..write('name: $name, ')
|
..write('name: $name, ')
|
||||||
..write('winnerId: $winnerId')
|
..write('winnerId: $winnerId, ')
|
||||||
|
..write('createdAt: $createdAt')
|
||||||
..write(')'))
|
..write(')'))
|
||||||
.toString();
|
.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(id, name, winnerId);
|
int get hashCode => Object.hash(id, name, winnerId, createdAt);
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) =>
|
bool operator ==(Object other) =>
|
||||||
identical(this, other) ||
|
identical(this, other) ||
|
||||||
(other is GameTableData &&
|
(other is GameTableData &&
|
||||||
other.id == this.id &&
|
other.id == this.id &&
|
||||||
other.name == this.name &&
|
other.name == this.name &&
|
||||||
other.winnerId == this.winnerId);
|
other.winnerId == this.winnerId &&
|
||||||
|
other.createdAt == this.createdAt);
|
||||||
}
|
}
|
||||||
|
|
||||||
class GameTableCompanion extends UpdateCompanion<GameTableData> {
|
class GameTableCompanion extends UpdateCompanion<GameTableData> {
|
||||||
final Value<String> id;
|
final Value<String> id;
|
||||||
final Value<String> name;
|
final Value<String> name;
|
||||||
final Value<String> winnerId;
|
final Value<String> winnerId;
|
||||||
|
final Value<DateTime> createdAt;
|
||||||
final Value<int> rowid;
|
final Value<int> rowid;
|
||||||
const GameTableCompanion({
|
const GameTableCompanion({
|
||||||
this.id = const Value.absent(),
|
this.id = const Value.absent(),
|
||||||
this.name = const Value.absent(),
|
this.name = const Value.absent(),
|
||||||
this.winnerId = const Value.absent(),
|
this.winnerId = const Value.absent(),
|
||||||
|
this.createdAt = const Value.absent(),
|
||||||
this.rowid = const Value.absent(),
|
this.rowid = const Value.absent(),
|
||||||
});
|
});
|
||||||
GameTableCompanion.insert({
|
GameTableCompanion.insert({
|
||||||
required String id,
|
required String id,
|
||||||
required String name,
|
required String name,
|
||||||
required String winnerId,
|
required String winnerId,
|
||||||
|
required DateTime createdAt,
|
||||||
this.rowid = const Value.absent(),
|
this.rowid = const Value.absent(),
|
||||||
}) : id = Value(id),
|
}) : id = Value(id),
|
||||||
name = Value(name),
|
name = Value(name),
|
||||||
winnerId = Value(winnerId);
|
winnerId = Value(winnerId),
|
||||||
|
createdAt = Value(createdAt);
|
||||||
static Insertable<GameTableData> custom({
|
static Insertable<GameTableData> custom({
|
||||||
Expression<String>? id,
|
Expression<String>? id,
|
||||||
Expression<String>? name,
|
Expression<String>? name,
|
||||||
Expression<String>? winnerId,
|
Expression<String>? winnerId,
|
||||||
|
Expression<DateTime>? createdAt,
|
||||||
Expression<int>? rowid,
|
Expression<int>? rowid,
|
||||||
}) {
|
}) {
|
||||||
return RawValuesInsertable({
|
return RawValuesInsertable({
|
||||||
if (id != null) 'id': id,
|
if (id != null) 'id': id,
|
||||||
if (name != null) 'name': name,
|
if (name != null) 'name': name,
|
||||||
if (winnerId != null) 'winner_id': winnerId,
|
if (winnerId != null) 'winner_id': winnerId,
|
||||||
|
if (createdAt != null) 'created_at': createdAt,
|
||||||
if (rowid != null) 'rowid': rowid,
|
if (rowid != null) 'rowid': rowid,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -635,12 +786,14 @@ class GameTableCompanion extends UpdateCompanion<GameTableData> {
|
|||||||
Value<String>? id,
|
Value<String>? id,
|
||||||
Value<String>? name,
|
Value<String>? name,
|
||||||
Value<String>? winnerId,
|
Value<String>? winnerId,
|
||||||
|
Value<DateTime>? createdAt,
|
||||||
Value<int>? rowid,
|
Value<int>? rowid,
|
||||||
}) {
|
}) {
|
||||||
return GameTableCompanion(
|
return GameTableCompanion(
|
||||||
id: id ?? this.id,
|
id: id ?? this.id,
|
||||||
name: name ?? this.name,
|
name: name ?? this.name,
|
||||||
winnerId: winnerId ?? this.winnerId,
|
winnerId: winnerId ?? this.winnerId,
|
||||||
|
createdAt: createdAt ?? this.createdAt,
|
||||||
rowid: rowid ?? this.rowid,
|
rowid: rowid ?? this.rowid,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -657,6 +810,9 @@ class GameTableCompanion extends UpdateCompanion<GameTableData> {
|
|||||||
if (winnerId.present) {
|
if (winnerId.present) {
|
||||||
map['winner_id'] = Variable<String>(winnerId.value);
|
map['winner_id'] = Variable<String>(winnerId.value);
|
||||||
}
|
}
|
||||||
|
if (createdAt.present) {
|
||||||
|
map['created_at'] = Variable<DateTime>(createdAt.value);
|
||||||
|
}
|
||||||
if (rowid.present) {
|
if (rowid.present) {
|
||||||
map['rowid'] = Variable<int>(rowid.value);
|
map['rowid'] = Variable<int>(rowid.value);
|
||||||
}
|
}
|
||||||
@@ -669,6 +825,7 @@ class GameTableCompanion extends UpdateCompanion<GameTableData> {
|
|||||||
..write('id: $id, ')
|
..write('id: $id, ')
|
||||||
..write('name: $name, ')
|
..write('name: $name, ')
|
||||||
..write('winnerId: $winnerId, ')
|
..write('winnerId: $winnerId, ')
|
||||||
|
..write('createdAt: $createdAt, ')
|
||||||
..write('rowid: $rowid')
|
..write('rowid: $rowid')
|
||||||
..write(')'))
|
..write(')'))
|
||||||
.toString();
|
.toString();
|
||||||
@@ -1437,12 +1594,14 @@ typedef $$PlayerTableTableCreateCompanionBuilder =
|
|||||||
PlayerTableCompanion Function({
|
PlayerTableCompanion Function({
|
||||||
required String id,
|
required String id,
|
||||||
required String name,
|
required String name,
|
||||||
|
required DateTime createdAt,
|
||||||
Value<int> rowid,
|
Value<int> rowid,
|
||||||
});
|
});
|
||||||
typedef $$PlayerTableTableUpdateCompanionBuilder =
|
typedef $$PlayerTableTableUpdateCompanionBuilder =
|
||||||
PlayerTableCompanion Function({
|
PlayerTableCompanion Function({
|
||||||
Value<String> id,
|
Value<String> id,
|
||||||
Value<String> name,
|
Value<String> name,
|
||||||
|
Value<DateTime> createdAt,
|
||||||
Value<int> rowid,
|
Value<int> rowid,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1534,6 +1693,11 @@ class $$PlayerTableTableFilterComposer
|
|||||||
builder: (column) => ColumnFilters(column),
|
builder: (column) => ColumnFilters(column),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ColumnFilters<DateTime> get createdAt => $composableBuilder(
|
||||||
|
column: $table.createdAt,
|
||||||
|
builder: (column) => ColumnFilters(column),
|
||||||
|
);
|
||||||
|
|
||||||
Expression<bool> gameTableRefs(
|
Expression<bool> gameTableRefs(
|
||||||
Expression<bool> Function($$GameTableTableFilterComposer f) f,
|
Expression<bool> Function($$GameTableTableFilterComposer f) f,
|
||||||
) {
|
) {
|
||||||
@@ -1628,6 +1792,11 @@ class $$PlayerTableTableOrderingComposer
|
|||||||
column: $table.name,
|
column: $table.name,
|
||||||
builder: (column) => ColumnOrderings(column),
|
builder: (column) => ColumnOrderings(column),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ColumnOrderings<DateTime> get createdAt => $composableBuilder(
|
||||||
|
column: $table.createdAt,
|
||||||
|
builder: (column) => ColumnOrderings(column),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
class $$PlayerTableTableAnnotationComposer
|
class $$PlayerTableTableAnnotationComposer
|
||||||
@@ -1645,6 +1814,9 @@ class $$PlayerTableTableAnnotationComposer
|
|||||||
GeneratedColumn<String> get name =>
|
GeneratedColumn<String> get name =>
|
||||||
$composableBuilder(column: $table.name, builder: (column) => column);
|
$composableBuilder(column: $table.name, builder: (column) => column);
|
||||||
|
|
||||||
|
GeneratedColumn<DateTime> get createdAt =>
|
||||||
|
$composableBuilder(column: $table.createdAt, builder: (column) => column);
|
||||||
|
|
||||||
Expression<T> gameTableRefs<T extends Object>(
|
Expression<T> gameTableRefs<T extends Object>(
|
||||||
Expression<T> Function($$GameTableTableAnnotationComposer a) f,
|
Expression<T> Function($$GameTableTableAnnotationComposer a) f,
|
||||||
) {
|
) {
|
||||||
@@ -1755,15 +1927,26 @@ class $$PlayerTableTableTableManager
|
|||||||
({
|
({
|
||||||
Value<String> id = const Value.absent(),
|
Value<String> id = const Value.absent(),
|
||||||
Value<String> name = const Value.absent(),
|
Value<String> name = const Value.absent(),
|
||||||
|
Value<DateTime> createdAt = const Value.absent(),
|
||||||
Value<int> rowid = const Value.absent(),
|
Value<int> rowid = const Value.absent(),
|
||||||
}) => PlayerTableCompanion(id: id, name: name, rowid: rowid),
|
}) => PlayerTableCompanion(
|
||||||
|
id: id,
|
||||||
|
name: name,
|
||||||
|
createdAt: createdAt,
|
||||||
|
rowid: rowid,
|
||||||
|
),
|
||||||
createCompanionCallback:
|
createCompanionCallback:
|
||||||
({
|
({
|
||||||
required String id,
|
required String id,
|
||||||
required String name,
|
required String name,
|
||||||
|
required DateTime createdAt,
|
||||||
Value<int> rowid = const Value.absent(),
|
Value<int> rowid = const Value.absent(),
|
||||||
}) =>
|
}) => PlayerTableCompanion.insert(
|
||||||
PlayerTableCompanion.insert(id: id, name: name, rowid: rowid),
|
id: id,
|
||||||
|
name: name,
|
||||||
|
createdAt: createdAt,
|
||||||
|
rowid: rowid,
|
||||||
|
),
|
||||||
withReferenceMapper: (p0) => p0
|
withReferenceMapper: (p0) => p0
|
||||||
.map(
|
.map(
|
||||||
(e) => (
|
(e) => (
|
||||||
@@ -1881,12 +2064,14 @@ typedef $$GroupTableTableCreateCompanionBuilder =
|
|||||||
GroupTableCompanion Function({
|
GroupTableCompanion Function({
|
||||||
required String id,
|
required String id,
|
||||||
required String name,
|
required String name,
|
||||||
|
required DateTime createdAt,
|
||||||
Value<int> rowid,
|
Value<int> rowid,
|
||||||
});
|
});
|
||||||
typedef $$GroupTableTableUpdateCompanionBuilder =
|
typedef $$GroupTableTableUpdateCompanionBuilder =
|
||||||
GroupTableCompanion Function({
|
GroupTableCompanion Function({
|
||||||
Value<String> id,
|
Value<String> id,
|
||||||
Value<String> name,
|
Value<String> name,
|
||||||
|
Value<DateTime> createdAt,
|
||||||
Value<int> rowid,
|
Value<int> rowid,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1958,6 +2143,11 @@ class $$GroupTableTableFilterComposer
|
|||||||
builder: (column) => ColumnFilters(column),
|
builder: (column) => ColumnFilters(column),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ColumnFilters<DateTime> get createdAt => $composableBuilder(
|
||||||
|
column: $table.createdAt,
|
||||||
|
builder: (column) => ColumnFilters(column),
|
||||||
|
);
|
||||||
|
|
||||||
Expression<bool> playerGroupTableRefs(
|
Expression<bool> playerGroupTableRefs(
|
||||||
Expression<bool> Function($$PlayerGroupTableTableFilterComposer f) f,
|
Expression<bool> Function($$PlayerGroupTableTableFilterComposer f) f,
|
||||||
) {
|
) {
|
||||||
@@ -2027,6 +2217,11 @@ class $$GroupTableTableOrderingComposer
|
|||||||
column: $table.name,
|
column: $table.name,
|
||||||
builder: (column) => ColumnOrderings(column),
|
builder: (column) => ColumnOrderings(column),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ColumnOrderings<DateTime> get createdAt => $composableBuilder(
|
||||||
|
column: $table.createdAt,
|
||||||
|
builder: (column) => ColumnOrderings(column),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
class $$GroupTableTableAnnotationComposer
|
class $$GroupTableTableAnnotationComposer
|
||||||
@@ -2044,6 +2239,9 @@ class $$GroupTableTableAnnotationComposer
|
|||||||
GeneratedColumn<String> get name =>
|
GeneratedColumn<String> get name =>
|
||||||
$composableBuilder(column: $table.name, builder: (column) => column);
|
$composableBuilder(column: $table.name, builder: (column) => column);
|
||||||
|
|
||||||
|
GeneratedColumn<DateTime> get createdAt =>
|
||||||
|
$composableBuilder(column: $table.createdAt, builder: (column) => column);
|
||||||
|
|
||||||
Expression<T> playerGroupTableRefs<T extends Object>(
|
Expression<T> playerGroupTableRefs<T extends Object>(
|
||||||
Expression<T> Function($$PlayerGroupTableTableAnnotationComposer a) f,
|
Expression<T> Function($$PlayerGroupTableTableAnnotationComposer a) f,
|
||||||
) {
|
) {
|
||||||
@@ -2128,15 +2326,26 @@ class $$GroupTableTableTableManager
|
|||||||
({
|
({
|
||||||
Value<String> id = const Value.absent(),
|
Value<String> id = const Value.absent(),
|
||||||
Value<String> name = const Value.absent(),
|
Value<String> name = const Value.absent(),
|
||||||
|
Value<DateTime> createdAt = const Value.absent(),
|
||||||
Value<int> rowid = const Value.absent(),
|
Value<int> rowid = const Value.absent(),
|
||||||
}) => GroupTableCompanion(id: id, name: name, rowid: rowid),
|
}) => GroupTableCompanion(
|
||||||
|
id: id,
|
||||||
|
name: name,
|
||||||
|
createdAt: createdAt,
|
||||||
|
rowid: rowid,
|
||||||
|
),
|
||||||
createCompanionCallback:
|
createCompanionCallback:
|
||||||
({
|
({
|
||||||
required String id,
|
required String id,
|
||||||
required String name,
|
required String name,
|
||||||
|
required DateTime createdAt,
|
||||||
Value<int> rowid = const Value.absent(),
|
Value<int> rowid = const Value.absent(),
|
||||||
}) =>
|
}) => GroupTableCompanion.insert(
|
||||||
GroupTableCompanion.insert(id: id, name: name, rowid: rowid),
|
id: id,
|
||||||
|
name: name,
|
||||||
|
createdAt: createdAt,
|
||||||
|
rowid: rowid,
|
||||||
|
),
|
||||||
withReferenceMapper: (p0) => p0
|
withReferenceMapper: (p0) => p0
|
||||||
.map(
|
.map(
|
||||||
(e) => (
|
(e) => (
|
||||||
@@ -2228,6 +2437,7 @@ typedef $$GameTableTableCreateCompanionBuilder =
|
|||||||
required String id,
|
required String id,
|
||||||
required String name,
|
required String name,
|
||||||
required String winnerId,
|
required String winnerId,
|
||||||
|
required DateTime createdAt,
|
||||||
Value<int> rowid,
|
Value<int> rowid,
|
||||||
});
|
});
|
||||||
typedef $$GameTableTableUpdateCompanionBuilder =
|
typedef $$GameTableTableUpdateCompanionBuilder =
|
||||||
@@ -2235,6 +2445,7 @@ typedef $$GameTableTableUpdateCompanionBuilder =
|
|||||||
Value<String> id,
|
Value<String> id,
|
||||||
Value<String> name,
|
Value<String> name,
|
||||||
Value<String> winnerId,
|
Value<String> winnerId,
|
||||||
|
Value<DateTime> createdAt,
|
||||||
Value<int> rowid,
|
Value<int> rowid,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -2319,6 +2530,11 @@ class $$GameTableTableFilterComposer
|
|||||||
builder: (column) => ColumnFilters(column),
|
builder: (column) => ColumnFilters(column),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ColumnFilters<DateTime> get createdAt => $composableBuilder(
|
||||||
|
column: $table.createdAt,
|
||||||
|
builder: (column) => ColumnFilters(column),
|
||||||
|
);
|
||||||
|
|
||||||
$$PlayerTableTableFilterComposer get winnerId {
|
$$PlayerTableTableFilterComposer get winnerId {
|
||||||
final $$PlayerTableTableFilterComposer composer = $composerBuilder(
|
final $$PlayerTableTableFilterComposer composer = $composerBuilder(
|
||||||
composer: this,
|
composer: this,
|
||||||
@@ -2412,6 +2628,11 @@ class $$GameTableTableOrderingComposer
|
|||||||
builder: (column) => ColumnOrderings(column),
|
builder: (column) => ColumnOrderings(column),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ColumnOrderings<DateTime> get createdAt => $composableBuilder(
|
||||||
|
column: $table.createdAt,
|
||||||
|
builder: (column) => ColumnOrderings(column),
|
||||||
|
);
|
||||||
|
|
||||||
$$PlayerTableTableOrderingComposer get winnerId {
|
$$PlayerTableTableOrderingComposer get winnerId {
|
||||||
final $$PlayerTableTableOrderingComposer composer = $composerBuilder(
|
final $$PlayerTableTableOrderingComposer composer = $composerBuilder(
|
||||||
composer: this,
|
composer: this,
|
||||||
@@ -2451,6 +2672,9 @@ class $$GameTableTableAnnotationComposer
|
|||||||
GeneratedColumn<String> get name =>
|
GeneratedColumn<String> get name =>
|
||||||
$composableBuilder(column: $table.name, builder: (column) => column);
|
$composableBuilder(column: $table.name, builder: (column) => column);
|
||||||
|
|
||||||
|
GeneratedColumn<DateTime> get createdAt =>
|
||||||
|
$composableBuilder(column: $table.createdAt, builder: (column) => column);
|
||||||
|
|
||||||
$$PlayerTableTableAnnotationComposer get winnerId {
|
$$PlayerTableTableAnnotationComposer get winnerId {
|
||||||
final $$PlayerTableTableAnnotationComposer composer = $composerBuilder(
|
final $$PlayerTableTableAnnotationComposer composer = $composerBuilder(
|
||||||
composer: this,
|
composer: this,
|
||||||
@@ -2560,11 +2784,13 @@ class $$GameTableTableTableManager
|
|||||||
Value<String> id = const Value.absent(),
|
Value<String> id = const Value.absent(),
|
||||||
Value<String> name = const Value.absent(),
|
Value<String> name = const Value.absent(),
|
||||||
Value<String> winnerId = const Value.absent(),
|
Value<String> winnerId = const Value.absent(),
|
||||||
|
Value<DateTime> createdAt = const Value.absent(),
|
||||||
Value<int> rowid = const Value.absent(),
|
Value<int> rowid = const Value.absent(),
|
||||||
}) => GameTableCompanion(
|
}) => GameTableCompanion(
|
||||||
id: id,
|
id: id,
|
||||||
name: name,
|
name: name,
|
||||||
winnerId: winnerId,
|
winnerId: winnerId,
|
||||||
|
createdAt: createdAt,
|
||||||
rowid: rowid,
|
rowid: rowid,
|
||||||
),
|
),
|
||||||
createCompanionCallback:
|
createCompanionCallback:
|
||||||
@@ -2572,11 +2798,13 @@ class $$GameTableTableTableManager
|
|||||||
required String id,
|
required String id,
|
||||||
required String name,
|
required String name,
|
||||||
required String winnerId,
|
required String winnerId,
|
||||||
|
required DateTime createdAt,
|
||||||
Value<int> rowid = const Value.absent(),
|
Value<int> rowid = const Value.absent(),
|
||||||
}) => GameTableCompanion.insert(
|
}) => GameTableCompanion.insert(
|
||||||
id: id,
|
id: id,
|
||||||
name: name,
|
name: name,
|
||||||
winnerId: winnerId,
|
winnerId: winnerId,
|
||||||
|
createdAt: createdAt,
|
||||||
rowid: rowid,
|
rowid: rowid,
|
||||||
),
|
),
|
||||||
withReferenceMapper: (p0) => p0
|
withReferenceMapper: (p0) => p0
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ class GameTable extends Table {
|
|||||||
TextColumn get name => text()();
|
TextColumn get name => text()();
|
||||||
TextColumn get winnerId =>
|
TextColumn get winnerId =>
|
||||||
text().references(PlayerTable, #id, onDelete: KeyAction.cascade)();
|
text().references(PlayerTable, #id, onDelete: KeyAction.cascade)();
|
||||||
|
DateTimeColumn get createdAt => dateTime()();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Set<Column<Object>> get primaryKey => {id};
|
Set<Column<Object>> get primaryKey => {id};
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import 'package:drift/drift.dart';
|
|||||||
class GroupTable extends Table {
|
class GroupTable extends Table {
|
||||||
TextColumn get id => text()();
|
TextColumn get id => text()();
|
||||||
TextColumn get name => text()();
|
TextColumn get name => text()();
|
||||||
|
DateTimeColumn get createdAt => dateTime()();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Set<Column<Object>> get primaryKey => {id};
|
Set<Column<Object>> get primaryKey => {id};
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import 'package:drift/drift.dart';
|
|||||||
class PlayerTable extends Table {
|
class PlayerTable extends Table {
|
||||||
TextColumn get id => text()();
|
TextColumn get id => text()();
|
||||||
TextColumn get name => text()();
|
TextColumn get name => text()();
|
||||||
|
DateTimeColumn get createdAt => dateTime()();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Set<Column<Object>> get primaryKey => {id};
|
Set<Column<Object>> get primaryKey => {id};
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import 'package:clock/clock.dart';
|
||||||
import 'package:game_tracker/data/dto/group.dart';
|
import 'package:game_tracker/data/dto/group.dart';
|
||||||
import 'package:game_tracker/data/dto/player.dart';
|
import 'package:game_tracker/data/dto/player.dart';
|
||||||
import 'package:uuid/uuid.dart';
|
import 'package:uuid/uuid.dart';
|
||||||
@@ -8,14 +9,17 @@ class Game {
|
|||||||
final List<Player>? players;
|
final List<Player>? players;
|
||||||
final Group? group;
|
final Group? group;
|
||||||
final String winner;
|
final String winner;
|
||||||
|
final DateTime createdAt;
|
||||||
|
|
||||||
Game({
|
Game({
|
||||||
String? id,
|
String? id,
|
||||||
|
DateTime? createdAt,
|
||||||
required this.name,
|
required this.name,
|
||||||
this.players,
|
this.players,
|
||||||
this.group,
|
this.group,
|
||||||
this.winner = '',
|
this.winner = '',
|
||||||
}) : id = id ?? const Uuid().v4();
|
}) : id = id ?? const Uuid().v4(),
|
||||||
|
createdAt = createdAt ?? clock.now();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import 'package:clock/clock.dart';
|
||||||
import 'package:game_tracker/data/dto/player.dart';
|
import 'package:game_tracker/data/dto/player.dart';
|
||||||
import 'package:uuid/uuid.dart';
|
import 'package:uuid/uuid.dart';
|
||||||
|
|
||||||
@@ -5,9 +6,15 @@ class Group {
|
|||||||
final String id;
|
final String id;
|
||||||
final String name;
|
final String name;
|
||||||
final List<Player> members;
|
final List<Player> members;
|
||||||
|
final DateTime createdAt;
|
||||||
|
|
||||||
Group({String? id, required this.name, required this.members})
|
Group({
|
||||||
: id = id ?? const Uuid().v4();
|
String? id,
|
||||||
|
DateTime? createdAt,
|
||||||
|
required this.name,
|
||||||
|
required this.members,
|
||||||
|
}) : id = id ?? const Uuid().v4(),
|
||||||
|
createdAt = createdAt ?? clock.now();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
|
import 'package:clock/clock.dart';
|
||||||
import 'package:uuid/uuid.dart';
|
import 'package:uuid/uuid.dart';
|
||||||
|
|
||||||
class Player {
|
class Player {
|
||||||
final String id;
|
final String id;
|
||||||
final String name;
|
final String name;
|
||||||
|
final DateTime createdAt;
|
||||||
|
|
||||||
Player({String? id, required this.name}) : id = id ?? const Uuid().v4();
|
Player({String? id, DateTime? createdAt, required this.name})
|
||||||
|
: id = id ?? const Uuid().v4(),
|
||||||
|
createdAt = createdAt ?? clock.now();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
|
|||||||
386
lib/presentation/views/main_menu/create_group_view.dart
Normal file
386
lib/presentation/views/main_menu/create_group_view.dart
Normal file
@@ -0,0 +1,386 @@
|
|||||||
|
import 'package:flutter/material.dart' hide ButtonStyle;
|
||||||
|
import 'package:game_tracker/core/custom_theme.dart';
|
||||||
|
import 'package:game_tracker/core/enums.dart';
|
||||||
|
import 'package:game_tracker/data/db/database.dart';
|
||||||
|
import 'package:game_tracker/data/dto/group.dart';
|
||||||
|
import 'package:game_tracker/data/dto/player.dart';
|
||||||
|
import 'package:game_tracker/presentation/widgets/buttons/custom_width_button.dart';
|
||||||
|
import 'package:game_tracker/presentation/widgets/custom_search_bar.dart';
|
||||||
|
import 'package:game_tracker/presentation/widgets/text_input_field.dart';
|
||||||
|
import 'package:game_tracker/presentation/widgets/tiles/text_icon_list_tile.dart';
|
||||||
|
import 'package:game_tracker/presentation/widgets/tiles/text_icon_tile.dart';
|
||||||
|
import 'package:game_tracker/presentation/widgets/top_centered_message.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:skeletonizer/skeletonizer.dart';
|
||||||
|
|
||||||
|
class CreateGroupView extends StatefulWidget {
|
||||||
|
const CreateGroupView({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<CreateGroupView> createState() => _CreateGroupViewState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CreateGroupViewState extends State<CreateGroupView> {
|
||||||
|
List<Player> selectedPlayers = [];
|
||||||
|
List<Player> suggestedPlayers = [];
|
||||||
|
List<Player> allPlayers = [];
|
||||||
|
late final AppDatabase db;
|
||||||
|
late Future<List<Player>> _allPlayersFuture;
|
||||||
|
late final List<Player> skeletonData = List.filled(
|
||||||
|
7,
|
||||||
|
Player(name: 'Player 0'),
|
||||||
|
);
|
||||||
|
final _groupNameController = TextEditingController();
|
||||||
|
final _searchBarController = TextEditingController();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
db = Provider.of<AppDatabase>(context, listen: false);
|
||||||
|
_searchBarController.addListener(() {
|
||||||
|
setState(() {});
|
||||||
|
});
|
||||||
|
_groupNameController.addListener(() {
|
||||||
|
setState(() {});
|
||||||
|
});
|
||||||
|
loadPlayerList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_groupNameController.dispose();
|
||||||
|
_searchBarController
|
||||||
|
.dispose(); // Listener entfernen und Controller aufräumen
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loadPlayerList() {
|
||||||
|
_allPlayersFuture = db.playerDao.getAllPlayers();
|
||||||
|
_allPlayersFuture.then((loadedPlayers) {
|
||||||
|
setState(() {
|
||||||
|
loadedPlayers.sort((a, b) => a.name.compareTo(b.name));
|
||||||
|
allPlayers = [...loadedPlayers];
|
||||||
|
suggestedPlayers = [...loadedPlayers];
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return SafeArea(
|
||||||
|
child: Scaffold(
|
||||||
|
backgroundColor: CustomTheme.backgroundColor,
|
||||||
|
appBar: AppBar(
|
||||||
|
backgroundColor: CustomTheme.backgroundColor,
|
||||||
|
scrolledUnderElevation: 0,
|
||||||
|
title: const Text(
|
||||||
|
'Create new group',
|
||||||
|
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
centerTitle: true,
|
||||||
|
),
|
||||||
|
body: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
margin: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
|
||||||
|
child: TextInputField(
|
||||||
|
controller: _groupNameController,
|
||||||
|
hintText: 'Group name',
|
||||||
|
onChanged: (value) {
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Container(
|
||||||
|
margin: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 12,
|
||||||
|
vertical: 10,
|
||||||
|
),
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
vertical: 10,
|
||||||
|
horizontal: 10,
|
||||||
|
),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: CustomTheme.boxColor,
|
||||||
|
border: Border.all(color: CustomTheme.boxBorder),
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
CustomSearchBar(
|
||||||
|
controller: _searchBarController,
|
||||||
|
constraints: const BoxConstraints(
|
||||||
|
maxHeight: 45,
|
||||||
|
minHeight: 45,
|
||||||
|
),
|
||||||
|
hintText: 'Search for players',
|
||||||
|
trailingButtonShown: true,
|
||||||
|
trailingButtonicon: Icons.add_circle,
|
||||||
|
trailingButtonEnabled: _searchBarController.text
|
||||||
|
.trim()
|
||||||
|
.isNotEmpty,
|
||||||
|
onTrailingButtonPressed: () async {
|
||||||
|
addNewPlayerFromSearch(
|
||||||
|
context: context,
|
||||||
|
searchBarController: _searchBarController,
|
||||||
|
db: db,
|
||||||
|
loadPlayerList: loadPlayerList,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
onChanged: (value) {
|
||||||
|
setState(() {
|
||||||
|
if (value.isEmpty) {
|
||||||
|
suggestedPlayers = allPlayers.where((player) {
|
||||||
|
return !selectedPlayers.contains(player);
|
||||||
|
}).toList();
|
||||||
|
} else {
|
||||||
|
suggestedPlayers = allPlayers.where((player) {
|
||||||
|
final bool nameMatches = player.name
|
||||||
|
.toLowerCase()
|
||||||
|
.contains(value.toLowerCase());
|
||||||
|
final bool isNotSelected = !selectedPlayers
|
||||||
|
.contains(player);
|
||||||
|
return nameMatches && isNotSelected;
|
||||||
|
}).toList();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
Text(
|
||||||
|
'Ausgewählte Spieler: (${selectedPlayers.length})',
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
Wrap(
|
||||||
|
alignment: WrapAlignment.start,
|
||||||
|
crossAxisAlignment: WrapCrossAlignment.start,
|
||||||
|
spacing: 8.0,
|
||||||
|
runSpacing: 8.0,
|
||||||
|
children: <Widget>[
|
||||||
|
for (var player in selectedPlayers)
|
||||||
|
TextIconTile(
|
||||||
|
text: player.name,
|
||||||
|
onIconTap: () {
|
||||||
|
setState(() {
|
||||||
|
final currentSearch = _searchBarController.text
|
||||||
|
.toLowerCase();
|
||||||
|
selectedPlayers.remove(player);
|
||||||
|
if (currentSearch.isEmpty ||
|
||||||
|
player.name.toLowerCase().contains(
|
||||||
|
currentSearch,
|
||||||
|
)) {
|
||||||
|
suggestedPlayers.add(player);
|
||||||
|
suggestedPlayers.sort(
|
||||||
|
(a, b) => a.name.compareTo(b.name),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
const Text(
|
||||||
|
'Alle Spieler:',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
FutureBuilder(
|
||||||
|
future: _allPlayersFuture,
|
||||||
|
builder:
|
||||||
|
(
|
||||||
|
BuildContext context,
|
||||||
|
AsyncSnapshot<List<Player>> snapshot,
|
||||||
|
) {
|
||||||
|
if (snapshot.hasError) {
|
||||||
|
return const Center(
|
||||||
|
child: TopCenteredMessage(
|
||||||
|
icon: Icons.report,
|
||||||
|
title: 'Error',
|
||||||
|
message: 'Player data couldn\'t\nbe loaded.',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (snapshot.connectionState ==
|
||||||
|
ConnectionState.done &&
|
||||||
|
(!snapshot.hasData ||
|
||||||
|
snapshot.data!.isEmpty ||
|
||||||
|
(selectedPlayers.isEmpty &&
|
||||||
|
allPlayers.isEmpty))) {
|
||||||
|
return const Center(
|
||||||
|
child: TopCenteredMessage(
|
||||||
|
icon: Icons.info,
|
||||||
|
title: 'Info',
|
||||||
|
message: 'No players created yet.',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
final bool isLoading =
|
||||||
|
snapshot.connectionState ==
|
||||||
|
ConnectionState.waiting;
|
||||||
|
return Expanded(
|
||||||
|
child: Skeletonizer(
|
||||||
|
effect: PulseEffect(
|
||||||
|
from: Colors.grey[800]!,
|
||||||
|
to: Colors.grey[600]!,
|
||||||
|
duration: const Duration(milliseconds: 800),
|
||||||
|
),
|
||||||
|
enabled: isLoading,
|
||||||
|
enableSwitchAnimation: true,
|
||||||
|
switchAnimationConfig:
|
||||||
|
const SwitchAnimationConfig(
|
||||||
|
duration: Duration(milliseconds: 200),
|
||||||
|
switchInCurve: Curves.linear,
|
||||||
|
switchOutCurve: Curves.linear,
|
||||||
|
transitionBuilder: AnimatedSwitcher
|
||||||
|
.defaultTransitionBuilder,
|
||||||
|
layoutBuilder:
|
||||||
|
AnimatedSwitcher.defaultLayoutBuilder,
|
||||||
|
),
|
||||||
|
child: Visibility(
|
||||||
|
visible:
|
||||||
|
(suggestedPlayers.isEmpty &&
|
||||||
|
allPlayers.isNotEmpty),
|
||||||
|
replacement: ListView.builder(
|
||||||
|
itemCount: suggestedPlayers.length,
|
||||||
|
itemBuilder:
|
||||||
|
(BuildContext context, int index) {
|
||||||
|
return TextIconListTile(
|
||||||
|
text: suggestedPlayers[index].name,
|
||||||
|
onPressed: () {
|
||||||
|
setState(() {
|
||||||
|
if (!selectedPlayers.contains(
|
||||||
|
suggestedPlayers[index],
|
||||||
|
)) {
|
||||||
|
selectedPlayers.add(
|
||||||
|
suggestedPlayers[index],
|
||||||
|
);
|
||||||
|
selectedPlayers.sort(
|
||||||
|
(a, b) => a.name.compareTo(
|
||||||
|
b.name,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
suggestedPlayers.remove(
|
||||||
|
suggestedPlayers[index],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
child: TopCenteredMessage(
|
||||||
|
icon: Icons.info,
|
||||||
|
title: 'Info',
|
||||||
|
message:
|
||||||
|
(selectedPlayers.length ==
|
||||||
|
allPlayers.length)
|
||||||
|
? 'No more players to add.'
|
||||||
|
: 'No players found with that name.',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
CustomWidthButton(
|
||||||
|
text: 'Create group',
|
||||||
|
sizeRelativeToWidth: 0.95,
|
||||||
|
buttonType: ButtonType.primary,
|
||||||
|
onPressed:
|
||||||
|
(_groupNameController.text.isEmpty || selectedPlayers.isEmpty)
|
||||||
|
? null
|
||||||
|
: () async {
|
||||||
|
bool success = await db.groupDao.addGroup(
|
||||||
|
group: Group(
|
||||||
|
name: _groupNameController.text.trim(),
|
||||||
|
members: selectedPlayers,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
if (!context.mounted) return;
|
||||||
|
if (success) {
|
||||||
|
_groupNameController.clear();
|
||||||
|
_searchBarController.clear();
|
||||||
|
selectedPlayers.clear();
|
||||||
|
Navigator.pop(context);
|
||||||
|
} else {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
backgroundColor: CustomTheme.boxColor,
|
||||||
|
content: const Center(
|
||||||
|
child: Text(
|
||||||
|
'Error while creating group, please try again',
|
||||||
|
style: TextStyle(color: Colors.white),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Adds a new player to the database from the search bar input.
|
||||||
|
/// Shows a snackbar indicating success or failure.
|
||||||
|
/// [context] - BuildContext to show the snackbar.
|
||||||
|
/// [searchBarController] - TextEditingController of the search bar.
|
||||||
|
/// [db] - AppDatabase instance to interact with the database.
|
||||||
|
/// [loadPlayerList] - Function to reload the player list after adding.
|
||||||
|
void addNewPlayerFromSearch({
|
||||||
|
required BuildContext context,
|
||||||
|
required TextEditingController searchBarController,
|
||||||
|
required AppDatabase db,
|
||||||
|
required Function loadPlayerList,
|
||||||
|
}) async {
|
||||||
|
String playerName = searchBarController.text.trim();
|
||||||
|
bool success = await db.playerDao.addPlayer(player: Player(name: playerName));
|
||||||
|
if (!context.mounted) return;
|
||||||
|
if (success) {
|
||||||
|
loadPlayerList();
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
backgroundColor: CustomTheme.boxColor,
|
||||||
|
content: Center(
|
||||||
|
child: Text(
|
||||||
|
'Successfully added player $playerName.',
|
||||||
|
style: const TextStyle(color: Colors.white),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
searchBarController.clear();
|
||||||
|
} else {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
backgroundColor: CustomTheme.boxColor,
|
||||||
|
content: Center(
|
||||||
|
child: Text(
|
||||||
|
'Could not add player $playerName.',
|
||||||
|
style: const TextStyle(color: Colors.white),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,7 +3,8 @@ import 'package:game_tracker/core/custom_theme.dart';
|
|||||||
import 'package:game_tracker/data/db/database.dart';
|
import 'package:game_tracker/data/db/database.dart';
|
||||||
import 'package:game_tracker/data/dto/group.dart';
|
import 'package:game_tracker/data/dto/group.dart';
|
||||||
import 'package:game_tracker/data/dto/player.dart';
|
import 'package:game_tracker/data/dto/player.dart';
|
||||||
import 'package:game_tracker/presentation/widgets/full_width_button.dart';
|
import 'package:game_tracker/presentation/views/main_menu/create_group_view.dart';
|
||||||
|
import 'package:game_tracker/presentation/widgets/buttons/custom_width_button.dart';
|
||||||
import 'package:game_tracker/presentation/widgets/tiles/group_tile.dart';
|
import 'package:game_tracker/presentation/widgets/tiles/group_tile.dart';
|
||||||
import 'package:game_tracker/presentation/widgets/top_centered_message.dart';
|
import 'package:game_tracker/presentation/widgets/top_centered_message.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
@@ -18,6 +19,7 @@ class GroupsView extends StatefulWidget {
|
|||||||
|
|
||||||
class _GroupsViewState extends State<GroupsView> {
|
class _GroupsViewState extends State<GroupsView> {
|
||||||
late Future<List<Group>> _allGroupsFuture;
|
late Future<List<Group>> _allGroupsFuture;
|
||||||
|
late final AppDatabase db;
|
||||||
|
|
||||||
final player = Player(name: 'Skeleton Player');
|
final player = Player(name: 'Skeleton Player');
|
||||||
late final List<Group> skeletonData = List.filled(
|
late final List<Group> skeletonData = List.filled(
|
||||||
@@ -31,7 +33,7 @@ class _GroupsViewState extends State<GroupsView> {
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
final db = Provider.of<AppDatabase>(context, listen: false);
|
db = Provider.of<AppDatabase>(context, listen: false);
|
||||||
_allGroupsFuture = db.groupDao.getAllGroups();
|
_allGroupsFuture = db.groupDao.getAllGroups();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,7 +104,23 @@ class _GroupsViewState extends State<GroupsView> {
|
|||||||
|
|
||||||
Positioned(
|
Positioned(
|
||||||
bottom: 80,
|
bottom: 80,
|
||||||
child: FullWidthButton(text: 'Create Group', onPressed: () {}),
|
child: CustomWidthButton(
|
||||||
|
text: 'Create Group',
|
||||||
|
sizeRelativeToWidth: 0.90,
|
||||||
|
onPressed: () async {
|
||||||
|
await Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) {
|
||||||
|
return const CreateGroupView();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
setState(() {
|
||||||
|
_allGroupsFuture = db.groupDao.getAllGroups();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:game_tracker/data/db/database.dart';
|
import 'package:game_tracker/data/db/database.dart';
|
||||||
import 'package:game_tracker/presentation/widgets/game_tile.dart';
|
import 'package:game_tracker/presentation/widgets/buttons/quick_create_button.dart';
|
||||||
import 'package:game_tracker/presentation/widgets/quick_create_button.dart';
|
import 'package:game_tracker/presentation/widgets/tiles/game_tile.dart';
|
||||||
import 'package:game_tracker/presentation/widgets/tiles/info_tile.dart';
|
import 'package:game_tracker/presentation/widgets/tiles/info_tile.dart';
|
||||||
import 'package:game_tracker/presentation/widgets/tiles/quick_info_tile.dart';
|
import 'package:game_tracker/presentation/widgets/tiles/quick_info_tile.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|||||||
120
lib/presentation/widgets/buttons/custom_width_button.dart
Normal file
120
lib/presentation/widgets/buttons/custom_width_button.dart
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:game_tracker/core/custom_theme.dart';
|
||||||
|
import 'package:game_tracker/core/enums.dart';
|
||||||
|
|
||||||
|
class CustomWidthButton extends StatelessWidget {
|
||||||
|
const CustomWidthButton({
|
||||||
|
super.key,
|
||||||
|
required this.text,
|
||||||
|
this.buttonType = ButtonType.primary,
|
||||||
|
required this.sizeRelativeToWidth,
|
||||||
|
this.onPressed,
|
||||||
|
});
|
||||||
|
|
||||||
|
final String text;
|
||||||
|
final double sizeRelativeToWidth;
|
||||||
|
final VoidCallback? onPressed;
|
||||||
|
final ButtonType buttonType;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final Color buttonBackgroundColor;
|
||||||
|
final Color disabledBackgroundColor;
|
||||||
|
final Color borderSideColor;
|
||||||
|
final Color textcolor;
|
||||||
|
final Color disabledTextColor;
|
||||||
|
|
||||||
|
if (buttonType == ButtonType.primary) {
|
||||||
|
textcolor = Colors.white;
|
||||||
|
disabledTextColor = Color.lerp(textcolor, Colors.black, 0.5)!;
|
||||||
|
buttonBackgroundColor = CustomTheme.primaryColor;
|
||||||
|
disabledBackgroundColor = Color.lerp(
|
||||||
|
buttonBackgroundColor,
|
||||||
|
Colors.black,
|
||||||
|
0.5,
|
||||||
|
)!;
|
||||||
|
|
||||||
|
return ElevatedButton(
|
||||||
|
onPressed: onPressed,
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
foregroundColor: textcolor,
|
||||||
|
disabledForegroundColor: disabledTextColor,
|
||||||
|
backgroundColor: buttonBackgroundColor,
|
||||||
|
disabledBackgroundColor: disabledBackgroundColor,
|
||||||
|
animationDuration: const Duration(),
|
||||||
|
minimumSize: Size(
|
||||||
|
MediaQuery.sizeOf(context).width * sizeRelativeToWidth,
|
||||||
|
60,
|
||||||
|
),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
text,
|
||||||
|
style: const TextStyle(fontWeight: FontWeight.w500, fontSize: 22),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else if (buttonType == ButtonType.secondary) {
|
||||||
|
textcolor = CustomTheme.primaryColor;
|
||||||
|
disabledTextColor = Color.lerp(textcolor, Colors.black, 0.5)!;
|
||||||
|
buttonBackgroundColor = Colors.transparent;
|
||||||
|
disabledBackgroundColor = Colors.transparent;
|
||||||
|
borderSideColor = onPressed != null
|
||||||
|
? CustomTheme.primaryColor
|
||||||
|
: Color.lerp(CustomTheme.primaryColor, Colors.black, 0.5)!;
|
||||||
|
|
||||||
|
return OutlinedButton(
|
||||||
|
onPressed: onPressed,
|
||||||
|
style: OutlinedButton.styleFrom(
|
||||||
|
foregroundColor: textcolor,
|
||||||
|
disabledForegroundColor: disabledTextColor,
|
||||||
|
backgroundColor: buttonBackgroundColor,
|
||||||
|
disabledBackgroundColor: disabledBackgroundColor,
|
||||||
|
animationDuration: const Duration(),
|
||||||
|
minimumSize: Size(
|
||||||
|
MediaQuery.sizeOf(context).width * sizeRelativeToWidth,
|
||||||
|
60,
|
||||||
|
),
|
||||||
|
side: BorderSide(color: borderSideColor, width: 2),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
text,
|
||||||
|
style: const TextStyle(fontWeight: FontWeight.w500, fontSize: 22),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
textcolor = CustomTheme.primaryColor;
|
||||||
|
disabledTextColor = Color.lerp(
|
||||||
|
CustomTheme.primaryColor,
|
||||||
|
Colors.black,
|
||||||
|
0.5,
|
||||||
|
)!;
|
||||||
|
buttonBackgroundColor = Colors.transparent;
|
||||||
|
disabledBackgroundColor = Colors.transparent;
|
||||||
|
|
||||||
|
return TextButton(
|
||||||
|
onPressed: onPressed,
|
||||||
|
style: TextButton.styleFrom(
|
||||||
|
foregroundColor: textcolor,
|
||||||
|
disabledForegroundColor: disabledTextColor,
|
||||||
|
backgroundColor: buttonBackgroundColor,
|
||||||
|
disabledBackgroundColor: disabledBackgroundColor,
|
||||||
|
animationDuration: const Duration(),
|
||||||
|
minimumSize: Size(
|
||||||
|
MediaQuery.sizeOf(context).width * sizeRelativeToWidth,
|
||||||
|
60,
|
||||||
|
),
|
||||||
|
side: const BorderSide(style: BorderStyle.none),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
text,
|
||||||
|
style: const TextStyle(fontWeight: FontWeight.w500, fontSize: 22),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
59
lib/presentation/widgets/custom_search_bar.dart
Normal file
59
lib/presentation/widgets/custom_search_bar.dart
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:game_tracker/core/custom_theme.dart';
|
||||||
|
|
||||||
|
class CustomSearchBar extends StatelessWidget {
|
||||||
|
final TextEditingController controller;
|
||||||
|
final String hintText;
|
||||||
|
final ValueChanged<String>? onChanged;
|
||||||
|
final BoxConstraints? constraints;
|
||||||
|
final bool trailingButtonShown;
|
||||||
|
final bool trailingButtonEnabled;
|
||||||
|
final VoidCallback? onTrailingButtonPressed;
|
||||||
|
final IconData trailingButtonicon;
|
||||||
|
|
||||||
|
const CustomSearchBar({
|
||||||
|
super.key,
|
||||||
|
required this.controller,
|
||||||
|
required this.hintText,
|
||||||
|
this.trailingButtonShown = false,
|
||||||
|
this.trailingButtonicon = Icons.clear,
|
||||||
|
this.trailingButtonEnabled = true,
|
||||||
|
this.onTrailingButtonPressed,
|
||||||
|
this.onChanged,
|
||||||
|
this.constraints,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return SearchBar(
|
||||||
|
controller: controller,
|
||||||
|
constraints:
|
||||||
|
constraints ?? const BoxConstraints(maxHeight: 45, minHeight: 45),
|
||||||
|
hintText: hintText,
|
||||||
|
onChanged: trailingButtonEnabled ? onChanged : null,
|
||||||
|
hintStyle: WidgetStateProperty.all(const TextStyle(fontSize: 16)),
|
||||||
|
leading: const Icon(Icons.search),
|
||||||
|
trailing: [
|
||||||
|
Visibility(
|
||||||
|
visible: trailingButtonShown,
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: trailingButtonEnabled ? onTrailingButtonPressed : null,
|
||||||
|
child: Icon(
|
||||||
|
trailingButtonicon,
|
||||||
|
color: trailingButtonEnabled
|
||||||
|
? null
|
||||||
|
: Colors.grey.withValues(alpha: 0.2),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 5),
|
||||||
|
],
|
||||||
|
backgroundColor: WidgetStateProperty.all(CustomTheme.boxColor),
|
||||||
|
side: WidgetStateProperty.all(BorderSide(color: CustomTheme.boxBorder)),
|
||||||
|
shape: WidgetStateProperty.all(
|
||||||
|
RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
|
||||||
|
),
|
||||||
|
elevation: WidgetStateProperty.all(0),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:game_tracker/core/custom_theme.dart';
|
|
||||||
|
|
||||||
class FullWidthButton extends StatelessWidget {
|
|
||||||
const FullWidthButton({super.key, required this.text, this.onPressed});
|
|
||||||
|
|
||||||
final String text;
|
|
||||||
final VoidCallback? onPressed;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return ElevatedButton(
|
|
||||||
onPressed: onPressed,
|
|
||||||
style: ElevatedButton.styleFrom(
|
|
||||||
minimumSize: Size(MediaQuery.sizeOf(context).width * 0.9, 60),
|
|
||||||
backgroundColor: CustomTheme.primaryColor,
|
|
||||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
|
|
||||||
),
|
|
||||||
child: Text(
|
|
||||||
text,
|
|
||||||
style: const TextStyle(
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
fontSize: 22,
|
|
||||||
color: Colors.white,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
38
lib/presentation/widgets/text_input_field.dart
Normal file
38
lib/presentation/widgets/text_input_field.dart
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:game_tracker/core/custom_theme.dart';
|
||||||
|
|
||||||
|
class TextInputField extends StatelessWidget {
|
||||||
|
final TextEditingController controller;
|
||||||
|
final ValueChanged<String>? onChanged;
|
||||||
|
final String hintText;
|
||||||
|
|
||||||
|
const TextInputField({
|
||||||
|
super.key,
|
||||||
|
required this.controller,
|
||||||
|
required this.hintText,
|
||||||
|
this.onChanged,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return TextField(
|
||||||
|
controller: controller,
|
||||||
|
onChanged: onChanged,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
filled: true,
|
||||||
|
fillColor: CustomTheme.boxColor,
|
||||||
|
hintText: hintText,
|
||||||
|
hintStyle: const TextStyle(fontSize: 18),
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderRadius: const BorderRadius.all(Radius.circular(12)),
|
||||||
|
borderSide: BorderSide(color: CustomTheme.boxBorder),
|
||||||
|
),
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderRadius: const BorderRadius.all(Radius.circular(12)),
|
||||||
|
borderSide: BorderSide(color: CustomTheme.boxBorder),
|
||||||
|
),
|
||||||
|
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,8 +9,8 @@ Widget doubleRowInfoTile(
|
|||||||
String titleLowerRight,
|
String titleLowerRight,
|
||||||
) {
|
) {
|
||||||
return Container(
|
return Container(
|
||||||
margin: EdgeInsets.symmetric(vertical: 5, horizontal: 10),
|
margin: const EdgeInsets.symmetric(vertical: 5, horizontal: 10),
|
||||||
padding: EdgeInsets.all(10),
|
padding: const EdgeInsets.all(10),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(20),
|
borderRadius: BorderRadius.circular(20),
|
||||||
color: CustomTheme.secondaryColor,
|
color: CustomTheme.secondaryColor,
|
||||||
@@ -22,18 +22,18 @@ Widget doubleRowInfoTile(
|
|||||||
Expanded(
|
Expanded(
|
||||||
flex: 10,
|
flex: 10,
|
||||||
child: Text(
|
child: Text(
|
||||||
"$titleOneUpperLeft $titleTwoUpperLeft",
|
'$titleOneUpperLeft $titleTwoUpperLeft',
|
||||||
style: TextStyle(fontSize: 20),
|
style: const TextStyle(fontSize: 20),
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Spacer(),
|
const Spacer(),
|
||||||
Expanded(
|
Expanded(
|
||||||
flex: 3,
|
flex: 3,
|
||||||
child: Text(
|
child: Text(
|
||||||
"$titleUpperRight",
|
titleUpperRight,
|
||||||
style: TextStyle(fontSize: 20),
|
style: const TextStyle(fontSize: 20),
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
textAlign: TextAlign.end,
|
textAlign: TextAlign.end,
|
||||||
@@ -46,18 +46,18 @@ Widget doubleRowInfoTile(
|
|||||||
Expanded(
|
Expanded(
|
||||||
flex: 10,
|
flex: 10,
|
||||||
child: Text(
|
child: Text(
|
||||||
"$titleLowerLeft",
|
titleLowerLeft,
|
||||||
style: TextStyle(fontSize: 20),
|
style: const TextStyle(fontSize: 20),
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Spacer(),
|
const Spacer(),
|
||||||
Expanded(
|
Expanded(
|
||||||
flex: 4,
|
flex: 4,
|
||||||
child: Text(
|
child: Text(
|
||||||
"$titleLowerRight",
|
titleLowerRight,
|
||||||
style: TextStyle(fontSize: 20),
|
style: const TextStyle(fontSize: 20),
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
textAlign: TextAlign.end,
|
textAlign: TextAlign.end,
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:game_tracker/core/custom_theme.dart';
|
import 'package:game_tracker/core/custom_theme.dart';
|
||||||
import 'package:game_tracker/data/dto/group.dart';
|
import 'package:game_tracker/data/dto/group.dart';
|
||||||
import 'package:skeletonizer/skeletonizer.dart';
|
import 'package:game_tracker/presentation/widgets/tiles/text_icon_tile.dart';
|
||||||
|
|
||||||
class GroupTile extends StatelessWidget {
|
class GroupTile extends StatelessWidget {
|
||||||
const GroupTile({super.key, required this.group});
|
const GroupTile({super.key, required this.group});
|
||||||
@@ -24,7 +24,8 @@ class GroupTile extends StatelessWidget {
|
|||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Flexible(
|
||||||
|
child: Text(
|
||||||
group.name,
|
group.name,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
@@ -32,7 +33,9 @@ class GroupTile extends StatelessWidget {
|
|||||||
fontSize: 18,
|
fontSize: 18,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const Spacer(),
|
),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'${group.members.length}',
|
'${group.members.length}',
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
@@ -44,6 +47,8 @@ class GroupTile extends StatelessWidget {
|
|||||||
const Icon(Icons.group, size: 22),
|
const Icon(Icons.group, size: 22),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
const SizedBox(height: 5),
|
const SizedBox(height: 5),
|
||||||
Wrap(
|
Wrap(
|
||||||
alignment: WrapAlignment.start,
|
alignment: WrapAlignment.start,
|
||||||
@@ -52,25 +57,7 @@ class GroupTile extends StatelessWidget {
|
|||||||
runSpacing: 8.0,
|
runSpacing: 8.0,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
for (var member in group.members)
|
for (var member in group.members)
|
||||||
Container(
|
TextIconTile(text: member.name, iconEnabled: false),
|
||||||
padding: const EdgeInsets.symmetric(
|
|
||||||
vertical: 5,
|
|
||||||
horizontal: 10,
|
|
||||||
),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: CustomTheme.onBoxColor,
|
|
||||||
borderRadius: BorderRadius.circular(12),
|
|
||||||
),
|
|
||||||
child: Skeleton.ignore(
|
|
||||||
child: Text(
|
|
||||||
member.name,
|
|
||||||
style: const TextStyle(
|
|
||||||
fontSize: 14,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 2.5),
|
const SizedBox(height: 2.5),
|
||||||
|
|||||||
52
lib/presentation/widgets/tiles/text_icon_list_tile.dart
Normal file
52
lib/presentation/widgets/tiles/text_icon_list_tile.dart
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:game_tracker/core/custom_theme.dart';
|
||||||
|
|
||||||
|
class TextIconListTile extends StatelessWidget {
|
||||||
|
final String text;
|
||||||
|
final VoidCallback? onPressed;
|
||||||
|
final bool iconEnabled;
|
||||||
|
|
||||||
|
const TextIconListTile({
|
||||||
|
super.key,
|
||||||
|
required this.text,
|
||||||
|
this.onPressed,
|
||||||
|
this.iconEnabled = true,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
margin: const EdgeInsets.symmetric(horizontal: 5, vertical: 5),
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 15),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: CustomTheme.boxColor,
|
||||||
|
border: Border.all(color: CustomTheme.boxBorder),
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
children: [
|
||||||
|
Flexible(
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 12.5),
|
||||||
|
child: Text(
|
||||||
|
text,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (iconEnabled)
|
||||||
|
GestureDetector(
|
||||||
|
onTap: onPressed,
|
||||||
|
child: const Icon(Icons.add, size: 20),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
47
lib/presentation/widgets/tiles/text_icon_tile.dart
Normal file
47
lib/presentation/widgets/tiles/text_icon_tile.dart
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:game_tracker/core/custom_theme.dart';
|
||||||
|
|
||||||
|
class TextIconTile extends StatelessWidget {
|
||||||
|
final String text;
|
||||||
|
final bool iconEnabled;
|
||||||
|
final VoidCallback? onIconTap;
|
||||||
|
|
||||||
|
const TextIconTile({
|
||||||
|
super.key,
|
||||||
|
required this.text,
|
||||||
|
this.onIconTap,
|
||||||
|
this.iconEnabled = true,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
padding: const EdgeInsets.all(5),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: CustomTheme.onBoxColor,
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
if (iconEnabled) const SizedBox(width: 3),
|
||||||
|
Flexible(
|
||||||
|
child: Text(
|
||||||
|
text,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (iconEnabled) ...<Widget>[
|
||||||
|
const SizedBox(width: 3),
|
||||||
|
GestureDetector(
|
||||||
|
onTap: onIconTap,
|
||||||
|
child: const Icon(Icons.close, size: 20),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,6 +20,7 @@ dependencies:
|
|||||||
provider: ^6.1.5
|
provider: ^6.1.5
|
||||||
skeletonizer: ^2.1.0+1
|
skeletonizer: ^2.1.0+1
|
||||||
uuid: ^4.5.2
|
uuid: ^4.5.2
|
||||||
|
clock: ^1.1.2
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import 'package:clock/clock.dart';
|
||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart';
|
||||||
import 'package:drift/native.dart';
|
import 'package:drift/native.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
@@ -15,6 +16,8 @@ void main() {
|
|||||||
late Player player5;
|
late Player player5;
|
||||||
late Group testgroup;
|
late Group testgroup;
|
||||||
late Game testgame;
|
late Game testgame;
|
||||||
|
final fixedDate = DateTime(2025, 19, 11, 00, 11, 23);
|
||||||
|
final fakeClock = Clock(() => fixedDate);
|
||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
database = AppDatabase(
|
database = AppDatabase(
|
||||||
@@ -25,18 +28,23 @@ void main() {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
withClock(fakeClock, () {
|
||||||
player1 = Player(name: 'Alice');
|
player1 = Player(name: 'Alice');
|
||||||
player2 = Player(name: 'Bob');
|
player2 = Player(name: 'Bob');
|
||||||
player3 = Player(name: 'Charlie');
|
player3 = Player(name: 'Charlie');
|
||||||
player4 = Player(name: 'Diana');
|
player4 = Player(name: 'Diana');
|
||||||
player5 = Player(name: 'Eve');
|
player5 = Player(name: 'Eve');
|
||||||
testgroup = Group(name: 'Test Group', members: [player1, player2, player3]);
|
testgroup = Group(
|
||||||
|
name: 'Test Group',
|
||||||
|
members: [player1, player2, player3],
|
||||||
|
);
|
||||||
testgame = Game(
|
testgame = Game(
|
||||||
name: 'Test Game',
|
name: 'Test Game',
|
||||||
group: testgroup,
|
group: testgroup,
|
||||||
players: [player4, player5],
|
players: [player4, player5],
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
tearDown(() async {
|
tearDown(() async {
|
||||||
await database.close();
|
await database.close();
|
||||||
});
|
});
|
||||||
@@ -50,6 +58,7 @@ void main() {
|
|||||||
expect(result.id, testgame.id);
|
expect(result.id, testgame.id);
|
||||||
expect(result.name, testgame.name);
|
expect(result.name, testgame.name);
|
||||||
expect(result.winner, testgame.winner);
|
expect(result.winner, testgame.winner);
|
||||||
|
expect(result.createdAt, testgame.createdAt);
|
||||||
|
|
||||||
if (result.group != null) {
|
if (result.group != null) {
|
||||||
expect(result.group!.members.length, testgroup.members.length);
|
expect(result.group!.members.length, testgroup.members.length);
|
||||||
@@ -67,6 +76,7 @@ void main() {
|
|||||||
for (int i = 0; i < testgame.players!.length; i++) {
|
for (int i = 0; i < testgame.players!.length; i++) {
|
||||||
expect(result.players![i].id, testgame.players![i].id);
|
expect(result.players![i].id, testgame.players![i].id);
|
||||||
expect(result.players![i].name, testgame.players![i].name);
|
expect(result.players![i].name, testgame.players![i].name);
|
||||||
|
expect(result.players![i].createdAt, testgame.players![i].createdAt);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fail('Players is null');
|
fail('Players is null');
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import 'package:clock/clock.dart';
|
||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart';
|
||||||
import 'package:drift/native.dart';
|
import 'package:drift/native.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
@@ -12,6 +13,9 @@ void main() {
|
|||||||
late Player player3;
|
late Player player3;
|
||||||
late Player player4;
|
late Player player4;
|
||||||
late Group testgroup;
|
late Group testgroup;
|
||||||
|
late Group testgroup2;
|
||||||
|
final fixedDate = DateTime(2025, 19, 11, 00, 11, 23);
|
||||||
|
final fakeClock = Clock(() => fixedDate);
|
||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
database = AppDatabase(
|
database = AppDatabase(
|
||||||
@@ -22,22 +26,27 @@ void main() {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
withClock(fakeClock, () {
|
||||||
player1 = Player(name: 'Alice');
|
player1 = Player(name: 'Alice');
|
||||||
player2 = Player(name: 'Bob');
|
player2 = Player(name: 'Bob');
|
||||||
player3 = Player(name: 'Charlie');
|
player3 = Player(name: 'Charlie');
|
||||||
player4 = Player(name: 'Diana');
|
player4 = Player(name: 'Diana');
|
||||||
testgroup = Group(name: 'Test Group', members: [player1, player2, player3]);
|
testgroup = Group(
|
||||||
|
name: 'Test Group',
|
||||||
|
members: [player1, player2, player3],
|
||||||
|
);
|
||||||
|
testgroup2 = Group(
|
||||||
|
id: 'gr2',
|
||||||
|
name: 'Second Group',
|
||||||
|
members: [player2, player3, player4],
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
tearDown(() async {
|
tearDown(() async {
|
||||||
await database.close();
|
await database.close();
|
||||||
});
|
});
|
||||||
group('group tests', () {
|
group('group tests', () {
|
||||||
test('all groups get fetched correctly', () async {
|
test('all groups get fetched correctly', () async {
|
||||||
final testgroup2 = Group(
|
|
||||||
id: 'gr2',
|
|
||||||
name: 'Second Group',
|
|
||||||
members: [player2, player3, player4],
|
|
||||||
);
|
|
||||||
await database.groupDao.addGroup(group: testgroup);
|
await database.groupDao.addGroup(group: testgroup);
|
||||||
await database.groupDao.addGroup(group: testgroup2);
|
await database.groupDao.addGroup(group: testgroup2);
|
||||||
|
|
||||||
@@ -48,11 +57,13 @@ void main() {
|
|||||||
expect(fetchedGroup1.name, testgroup.name);
|
expect(fetchedGroup1.name, testgroup.name);
|
||||||
expect(fetchedGroup1.members.length, testgroup.members.length);
|
expect(fetchedGroup1.members.length, testgroup.members.length);
|
||||||
expect(fetchedGroup1.members.elementAt(0).id, player1.id);
|
expect(fetchedGroup1.members.elementAt(0).id, player1.id);
|
||||||
|
expect(fetchedGroup1.members.elementAt(0).createdAt, player1.createdAt);
|
||||||
|
|
||||||
final fetchedGroup2 = allGroups.firstWhere((g) => g.id == testgroup2.id);
|
final fetchedGroup2 = allGroups.firstWhere((g) => g.id == testgroup2.id);
|
||||||
expect(fetchedGroup2.name, testgroup2.name);
|
expect(fetchedGroup2.name, testgroup2.name);
|
||||||
expect(fetchedGroup2.members.length, testgroup2.members.length);
|
expect(fetchedGroup2.members.length, testgroup2.members.length);
|
||||||
expect(fetchedGroup2.members.elementAt(0).id, player2.id);
|
expect(fetchedGroup2.members.elementAt(0).id, player2.id);
|
||||||
|
expect(fetchedGroup2.members.elementAt(0).createdAt, player2.createdAt);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('group and group members gets added correctly', () async {
|
test('group and group members gets added correctly', () async {
|
||||||
@@ -64,11 +75,13 @@ void main() {
|
|||||||
|
|
||||||
expect(result.id, testgroup.id);
|
expect(result.id, testgroup.id);
|
||||||
expect(result.name, testgroup.name);
|
expect(result.name, testgroup.name);
|
||||||
|
expect(result.createdAt, testgroup.createdAt);
|
||||||
|
|
||||||
expect(result.members.length, testgroup.members.length);
|
expect(result.members.length, testgroup.members.length);
|
||||||
for (int i = 0; i < testgroup.members.length; i++) {
|
for (int i = 0; i < testgroup.members.length; i++) {
|
||||||
expect(result.members[i].id, testgroup.members[i].id);
|
expect(result.members[i].id, testgroup.members[i].id);
|
||||||
expect(result.members[i].name, testgroup.members[i].name);
|
expect(result.members[i].name, testgroup.members[i].name);
|
||||||
|
expect(result.members[i].createdAt, testgroup.members[i].createdAt);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -124,8 +137,6 @@ void main() {
|
|||||||
|
|
||||||
expect(playerNotAdded, true);
|
expect(playerNotAdded, true);
|
||||||
|
|
||||||
expect(playerAdded, true);
|
|
||||||
|
|
||||||
final result = await database.groupDao.getGroupById(
|
final result = await database.groupDao.getGroupById(
|
||||||
groupId: testgroup.id,
|
groupId: testgroup.id,
|
||||||
);
|
);
|
||||||
@@ -133,6 +144,7 @@ void main() {
|
|||||||
|
|
||||||
final addedPlayer = result.members.firstWhere((p) => p.id == player4.id);
|
final addedPlayer = result.members.firstWhere((p) => p.id == player4.id);
|
||||||
expect(addedPlayer.name, player4.name);
|
expect(addedPlayer.name, player4.name);
|
||||||
|
expect(addedPlayer.createdAt, player4.createdAt);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Removing player from group works correctly', () async {
|
test('Removing player from group works correctly', () async {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import 'package:clock/clock.dart';
|
||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart';
|
||||||
import 'package:drift/native.dart';
|
import 'package:drift/native.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
@@ -7,6 +8,9 @@ import 'package:game_tracker/data/dto/player.dart';
|
|||||||
void main() {
|
void main() {
|
||||||
late AppDatabase database;
|
late AppDatabase database;
|
||||||
late Player testPlayer;
|
late Player testPlayer;
|
||||||
|
late Player testPlayer2;
|
||||||
|
final fixedDate = DateTime(2025, 19, 11, 00, 11, 23);
|
||||||
|
final fakeClock = Clock(() => fixedDate);
|
||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
database = AppDatabase(
|
database = AppDatabase(
|
||||||
@@ -17,7 +21,10 @@ void main() {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
withClock(fakeClock, () {
|
||||||
testPlayer = Player(name: 'Test Player');
|
testPlayer = Player(name: 'Test Player');
|
||||||
|
testPlayer2 = Player(name: 'Second Group');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
tearDown(() async {
|
tearDown(() async {
|
||||||
await database.close();
|
await database.close();
|
||||||
@@ -25,7 +32,6 @@ void main() {
|
|||||||
|
|
||||||
group('player tests', () {
|
group('player tests', () {
|
||||||
test('all players get fetched correctly', () async {
|
test('all players get fetched correctly', () async {
|
||||||
final testPlayer2 = Player(name: 'Second Group');
|
|
||||||
await database.playerDao.addPlayer(player: testPlayer);
|
await database.playerDao.addPlayer(player: testPlayer);
|
||||||
await database.playerDao.addPlayer(player: testPlayer2);
|
await database.playerDao.addPlayer(player: testPlayer2);
|
||||||
|
|
||||||
@@ -36,11 +42,13 @@ void main() {
|
|||||||
(g) => g.id == testPlayer.id,
|
(g) => g.id == testPlayer.id,
|
||||||
);
|
);
|
||||||
expect(fetchedPlayer1.name, testPlayer.name);
|
expect(fetchedPlayer1.name, testPlayer.name);
|
||||||
|
expect(fetchedPlayer1.createdAt, testPlayer.createdAt);
|
||||||
|
|
||||||
final fetchedPlayer2 = allPlayers.firstWhere(
|
final fetchedPlayer2 = allPlayers.firstWhere(
|
||||||
(g) => g.id == testPlayer2.id,
|
(g) => g.id == testPlayer2.id,
|
||||||
);
|
);
|
||||||
expect(fetchedPlayer2.name, testPlayer2.name);
|
expect(fetchedPlayer2.name, testPlayer2.name);
|
||||||
|
expect(fetchedPlayer2.createdAt, testPlayer2.createdAt);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('players get inserted correcly ', () async {
|
test('players get inserted correcly ', () async {
|
||||||
@@ -51,6 +59,7 @@ void main() {
|
|||||||
|
|
||||||
expect(result.id, testPlayer.id);
|
expect(result.id, testPlayer.id);
|
||||||
expect(result.name, testPlayer.name);
|
expect(result.name, testPlayer.name);
|
||||||
|
expect(result.createdAt, testPlayer.createdAt);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('players get deleted correcly ', () async {
|
test('players get deleted correcly ', () async {
|
||||||
|
|||||||
Reference in New Issue
Block a user