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: 5 additions & 5 deletions score-ios/Models/GraphQL/schema.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ type Query {
offset: Int = 0
): [GameType]
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]
Expand Down Expand Up @@ -70,7 +70,7 @@ 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).
Expand All @@ -81,7 +81,7 @@ type YoutubeVideoType {
title: String!
description: String!
thumbnail: String!
b64Thumbnail: String!
b64Thumbnail: String
url: String!
publishedAt: String!
duration: String
Expand Down Expand Up @@ -183,7 +183,7 @@ type Mutation {
createTeam(b64Image: String, color: String!, image: String, name: String!): CreateTeam

"""Creates a new youtube video."""
createYoutubeVideo(b64Thumbnail: String!, description: String!, duration: 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
Expand All @@ -203,4 +203,4 @@ type CreateYoutubeVideo {

type CreateArticle {
article: ArticleType
}
}
32 changes: 0 additions & 32 deletions score-ios/Models/Sport.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,32 +15,16 @@ enum Sport : String, Identifiable, CaseIterable, CustomStringConvertible {

// Both
case Basketball
// case CrossCountry
case IceHockey
case Lacrosse
case Soccer
// case Squash
// case SwimmingDiving
// case Tennis
// case TrackField

// Women
// case Fencing
case FieldHockey
// case Gymnastics
// case Rowing
// case Sailing
// case Softball
// case Volleyball

// Men
case Baseball
case Football
// case Golf
// case RowingHeavyweight
// case RowingLightweight
// case SprintFootball
// case Wrestling

// init from a string from backend (might include spaces)
init?(normalizedValue: String) {
Expand All @@ -60,28 +44,12 @@ enum Sport : String, Identifiable, CaseIterable, CustomStringConvertible {
switch self {
case .All: return "All"
case .Basketball: return "Basketball"
// case .CrossCountry: return "Cross Country"
case .IceHockey: return "Ice Hockey"
case .Lacrosse: return "Lacrosse"
case .Soccer: return "Soccer"
// case .Squash: return "Squash"
// case .SwimmingDiving: return "Swimming"
// case .Tennis: return "Tennis"
// case .TrackField: return "Track and Field"
// case .Fencing: return "Fencing"
case .FieldHockey: return "Field Hockey"
// case .Gymnastics: return "Gymnastics"
// case .Rowing: return "Rowing"
// case .Sailing: return "Sailing"
// case .Softball: return "Softball"
// case .Volleyball: return "Volleyball"
case .Baseball: return "Baseball"
case .Football: return "Football"
// case .Golf: return "Golf"
// case .RowingHeavyweight: return "HW Rowing"
// case .RowingLightweight: return "LW Rowing"
// case .SprintFootball: return "Sprint Football"
// case .Wrestling: return "Wrestling"
}
}
}
Expand Down
14 changes: 7 additions & 7 deletions score-ios/ViewModels/GamesViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import GameAPI
// State enum to track the loading state
enum DataState {
case idle // Initial state, nothing has been fetched yet
case loading // Fetch in progress
case loading // Initial fetch in progress
case refreshing // Refreshing in progress
case success // Fetch completed successfully
case error(error: ScoreError) // Fetch failed with an error message
}
Expand Down Expand Up @@ -143,11 +144,10 @@ class GamesViewModel: ObservableObject
// TODO: Remove once backend is has implemented pagination with sorted dates and pages by game type
func fetchGames() {
// Set loading state before fetch
dataState = .loading
// Clear the current arrays
self.games.removeAll()
self.allPastGames.removeAll()
self.allUpcomingGames.removeAll()
dataState = (hasNotFetchedYet ? .loading : .refreshing)

self.privateUpcomingGames.removeAll()
self.privatePastGames.removeAll()

// Start fetching from the first page
fetchGamesRecursively(limit: 50, offset: 0, accumulatedGames: [])
Expand Down Expand Up @@ -272,7 +272,7 @@ class GamesViewModel: ObservableObject
// Sort all the collections
self.allPastGames.sort(by: {$0.date > $1.date})
self.allUpcomingGames.sort(by: {$0.date < $1.date})
self.games = updatedGames.sorted(by: {$0.date < $1.date})
self.games.sort(by: {$0.date < $1.date})
self.topUpcomingGames = Array(self.allUpcomingGames.prefix(3))
self.topPastGames = Array(self.allPastGames.prefix(3))
self.filter()
Expand Down
15 changes: 4 additions & 11 deletions score-ios/ViewModels/HighlightsViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,7 @@ class HighlightsViewModel: ObservableObject {

// MARK: - Loading
func loadHighlights() {
dataState = .loading

self.allHighlights.removeAll()
self.mainTodayHighlights.removeAll()
self.mainPastThreeDaysHighlights.removeAll()
self.detailedTodayHighlights.removeAll()
self.detailedPastThreeDaysHighlights.removeAll()
self.allHighlightsSearchResults.removeAll()
dataState = (hasNotFetchedYet ? .loading : .refreshing)

Task {
do {
Expand All @@ -61,7 +54,7 @@ class HighlightsViewModel: ObservableObject {
}
}

func retryFetch() {
func retryFetch(isRefresh: Bool) {
loadHighlights()
}

Expand All @@ -71,8 +64,8 @@ class HighlightsViewModel: ObservableObject {
private func processHighlights(_ articleDataArray: [ArticlesQuery.Data.Article], _ youTubeVideoDataArray: [YoutubeVideosQuery.Data.YoutubeVideo]) {
let localArticles = articleDataArray.map { Article(from: $0) }
let localYouTubeVideos = youTubeVideoDataArray.map {YouTubeVideo(from: $0)}
self.privateAllHighlights += localArticles.map { Highlight.article($0) } + localYouTubeVideos.map { Highlight.video($0) }

self.privateAllHighlights = localArticles.map { Highlight.article($0) } + localYouTubeVideos.map { Highlight.video($0) }
self.allHighlights = self.uniqueHighlights(from: self.privateAllHighlights)
self.allHighlights.sort(by: { $0.publishedAt > $1.publishedAt })
self.filter()
Expand Down
106 changes: 60 additions & 46 deletions score-ios/Views/DetailedViews/DetailedHighlightView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,45 +15,18 @@ struct DetailedHighlightsView: View {
var highlightScope: HighlightsScope

var body: some View {
VStack(alignment: .leading, spacing: 16) {
// Custom header
ZStack {
Text(title)
.font(Constants.Fonts.header)
.foregroundStyle(Constants.Colors.black)

HStack {
Button(action: { dismiss() }) {
Image("arrow_back_ios")
.resizable()
.frame(width: 9.87, height: 18.57)
}

Spacer()
}
}
.padding(.top, 24)
.padding(.horizontal, 24)
VStack{
headerView

Divider().background(.clear)

VStack(alignment: .leading, spacing: 0) {
SearchView(title: "Search \(title)", scope: highlightScope)
.padding(.horizontal, 24)
.padding(.top, 20)

SportSelectorView()
.padding(.top, 20)
}
.cornerRadius(12, corners: [.bottomLeft, .bottomRight])

VStack(alignment: .leading, spacing: 0) {
if(highlightsForScope.isEmpty) {
NoHighlightView()
.frame(maxWidth: .infinity)
}
else{
ScrollView{
ScrollView {
LazyVStack(alignment: .leading, spacing: 16) {
if(highlightsForScope.isEmpty) {
NoHighlightView()
.frame(maxWidth: .infinity)
.frame(minHeight: UIScreen.main.bounds.height - 350)
// push view to the middle of the screen
}
else{
LazyVStack(alignment: .center) {
ForEach(highlightsForScope, id: \.id) { highlight in
HighlightTile(highlight: highlight, isVertical: true)
Expand All @@ -64,14 +37,17 @@ struct DetailedHighlightsView: View {
}
}
}
.background(Constants.Colors.white.ignoresSafeArea())
.refreshable {
viewModel.loadHighlights()
}
.safeAreaInset(edge: .bottom) {
Color.clear.frame(height: 200)
}

.navigationBarBackButtonHidden(true)
.navigationBarTitleDisplayMode(.inline)
}
.safeAreaInset(edge: .bottom) {
Color.clear.frame(height: 200)
}

.navigationBarBackButtonHidden(true)
.navigationBarTitleDisplayMode(.inline)

.environmentObject(viewModel)
.onAppear {
if viewModel.hasNotFetchedYet {
Expand All @@ -96,12 +72,50 @@ struct DetailedHighlightsView: View {
return viewModel.allHighlights
}
}

private var headerView: some View {
VStack(alignment: .leading, spacing: 16) {
// Custom header
ZStack {
Text(title)
.font(Constants.Fonts.header)
.foregroundStyle(Constants.Colors.black)

HStack {
Button(action: { dismiss() }) {
Image("arrow_back_ios")
.resizable()
.frame(width: 9.87, height: 18.57)
}

Spacer()
}
}
.padding(.top, 24)
.padding(.horizontal, 24)

Divider().background(.clear)

VStack(alignment: .leading, spacing: 0) {
SearchView(title: "Search \(title)", scope: highlightScope)
.padding(.horizontal, 24)
.padding(.top, 20)

SportSelectorView()
.padding(.top, 20)
}
.cornerRadius(12, corners: [.bottomLeft, .bottomRight])
}
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.bottom, 12)
.background(Constants.Colors.white)
}
}

#Preview {
DetailedHighlightsView(
title: "Today",
highlightScope: .pastThreeDays
highlightScope: .today
)
.environmentObject(HighlightsViewModel.shared)
}
51 changes: 33 additions & 18 deletions score-ios/Views/ListViews/HighlightView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,18 @@ struct HighlightView: View {
@EnvironmentObject var viewModel: HighlightsViewModel

var body: some View {

Group{
switch viewModel.dataState {
case .idle, .loading:
HighlightLoadingView()

default:
HighlightContentView()
VStack{
headerView

HighlightContentView()
}
}
}
.onAppear {
Expand All @@ -29,30 +35,36 @@ struct HighlightView: View {
viewModel.filter()
}
}

var headerView: some View {
VStack {
Text("Highlights")
.font(Constants.Fonts.semibold24)
.foregroundStyle(Constants.Colors.black)
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.top, 24)
.padding(.horizontal, 24)

SearchView(title: "Search All Highlights", scope: .all)
.padding(.horizontal, 20)
.padding(.top, 12)

SportSelectorView()
.padding(.horizontal, 20)
.padding(.top, 12)
}
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.bottom, 12)
.background(Constants.Colors.white)
}
}

struct HighlightContentView: View {
@EnvironmentObject var viewModel: HighlightsViewModel

var body: some View {

ScrollView(showsIndicators: false) {
VStack(alignment: .leading, spacing: 4) {
Text("Highlights")
.font(Constants.Fonts.semibold24)
.foregroundStyle(Constants.Colors.black)
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.top, 24)
.padding(.horizontal, 24)

SearchView(title: "Search All Highlights", scope: .all)
.padding(.horizontal, 20)
.padding(.top, 12)

SportSelectorView()
.padding(.horizontal, 20)
.padding(.top, 12)

LazyVStack(alignment: .leading, spacing: 4) {
if viewModel.mainPastThreeDaysHighlights.isEmpty && viewModel.mainTodayHighlights.isEmpty {
NoHighlightView()
.frame(maxWidth: .infinity)
Expand All @@ -76,6 +88,9 @@ struct HighlightContentView: View {
}
}
}
.refreshable {
viewModel.loadHighlights()
}
}
}

Expand Down
Loading