diff --git a/score-ios.xcodeproj/project.pbxproj b/score-ios.xcodeproj/project.pbxproj index 779464a..53f4cbb 100644 --- a/score-ios.xcodeproj/project.pbxproj +++ b/score-ios.xcodeproj/project.pbxproj @@ -7,6 +7,8 @@ objects = { /* Begin PBXBuildFile section */ + 1C87865D2D8CD76900EBDF74 /* TrailingFadeGradient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C87865C2D8CD76900EBDF74 /* TrailingFadeGradient.swift */; }; + 1C87865F2D8CDADC00EBDF74 /* String+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C87865E2D8CDADC00EBDF74 /* String+Extension.swift */; }; CE335CD32C922E8D0037F572 /* PrimaryColors.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE335CD22C922E8D0037F572 /* PrimaryColors.swift */; }; CE335CD52C922ECB0037F572 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE335CD42C922ECB0037F572 /* Constants.swift */; }; CE335CD72C922F390037F572 /* Dates.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE335CD62C922F390037F572 /* Dates.swift */; }; @@ -96,6 +98,8 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 1C87865C2D8CD76900EBDF74 /* TrailingFadeGradient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrailingFadeGradient.swift; sourceTree = ""; }; + 1C87865E2D8CDADC00EBDF74 /* String+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Extension.swift"; sourceTree = ""; }; CE335CD22C922E8D0037F572 /* PrimaryColors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrimaryColors.swift; sourceTree = ""; }; CE335CD42C922ECB0037F572 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = ""; }; CE335CD62C922F390037F572 /* Dates.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Dates.swift; sourceTree = ""; }; @@ -198,6 +202,21 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 1C87865B2D8CD73C00EBDF74 /* ViewModifiers */ = { + isa = PBXGroup; + children = ( + 1C87865C2D8CD76900EBDF74 /* TrailingFadeGradient.swift */, + ); + path = ViewModifiers; + sourceTree = ""; + }; + CE335CCA2C9226EB0037F572 /* Configs */ = { + isa = PBXGroup; + children = ( + ); + path = Configs; + sourceTree = ""; + }; CE335CCC2C9226F90037F572 /* Models */ = { isa = PBXGroup; children = ( @@ -226,11 +245,13 @@ CE335CCE2C9227050037F572 /* Utils */ = { isa = PBXGroup; children = ( + 1C87865B2D8CD73C00EBDF74 /* ViewModifiers */, CE335CD22C922E8D0037F572 /* PrimaryColors.swift */, CE335CD42C922ECB0037F572 /* Constants.swift */, CE335CD62C922F390037F572 /* Dates.swift */, CE528FA32C9653C200C238B5 /* Error.swift */, CE3C9C422D011A23008BFB4C /* OrdinalSuffix.swift */, + 1C87865E2D8CDADC00EBDF74 /* String+Extension.swift */, ); path = Utils; sourceTree = ""; @@ -650,6 +671,7 @@ D86347AF2CDBD2F4003DD8F6 /* PastGameCard.swift in Sources */, CE8ED5122D6C3FCB00A274DE /* CarouselView.swift in Sources */, CE528FF72C979DA000C238B5 /* GameView.swift in Sources */, + 1C87865D2D8CD76900EBDF74 /* TrailingFadeGradient.swift in Sources */, CE8ED4F82D6BF42B00A274DE /* Sport.swift in Sources */, D87882282CC060FC00421F67 /* GameDetailedScoreView.swift in Sources */, D83EE8862CC9917C008B693C /* ScoreSummaryTile.swift in Sources */, @@ -671,6 +693,7 @@ CE8ED5142D6C42D400A274DE /* GameSectionHeaderView.swift in Sources */, D86347B12CDBFF7C003DD8F6 /* UpcomingGamesView.swift in Sources */, D86347DF2CE98B3C003DD8F6 /* MainTabView.swift in Sources */, + 1C87865F2D8CDADC00EBDF74 /* String+Extension.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/score-ios.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/score-ios.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 092041f..f3f8c4a 100644 --- a/score-ios.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/score-ios.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,4 +1,5 @@ { + "originHash" : "6b067d3fafa8b6816a1507517f5f83e403209fe5e4f2246c62127d371c045b62", "pins" : [ { "identity" : "apollo-ios", @@ -19,5 +20,5 @@ } } ], - "version" : 2 + "version" : 3 } diff --git a/score-ios/Utils/String+Extension.swift b/score-ios/Utils/String+Extension.swift new file mode 100644 index 0000000..a36d26b --- /dev/null +++ b/score-ios/Utils/String+Extension.swift @@ -0,0 +1,17 @@ +// +// String+Extension.swift +// score-ios +// +// Created by Jay Zheng on 3/20/25. +// + +import SwiftUI + +extension String { + /// remove "University of " and replay it with "U", eg. University of Miama -> UMiami + func removingUniversityPrefix() -> String { + return self.localizedCaseInsensitiveContains("University of ") + ? self.replacingOccurrences(of: "University of ", with: "U ", options: .caseInsensitive) + : self + } +} diff --git a/score-ios/Utils/ViewModifiers/TrailingFadeGradient.swift b/score-ios/Utils/ViewModifiers/TrailingFadeGradient.swift new file mode 100644 index 0000000..8d12bc5 --- /dev/null +++ b/score-ios/Utils/ViewModifiers/TrailingFadeGradient.swift @@ -0,0 +1,41 @@ +// +// TrailingFadeGradient.swift +// score-ios +// +// Created by Jay Zheng on 3/20/25. +// + +import SwiftUI + +/// A view modifier that adds a trailing fade gradient to indicate scrollable content +struct TrailingFadeGradient: ViewModifier { + var width: CGFloat + var backgroundColor: Color + + init(width: CGFloat = 30, backgroundColor: Color = .white) { + self.width = width + self.backgroundColor = backgroundColor + } + + func body(content: Content) -> some View { + content + .overlay( + LinearGradient( + gradient: Gradient(colors: [.clear, backgroundColor]), + startPoint: .leading, + endPoint: .trailing + ) + .frame(width: width) + .allowsHitTesting(false), + alignment: .trailing + ) + } +} +// Add this as a view extension +extension View { + /// Adds a trailing fade gradient to indicate scrollable content + func withTrailingFadeGradient(width: CGFloat = 30, backgroundColor: Color = .white) -> some View { + self.modifier(TrailingFadeGradient(width: width, backgroundColor: backgroundColor)) + } +} + diff --git a/score-ios/ViewModels/GamesViewModel.swift b/score-ios/ViewModels/GamesViewModel.swift index 9573531..81b679e 100644 --- a/score-ios/ViewModels/GamesViewModel.swift +++ b/score-ios/ViewModels/GamesViewModel.swift @@ -8,7 +8,7 @@ import Foundation import SwiftUI -class GamesViewModel: ObservableObject +class GamesViewModel: ObservableObject { @Published var errorMessage: String? @Published var games: [Game] = [] // List of all games diff --git a/score-ios/Views/DetailedViews/DynamicScoreBox.swift b/score-ios/Views/DetailedViews/DynamicScoreBox.swift index bec86b5..ac2c499 100644 --- a/score-ios/Views/DetailedViews/DynamicScoreBox.swift +++ b/score-ios/Views/DetailedViews/DynamicScoreBox.swift @@ -122,11 +122,14 @@ extension DynamicScoreBox { private func thirdRow(columnWidth: CGFloat) -> some View { HStack(spacing: 0) { - Text(game.opponent.name) - .lineLimit(1) - .font(Constants.Fonts.gameText) - .frame(width: 55, alignment: .leading) - .padding(.leading, 5) + ScrollView(.horizontal, showsIndicators: false){ + Text(game.opponent.name.removingUniversityPrefix()) + .lineLimit(1) + .font(Constants.Fonts.gameText) + .frame(alignment: .leading) + .padding(.leading, 5) + } + .withTrailingFadeGradient() ForEach(0..