From 6c49dd326ca406b7b3882f34535606360616a5e2 Mon Sep 17 00:00:00 2001 From: sidhdhi canopas Date: Tue, 6 Feb 2024 11:43:12 +0530 Subject: [PATCH] code refactor --- data/.flutter-plugins-dependencies | 2 +- data/lib/extensions/string_extensions.dart | 5 + data/lib/service/team/team_service.dart | 161 +++++----- khelo/assets/locales/app_en.arb | 23 +- .../domain/extensions/string_extensions.dart | 2 +- khelo/lib/ui/flow/profile/profile_screen.dart | 2 +- .../edit_profile/edit_profile_screen.dart | 295 +++++++++++------- .../flow/team/add_team/add_team_screen.dart | 33 +- .../team/add_team/add_team_view_model.dart | 94 +++--- .../add_team/add_team_view_model.freezed.dart | 144 +++++---- .../add_team_member_screen.dart | 37 ++- .../add_team_member_view_model.dart | 14 +- .../add_team_member_view_model.freezed.dart | 37 ++- .../verify_add_team_member_dialog.dart | 27 +- khelo/lib/ui/flow/team/team_list_screen.dart | 20 +- .../ui/flow/team/team_list_view_model.dart | 2 +- khelo/pubspec.lock | 2 +- khelo/pubspec.yaml | 1 - 18 files changed, 516 insertions(+), 385 deletions(-) create mode 100644 data/lib/extensions/string_extensions.dart diff --git a/data/.flutter-plugins-dependencies b/data/.flutter-plugins-dependencies index ef0d35d6..9f761ce9 100644 --- a/data/.flutter-plugins-dependencies +++ b/data/.flutter-plugins-dependencies @@ -1 +1 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"cloud_firestore","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/cloud_firestore-4.14.0/","native_build":true,"dependencies":["firebase_core"]},{"name":"device_info_plus","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/device_info_plus-9.1.1/","native_build":true,"dependencies":[]},{"name":"firebase_auth","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/firebase_auth-4.16.0/","native_build":true,"dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/firebase_core-2.24.2/","native_build":true,"dependencies":[]},{"name":"firebase_storage","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/firebase_storage-11.6.0/","native_build":true,"dependencies":["firebase_core"]},{"name":"flutter_timezone","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/flutter_timezone-1.0.8/","native_build":true,"dependencies":[]},{"name":"package_info_plus","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/package_info_plus-5.0.1/","native_build":true,"dependencies":[]},{"name":"shared_preferences_foundation","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/shared_preferences_foundation-2.3.5/","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"android":[{"name":"cloud_firestore","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/cloud_firestore-4.14.0/","native_build":true,"dependencies":["firebase_core"]},{"name":"device_info_plus","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/device_info_plus-9.1.1/","native_build":true,"dependencies":[]},{"name":"firebase_auth","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/firebase_auth-4.16.0/","native_build":true,"dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/firebase_core-2.24.2/","native_build":true,"dependencies":[]},{"name":"firebase_storage","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/firebase_storage-11.6.0/","native_build":true,"dependencies":["firebase_core"]},{"name":"flutter_timezone","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/flutter_timezone-1.0.8/","native_build":true,"dependencies":[]},{"name":"package_info_plus","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/package_info_plus-5.0.1/","native_build":true,"dependencies":[]},{"name":"shared_preferences_android","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/shared_preferences_android-2.2.1/","native_build":true,"dependencies":[]}],"macos":[{"name":"cloud_firestore","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/cloud_firestore-4.14.0/","native_build":true,"dependencies":["firebase_core"]},{"name":"device_info_plus","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/device_info_plus-9.1.1/","native_build":true,"dependencies":[]},{"name":"firebase_auth","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/firebase_auth-4.16.0/","native_build":true,"dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/firebase_core-2.24.2/","native_build":true,"dependencies":[]},{"name":"firebase_storage","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/firebase_storage-11.6.0/","native_build":true,"dependencies":["firebase_core"]},{"name":"flutter_timezone","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/flutter_timezone-1.0.8/","native_build":true,"dependencies":[]},{"name":"package_info_plus","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/package_info_plus-5.0.1/","native_build":true,"dependencies":[]},{"name":"shared_preferences_foundation","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/shared_preferences_foundation-2.3.5/","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"linux":[{"name":"device_info_plus","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/device_info_plus-9.1.1/","native_build":false,"dependencies":[]},{"name":"package_info_plus","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/package_info_plus-5.0.1/","native_build":false,"dependencies":[]},{"name":"path_provider_linux","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/path_provider_linux-2.2.1/","native_build":false,"dependencies":[]},{"name":"shared_preferences_linux","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/shared_preferences_linux-2.3.2/","native_build":false,"dependencies":["path_provider_linux"]}],"windows":[{"name":"cloud_firestore","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/cloud_firestore-4.14.0/","native_build":true,"dependencies":["firebase_core"]},{"name":"device_info_plus","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/device_info_plus-9.1.1/","native_build":false,"dependencies":[]},{"name":"firebase_auth","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/firebase_auth-4.16.0/","native_build":true,"dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/firebase_core-2.24.2/","native_build":true,"dependencies":[]},{"name":"firebase_storage","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/firebase_storage-11.6.0/","native_build":true,"dependencies":["firebase_core"]},{"name":"package_info_plus","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/package_info_plus-5.0.1/","native_build":false,"dependencies":[]},{"name":"path_provider_windows","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/path_provider_windows-2.2.1/","native_build":false,"dependencies":[]},{"name":"shared_preferences_windows","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/shared_preferences_windows-2.3.2/","native_build":false,"dependencies":["path_provider_windows"]}],"web":[{"name":"cloud_firestore_web","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/cloud_firestore_web-3.9.0/","dependencies":["firebase_core_web"]},{"name":"device_info_plus","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/device_info_plus-9.1.1/","dependencies":[]},{"name":"firebase_auth_web","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/firebase_auth_web-5.8.13/","dependencies":["firebase_core_web"]},{"name":"firebase_core_web","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/firebase_core_web-2.10.0/","dependencies":[]},{"name":"firebase_storage_web","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/firebase_storage_web-3.6.17/","dependencies":["firebase_core_web"]},{"name":"flutter_timezone","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/flutter_timezone-1.0.8/","dependencies":[]},{"name":"package_info_plus","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/package_info_plus-5.0.1/","dependencies":[]},{"name":"shared_preferences_web","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/shared_preferences_web-2.2.2/","dependencies":[]}]},"dependencyGraph":[{"name":"cloud_firestore","dependencies":["cloud_firestore_web","firebase_core"]},{"name":"cloud_firestore_web","dependencies":["firebase_core","firebase_core_web"]},{"name":"device_info_plus","dependencies":[]},{"name":"firebase_auth","dependencies":["firebase_auth_web","firebase_core"]},{"name":"firebase_auth_web","dependencies":["firebase_core","firebase_core_web"]},{"name":"firebase_core","dependencies":["firebase_core_web"]},{"name":"firebase_core_web","dependencies":[]},{"name":"firebase_storage","dependencies":["firebase_core","firebase_storage_web"]},{"name":"firebase_storage_web","dependencies":["firebase_core","firebase_core_web"]},{"name":"flutter_timezone","dependencies":[]},{"name":"package_info_plus","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_android","shared_preferences_foundation","shared_preferences_linux","shared_preferences_web","shared_preferences_windows"]},{"name":"shared_preferences_android","dependencies":[]},{"name":"shared_preferences_foundation","dependencies":[]},{"name":"shared_preferences_linux","dependencies":["path_provider_linux"]},{"name":"shared_preferences_web","dependencies":[]},{"name":"shared_preferences_windows","dependencies":["path_provider_windows"]}],"date_created":"2024-02-05 15:22:46.192325","version":"3.16.8"} \ No newline at end of file +{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"cloud_firestore","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/cloud_firestore-4.14.0/","native_build":true,"dependencies":["firebase_core"]},{"name":"device_info_plus","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/device_info_plus-9.1.1/","native_build":true,"dependencies":[]},{"name":"firebase_auth","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/firebase_auth-4.16.0/","native_build":true,"dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/firebase_core-2.24.2/","native_build":true,"dependencies":[]},{"name":"firebase_storage","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/firebase_storage-11.6.0/","native_build":true,"dependencies":["firebase_core"]},{"name":"flutter_timezone","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/flutter_timezone-1.0.8/","native_build":true,"dependencies":[]},{"name":"package_info_plus","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/package_info_plus-5.0.1/","native_build":true,"dependencies":[]},{"name":"shared_preferences_foundation","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/shared_preferences_foundation-2.3.5/","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"android":[{"name":"cloud_firestore","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/cloud_firestore-4.14.0/","native_build":true,"dependencies":["firebase_core"]},{"name":"device_info_plus","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/device_info_plus-9.1.1/","native_build":true,"dependencies":[]},{"name":"firebase_auth","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/firebase_auth-4.16.0/","native_build":true,"dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/firebase_core-2.24.2/","native_build":true,"dependencies":[]},{"name":"firebase_storage","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/firebase_storage-11.6.0/","native_build":true,"dependencies":["firebase_core"]},{"name":"flutter_timezone","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/flutter_timezone-1.0.8/","native_build":true,"dependencies":[]},{"name":"package_info_plus","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/package_info_plus-5.0.1/","native_build":true,"dependencies":[]},{"name":"shared_preferences_android","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/shared_preferences_android-2.2.1/","native_build":true,"dependencies":[]}],"macos":[{"name":"cloud_firestore","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/cloud_firestore-4.14.0/","native_build":true,"dependencies":["firebase_core"]},{"name":"device_info_plus","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/device_info_plus-9.1.1/","native_build":true,"dependencies":[]},{"name":"firebase_auth","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/firebase_auth-4.16.0/","native_build":true,"dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/firebase_core-2.24.2/","native_build":true,"dependencies":[]},{"name":"firebase_storage","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/firebase_storage-11.6.0/","native_build":true,"dependencies":["firebase_core"]},{"name":"flutter_timezone","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/flutter_timezone-1.0.8/","native_build":true,"dependencies":[]},{"name":"package_info_plus","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/package_info_plus-5.0.1/","native_build":true,"dependencies":[]},{"name":"shared_preferences_foundation","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/shared_preferences_foundation-2.3.5/","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"linux":[{"name":"device_info_plus","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/device_info_plus-9.1.1/","native_build":false,"dependencies":[]},{"name":"package_info_plus","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/package_info_plus-5.0.1/","native_build":false,"dependencies":[]},{"name":"path_provider_linux","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/path_provider_linux-2.2.1/","native_build":false,"dependencies":[]},{"name":"shared_preferences_linux","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/shared_preferences_linux-2.3.2/","native_build":false,"dependencies":["path_provider_linux"]}],"windows":[{"name":"cloud_firestore","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/cloud_firestore-4.14.0/","native_build":true,"dependencies":["firebase_core"]},{"name":"device_info_plus","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/device_info_plus-9.1.1/","native_build":false,"dependencies":[]},{"name":"firebase_auth","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/firebase_auth-4.16.0/","native_build":true,"dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/firebase_core-2.24.2/","native_build":true,"dependencies":[]},{"name":"firebase_storage","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/firebase_storage-11.6.0/","native_build":true,"dependencies":["firebase_core"]},{"name":"package_info_plus","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/package_info_plus-5.0.1/","native_build":false,"dependencies":[]},{"name":"path_provider_windows","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/path_provider_windows-2.2.1/","native_build":false,"dependencies":[]},{"name":"shared_preferences_windows","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/shared_preferences_windows-2.3.2/","native_build":false,"dependencies":["path_provider_windows"]}],"web":[{"name":"cloud_firestore_web","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/cloud_firestore_web-3.9.0/","dependencies":["firebase_core_web"]},{"name":"device_info_plus","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/device_info_plus-9.1.1/","dependencies":[]},{"name":"firebase_auth_web","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/firebase_auth_web-5.8.13/","dependencies":["firebase_core_web"]},{"name":"firebase_core_web","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/firebase_core_web-2.10.0/","dependencies":[]},{"name":"firebase_storage_web","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/firebase_storage_web-3.6.17/","dependencies":["firebase_core_web"]},{"name":"flutter_timezone","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/flutter_timezone-1.0.8/","dependencies":[]},{"name":"package_info_plus","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/package_info_plus-5.0.1/","dependencies":[]},{"name":"shared_preferences_web","path":"/Users/sidhdhi.p/.pub-cache/hosted/pub.dev/shared_preferences_web-2.2.2/","dependencies":[]}]},"dependencyGraph":[{"name":"cloud_firestore","dependencies":["cloud_firestore_web","firebase_core"]},{"name":"cloud_firestore_web","dependencies":["firebase_core","firebase_core_web"]},{"name":"device_info_plus","dependencies":[]},{"name":"firebase_auth","dependencies":["firebase_auth_web","firebase_core"]},{"name":"firebase_auth_web","dependencies":["firebase_core","firebase_core_web"]},{"name":"firebase_core","dependencies":["firebase_core_web"]},{"name":"firebase_core_web","dependencies":[]},{"name":"firebase_storage","dependencies":["firebase_core","firebase_storage_web"]},{"name":"firebase_storage_web","dependencies":["firebase_core","firebase_core_web"]},{"name":"flutter_timezone","dependencies":[]},{"name":"package_info_plus","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_android","shared_preferences_foundation","shared_preferences_linux","shared_preferences_web","shared_preferences_windows"]},{"name":"shared_preferences_android","dependencies":[]},{"name":"shared_preferences_foundation","dependencies":[]},{"name":"shared_preferences_linux","dependencies":["path_provider_linux"]},{"name":"shared_preferences_web","dependencies":[]},{"name":"shared_preferences_windows","dependencies":["path_provider_windows"]}],"date_created":"2024-02-06 11:41:53.139840","version":"3.16.8"} \ No newline at end of file diff --git a/data/lib/extensions/string_extensions.dart b/data/lib/extensions/string_extensions.dart new file mode 100644 index 00000000..ed845ea3 --- /dev/null +++ b/data/lib/extensions/string_extensions.dart @@ -0,0 +1,5 @@ +extension StringManipulator on String { + String get caseAndSpaceInsensitive { + return trim().replaceAll(RegExp(r'\s+'), "").toLowerCase(); + } +} diff --git a/data/lib/service/team/team_service.dart b/data/lib/service/team/team_service.dart index fbbe0f2a..38e15dc7 100644 --- a/data/lib/service/team/team_service.dart +++ b/data/lib/service/team/team_service.dart @@ -1,33 +1,58 @@ import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:data/api/team/team_model.dart'; import 'package:data/api/user/user_models.dart'; +import 'package:data/extensions/string_extensions.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import '../../storage/app_preferences.dart'; final teamServiceProvider = Provider((ref) { - final service = TeamService(FirebaseFirestore.instance); - ref.listen(currentUserPod, (_, next) => service.currentUserId = next?.id); + final service = + TeamService(ref.read(currentUserPod)?.id, FirebaseFirestore.instance); + + ref.listen(currentUserPod, (_, next) => service._currentUserId = next?.id); return service; }); class TeamService { - String? currentUserId; + String? _currentUserId; final FirebaseFirestore _firestore; - final String collectionName = 'teams'; - final String subCollectionName = 'players'; + final String _collectionName = 'teams'; + final String _subCollectionName = 'players'; + + TeamService(this._currentUserId, this._firestore); - TeamService(this._firestore); + Future updateTeam(TeamModel team, List players) async { + DocumentReference teamRef = + _firestore.collection(_collectionName).doc(team.id); + WriteBatch batch = _firestore.batch(); + + batch.set(teamRef, team.toJson(), SetOptions(merge: true)); + String newTeamId = teamRef.id; + + for (var player in players) { + DocumentReference playerRef = + teamRef.collection(_subCollectionName).doc(player.id); + batch.set(playerRef, player.toJson(), SetOptions(merge: true)); + } + + if (team.id == null) { + batch.update(teamRef, {'id': newTeamId}); + } + await batch.commit(); + return newTeamId; + } Future getTeamById(String teamId) async { - CollectionReference teamsCollection = _firestore.collection(collectionName); + CollectionReference teamsCollection = + _firestore.collection(_collectionName); DocumentSnapshot teamDoc = await teamsCollection.doc(teamId).get(); TeamModel team = TeamModel.fromJson(teamDoc.data() as Map); CollectionReference playersCollection = - teamDoc.reference.collection(subCollectionName); + teamDoc.reference.collection(_subCollectionName); QuerySnapshot playersSnapshot = await playersCollection.get(); final players = playersSnapshot.docs.map((playerDoc) { @@ -37,9 +62,9 @@ class TeamService { return team.copyWith(players: players); } - // get Team with Players - Future> getTeamsWithPlayers() async { - CollectionReference teamsCollection = _firestore.collection(collectionName); + Future> getTeams() async { + CollectionReference teamsCollection = + _firestore.collection(_collectionName); QuerySnapshot mainCollectionSnapshot = await teamsCollection.get(); @@ -49,129 +74,87 @@ class TeamService { TeamModel team = TeamModel.fromJson(mainDoc.data() as Map); - CollectionReference playersCollection = - mainDoc.reference.collection(subCollectionName); - - QuerySnapshot playersSnapshot = await playersCollection.get(); - - final players = playersSnapshot.docs.map((playerDoc) { - return UserModel.fromJson(playerDoc.data() as Map); - }).toList(); - - team = team.copyWith(players: players); - teams.add(team); + if (team.created_by == _currentUserId) { + CollectionReference playersCollection = + mainDoc.reference.collection(_subCollectionName); + + QuerySnapshot playersSnapshot = await playersCollection.get(); + + final players = playersSnapshot.docs.map((playerDoc) { + return UserModel.fromJson(playerDoc.data() as Map); + }).toList(); + + team = team.copyWith(players: players); + teams.add(team); + } else { + CollectionReference playersCollection = + mainDoc.reference.collection(_subCollectionName); + QuerySnapshot playersSnapshot = await playersCollection + .where('id', isEqualTo: _currentUserId) + .get(); + + if (playersSnapshot.docs.isNotEmpty) { + final players = playersSnapshot.docs.map((playerDoc) { + return UserModel.fromJson(playerDoc.data() as Map); + }).toList(); + + team = team.copyWith(players: players); + teams.add(team); + } + } } return teams; } - // update team - Future updateTeam(TeamModel team, List players) async { - DocumentReference teamRef = - _firestore.collection(collectionName).doc(team.id); - - WriteBatch batch = _firestore.batch(); - - batch.set(teamRef, team.toJson(), SetOptions(merge: true)); - - for (var player in players) { - DocumentReference playerRef = - teamRef.collection(subCollectionName).doc(player.id); - batch.set(playerRef, player.toJson(), SetOptions(merge: true)); - } - - await batch.commit(); - } - - // delete team Future deleteTeam(String teamId) async { - await _firestore.collection(collectionName).doc(teamId).delete(); - } - - Future deleteTeamWithCollection(String teamId) async { await _firestore.runTransaction((transaction) async { CollectionReference teamCollection = - _firestore.collection(collectionName); + _firestore.collection(_collectionName); DocumentReference teamDocRef = teamCollection.doc(teamId); - // Delete sub-collection CollectionReference subCollection = - teamDocRef.collection(subCollectionName); + teamDocRef.collection(_subCollectionName); QuerySnapshot subCollectionSnapshot = await subCollection.get(); for (QueryDocumentSnapshot docSnapshot in subCollectionSnapshot.docs) { transaction.delete(docSnapshot.reference); } - // Delete team document transaction.delete(teamDocRef); }); } -// add players plural Future addPlayersToTeam(String teamId, List players) async { DocumentReference teamRef = - _firestore.collection(collectionName).doc(teamId); + _firestore.collection(_collectionName).doc(teamId); WriteBatch batch = _firestore.batch(); for (var player in players) { DocumentReference playerRef = - teamRef.collection(subCollectionName).doc(player.id); + teamRef.collection(_subCollectionName).doc(player.id); batch.set(playerRef, player.toJson(), SetOptions(merge: true)); } await batch.commit(); } -// remove players plural Future removePlayersFromTeam( String teamId, List playerIds) async { CollectionReference playersCollection = _firestore - .collection(collectionName) + .collection(_collectionName) .doc(teamId) - .collection(subCollectionName); + .collection(_subCollectionName); for (String playerId in playerIds) { playersCollection.doc(playerId).delete(); } } -// add player singular - Future addPlayerToTeam(String teamId, UserModel player) async { - CollectionReference playersCollection = _firestore - .collection(collectionName) - .doc(teamId) - .collection(subCollectionName); - - await playersCollection.add(player.toJson()); - } - -// update player singular - Future updatePlayerInTeam( - String teamId, String playerId, UserModel updatedPlayer) async { - CollectionReference playersCollection = _firestore - .collection(collectionName) - .doc(teamId) - .collection(subCollectionName); - - await playersCollection.doc(playerId).update(updatedPlayer.toJson()); - } - -// delete player singular - Future deletePlayerFromTeam(String teamId, String playerId) async { - CollectionReference playersCollection = _firestore - .collection(collectionName) - .doc(teamId) - .collection(subCollectionName); - - await playersCollection.doc(playerId).delete(); - } - -// is Team name available Future isTeamNameAvailable(String teamName) async { QuerySnapshot teamSnap = await _firestore - .collection(collectionName) - .where('name_lowercase', isEqualTo: teamName.toLowerCase()) + .collection(_collectionName) + .where('name_lowercase', isEqualTo: teamName.caseAndSpaceInsensitive) .get(); return teamSnap.docs.isEmpty; diff --git a/khelo/assets/locales/app_en.arb b/khelo/assets/locales/app_en.arb index 66c2b72c..11be6d33 100644 --- a/khelo/assets/locales/app_en.arb +++ b/khelo/assets/locales/app_en.arb @@ -12,6 +12,19 @@ "common_sign_out_title": "Sign out", "common_add_title": "Add", "common_save_title": "Save", + "common_not_specified_title": "Not Specified", + "common_obscure_phone_number_text": "+{countryCode} ***** ***{lastDigits}", + "@common_obscure_phone_number_text": { + "description": "+{countryCode} ***** ***{lastDigits}", + "placeholders": { + "countryCode": { + "type": "String" + }, + "lastDigits": { + "type": "String" + } + } + }, "alert_confirm_default_title": "Are you sure?", "alert_confirm_default_message": "Are you sure you want to {deleteText}?", @@ -85,11 +98,19 @@ "add_team_add_as_member_description_text": "Add me as a team member", "add_team_enter_team_name_placeholder_text": "Enter team name", "add_team_location_text": "Location", + "add_team_players_text": "PLAYERS", + "add_team_add_hint_text": "Added user will be shown here, tap on '+' button to add team member.", "add_team_member_screen_title": "Add team member", - "add_team_member_search_placeholder_text": "Search member with name", + "add_team_member_search_placeholder_text": "Search member name", "add_team_member_verify_placeholder_text": "Enter the last five digits of the phone number of the selected player.", "add_team_member_verify_title": "Verify", + "add_team_member_search_hint_text": "Search the person name above to add them in your team.", + "add_team_member_add_text": "ADD", + "add_team_member_added_text": "ADDED", + + "team_list_add_members_title": "Add Members", + "team_list_edit_team_title": "Edit Team", "my_game_teams_tab_title": "Teams", "my_game_matches_tab_title": "Matches" diff --git a/khelo/lib/domain/extensions/string_extensions.dart b/khelo/lib/domain/extensions/string_extensions.dart index 3574dfa3..1b4e52e9 100644 --- a/khelo/lib/domain/extensions/string_extensions.dart +++ b/khelo/lib/domain/extensions/string_extensions.dart @@ -5,4 +5,4 @@ extension EmailValidator on String { r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$') .hasMatch(this); } -} +} \ No newline at end of file diff --git a/khelo/lib/ui/flow/profile/profile_screen.dart b/khelo/lib/ui/flow/profile/profile_screen.dart index ac06456d..c123b745 100644 --- a/khelo/lib/ui/flow/profile/profile_screen.dart +++ b/khelo/lib/ui/flow/profile/profile_screen.dart @@ -16,7 +16,7 @@ import 'package:style/text/app_text_style.dart'; class ProfileScreen extends ConsumerWidget { const ProfileScreen({super.key}); - _observeUserSession(BuildContext context, WidgetRef ref) { + void _observeUserSession(BuildContext context, WidgetRef ref) { ref.listen(hasUserSession, (previous, next) { if (!next) { AppRoute.intro.go(context); diff --git a/khelo/lib/ui/flow/settings/edit_profile/edit_profile_screen.dart b/khelo/lib/ui/flow/settings/edit_profile/edit_profile_screen.dart index 4960e1f7..a69a6d49 100644 --- a/khelo/lib/ui/flow/settings/edit_profile/edit_profile_screen.dart +++ b/khelo/lib/ui/flow/settings/edit_profile/edit_profile_screen.dart @@ -9,6 +9,7 @@ import 'package:khelo/domain/extensions/context_extensions.dart'; import 'package:khelo/ui/app_route.dart'; import 'package:khelo/ui/flow/settings/edit_profile/edit_profile_view_model.dart'; import 'package:style/animations/on_tap_scale.dart'; +import 'package:style/button/bottom_sticky_overlay.dart'; import 'package:style/button/primary_button.dart'; import 'package:style/extensions/context_extensions.dart'; import 'package:style/indicator/progress_indicator.dart'; @@ -23,7 +24,7 @@ class EditProfileScreen extends ConsumerWidget { final double profileViewHeight = 130; - _observeIsSaved(BuildContext context, WidgetRef ref) { + void _observeIsSaved(BuildContext context, WidgetRef ref) { ref.listen(editProfileStateProvider.select((state) => state.isSaved), (previous, next) { if (next) { @@ -60,131 +61,166 @@ class EditProfileScreen extends ConsumerWidget { ] ], body: Material( + color: Colors.transparent, child: Builder( builder: (context) { - return ListView( - padding: context.mediaQueryPadding + - const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0), + return Stack( children: [ - _profileImageView(context, notifier, state), - const SizedBox( - height: 16, - ), - _textInputField( - context, - notifier, - state, - context.l10n.edit_profile_name_placeholder, - state.nameController), - const SizedBox( - height: 16, - ), - _textInputField( - context, - notifier, - state, - context.l10n.edit_profile_email_placeholder, - state.emailController), - const SizedBox( - height: 16, - ), - _textInputField( - context, - notifier, - state, - context.l10n.edit_profile_location_placeholder, - state.locationController), - _sectionTitle( - context, context.l10n.edit_profile_dob_placeholder), - OnTapScale( - onTap: () => _selectDate(context, notifier, state), - child: Text.rich(TextSpan(children: [ - WidgetSpan( - child: Padding( - padding: const EdgeInsets.only(right: 8.0), - child: Icon(Icons.cake_rounded, - color: context.colorScheme.textPrimary), - )), - TextSpan( - text: DateFormat.yMMMMd().format(state.dob), - style: AppTextStyle.subtitle1.copyWith( - color: context.colorScheme.textSecondary)), - ])), - ), - _sectionTitle( - context, context.l10n.edit_profile_gender_placeholder), - _genderOptionView(context, notifier, state), - const SizedBox( - height: 16, - ), - DropdownButton( - alignment: Alignment.center, - value: state.playerRole, - hint: Text( - context.l10n.edit_profile_player_role_placeholder), - items: PlayerRole.values.map((PlayerRole items) { - return DropdownMenuItem( - value: items, - child: Text(_getPlayerRoleString(context, items)), - ); - }).toList(), - onChanged: (PlayerRole? newValue) { - if (newValue != null && newValue != state.playerRole) { - notifier.onPlayerRoleChange(newValue); - } - }), - const SizedBox( - height: 16, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, + ListView( + padding: context.mediaQueryPadding + + const EdgeInsets.symmetric( + vertical: 8.0, horizontal: 16.0) + + BottomStickyOverlay.padding, children: [ - DropdownButton( - value: state.battingStyle, - hint: Text(context - .l10n.edit_profile_batting_style_placeholder), - items: BattingStyle.values.map((BattingStyle items) { - return DropdownMenuItem( - value: items, - child: - Text(_getBattingStyleString(context, items)), - ); - }).toList(), - onChanged: (BattingStyle? newValue) { - if (newValue != null && - newValue != state.battingStyle) { - notifier.onBattingStyleChange(newValue); - } - }), - DropdownButton( - value: state.bowlingStyle, - hint: Text(context - .l10n.edit_profile_bowling_style_placeholder), - items: BowlingStyle.values.map((BowlingStyle items) { - return DropdownMenuItem( - value: items, - child: - Text(_getBowlingStyleString(context, items)), - ); - }).toList(), - onChanged: (BowlingStyle? newValue) { - if (newValue != null && - newValue != state.bowlingStyle) { - notifier.onBowlingStyleChange(newValue); - } - }) + _profileImageView(context, notifier, state), + const SizedBox( + height: 16, + ), + _textInputField( + context, + notifier, + state, + context.l10n.edit_profile_name_placeholder, + state.nameController), + const SizedBox( + height: 16, + ), + _textInputField( + context, + notifier, + state, + context.l10n.edit_profile_email_placeholder, + state.emailController), + const SizedBox( + height: 16, + ), + _textInputField( + context, + notifier, + state, + context.l10n.edit_profile_location_placeholder, + state.locationController), + _sectionTitle( + context, context.l10n.edit_profile_dob_placeholder), + OnTapScale( + onTap: () => _selectDate(context, notifier, state), + child: Text.rich(TextSpan(children: [ + WidgetSpan( + child: Padding( + padding: const EdgeInsets.only(right: 8.0), + child: Icon(Icons.cake_rounded, + color: context.colorScheme.textPrimary), + )), + TextSpan( + text: DateFormat.yMMMMd().format(state.dob), + style: AppTextStyle.subtitle1.copyWith( + color: context.colorScheme.textSecondary)), + ])), + ), + _sectionTitle(context, + context.l10n.edit_profile_gender_placeholder), + _genderOptionView(context, notifier, state), + const SizedBox( + height: 16, + ), + Wrap( + alignment: WrapAlignment.center, + children: [ + DropdownButton( + alignment: Alignment.center, + value: state.playerRole, + dropdownColor: + context.colorScheme.containerLowOnSurface, + isExpanded: false, + hint: Text( + context.l10n + .edit_profile_player_role_placeholder, + style: AppTextStyle.header4.copyWith( + color: context.colorScheme.textDisabled)), + items: PlayerRole.values.map((PlayerRole items) { + return DropdownMenuItem( + value: items, + child: Text( + _getPlayerRoleString(context, items), + style: AppTextStyle.body1.copyWith( + color: context.colorScheme.textPrimary), + ), + ); + }).toList(), + onChanged: (PlayerRole? newValue) { + if (newValue != null && + newValue != state.playerRole) { + notifier.onPlayerRoleChange(newValue); + } + }), + ], + ), + const SizedBox( + height: 16, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + DropdownButton( + value: state.battingStyle, + dropdownColor: + context.colorScheme.containerLowOnSurface, + hint: Text( + context.l10n + .edit_profile_batting_style_placeholder, + style: AppTextStyle.header4.copyWith( + color: context.colorScheme.textDisabled)), + items: + BattingStyle.values.map((BattingStyle items) { + return DropdownMenuItem( + value: items, + child: Text( + _getBattingStyleString(context, items), + style: AppTextStyle.body1.copyWith( + color: context.colorScheme.textPrimary), + ), + ); + }).toList(), + onChanged: (BattingStyle? newValue) { + if (newValue != null && + newValue != state.battingStyle) { + notifier.onBattingStyleChange(newValue); + } + }), + DropdownButton( + value: state.bowlingStyle, + dropdownColor: + context.colorScheme.containerLowOnSurface, + hint: Text( + context.l10n + .edit_profile_bowling_style_placeholder, + style: AppTextStyle.header4.copyWith( + color: context.colorScheme.textDisabled)), + items: + BowlingStyle.values.map((BowlingStyle items) { + return DropdownMenuItem( + value: items, + child: Text( + _getBowlingStyleString(context, items), + style: AppTextStyle.body1.copyWith( + color: context.colorScheme.textPrimary), + ), + ); + }).toList(), + onChanged: (BowlingStyle? newValue) { + if (newValue != null && + newValue != state.bowlingStyle) { + notifier.onBowlingStyleChange(newValue); + } + }) + ], + ), + const SizedBox( + height: 24, + ), ], ), - const SizedBox( - height: 24, - ), - PrimaryButton( - context.l10n.edit_profile_save_title, - expanded: false, - progress: state.isSaveInProgress, - enabled: state.isButtonEnable && !state.isImageUploading, - onPressed: () => notifier.onSubmitTap(), - ) + _stickyButton(context, notifier, state) ], ); }, @@ -263,8 +299,12 @@ class EditProfileScreen extends ConsumerWidget { return TextField( controller: controller, onChanged: (value) => notifier.onValueChange(), + style: + AppTextStyle.header4.copyWith(color: context.colorScheme.textPrimary), decoration: InputDecoration( labelText: label, + labelStyle: AppTextStyle.header4 + .copyWith(color: context.colorScheme.textDisabled), border: const OutlineInputBorder(), ), ); @@ -440,4 +480,19 @@ class EditProfileScreen extends ConsumerWidget { }, ); } + + Widget _stickyButton( + BuildContext context, + EditProfileViewNotifier notifier, + EditProfileState state, + ) { + return BottomStickyOverlay( + child: PrimaryButton( + context.l10n.edit_profile_save_title, + progress: state.isSaveInProgress, + enabled: state.isButtonEnable && !state.isImageUploading, + onPressed: () => notifier.onSubmitTap(), + ), + ); + } } diff --git a/khelo/lib/ui/flow/team/add_team/add_team_screen.dart b/khelo/lib/ui/flow/team/add_team/add_team_screen.dart index 8c905d1d..bd82818e 100644 --- a/khelo/lib/ui/flow/team/add_team/add_team_screen.dart +++ b/khelo/lib/ui/flow/team/add_team/add_team_screen.dart @@ -100,11 +100,13 @@ class _AddTeamScreenState extends ConsumerState { ], ], body: Material( + color: Colors.transparent, child: Stack( children: [ ListView( padding: context.mediaQueryPadding + - const EdgeInsets.symmetric(horizontal: 16), + const EdgeInsets.symmetric(horizontal: 16) + + BottomStickyOverlay.padding, keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag, children: [ _profileImageView(context, notifier, state), @@ -119,9 +121,13 @@ class _AddTeamScreenState extends ConsumerState { inputFormatters: [ FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 ]')), ], + style: AppTextStyle.header4 + .copyWith(color: context.colorScheme.textPrimary), decoration: InputDecoration( hintText: context.l10n.add_team_enter_team_name_placeholder_text, + hintStyle: AppTextStyle.header4 + .copyWith(color: context.colorScheme.textDisabled), suffixIcon: state.checkingForAvailability ? const AppProgressIndicator( size: AppProgressIndicatorSize.small, @@ -148,8 +154,12 @@ class _AddTeamScreenState extends ConsumerState { notifier.onValueChange(); }, controller: state.locationController, + style: AppTextStyle.header4 + .copyWith(color: context.colorScheme.textPrimary), decoration: InputDecoration( hintText: context.l10n.add_team_location_text, + hintStyle: AppTextStyle.header4 + .copyWith(color: context.colorScheme.textDisabled), border: const OutlineInputBorder(), ), ), @@ -178,14 +188,15 @@ class _AddTeamScreenState extends ConsumerState { Row( children: [ Text( - "PLAYERS", + context.l10n.add_team_players_text, style: AppTextStyle.header3 .copyWith(color: context.colorScheme.textPrimary), ), IconButton( onPressed: () async { final players = await AppRoute.addTeamMember( - team: state.editTeam!) + team: state.editTeam! + .copyWith(players: state.teamMembers)) .push>(context); if (players != null) { notifier.updatePlayersList(players); @@ -197,19 +208,18 @@ class _AddTeamScreenState extends ConsumerState { const SizedBox( height: 16, ), - for (final UserModel player - in state.editTeam!.players ?? []) ...[ + for (final UserModel player in state.teamMembers) ...[ _userProfileCell(context, notifier, state, player), const SizedBox( height: 16, ), ], - if ((state.editTeam!.players ?? []).isEmpty) ...[ + if ((state.teamMembers).isEmpty) ...[ const SizedBox( height: 16, ), Text( - "Added user will be shown here, tap on '+' button to add team member", + context.l10n.add_team_add_hint_text, textAlign: TextAlign.center, style: AppTextStyle.subtitle1 .copyWith(color: context.colorScheme.textPrimary), @@ -219,6 +229,9 @@ class _AddTeamScreenState extends ConsumerState { ), const Divider(), ], + const SizedBox( + height: 100, + ), ], ], ), @@ -333,7 +346,7 @@ class _AddTeamScreenState extends ConsumerState { Text( user.player_role != null ? _getPlayerRoleString(context, user.player_role!) - : "Not Specified", + : context.l10n.common_not_specified_title, style: AppTextStyle.subtitle2 .copyWith(color: context.colorScheme.textSecondary)), if (user.phone != null) ...[ @@ -341,7 +354,9 @@ class _AddTeamScreenState extends ConsumerState { height: 2, ), Text( - "***** ***${user.phone!.substring(user.phone!.length - 2)}", + context.l10n.common_obscure_phone_number_text( + user.phone!.substring(1, 3), + user.phone!.substring(user.phone!.length - 2)), style: AppTextStyle.subtitle2 .copyWith(color: context.colorScheme.textSecondary), ), diff --git a/khelo/lib/ui/flow/team/add_team/add_team_view_model.dart b/khelo/lib/ui/flow/team/add_team/add_team_view_model.dart index 57a50451..422e49e4 100644 --- a/khelo/lib/ui/flow/team/add_team/add_team_view_model.dart +++ b/khelo/lib/ui/flow/team/add_team/add_team_view_model.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'package:data/api/user/user_models.dart'; +import 'package:data/extensions/string_extensions.dart'; import 'package:data/service/file_upload/file_upload_service.dart'; import 'package:data/service/team/team_service.dart'; import 'package:data/api/team/team_model.dart'; @@ -8,7 +9,6 @@ import 'package:data/storage/app_preferences.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; -import 'package:uuid/uuid.dart'; part 'add_team_view_model.freezed.dart'; @@ -38,8 +38,10 @@ class AddTeamViewNotifier extends StateNotifier { void setData({TeamModel? editTeam}) { state.nameController.text = editTeam?.name ?? ""; state.locationController.text = editTeam?.city ?? ""; - state = - state.copyWith(imageUrl: editTeam?.profile_img_url, editTeam: editTeam); + state = state.copyWith( + imageUrl: editTeam?.profile_img_url, + editTeam: editTeam, + teamMembers: editTeam?.players ?? []); } void _updateUser(UserModel? user) { @@ -50,14 +52,8 @@ class AddTeamViewNotifier extends StateNotifier { if (state.editTeam == null) { return; } - // final team = - // await _teamService.getTeamById(state.editTeam!.id ?? "INVALID ID"); - // final filteredPlayers = team.players - // ?.where((element) => !state.memberToDelete.contains(element.id)) - // .toList(); - state = state.copyWith( - editTeam: state.editTeam - ?.copyWith(players: [...?state.editTeam?.players, ...players])); + state = state.copyWith(teamMembers: [...state.teamMembers, ...players]); + onValueChange(); } void onAddMeCheckBoxTap() { @@ -111,10 +107,14 @@ class AddTeamViewNotifier extends StateNotifier { players.add(state.currentUser!); } + if (state.editTeam != null) { + players = state.teamMembers; + } + TeamModel team = TeamModel( - id: state.editTeam?.id ?? const Uuid().v4(), + id: state.editTeam?.id, name: name, - name_lowercase: name.toLowerCase().replaceAll(RegExp(r'\s+'), ""), + name_lowercase: name.caseAndSpaceInsensitive, profile_img_url: state.imageUrl, city: location.toLowerCase(), created_by: state.currentUser!.id, @@ -125,11 +125,11 @@ class AddTeamViewNotifier extends StateNotifier { if (previousImageUrl != null) { await deleteUnusedImage(previousImageUrl); } + if (state.editTeam != null) { - final filterList = state.memberToDelete - .where((element) => !(state.editTeam!.players ?? []) - .map((e) => e.id) - .contains(element)) + final filterList = (state.editTeam!.players ?? []) + .where((element) => !state.teamMembers.contains(element)) + .map((e) => e.id) .toList(); await _teamService.removePlayersFromTeam( @@ -147,16 +147,11 @@ class AddTeamViewNotifier extends StateNotifier { } Future onValueChange() async { - final searchName = - state.nameController.text.trim().replaceAll(RegExp(r'\s+'), ""); - final isAvailable = await _teamService.isTeamNameAvailable(searchName); - state = state.copyWith( - isNameAvailable: isAvailable || - state.editTeam?.name_lowercase == searchName.toLowerCase()); - final isEnable = state.nameController.text.trim().length >= 3 && state.locationController.text.trim().length >= 3 && - state.isNameAvailable == true; + (state.isNameAvailable == true || + state.editTeam?.name_lowercase == + state.nameController.text.caseAndSpaceInsensitive); state = state.copyWith(isAddBtnEnable: isEnable); } @@ -169,13 +164,13 @@ class AddTeamViewNotifier extends StateNotifier { state = state.copyWith(checkingForAvailability: true); } _debounce = Timer(const Duration(milliseconds: 500), () async { - if (state.nameController.text.trim().length >= 3) { - final searchName = - state.nameController.text.trim().replaceAll(RegExp(r'\s+'), ""); + if (state.nameController.text.trim().length >= 3 && + state.nameController.text.trim() != state.editTeam?.name) { + final searchName = state.nameController.text.caseAndSpaceInsensitive; final isAvailable = await _teamService.isTeamNameAvailable(searchName); state = state.copyWith( - isNameAvailable: isAvailable || - state.editTeam?.name_lowercase == searchName.toLowerCase(), + isNameAvailable: + isAvailable || state.editTeam?.name_lowercase == searchName, checkingForAvailability: false); } else { state = state.copyWith( @@ -196,40 +191,33 @@ class AddTeamViewNotifier extends StateNotifier { } Future onRemoveUserFromTeam(UserModel user) async { - final updatedList = state.editTeam?.players?.toList(); - if (updatedList == null) { - return; - } + final updatedList = state.teamMembers.toList(); updatedList.removeWhere((element) => element.id == user.id); - - // add only if not contain already - final deleteMember = state.memberToDelete.contains(user.id) - ? state.memberToDelete - : [...state.memberToDelete, user.id]; - state = state.copyWith( - editTeam: state.editTeam?.copyWith(players: updatedList), - memberToDelete: deleteMember); + state = state.copyWith(teamMembers: updatedList); onValueChange(); } Future onTeamDelete() async { + if (state.editTeam == null) { + return; + } + try { String? teamProfileImageUrl; String? currentImageUrl; if (state.imageUrl != null) { - if (state.imageUrl != state.editTeam?.profile_img_url && - state.editTeam?.profile_img_url != null) { + if (state.imageUrl != state.editTeam!.profile_img_url && + state.editTeam!.profile_img_url != null) { teamProfileImageUrl = state.editTeam!.profile_img_url!; } currentImageUrl = state.imageUrl!; } else { - if (state.editTeam?.profile_img_url != null) { + if (state.editTeam!.profile_img_url != null) { teamProfileImageUrl = state.editTeam!.profile_img_url!; } } - await _teamService - .deleteTeamWithCollection(state.editTeam?.id ?? "INVALID ID"); + await _teamService.deleteTeam(state.editTeam!.id ?? "INVALID ID"); state = state.copyWith(isPop: true); if (teamProfileImageUrl != null) { @@ -239,7 +227,7 @@ class AddTeamViewNotifier extends StateNotifier { await deleteUnusedImage(currentImageUrl); } // do not merge above both if-conditions in if-else or any other control-flow, at a time both variable may have non-null value } catch (e) { - debugPrint("EditProfileViewNotifier: error while delete account -> $e"); + debugPrint("AddTeamViewNotifier: error while delete team -> $e"); } } @@ -255,17 +243,17 @@ class AddTeamState with _$AddTeamState { const factory AddTeamState({ required TextEditingController nameController, required TextEditingController locationController, - @Default(null) String? imageUrl, @Default(false) bool isImageUploading, - @Default(null) bool? isNameAvailable, @Default(true) bool isAddMeCheckBoxEnable, @Default(false) bool checkingForAvailability, @Default(false) bool isAddBtnEnable, @Default(false) bool isAddInProgress, @Default(false) bool isPop, - @Default([]) List memberToDelete, - @Default(null) TeamModel? team, - @Default(null) TeamModel? editTeam, + @Default([]) List teamMembers, + String? imageUrl, + bool? isNameAvailable, + TeamModel? team, + TeamModel? editTeam, UserModel? currentUser, }) = _AddTeamState; } diff --git a/khelo/lib/ui/flow/team/add_team/add_team_view_model.freezed.dart b/khelo/lib/ui/flow/team/add_team/add_team_view_model.freezed.dart index a3cfbaed..29f8bc83 100644 --- a/khelo/lib/ui/flow/team/add_team/add_team_view_model.freezed.dart +++ b/khelo/lib/ui/flow/team/add_team/add_team_view_model.freezed.dart @@ -20,15 +20,15 @@ mixin _$AddTeamState { throw _privateConstructorUsedError; TextEditingController get locationController => throw _privateConstructorUsedError; - String? get imageUrl => throw _privateConstructorUsedError; bool get isImageUploading => throw _privateConstructorUsedError; - bool? get isNameAvailable => throw _privateConstructorUsedError; bool get isAddMeCheckBoxEnable => throw _privateConstructorUsedError; bool get checkingForAvailability => throw _privateConstructorUsedError; bool get isAddBtnEnable => throw _privateConstructorUsedError; bool get isAddInProgress => throw _privateConstructorUsedError; bool get isPop => throw _privateConstructorUsedError; - List get memberToDelete => throw _privateConstructorUsedError; + List get teamMembers => throw _privateConstructorUsedError; + String? get imageUrl => throw _privateConstructorUsedError; + bool? get isNameAvailable => throw _privateConstructorUsedError; TeamModel? get team => throw _privateConstructorUsedError; TeamModel? get editTeam => throw _privateConstructorUsedError; UserModel? get currentUser => throw _privateConstructorUsedError; @@ -47,15 +47,15 @@ abstract class $AddTeamStateCopyWith<$Res> { $Res call( {TextEditingController nameController, TextEditingController locationController, - String? imageUrl, bool isImageUploading, - bool? isNameAvailable, bool isAddMeCheckBoxEnable, bool checkingForAvailability, bool isAddBtnEnable, bool isAddInProgress, bool isPop, - List memberToDelete, + List teamMembers, + String? imageUrl, + bool? isNameAvailable, TeamModel? team, TeamModel? editTeam, UserModel? currentUser}); @@ -80,15 +80,15 @@ class _$AddTeamStateCopyWithImpl<$Res, $Val extends AddTeamState> $Res call({ Object? nameController = null, Object? locationController = null, - Object? imageUrl = freezed, Object? isImageUploading = null, - Object? isNameAvailable = freezed, Object? isAddMeCheckBoxEnable = null, Object? checkingForAvailability = null, Object? isAddBtnEnable = null, Object? isAddInProgress = null, Object? isPop = null, - Object? memberToDelete = null, + Object? teamMembers = null, + Object? imageUrl = freezed, + Object? isNameAvailable = freezed, Object? team = freezed, Object? editTeam = freezed, Object? currentUser = freezed, @@ -102,18 +102,10 @@ class _$AddTeamStateCopyWithImpl<$Res, $Val extends AddTeamState> ? _value.locationController : locationController // ignore: cast_nullable_to_non_nullable as TextEditingController, - imageUrl: freezed == imageUrl - ? _value.imageUrl - : imageUrl // ignore: cast_nullable_to_non_nullable - as String?, isImageUploading: null == isImageUploading ? _value.isImageUploading : isImageUploading // ignore: cast_nullable_to_non_nullable as bool, - isNameAvailable: freezed == isNameAvailable - ? _value.isNameAvailable - : isNameAvailable // ignore: cast_nullable_to_non_nullable - as bool?, isAddMeCheckBoxEnable: null == isAddMeCheckBoxEnable ? _value.isAddMeCheckBoxEnable : isAddMeCheckBoxEnable // ignore: cast_nullable_to_non_nullable @@ -134,10 +126,18 @@ class _$AddTeamStateCopyWithImpl<$Res, $Val extends AddTeamState> ? _value.isPop : isPop // ignore: cast_nullable_to_non_nullable as bool, - memberToDelete: null == memberToDelete - ? _value.memberToDelete - : memberToDelete // ignore: cast_nullable_to_non_nullable - as List, + teamMembers: null == teamMembers + ? _value.teamMembers + : teamMembers // ignore: cast_nullable_to_non_nullable + as List, + imageUrl: freezed == imageUrl + ? _value.imageUrl + : imageUrl // ignore: cast_nullable_to_non_nullable + as String?, + isNameAvailable: freezed == isNameAvailable + ? _value.isNameAvailable + : isNameAvailable // ignore: cast_nullable_to_non_nullable + as bool?, team: freezed == team ? _value.team : team // ignore: cast_nullable_to_non_nullable @@ -201,15 +201,15 @@ abstract class _$$AddTeamStateImplCopyWith<$Res> $Res call( {TextEditingController nameController, TextEditingController locationController, - String? imageUrl, bool isImageUploading, - bool? isNameAvailable, bool isAddMeCheckBoxEnable, bool checkingForAvailability, bool isAddBtnEnable, bool isAddInProgress, bool isPop, - List memberToDelete, + List teamMembers, + String? imageUrl, + bool? isNameAvailable, TeamModel? team, TeamModel? editTeam, UserModel? currentUser}); @@ -235,15 +235,15 @@ class __$$AddTeamStateImplCopyWithImpl<$Res> $Res call({ Object? nameController = null, Object? locationController = null, - Object? imageUrl = freezed, Object? isImageUploading = null, - Object? isNameAvailable = freezed, Object? isAddMeCheckBoxEnable = null, Object? checkingForAvailability = null, Object? isAddBtnEnable = null, Object? isAddInProgress = null, Object? isPop = null, - Object? memberToDelete = null, + Object? teamMembers = null, + Object? imageUrl = freezed, + Object? isNameAvailable = freezed, Object? team = freezed, Object? editTeam = freezed, Object? currentUser = freezed, @@ -257,18 +257,10 @@ class __$$AddTeamStateImplCopyWithImpl<$Res> ? _value.locationController : locationController // ignore: cast_nullable_to_non_nullable as TextEditingController, - imageUrl: freezed == imageUrl - ? _value.imageUrl - : imageUrl // ignore: cast_nullable_to_non_nullable - as String?, isImageUploading: null == isImageUploading ? _value.isImageUploading : isImageUploading // ignore: cast_nullable_to_non_nullable as bool, - isNameAvailable: freezed == isNameAvailable - ? _value.isNameAvailable - : isNameAvailable // ignore: cast_nullable_to_non_nullable - as bool?, isAddMeCheckBoxEnable: null == isAddMeCheckBoxEnable ? _value.isAddMeCheckBoxEnable : isAddMeCheckBoxEnable // ignore: cast_nullable_to_non_nullable @@ -289,10 +281,18 @@ class __$$AddTeamStateImplCopyWithImpl<$Res> ? _value.isPop : isPop // ignore: cast_nullable_to_non_nullable as bool, - memberToDelete: null == memberToDelete - ? _value._memberToDelete - : memberToDelete // ignore: cast_nullable_to_non_nullable - as List, + teamMembers: null == teamMembers + ? _value._teamMembers + : teamMembers // ignore: cast_nullable_to_non_nullable + as List, + imageUrl: freezed == imageUrl + ? _value.imageUrl + : imageUrl // ignore: cast_nullable_to_non_nullable + as String?, + isNameAvailable: freezed == isNameAvailable + ? _value.isNameAvailable + : isNameAvailable // ignore: cast_nullable_to_non_nullable + as bool?, team: freezed == team ? _value.team : team // ignore: cast_nullable_to_non_nullable @@ -315,19 +315,19 @@ class _$AddTeamStateImpl implements _AddTeamState { const _$AddTeamStateImpl( {required this.nameController, required this.locationController, - this.imageUrl = null, this.isImageUploading = false, - this.isNameAvailable = null, this.isAddMeCheckBoxEnable = true, this.checkingForAvailability = false, this.isAddBtnEnable = false, this.isAddInProgress = false, this.isPop = false, - final List memberToDelete = const [], - this.team = null, - this.editTeam = null, + final List teamMembers = const [], + this.imageUrl, + this.isNameAvailable, + this.team, + this.editTeam, this.currentUser}) - : _memberToDelete = memberToDelete; + : _teamMembers = teamMembers; @override final TextEditingController nameController; @@ -335,15 +335,9 @@ class _$AddTeamStateImpl implements _AddTeamState { final TextEditingController locationController; @override @JsonKey() - final String? imageUrl; - @override - @JsonKey() final bool isImageUploading; @override @JsonKey() - final bool? isNameAvailable; - @override - @JsonKey() final bool isAddMeCheckBoxEnable; @override @JsonKey() @@ -357,27 +351,29 @@ class _$AddTeamStateImpl implements _AddTeamState { @override @JsonKey() final bool isPop; - final List _memberToDelete; + final List _teamMembers; @override @JsonKey() - List get memberToDelete { - if (_memberToDelete is EqualUnmodifiableListView) return _memberToDelete; + List get teamMembers { + if (_teamMembers is EqualUnmodifiableListView) return _teamMembers; // ignore: implicit_dynamic_type - return EqualUnmodifiableListView(_memberToDelete); + return EqualUnmodifiableListView(_teamMembers); } @override - @JsonKey() + final String? imageUrl; + @override + final bool? isNameAvailable; + @override final TeamModel? team; @override - @JsonKey() final TeamModel? editTeam; @override final UserModel? currentUser; @override String toString() { - return 'AddTeamState(nameController: $nameController, locationController: $locationController, imageUrl: $imageUrl, isImageUploading: $isImageUploading, isNameAvailable: $isNameAvailable, isAddMeCheckBoxEnable: $isAddMeCheckBoxEnable, checkingForAvailability: $checkingForAvailability, isAddBtnEnable: $isAddBtnEnable, isAddInProgress: $isAddInProgress, isPop: $isPop, memberToDelete: $memberToDelete, team: $team, editTeam: $editTeam, currentUser: $currentUser)'; + return 'AddTeamState(nameController: $nameController, locationController: $locationController, isImageUploading: $isImageUploading, isAddMeCheckBoxEnable: $isAddMeCheckBoxEnable, checkingForAvailability: $checkingForAvailability, isAddBtnEnable: $isAddBtnEnable, isAddInProgress: $isAddInProgress, isPop: $isPop, teamMembers: $teamMembers, imageUrl: $imageUrl, isNameAvailable: $isNameAvailable, team: $team, editTeam: $editTeam, currentUser: $currentUser)'; } @override @@ -389,12 +385,8 @@ class _$AddTeamStateImpl implements _AddTeamState { other.nameController == nameController) && (identical(other.locationController, locationController) || other.locationController == locationController) && - (identical(other.imageUrl, imageUrl) || - other.imageUrl == imageUrl) && (identical(other.isImageUploading, isImageUploading) || other.isImageUploading == isImageUploading) && - (identical(other.isNameAvailable, isNameAvailable) || - other.isNameAvailable == isNameAvailable) && (identical(other.isAddMeCheckBoxEnable, isAddMeCheckBoxEnable) || other.isAddMeCheckBoxEnable == isAddMeCheckBoxEnable) && (identical( @@ -406,7 +398,11 @@ class _$AddTeamStateImpl implements _AddTeamState { other.isAddInProgress == isAddInProgress) && (identical(other.isPop, isPop) || other.isPop == isPop) && const DeepCollectionEquality() - .equals(other._memberToDelete, _memberToDelete) && + .equals(other._teamMembers, _teamMembers) && + (identical(other.imageUrl, imageUrl) || + other.imageUrl == imageUrl) && + (identical(other.isNameAvailable, isNameAvailable) || + other.isNameAvailable == isNameAvailable) && (identical(other.team, team) || other.team == team) && (identical(other.editTeam, editTeam) || other.editTeam == editTeam) && @@ -419,15 +415,15 @@ class _$AddTeamStateImpl implements _AddTeamState { runtimeType, nameController, locationController, - imageUrl, isImageUploading, - isNameAvailable, isAddMeCheckBoxEnable, checkingForAvailability, isAddBtnEnable, isAddInProgress, isPop, - const DeepCollectionEquality().hash(_memberToDelete), + const DeepCollectionEquality().hash(_teamMembers), + imageUrl, + isNameAvailable, team, editTeam, currentUser); @@ -443,15 +439,15 @@ abstract class _AddTeamState implements AddTeamState { const factory _AddTeamState( {required final TextEditingController nameController, required final TextEditingController locationController, - final String? imageUrl, final bool isImageUploading, - final bool? isNameAvailable, final bool isAddMeCheckBoxEnable, final bool checkingForAvailability, final bool isAddBtnEnable, final bool isAddInProgress, final bool isPop, - final List memberToDelete, + final List teamMembers, + final String? imageUrl, + final bool? isNameAvailable, final TeamModel? team, final TeamModel? editTeam, final UserModel? currentUser}) = _$AddTeamStateImpl; @@ -461,12 +457,8 @@ abstract class _AddTeamState implements AddTeamState { @override TextEditingController get locationController; @override - String? get imageUrl; - @override bool get isImageUploading; @override - bool? get isNameAvailable; - @override bool get isAddMeCheckBoxEnable; @override bool get checkingForAvailability; @@ -477,7 +469,11 @@ abstract class _AddTeamState implements AddTeamState { @override bool get isPop; @override - List get memberToDelete; + List get teamMembers; + @override + String? get imageUrl; + @override + bool? get isNameAvailable; @override TeamModel? get team; @override diff --git a/khelo/lib/ui/flow/team/add_team_member/add_team_member_screen.dart b/khelo/lib/ui/flow/team/add_team_member/add_team_member_screen.dart index 02520060..1412bd81 100644 --- a/khelo/lib/ui/flow/team/add_team_member/add_team_member_screen.dart +++ b/khelo/lib/ui/flow/team/add_team_member/add_team_member_screen.dart @@ -10,6 +10,7 @@ import 'package:khelo/ui/flow/team/add_team_member/add_team_member_view_model.da import 'package:khelo/ui/flow/team/add_team_member/components/verify_add_team_member_dialog.dart'; import 'package:style/animations/on_tap_scale.dart'; import 'package:style/extensions/context_extensions.dart'; +import 'package:style/indicator/progress_indicator.dart'; import 'package:style/text/app_text_style.dart'; class AddTeamMemberScreen extends ConsumerWidget { @@ -38,11 +39,18 @@ class AddTeamMemberScreen extends ConsumerWidget { actions: [ Visibility( visible: state.selectedUsers.isNotEmpty, - child: IconButton( - onPressed: () { - notifier.addPlayersToTeam(team.id ?? "INVALID ID"); - }, - icon: const Icon(Icons.check)), + child: state.isAddInProgress + ? const AppProgressIndicator( + size: AppProgressIndicatorSize.small, + ) + : IconButton( + onPressed: () { + notifier.addPlayersToTeam(team.id ?? "INVALID ID"); + }, + icon: Icon( + Icons.check, + color: context.colorScheme.primary, + )), ) ], body: Padding( @@ -53,9 +61,14 @@ class AddTeamMemberScreen extends ConsumerWidget { _searchTextField(context, notifier, state), Expanded( child: state.searchedUsers.isEmpty - ? const Center( + ? Center( child: Text( - "search above person to add them in your team"), + context.l10n.add_team_member_search_hint_text, + textAlign: TextAlign.center, + style: AppTextStyle.subtitle1.copyWith( + color: context.colorScheme.textDisabled, + fontSize: 20), + ), ) : ListView.separated( separatorBuilder: (context, index) { @@ -166,7 +179,7 @@ class AddTeamMemberScreen extends ConsumerWidget { Text( user.player_role != null ? _getPlayerRoleString(context, user.player_role!) - : "Not Specified", + : context.l10n.common_not_specified_title, style: AppTextStyle.subtitle2 .copyWith(color: context.colorScheme.textSecondary)), if (user.phone != null) ...[ @@ -174,7 +187,9 @@ class AddTeamMemberScreen extends ConsumerWidget { height: 2, ), Text( - "***** ***${user.phone!.substring(user.phone!.length - 2)}", + context.l10n.common_obscure_phone_number_text( + user.phone!.substring(1, 3), + user.phone!.substring(user.phone!.length - 2)), style: AppTextStyle.subtitle2 .copyWith(color: context.colorScheme.textSecondary), ), @@ -209,8 +224,8 @@ class AddTeamMemberScreen extends ConsumerWidget { borderRadius: BorderRadius.circular(20)), child: Text(team.players?.contains(user) == true || state.selectedUsers.contains(user) - ? "ADDED" - : "ADD"), + ? context.l10n.add_team_member_added_text + : context.l10n.add_team_member_add_text), ), ), ], diff --git a/khelo/lib/ui/flow/team/add_team_member/add_team_member_view_model.dart b/khelo/lib/ui/flow/team/add_team_member/add_team_member_view_model.dart index 9b617179..7d7e280c 100644 --- a/khelo/lib/ui/flow/team/add_team_member/add_team_member_view_model.dart +++ b/khelo/lib/ui/flow/team/add_team_member/add_team_member_view_model.dart @@ -54,9 +54,16 @@ class AddTeamMemberViewNotifier extends StateNotifier { state = state.copyWith(selectedUsers: updatedList); } - void addPlayersToTeam(String id) { - _teamService.addPlayersToTeam(id, state.selectedUsers); - state = state.copyWith(isAdded: true); + Future addPlayersToTeam(String id) async { + state = state.copyWith(isAddInProgress: true); + try { + await _teamService.addPlayersToTeam(id, state.selectedUsers); + state = state.copyWith(isAddInProgress: false, isAdded: true); + } catch (e) { + state = state.copyWith(isAddInProgress: false); + debugPrint( + "AddTeamMemberViewNotifier: error while adding players to team -> $e"); + } } @override @@ -75,5 +82,6 @@ class AddTeamMemberState with _$AddTeamMemberState { @Default([]) List selectedUsers, Object? error, @Default(false) bool isAdded, + @Default(false) bool isAddInProgress, }) = _AddTeamMemberState; } diff --git a/khelo/lib/ui/flow/team/add_team_member/add_team_member_view_model.freezed.dart b/khelo/lib/ui/flow/team/add_team_member/add_team_member_view_model.freezed.dart index 4e52be9d..c1dce207 100644 --- a/khelo/lib/ui/flow/team/add_team_member/add_team_member_view_model.freezed.dart +++ b/khelo/lib/ui/flow/team/add_team_member/add_team_member_view_model.freezed.dart @@ -24,6 +24,7 @@ mixin _$AddTeamMemberState { List get selectedUsers => throw _privateConstructorUsedError; Object? get error => throw _privateConstructorUsedError; bool get isAdded => throw _privateConstructorUsedError; + bool get isAddInProgress => throw _privateConstructorUsedError; @JsonKey(ignore: true) $AddTeamMemberStateCopyWith get copyWith => @@ -42,7 +43,8 @@ abstract class $AddTeamMemberStateCopyWith<$Res> { List searchedUsers, List selectedUsers, Object? error, - bool isAdded}); + bool isAdded, + bool isAddInProgress}); } /// @nodoc @@ -64,6 +66,7 @@ class _$AddTeamMemberStateCopyWithImpl<$Res, $Val extends AddTeamMemberState> Object? selectedUsers = null, Object? error = freezed, Object? isAdded = null, + Object? isAddInProgress = null, }) { return _then(_value.copyWith( searchController: null == searchController @@ -87,6 +90,10 @@ class _$AddTeamMemberStateCopyWithImpl<$Res, $Val extends AddTeamMemberState> ? _value.isAdded : isAdded // ignore: cast_nullable_to_non_nullable as bool, + isAddInProgress: null == isAddInProgress + ? _value.isAddInProgress + : isAddInProgress // ignore: cast_nullable_to_non_nullable + as bool, ) as $Val); } } @@ -105,7 +112,8 @@ abstract class _$$AddTeamMemberStateImplCopyWith<$Res> List searchedUsers, List selectedUsers, Object? error, - bool isAdded}); + bool isAdded, + bool isAddInProgress}); } /// @nodoc @@ -125,6 +133,7 @@ class __$$AddTeamMemberStateImplCopyWithImpl<$Res> Object? selectedUsers = null, Object? error = freezed, Object? isAdded = null, + Object? isAddInProgress = null, }) { return _then(_$AddTeamMemberStateImpl( searchController: null == searchController @@ -148,6 +157,10 @@ class __$$AddTeamMemberStateImplCopyWithImpl<$Res> ? _value.isAdded : isAdded // ignore: cast_nullable_to_non_nullable as bool, + isAddInProgress: null == isAddInProgress + ? _value.isAddInProgress + : isAddInProgress // ignore: cast_nullable_to_non_nullable + as bool, )); } } @@ -161,7 +174,8 @@ class _$AddTeamMemberStateImpl implements _AddTeamMemberState { final List searchedUsers = const [], final List selectedUsers = const [], this.error, - this.isAdded = false}) + this.isAdded = false, + this.isAddInProgress = false}) : _searchedUsers = searchedUsers, _selectedUsers = selectedUsers; @@ -192,10 +206,13 @@ class _$AddTeamMemberStateImpl implements _AddTeamMemberState { @override @JsonKey() final bool isAdded; + @override + @JsonKey() + final bool isAddInProgress; @override String toString() { - return 'AddTeamMemberState(searchController: $searchController, verifyNumberController: $verifyNumberController, searchedUsers: $searchedUsers, selectedUsers: $selectedUsers, error: $error, isAdded: $isAdded)'; + return 'AddTeamMemberState(searchController: $searchController, verifyNumberController: $verifyNumberController, searchedUsers: $searchedUsers, selectedUsers: $selectedUsers, error: $error, isAdded: $isAdded, isAddInProgress: $isAddInProgress)'; } @override @@ -212,7 +229,9 @@ class _$AddTeamMemberStateImpl implements _AddTeamMemberState { const DeepCollectionEquality() .equals(other._selectedUsers, _selectedUsers) && const DeepCollectionEquality().equals(other.error, error) && - (identical(other.isAdded, isAdded) || other.isAdded == isAdded)); + (identical(other.isAdded, isAdded) || other.isAdded == isAdded) && + (identical(other.isAddInProgress, isAddInProgress) || + other.isAddInProgress == isAddInProgress)); } @override @@ -223,7 +242,8 @@ class _$AddTeamMemberStateImpl implements _AddTeamMemberState { const DeepCollectionEquality().hash(_searchedUsers), const DeepCollectionEquality().hash(_selectedUsers), const DeepCollectionEquality().hash(error), - isAdded); + isAdded, + isAddInProgress); @JsonKey(ignore: true) @override @@ -240,7 +260,8 @@ abstract class _AddTeamMemberState implements AddTeamMemberState { final List searchedUsers, final List selectedUsers, final Object? error, - final bool isAdded}) = _$AddTeamMemberStateImpl; + final bool isAdded, + final bool isAddInProgress}) = _$AddTeamMemberStateImpl; @override TextEditingController get searchController; @@ -255,6 +276,8 @@ abstract class _AddTeamMemberState implements AddTeamMemberState { @override bool get isAdded; @override + bool get isAddInProgress; + @override @JsonKey(ignore: true) _$$AddTeamMemberStateImplCopyWith<_$AddTeamMemberStateImpl> get copyWith => throw _privateConstructorUsedError; diff --git a/khelo/lib/ui/flow/team/add_team_member/components/verify_add_team_member_dialog.dart b/khelo/lib/ui/flow/team/add_team_member/components/verify_add_team_member_dialog.dart index 9ae55d65..b244468b 100644 --- a/khelo/lib/ui/flow/team/add_team_member/components/verify_add_team_member_dialog.dart +++ b/khelo/lib/ui/flow/team/add_team_member/components/verify_add_team_member_dialog.dart @@ -21,12 +21,24 @@ class _VerifyAddTeamMemberDialogState extends State { @override Widget build(BuildContext context) { return AlertDialog( - title: Text(context.l10n.add_team_member_verify_title), + backgroundColor: context.colorScheme.containerLowOnSurface, + title: Text( + context.l10n.add_team_member_verify_title, + style: AppTextStyle.header1 + .copyWith(color: context.colorScheme.textPrimary, fontSize: 26), + ), content: Wrap( children: [ - Text(context.l10n.add_team_member_verify_placeholder_text), + Text( + context.l10n.add_team_member_verify_placeholder_text, + style: AppTextStyle.header4 + .copyWith(color: context.colorScheme.textPrimary, fontSize: 20), + ), TextField( maxLength: 5, + decoration: InputDecoration( + counterStyle: AppTextStyle.body1 + .copyWith(color: context.colorScheme.textDisabled)), textAlign: TextAlign.center, style: AppTextStyle.subtitle1 .copyWith(color: context.colorScheme.textPrimary, fontSize: 34), @@ -47,9 +59,9 @@ class _VerifyAddTeamMemberDialogState extends State { context.pop(); }, child: Text( - "Cancel", - style: AppTextStyle.button - .copyWith(color: context.colorScheme.textPrimary), + context.l10n.common_cancel_title, + style: AppTextStyle.button.copyWith( + color: context.colorScheme.textPrimary, fontSize: 18), )), TextButton( onPressed: verificationNumber.trim().length == 5 @@ -62,11 +74,12 @@ class _VerifyAddTeamMemberDialogState extends State { } : null, child: Text( - "Verify", + context.l10n.add_team_member_verify_title, style: AppTextStyle.button.copyWith( color: verificationNumber.trim().length == 5 ? context.colorScheme.textPrimary - : context.colorScheme.textDisabled), + : context.colorScheme.textDisabled, + fontSize: 18), )), ], ); diff --git a/khelo/lib/ui/flow/team/team_list_screen.dart b/khelo/lib/ui/flow/team/team_list_screen.dart index ea777678..7c6f7f5b 100644 --- a/khelo/lib/ui/flow/team/team_list_screen.dart +++ b/khelo/lib/ui/flow/team/team_list_screen.dart @@ -2,6 +2,7 @@ import 'package:cached_network_image/cached_network_image.dart'; import 'package:data/api/team/team_model.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:khelo/domain/extensions/context_extensions.dart'; import 'package:khelo/ui/app_route.dart'; import 'package:khelo/ui/flow/team/team_list_view_model.dart'; import 'package:style/button/large_icon_button.dart'; @@ -85,26 +86,35 @@ class TeamListScreen extends ConsumerWidget { style: AppTextStyle.header4 .copyWith(color: context.colorScheme.textPrimary), ), - Text(team.city ?? "Not Specified", + Text(team.city ?? context.l10n.common_not_specified_title, style: AppTextStyle.subtitle2 .copyWith(color: context.colorScheme.textSecondary)), ], ), ), PopupMenuButton( + color: context.colorScheme.containerLowOnSurface, + iconColor: context.colorScheme.textPrimary, onSelected: (value) async { - if (value == "Add Members") { + if (value == context.l10n.team_list_add_members_title) { await AppRoute.addTeamMember(team: team).push(context); - } else if (value == "Edit Team") { + } else if (value == context.l10n.team_list_edit_team_title) { await AppRoute.addTeam(team: team).push(context); } notifier.loadTeamList(); }, itemBuilder: (BuildContext context) { - return {'Add Members', 'Edit Team'}.map((String choice) { + return { + context.l10n.team_list_add_members_title, + context.l10n.team_list_edit_team_title + }.map((String choice) { return PopupMenuItem( value: choice, - child: Text(choice), + child: Text( + choice, + style: AppTextStyle.subtitle1 + .copyWith(color: context.colorScheme.textPrimary), + ), ); }).toList(); }, diff --git a/khelo/lib/ui/flow/team/team_list_view_model.dart b/khelo/lib/ui/flow/team/team_list_view_model.dart index 749de460..b20b5dd1 100644 --- a/khelo/lib/ui/flow/team/team_list_view_model.dart +++ b/khelo/lib/ui/flow/team/team_list_view_model.dart @@ -22,7 +22,7 @@ class TeamListViewNotifier extends StateNotifier { Future loadTeamList() async { state = state.copyWith(loading: true); try { - final res = await _teamService.getTeamsWithPlayers(); + final res = await _teamService.getTeams(); state = state.copyWith(teams: res, loading: false); } catch (e) { state = state.copyWith(loading: false); diff --git a/khelo/pubspec.lock b/khelo/pubspec.lock index a4f37e7e..98e2e308 100644 --- a/khelo/pubspec.lock +++ b/khelo/pubspec.lock @@ -1249,7 +1249,7 @@ packages: source: hosted version: "1.3.2" uuid: - dependency: "direct main" + dependency: transitive description: name: uuid sha256: cd210a09f7c18cbe5a02511718e0334de6559871052c90a90c0cca46a4aa81c8 diff --git a/khelo/pubspec.yaml b/khelo/pubspec.yaml index 814394bb..10ffc613 100644 --- a/khelo/pubspec.yaml +++ b/khelo/pubspec.yaml @@ -52,7 +52,6 @@ dependencies: # io freezed_annotation: ^2.4.1 - uuid: ^4.0.0 # auth firebase_core: ^2.24.2