diff --git a/.gitignore b/.gitignore index f9da8ae1..1cc6b18f 100644 --- a/.gitignore +++ b/.gitignore @@ -27,6 +27,9 @@ xcuserdata/ *.dSYM.zip *.dSYM +## Swift Package Manager +*Package.resolved + # CocoaPods # # We recommend against adding the Pods directory to your .gitignore. However diff --git a/Campus-iOS.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Campus-iOS.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved deleted file mode 100644 index 9d9d4681..00000000 --- a/Campus-iOS.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ /dev/null @@ -1,187 +0,0 @@ -{ - "object": { - "pins": [ - { - "package": "abseil", - "repositoryURL": "https://github.com/firebase/abseil-cpp-SwiftPM.git", - "state": { - "branch": null, - "revision": "fffc3c2729be5747390ad02d5100291a0d9ad26a", - "version": "0.20200225.4" - } - }, - { - "package": "Alamofire", - "repositoryURL": "https://github.com/Alamofire/Alamofire.git", - "state": { - "branch": null, - "revision": "f82c23a8a7ef8dc1a49a8bfc6a96883e79121864", - "version": "5.5.0" - } - }, - { - "package": "BoringSSL-GRPC", - "repositoryURL": "https://github.com/firebase/boringssl-SwiftPM.git", - "state": { - "branch": null, - "revision": "734a8247442fde37df4364c21f6a0085b6a36728", - "version": "0.7.2" - } - }, - { - "package": "Firebase", - "repositoryURL": "https://github.com/firebase/firebase-ios-sdk.git", - "state": { - "branch": null, - "revision": "5344857522053b5d4403ec8173ec0d23200a97ea", - "version": "8.11.0" - } - }, - { - "package": "GoogleAppMeasurement", - "repositoryURL": "https://github.com/google/GoogleAppMeasurement.git", - "state": { - "branch": null, - "revision": "9b2f6aca5b4685c45f9f5481f19bee8e7982c538", - "version": "8.9.1" - } - }, - { - "package": "GoogleDataTransport", - "repositoryURL": "https://github.com/google/GoogleDataTransport.git", - "state": { - "branch": null, - "revision": "15ccdfd25ac55b9239b82809531ff26605e7556e", - "version": "9.1.2" - } - }, - { - "package": "GoogleUtilities", - "repositoryURL": "https://github.com/google/GoogleUtilities.git", - "state": { - "branch": null, - "revision": "b3bb0c5551fb3f80ca939829639ab5b093edd14f", - "version": "7.7.0" - } - }, - { - "package": "gRPC", - "repositoryURL": "https://github.com/firebase/grpc-SwiftPM.git", - "state": { - "branch": null, - "revision": "fb405dd2c7901485f7e158b24e3a0a47e4efd8b5", - "version": "1.28.4" - } - }, - { - "package": "GTMSessionFetcher", - "repositoryURL": "https://github.com/google/gtm-session-fetcher.git", - "state": { - "branch": null, - "revision": "bc6a19702ac76ac4e488b68148710eb815f9bc56", - "version": "1.7.0" - } - }, - { - "package": "KeychainAccess", - "repositoryURL": "https://github.com/kishikawakatsumi/KeychainAccess.git", - "state": { - "branch": null, - "revision": "84e546727d66f1adc5439debad16270d0fdd04e7", - "version": "4.2.2" - } - }, - { - "package": "KVKCalendar", - "repositoryURL": "https://github.com/kvyatkovskys/KVKCalendar.git", - "state": { - "branch": null, - "revision": "c4728c93df4a52a4921b8825944128a2c8e08bd9", - "version": "0.5.8" - } - }, - { - "package": "leveldb", - "repositoryURL": "https://github.com/firebase/leveldb.git", - "state": { - "branch": null, - "revision": "0706abcc6b0bd9cedfbb015ba840e4a780b5159b", - "version": "1.22.2" - } - }, - { - "package": "LRUCache", - "repositoryURL": "https://github.com/nicklockwood/LRUCache.git", - "state": { - "branch": null, - "revision": "40039c212a82a044c0e2aff5c9f1daaf1f1f0624", - "version": "1.0.2" - } - }, - { - "package": "nanopb", - "repositoryURL": "https://github.com/firebase/nanopb.git", - "state": { - "branch": null, - "revision": "7ee9ef9f627d85cbe1b8c4f49a3ed26eed216c77", - "version": "2.30908.0" - } - }, - { - "package": "Promises", - "repositoryURL": "https://github.com/google/promises.git", - "state": { - "branch": null, - "revision": "611337c330350c9c1823ad6d671e7f936af5ee13", - "version": "2.0.0" - } - }, - { - "package": "Snap", - "repositoryURL": "https://github.com/nerdsupremacist/Snap.git", - "state": { - "branch": null, - "revision": "29943b7064547f391ea8352dea04903e2263d831", - "version": "0.2.2" - } - }, - { - "package": "SwiftProtobuf", - "repositoryURL": "https://github.com/apple/swift-protobuf.git", - "state": { - "branch": null, - "revision": "7e2c5f3cbbeea68e004915e3a8961e20bd11d824", - "version": "1.18.0" - } - }, - { - "package": "SwiftUICharts", - "repositoryURL": "https://github.com/willdale/SwiftUICharts", - "state": { - "branch": null, - "revision": "6ba7163599e26a8292a77e8be5c4ddcbfbdc5c70", - "version": "2.9.7" - } - }, - { - "package": "SWXMLHash", - "repositoryURL": "https://github.com/drmohundro/SWXMLHash.git", - "state": { - "branch": null, - "revision": "6469881a3f30417c5bb02404ea4b69207f297592", - "version": "6.0.0" - } - }, - { - "package": "XMLCoder", - "repositoryURL": "https://github.com/MaxDesiatov/XMLCoder", - "state": { - "branch": null, - "revision": "f30119af03996939cc4f54e0bf0dda9f88a84da5", - "version": "0.13.1" - } - } - ] - }, - "version": 1 -} diff --git a/Campus-iOS/HelperViews/Collapsible.swift b/Campus-iOS/HelperViews/Collapsible.swift index cb96d488..82fcc2e9 100644 --- a/Campus-iOS/HelperViews/Collapsible.swift +++ b/Campus-iOS/HelperViews/Collapsible.swift @@ -25,7 +25,8 @@ struct Collapsible: View { HStack { self.title() Spacer() - Image(systemName: self.collapsed ? "chevron.down" : "chevron.up") + Image(systemName: "chevron.right") + .rotationEffect(Angle.degrees(self.collapsed ? 0 : 90)) } .padding() .background(Color.white.opacity(0.01)) @@ -33,12 +34,13 @@ struct Collapsible: View { ) .buttonStyle(PlainButtonStyle()) - - self.content() - .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: collapsed ? 0 : .none, alignment: .top) - .clipped() - .animation(.easeOut, value: self.collapsed) - .transition(.slide) + if(!collapsed) { + self.content() + .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: collapsed ? 0 : .none, alignment: .top) + .clipped() + .animation(.easeOut, value: self.collapsed) + .transition(.slide) + } } } } diff --git a/Campus-iOS/NewsComponent/ViewModel/NewsViewModel.swift b/Campus-iOS/NewsComponent/ViewModel/NewsViewModel.swift index 61f7eeef..d4f9ebcd 100644 --- a/Campus-iOS/NewsComponent/ViewModel/NewsViewModel.swift +++ b/Campus-iOS/NewsComponent/ViewModel/NewsViewModel.swift @@ -17,6 +17,7 @@ class NewsViewModel: ObservableObject { init() { // TODO: Get from cache, if not found, then fetch + fetch() } diff --git a/Campus-iOS/NewsComponent/Views/NewsCard.swift b/Campus-iOS/NewsComponent/Views/NewsCard.swift index 3d53d8cb..228d8ef9 100644 --- a/Campus-iOS/NewsComponent/Views/NewsCard.swift +++ b/Campus-iOS/NewsComponent/Views/NewsCard.swift @@ -7,6 +7,32 @@ import SwiftUI +struct LoadMoreCard: View { + @Environment(\.colorScheme) var colorScheme + + let loadingMethod: () -> () + + var body: some View { + Button { + withAnimation { + loadingMethod() + } + } label: { + HStack { + Text("Show more...") + .font(.body) + .foregroundColor(.blue) + } + .foregroundColor(colorScheme == .dark ? .white : .black) + .frame(width: UIScreen.main.bounds.width * 0.4, height: UIScreen.main.bounds.width * 0.6) + } + .background(Color(.systemGray6)) + .cornerRadius(15) + .shadow(color: Color.black.opacity(0.2), radius: 7, x: 0, y: 2) + .contentShape(Rectangle()) + } +} + struct NewsCard: View { var title: String var source: String? @@ -33,6 +59,7 @@ struct NewsCard: View { } var body: some View { + VStack(alignment: .center, spacing: 0) { if self.image.isEmpty { @@ -134,11 +161,13 @@ struct NewsCard: View { .background(Color(.systemGray6)) .cornerRadius(15) .shadow(color: Color.black.opacity(0.2), radius: 7, x: 0, y: 2) + } } struct ProductCard_Previews: PreviewProvider { static var previews: some View { - NewsCard(title: "SMOOTHIE BOWL", source: "FEELING FIT", created: Date(), image: "https://app.tum.de/File/news/newspread/dab04abdf3954d3e1bf56cef44d68662.jpg", latest: true) + NewsCard(title: "SMOOTHIE BOWL", source: "FEELING FIT", created: Date(), image: "https://app.tum.de/File/news/newspread/dab04abdf3954d3e1bf56cef44d68662.jpg", latest: false) + LoadMoreCard(loadingMethod: {print("loading mehtod")}) } } diff --git a/Campus-iOS/NewsComponent/Views/NewsCardsHorizontalScrollingView.swift b/Campus-iOS/NewsComponent/Views/NewsCardsHorizontalScrollingView.swift index 76d1baff..9d50a3aa 100644 --- a/Campus-iOS/NewsComponent/Views/NewsCardsHorizontalScrollingView.swift +++ b/Campus-iOS/NewsComponent/Views/NewsCardsHorizontalScrollingView.swift @@ -12,11 +12,33 @@ struct NewsCardsHorizontalScrollingView: View { @AppStorage("useBuildInWebView") var useBuildInWebView: Bool = true @State var isWebViewShowed = false @State var news: [News] + @State var visibleNews: [News] + @State var showLoadButton = true + + var sortedNews: [News] = [] + + init(news: [News]) { + sortedNews = news.sorted(by: { news1, news2 in + if let date1 = news1.date, let date2 = news2.date { + return date1.compare(date2) == .orderedDescending + } else { + return false + } + }) + + self.news = sortedNews + + visibleNews = Array(sortedNews.prefix(upTo: 5)) + } + + func showMoreNews() { + + } var body: some View { ScrollView(.horizontal, showsIndicators: false) { HStack(spacing: 30) { - ForEach(news, id: \.id) { news in + ForEach(visibleNews, id: \.id) { news in GeometryReader { geometry in if let link = news.link { if self.useBuildInWebView { @@ -41,6 +63,26 @@ struct NewsCardsHorizontalScrollingView: View { .frame(width: 250, height: 250) Spacer(minLength: 1) } + + if visibleNews.count < sortedNews.count { + GeometryReader { geometry in + + LoadMoreCard(loadingMethod: { + // Amount of how many news are still hidden + let diffAmount = sortedNews.count - visibleNews.count + + if diffAmount > 0 { + // If the diff is >= 5 than append the next 5 news. Otherwise (diff < 5) just append the last e.g. 2 news. (In this example: diffAmount = 2) + // The -1 is neccessary due to the counting: We start from visibleNews.count to (visibleNews.count + 5 - 1) in order to get the next 5 news + visibleNews.append(contentsOf: sortedNews[visibleNews.count...(visibleNews.count + (diffAmount >= 5 ? 5 : diffAmount) - 1)]) + } + }) + .rotation3DEffect(Angle(degrees: Double(geometry.frame(in: .global).minX - 50) / -20), axis: (x: 0, y: 100.0, z: 0)) + + } + .frame(width: 150, height: 250) + Spacer(minLength: 1) + } } .padding([.top, .leading], 30) } @@ -52,6 +94,6 @@ struct NewsCardsHorizontalScrollingView_Previews: PreviewProvider { static let news = News(id: "1", sourceId: 1, date: Date(), created: Date(), title: "Dummy Title", link: URL(string: "https://github.com/orgs/TUM-Dev"), imageURL: "https://app.tum.de/File/news/newspread/dab04abdf3954d3e1bf56cef44d68662.jpg") static var previews: some View { - NewsCardsHorizontalScrollingView(news: [news, news]) + NewsCardsHorizontalScrollingView(news: [news, news, news, news, news]) } }