Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ dependencies {
implementation(libs.androidx.constraintlayout)
implementation(libs.androidx.runtime.android)
testImplementation(libs.junit)
testImplementation("com.squareup.okhttp3:mockwebserver:4.12.0")
debugImplementation("androidx.compose.ui:ui-tooling")
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
Expand All @@ -108,10 +109,11 @@ dependencies {
apollo {
service("service") {
packageName.set("com.example.score")
introspection {
endpointUrl.set("\"${secrets.getProperty("API_URL_DEV")}\"")
schemaFile.set(file("src/main/graphql/schema.graphqls"))
secrets.getProperty("API_URL_DEV")?.takeIf { it.isNotBlank() }?.let { apiUrl ->
introspection {
endpointUrl.set(apiUrl)
schemaFile.set(file("src/main/graphql/schema.graphqls"))
}
}
}
}

51 changes: 22 additions & 29 deletions app/src/main/graphql/FragmentedGame.graphql
Original file line number Diff line number Diff line change
@@ -1,33 +1,26 @@
query PagedGames($limit: Int!, $offset: Int!) {
games(limit: $limit, offset: $offset) {
id
city
date
gender
location
opponentId
result
sport
state
time
scoreBreakdown
utcDate
team {
id
color
image
name
}
boxScore {
team
period
time
description
scorer
assist
scoreBy
corScore
oppScore
}
...GameListItem
}
}

query InitialGames($startDate: DateTime!, $endDate: DateTime!) {
gamesByDate(startDate: $startDate, endDate: $endDate) {
...GameListItem
}
}

fragment GameListItem on GameType {
id
city
date
gender
result
sport
time
team {
color
image
name
}
}
86 changes: 82 additions & 4 deletions app/src/main/graphql/schema.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,21 @@ type Query {

game(id: String!): GameType

gameByData(city: String!, date: String!, gender: String!, location: String, opponentId: String!, sport: String!, state: String!, time: String!, ticketLink: String): GameType
gameByData(city: String!, date: String!, gender: String!, location: String, opponentId: String!, sport: String!, state: String!, time: String!): GameType

gamesBySport(sport: String!): [GameType]

gamesByGender(gender: String!): [GameType]

gamesBySportGender(sport: String!, gender: String!): [GameType]

gamesByDate(startDate: DateTime!, endDate: DateTime!): [GameType]

"""
Current user's favorited games (requires auth).
"""
myFavoritedGames: [GameType]

teams: [TeamType]

team(id: String!): TeamType
Expand Down Expand Up @@ -55,9 +62,11 @@ Attributes:
- id: The YouTube video ID (optional).
- title: The title of the video.
- description: The description of the video.
- thumbnail: The URL of the video's thumbnail.
- thumbnail: The URL of the video's thumbnail. (optional)
- url: The URL to the video.
- published_at: The date and time the video was published.
- duration: The duration of the video (optional).
- sportsType: The sport type extracted from the video title.
"""
type YoutubeVideoType {
id: String
Expand All @@ -68,11 +77,15 @@ type YoutubeVideoType {

thumbnail: String!

b64Thumbnail: String!
b64Thumbnail: String

url: String!

publishedAt: String!

duration: String

sportsType: String
}

"""
Expand Down Expand Up @@ -181,6 +194,13 @@ type TeamType {
name: String!
}

"""
The `DateTime` scalar type represents a DateTime
value as specified by
[iso8601](https://en.wikipedia.org/wiki/ISO_8601).
"""
scalar DateTime

type Mutation {
"""
Creates a new game.
Expand All @@ -195,12 +215,42 @@ type Mutation {
"""
Creates a new youtube video.
"""
createYoutubeVideo(b64Thumbnail: String!, description: String!, id: String!, publishedAt: String!, thumbnail: String!, title: String!, url: String!): CreateYoutubeVideo
createYoutubeVideo(b64Thumbnail: String, description: String!, duration: String!, id: String!, publishedAt: String!, thumbnail: String!, title: String!, url: String!): CreateYoutubeVideo

"""
Creates a new article.
"""
createArticle(image: String, publishedAt: String!, slug: String!, sportsType: String!, title: String!, url: String!): CreateArticle

"""
Login by net_id; returns access_token and refresh_token.
"""
loginUser("User's net ID (e.g. Cornell netid)." netId: String!): LoginUser

"""
Create a new user by net_id; returns access_token and refresh_token (no separate login needed).
"""
signupUser("Email address." email: String, "Display name." name: String, "User's net ID (e.g. Cornell netid)." netId: String!): SignupUser

"""
Exchange a valid refresh token (in Authorization header) for a new access_token.
"""
refreshAccessToken: RefreshAccessToken

"""
Revoke the current token (access or refresh). Send token in Authorization header.
"""
logoutUser: LogoutUser

"""
Add a game to the current user's favorites (requires auth).
"""
addFavoriteGame("ID of the game to add to favorites." gameId: String!): AddFavoriteGame

"""
Remove a game from the current user's favorites (requires auth).
"""
removeFavoriteGame("ID of the game to remove from favorites." gameId: String!): RemoveFavoriteGame
}

type CreateGame {
Expand All @@ -219,6 +269,34 @@ type CreateArticle {
article: ArticleType
}

type LoginUser {
accessToken: String

refreshToken: String
}

type SignupUser {
accessToken: String

refreshToken: String
}

type RefreshAccessToken {
newAccessToken: String
}

type LogoutUser {
success: Boolean
}

type AddFavoriteGame {
success: Boolean
}

type RemoveFavoriteGame {
success: Boolean
}

"""
A GraphQL Schema defines the capabilities of a GraphQL server. It exposes all available types and directives on the server, as well as the entry points for query, mutation and subscription operations.
"""
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.cornellappdev.score.model

import com.cornellappdev.score.util.parseColor
import com.cornellappdev.score.util.parseResultScore
import com.example.score.fragment.GameListItem

fun GameListItem.isMens(): Boolean = gender == "Mens"

fun GameListItem.toGame(): Game? {
val gameTeam = team ?: return null
val imageUrl = gameTeam.image ?: return null
val scores = result?.split(",")?.getOrNull(1)?.split("-")
val fallbackScores = parseResultScore(result)
return Game(
id = id ?: "",
teamLogo = imageUrl,
time = time,
teamName = gameTeam.name,
teamColor = parseColor(gameTeam.color).copy(alpha = 0.4f * 255),
gender = if (isMens()) "Men's" else "Women's",
sport = sport,
date = date,
city = city,
cornellScore = scores?.getOrNull(0)?.toNumberOrNull() ?: fallbackScores?.first,
otherScore = scores?.getOrNull(1)?.toNumberOrNull() ?: fallbackScores?.second
)
}

private fun String.toNumberOrNull(): Number? =
if (contains(".")) toFloatOrNull() else toIntOrNull()
Loading
Loading