From 826118fb38e18426831e67df8b9e9b5f55422479 Mon Sep 17 00:00:00 2001
From: Emil Jiang <eyj7@cornell.edu>
Date: Thu, 13 Mar 2025 11:49:54 -0400
Subject: [PATCH 1/3] gamedetails networking

---
 app/src/main/graphql/GameById.graphql         | 32 ++++++++++
 .../com/cornellappdev/score/model/Game.kt     | 39 ++++++++++++
 .../score/model/ScoreRepository.kt            | 60 ++++++++++++++++++-
 3 files changed, 130 insertions(+), 1 deletion(-)
 create mode 100644 app/src/main/graphql/GameById.graphql

diff --git a/app/src/main/graphql/GameById.graphql b/app/src/main/graphql/GameById.graphql
new file mode 100644
index 0000000..aced4b7
--- /dev/null
+++ b/app/src/main/graphql/GameById.graphql
@@ -0,0 +1,32 @@
+query GameById($id: String!) {
+    game(id: $id){
+        id
+        city
+        date
+        gender
+        location
+        opponentId
+        result
+        sport
+        state
+        time
+        scoreBreakdown
+        team {
+            id
+            color
+            image
+            name
+        }
+        boxScore {
+            team
+            period
+            time
+            description
+            scorer
+            assist
+            scoreBy
+            corScore
+            oppScore
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/cornellappdev/score/model/Game.kt b/app/src/main/java/com/cornellappdev/score/model/Game.kt
index 7a71627..b0a8c92 100644
--- a/app/src/main/java/com/cornellappdev/score/model/Game.kt
+++ b/app/src/main/java/com/cornellappdev/score/model/Game.kt
@@ -15,6 +15,45 @@ data class Game(
     val city: String
 )
 
+/**
+ * Clean up?
+ */
+data class GameDetailsTeam(
+    val id: String?,
+    val color: String?,
+    val image: String?,
+    val name: String?
+)
+
+data class GameDetailsBoxScore(
+    val team: String?,
+    val period: String?,
+    val time: String?,
+    val description: String?,
+    val scorer: String?,
+    val assist: String?,
+    val scoreBy: String?,
+    val corScore: Int?,
+    val oppScore: Int?
+)
+
+data class GameDetailsGame(
+    val id: String,
+    val city: String?,
+    val date: String?,
+    val gender: String?,
+    val location: String?,
+    val opponentId: String?,
+    val result: String?,
+    val sport: String?,
+    val state: String?,
+    val time: String?,
+    val scoreBreakdown: List<List<String?>?>?,
+    val team: GameDetailsTeam?,
+    val boxScore: List<GameDetailsBoxScore>?
+)
+
+
 //Data for HomeScreen game displays
 data class GameCardData(
     val teamLogo: String,
diff --git a/app/src/main/java/com/cornellappdev/score/model/ScoreRepository.kt b/app/src/main/java/com/cornellappdev/score/model/ScoreRepository.kt
index 073c0e4..a47343b 100644
--- a/app/src/main/java/com/cornellappdev/score/model/ScoreRepository.kt
+++ b/app/src/main/java/com/cornellappdev/score/model/ScoreRepository.kt
@@ -2,10 +2,13 @@ package com.cornellappdev.score.model
 
 import android.util.Log
 import com.apollographql.apollo.ApolloClient
+import com.example.score.GameByIdQuery
 import com.example.score.GamesQuery
 import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.launch
 import javax.inject.Inject
 import javax.inject.Singleton
@@ -26,7 +29,8 @@ class ScoreRepository @Inject constructor(
         MutableStateFlow<ApiResponse<List<Game>>>(ApiResponse.Loading)
     val upcomingGamesFlow = _upcomingGamesFlow.asStateFlow()
 
-
+    private val _currGameFlow = MutableStateFlow<ApiResponse<GameDetailsGame>>(ApiResponse.Loading)
+    val currGamesFlow = _currGameFlow.asStateFlow()
     /**
      * Asynchronously fetches the list of games from the API. Once finished, will send down
      * `upcomingGamesFlow` to be observed.
@@ -58,4 +62,58 @@ class ScoreRepository @Inject constructor(
             _upcomingGamesFlow.value = ApiResponse.Error
         }
     }
+
+    fun getGameById(id: String) = appScope.launch {
+        _currGameFlow.value = ApiResponse.Loading
+        try {
+            val response = apolloClient.query(GameByIdQuery(id)).execute()
+            val game = response.data?.game
+
+            if (game != null) {
+                val temp = GameDetailsGame(
+                    id = game.id ?: "",
+                    city = game.city,
+                    date = game.date,
+                    gender = game.gender,
+                    location = game.location,
+                    opponentId = game.opponentId,
+                    result = game.result,
+                    sport = game.sport,
+                    state = game.state,
+                    time = game.time,
+                    scoreBreakdown = game.scoreBreakdown,
+                    team = game.team?.let { team ->
+                        GameDetailsTeam(
+                            id = team.id,
+                            color = team.color,
+                            image = team.image,
+                            name = team.name
+                        )
+                    },
+                    boxScore = game.boxScore?.mapNotNull { boxScore ->
+                        boxScore?.let {
+                            GameDetailsBoxScore(
+                                team = it.team,
+                                period = it.period,
+                                time = it.time,
+                                description = it.description,
+                                scorer = it.scorer,
+                                assist = it.assist,
+                                scoreBy = it.scoreBy,
+                                corScore = it.corScore,
+                                oppScore = it.oppScore
+                            )
+                        }
+                    }
+                )
+                _currGameFlow.value = ApiResponse.Success(temp)
+            } else {
+                _currGameFlow.value = ApiResponse.Error
+            }
+        } catch (e: Exception) {
+            Log.e("ScoreRepository", "Error fetching game with id: ${id}: ", e)
+            _currGameFlow.value = ApiResponse.Error
+        }
+    }
+
 }
\ No newline at end of file

From 8cbd945010ee7cf443d3b4c5453496265a1d0e47 Mon Sep 17 00:00:00 2001
From: Emil Jiang <eyj7@cornell.edu>
Date: Tue, 18 Mar 2025 22:57:43 -0400
Subject: [PATCH 2/3] all PR comments addressed except for toResult

---
 .../com/cornellappdev/score/model/Game.kt     |  3 --
 .../score/model/GameByIdQueryMappers.kt       | 44 ++++++++++++++++
 .../score/model/ScoreRepository.kt            | 52 ++++---------------
 3 files changed, 54 insertions(+), 45 deletions(-)
 create mode 100644 app/src/main/java/com/cornellappdev/score/model/GameByIdQueryMappers.kt

diff --git a/app/src/main/java/com/cornellappdev/score/model/Game.kt b/app/src/main/java/com/cornellappdev/score/model/Game.kt
index b0a8c92..a522552 100644
--- a/app/src/main/java/com/cornellappdev/score/model/Game.kt
+++ b/app/src/main/java/com/cornellappdev/score/model/Game.kt
@@ -15,9 +15,6 @@ data class Game(
     val city: String
 )
 
-/**
- * Clean up?
- */
 data class GameDetailsTeam(
     val id: String?,
     val color: String?,
diff --git a/app/src/main/java/com/cornellappdev/score/model/GameByIdQueryMappers.kt b/app/src/main/java/com/cornellappdev/score/model/GameByIdQueryMappers.kt
new file mode 100644
index 0000000..fe4213e
--- /dev/null
+++ b/app/src/main/java/com/cornellappdev/score/model/GameByIdQueryMappers.kt
@@ -0,0 +1,44 @@
+package com.cornellappdev.score.model
+
+import com.example.score.GameByIdQuery
+
+fun GameByIdQuery.Game.toGameDetails(): GameDetailsGame {
+    return GameDetailsGame(
+        id = this.id ?: "",
+        city = this.city,
+        date = this.date,
+        gender = this.gender,
+        location = this.location,
+        opponentId = this.opponentId,
+        result = this.result,
+        sport = this.sport,
+        state = this.state,
+        time = this.time,
+        scoreBreakdown = this.scoreBreakdown,
+        team = this.team?.toGameDetailsTeam(),
+        boxScore = this.boxScore?.mapNotNull { it?.toGameDetailsBoxScore() }
+    )
+}
+fun GameByIdQuery.Team.toGameDetailsTeam(): GameDetailsTeam {
+    return GameDetailsTeam(
+        id = this.id,
+        color = this.color,
+        image = this.image,
+        name = this.name
+    )
+}
+
+fun GameByIdQuery.BoxScore.toGameDetailsBoxScore(): GameDetailsBoxScore {
+    return GameDetailsBoxScore(
+        team = this.team,
+        period = this.period,
+        time = this.time,
+        description = this.description,
+        scorer = this.scorer,
+        assist = this.assist,
+        scoreBy = this.scoreBy,
+        corScore = this.corScore,
+        oppScore = this.oppScore
+    )
+}
+
diff --git a/app/src/main/java/com/cornellappdev/score/model/ScoreRepository.kt b/app/src/main/java/com/cornellappdev/score/model/ScoreRepository.kt
index a47343b..dd9aba9 100644
--- a/app/src/main/java/com/cornellappdev/score/model/ScoreRepository.kt
+++ b/app/src/main/java/com/cornellappdev/score/model/ScoreRepository.kt
@@ -29,8 +29,8 @@ class ScoreRepository @Inject constructor(
         MutableStateFlow<ApiResponse<List<Game>>>(ApiResponse.Loading)
     val upcomingGamesFlow = _upcomingGamesFlow.asStateFlow()
 
-    private val _currGameFlow = MutableStateFlow<ApiResponse<GameDetailsGame>>(ApiResponse.Loading)
-    val currGamesFlow = _currGameFlow.asStateFlow()
+    private val _currentGameFlow = MutableStateFlow<ApiResponse<GameDetailsGame>>(ApiResponse.Loading)
+    val currentGamesFlow = _currentGameFlow.asStateFlow()
     /**
      * Asynchronously fetches the list of games from the API. Once finished, will send down
      * `upcomingGamesFlow` to be observed.
@@ -63,56 +63,24 @@ class ScoreRepository @Inject constructor(
         }
     }
 
+    /**
+     * Asynchronously fetches game details for a particular game. Once finished, will send down
+     * `currentGamesFlow` to be observed.
+     */
     fun getGameById(id: String) = appScope.launch {
-        _currGameFlow.value = ApiResponse.Loading
+        _currentGameFlow.value = ApiResponse.Loading
         try {
             val response = apolloClient.query(GameByIdQuery(id)).execute()
             val game = response.data?.game
 
             if (game != null) {
-                val temp = GameDetailsGame(
-                    id = game.id ?: "",
-                    city = game.city,
-                    date = game.date,
-                    gender = game.gender,
-                    location = game.location,
-                    opponentId = game.opponentId,
-                    result = game.result,
-                    sport = game.sport,
-                    state = game.state,
-                    time = game.time,
-                    scoreBreakdown = game.scoreBreakdown,
-                    team = game.team?.let { team ->
-                        GameDetailsTeam(
-                            id = team.id,
-                            color = team.color,
-                            image = team.image,
-                            name = team.name
-                        )
-                    },
-                    boxScore = game.boxScore?.mapNotNull { boxScore ->
-                        boxScore?.let {
-                            GameDetailsBoxScore(
-                                team = it.team,
-                                period = it.period,
-                                time = it.time,
-                                description = it.description,
-                                scorer = it.scorer,
-                                assist = it.assist,
-                                scoreBy = it.scoreBy,
-                                corScore = it.corScore,
-                                oppScore = it.oppScore
-                            )
-                        }
-                    }
-                )
-                _currGameFlow.value = ApiResponse.Success(temp)
+                _currentGameFlow.value = ApiResponse.Success(game.toGameDetails())
             } else {
-                _currGameFlow.value = ApiResponse.Error
+                _currentGameFlow.value = ApiResponse.Error
             }
         } catch (e: Exception) {
             Log.e("ScoreRepository", "Error fetching game with id: ${id}: ", e)
-            _currGameFlow.value = ApiResponse.Error
+            _currentGameFlow.value = ApiResponse.Error
         }
     }
 

From cd5cf1698a3597fc69185f33b1e680bb2e1ad13d Mon Sep 17 00:00:00 2001
From: Emil Jiang <eyj7@cornell.edu>
Date: Wed, 19 Mar 2025 00:34:56 -0400
Subject: [PATCH 3/3] fixed data classes to match schema

---
 .../com/cornellappdev/score/model/Game.kt     | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/app/src/main/java/com/cornellappdev/score/model/Game.kt b/app/src/main/java/com/cornellappdev/score/model/Game.kt
index a522552..5ec9399 100644
--- a/app/src/main/java/com/cornellappdev/score/model/Game.kt
+++ b/app/src/main/java/com/cornellappdev/score/model/Game.kt
@@ -17,9 +17,9 @@ data class Game(
 
 data class GameDetailsTeam(
     val id: String?,
-    val color: String?,
+    val color: String,
     val image: String?,
-    val name: String?
+    val name: String
 )
 
 data class GameDetailsBoxScore(
@@ -35,15 +35,15 @@ data class GameDetailsBoxScore(
 )
 
 data class GameDetailsGame(
-    val id: String,
-    val city: String?,
-    val date: String?,
-    val gender: String?,
+    val id: String?,
+    val city: String,
+    val date: String,
+    val gender: String,
     val location: String?,
-    val opponentId: String?,
+    val opponentId: String,
     val result: String?,
-    val sport: String?,
-    val state: String?,
+    val sport: String,
+    val state: String,
     val time: String?,
     val scoreBreakdown: List<List<String?>?>?,
     val team: GameDetailsTeam?,
@@ -51,6 +51,7 @@ data class GameDetailsGame(
 )
 
 
+
 //Data for HomeScreen game displays
 data class GameCardData(
     val teamLogo: String,