changeset 440:01fa77358b82

Fixes #47
author Dennis Concepción Martín <dennisconcepcionmartin@gmail.com>
date Sun, 20 Jun 2021 16:58:36 +0200
parents aa1f4b614b2b
children 417148200aaf
files LazyBear.xcodeproj/project.pbxproj LazyBear.xcodeproj/project.xcworkspace/xcuserdata/dennis.xcuserdatad/UserInterfaceState.xcuserstate LazyBear/LazyBearApp.swift LazyBear/Views/Company/CompanyView.swift LazyBear/Views/Company/Helpers/ChartHelper.swift LazyBear/Views/Company/Helpers/KeyStatsHelper.swift LazyBear/Views/Company/Helpers/KeyStatsList.swift LazyBear/Views/Company/Networking/Company.swift
diffstat 8 files changed, 173 insertions(+), 35 deletions(-) [+]
line wrap: on
line diff
--- a/LazyBear.xcodeproj/project.pbxproj	Sun Jun 20 14:31:39 2021 +0200
+++ b/LazyBear.xcodeproj/project.pbxproj	Sun Jun 20 16:58:36 2021 +0200
@@ -13,6 +13,7 @@
 		9502BBFB267F5EE8003B0A59 /* ChartHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9502BBFA267F5EE8003B0A59 /* ChartHelper.swift */; };
 		9502BBFD267F63F3003B0A59 /* CustomRectangleBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9502BBFC267F63F3003B0A59 /* CustomRectangleBox.swift */; };
 		9502BBFF267F6454003B0A59 /* KeyStatsHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9502BBFE267F6454003B0A59 /* KeyStatsHelper.swift */; };
+		9502BC01267F8771003B0A59 /* KeyStatsList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9502BC00267F8771003B0A59 /* KeyStatsList.swift */; };
 		950857A7266BD12D005357BA /* BetterSafariView in Frameworks */ = {isa = PBXBuildFile; productRef = 950857A6266BD12D005357BA /* BetterSafariView */; };
 		950B6F3D267643460029E447 /* Purchases in Frameworks */ = {isa = PBXBuildFile; productRef = 950B6F3C267643460029E447 /* Purchases */; };
 		950B6F3F267643640029E447 /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 950B6F3E267643640029E447 /* StoreKit.framework */; };
@@ -175,6 +176,7 @@
 		9502BBFA267F5EE8003B0A59 /* ChartHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChartHelper.swift; sourceTree = "<group>"; };
 		9502BBFC267F63F3003B0A59 /* CustomRectangleBox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomRectangleBox.swift; sourceTree = "<group>"; };
 		9502BBFE267F6454003B0A59 /* KeyStatsHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyStatsHelper.swift; sourceTree = "<group>"; };
+		9502BC00267F8771003B0A59 /* KeyStatsList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyStatsList.swift; sourceTree = "<group>"; };
 		950B6F3E267643640029E447 /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = System/Library/Frameworks/StoreKit.framework; sourceTree = SDKROOT; };
 		950B6F412676454A0029E447 /* RevenueCatTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RevenueCatTest.swift; sourceTree = "<group>"; };
 		950C36E2260FB6180081CF53 /* HapticsManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HapticsManager.swift; sourceTree = "<group>"; };
@@ -638,6 +640,7 @@
 				9502BBFC267F63F3003B0A59 /* CustomRectangleBox.swift */,
 				9502BBFA267F5EE8003B0A59 /* ChartHelper.swift */,
 				9502BBFE267F6454003B0A59 /* KeyStatsHelper.swift */,
+				9502BC00267F8771003B0A59 /* KeyStatsList.swift */,
 			);
 			path = Helpers;
 			sourceTree = "<group>";
@@ -1023,6 +1026,7 @@
 				95672B9B25DDA54800DCBE4A /* LazyBear.xcdatamodeld in Sources */,
 				95C8C0E0262A369F0082D1D9 /* ProfileResponse.swift in Sources */,
 				95A4B935263EA31C0056F036 /* WatchlistCreatorSearchBar.swift in Sources */,
+				9502BC01267F8771003B0A59 /* KeyStatsList.swift in Sources */,
 				95123AB826766497001BFAF3 /* CurrencySheet.swift in Sources */,
 				95AF0FF92671342E0049C4AB /* DisplayWordsModel.swift in Sources */,
 				95AD4A2D26078C1400498079 /* ContentView.swift in Sources */,
Binary file LazyBear.xcodeproj/project.xcworkspace/xcuserdata/dennis.xcuserdatad/UserInterfaceState.xcuserstate has changed
--- a/LazyBear/LazyBearApp.swift	Sun Jun 20 14:31:39 2021 +0200
+++ b/LazyBear/LazyBearApp.swift	Sun Jun 20 16:58:36 2021 +0200
@@ -17,7 +17,7 @@
 
     var body: some Scene {
         WindowGroup {
-            CompanyView(symbol: "aapl", name: "aaple inc")
+            ContentView()
                 .environment(\.managedObjectContext, persistenceController.container.viewContext)
         }
     }
--- a/LazyBear/Views/Company/CompanyView.swift	Sun Jun 20 14:31:39 2021 +0200
+++ b/LazyBear/Views/Company/CompanyView.swift	Sun Jun 20 16:58:36 2021 +0200
@@ -10,8 +10,9 @@
 struct CompanyView: View {
     var symbol: String
     var name: String
-    
     @ObservedObject var company = Company()
+    var ranges = ["1D", "5D", "1M", "3M", "6M", "1Y", "5Y"]  /// DatePicker ranges
+    @State private var selectedRange = "3M"  /// Selected DatePicker range
     
     var body: some View {
         if company.showView {
@@ -28,7 +29,19 @@
                         }
                         .padding(.horizontal)
                         
-                        ChartHelper(quote: company.data.quote, historicalPrices: company.data.historicalPrices)
+                        Picker("", selection: $selectedRange) {
+                            ForEach(ranges, id: \.self) {
+                                Text($0)
+                            }
+                        }
+                        .pickerStyle(SegmentedPickerStyle())
+                        .padding(.horizontal)
+                        .onChange(of: selectedRange, perform: { range in
+                            let url = "https://api.lazybear.app/company/symbol=\(symbol)/type=refresh/range=\(range.lowercased())"
+                            company.request(url, .refresh)
+                        })
+                        
+                        ChartHelper(company: company)
                         KeyStatsHelper(keyStats: company.data.keyStats)
                     }
                 }
--- a/LazyBear/Views/Company/Helpers/ChartHelper.swift	Sun Jun 20 14:31:39 2021 +0200
+++ b/LazyBear/Views/Company/Helpers/ChartHelper.swift	Sun Jun 20 16:58:36 2021 +0200
@@ -6,18 +6,17 @@
 //
 
 import SwiftUI
+import StockCharts
 
 struct ChartHelper: View {
-    var quote: [QuoteModel]?
-    var historicalPrices: [HistoricalPricesModel]?
+    @ObservedObject var company: Company
     
     var body: some View {
         CustomRectangleBox()
             .frame(height: 270)
-            .padding(.horizontal)
             .overlay(
                 VStack {
-                    if let quote = quote?.first {
+                    if let quote = company.data.quote?.first {
                         HStack(alignment: .center) {
                             Text("\(quote.latestPrice ?? 0, specifier: "%.2f")")
                                 .foregroundColor(quote.changePercent ?? 0 < 0 ? .red: .green)
@@ -27,23 +26,33 @@
                                 .foregroundColor(quote.changePercent ?? 0 < 0 ? .red: .green)
                                 .font(.callout)
                                 .fontWeight(.semibold)
+                            
+                            Spacer()
                         }
-                        .padding(.top)
+                        .padding()
+                        
+                        if let historicalPrices = company.data.historicalPrices {
+                            let prices = historicalPrices.compactMap { $0.close }
+                            let dates = historicalPrices.compactMap { $0.date }
+                            if company.showChart {
+                                LineChartView(data: prices, dates: dates, hours: nil, dragGesture: true)
+                            } else {
+                                Spacer()
+                                ProgressView()
+                                Spacer()
+                            }
+                        }
                     }
+                    
+                    Spacer()
                 }
             )
+            .padding(.horizontal)
     }
 }
 
 struct ChartHelper_Previews: PreviewProvider {
     static var previews: some View {
-        ChartHelper(
-            quote: [
-                QuoteModel(companyName: "apple inc", latestPrice: 120.3, changePercent: 0.03)
-            ],
-            historicalPrices: [
-                HistoricalPricesModel(close: 120.3, date: "2020-01-01", minute: nil)
-            ]
-        )
+        ChartHelper(company: Company())
     }
 }
--- a/LazyBear/Views/Company/Helpers/KeyStatsHelper.swift	Sun Jun 20 14:31:39 2021 +0200
+++ b/LazyBear/Views/Company/Helpers/KeyStatsHelper.swift	Sun Jun 20 16:58:36 2021 +0200
@@ -9,8 +9,8 @@
 
 struct KeyStatsHelper: View {
     var keyStats: KeyStatsModel?
-    
     let displayWords: DisplayWordsModel = parseJSON("DisplayWords.json")
+    @State private var showList = false
     
     var body: some View {
         if let keyStats = keyStats {
@@ -23,30 +23,36 @@
                         if let unwrappedValue = unwrapAnyOptional(value: child.value) {
                             let label = String(child.label!)
                             
-                            Capsule()
-                                .frame(width: 250, height: 40)
-                                .foregroundColor(.white)
-                                .shadow(color: Color(.systemGray).opacity(0.25), radius: 10, x: 0.0, y: 0.0)
-                                .overlay(
-                                    HStack {
-                                        Text("\(displayWords.keyStats[label]!):")
-                                            .font(.callout)
-                                            .fontWeight(.semibold)
-                                            .lineLimit(1)
-                                        
-                                        Spacer()
-                                        Text(unwrappedValue)
-                                            .font(.callout)
-                                            .lineLimit(1)
-                                    }
-                                    .padding()
-                                )
+                            Button(action: { showList = true }) {
+                                Capsule()
+                                    .frame(width: 250, height: 40)
+                                    .foregroundColor(.white)
+                                    .shadow(color: Color(.systemGray).opacity(0.25), radius: 10, x: 0.0, y: 0.0)
+                                    .overlay(
+                                        HStack {
+                                            Text("\(displayWords.keyStats[label]!):")
+                                                .font(.callout)
+                                                .fontWeight(.semibold)
+                                                .lineLimit(1)
+                                            
+                                            Spacer()
+                                            Text(unwrappedValue)
+                                                .font(.callout)
+                                                .lineLimit(1)
+                                        }
+                                        .padding()
+                                    )
+                            }
+                            .buttonStyle(PlainButtonStyle())
                         }
                     }
                 }
                 .frame(height: 80)
                 .padding(.horizontal)
             }
+            .sheet(isPresented: $showList) {
+                KeyStatsList(keyStats: keyStats)
+            }
         }
     }
     
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LazyBear/Views/Company/Helpers/KeyStatsList.swift	Sun Jun 20 16:58:36 2021 +0200
@@ -0,0 +1,103 @@
+//
+//  KeyStatsList.swift
+//  LazyBear
+//
+//  Created by Dennis Concepción Martín on 20/6/21.
+//
+
+import SwiftUI
+
+struct KeyStatsList: View {
+    var keyStats: KeyStatsModel
+    
+    let displayWords: DisplayWordsModel = parseJSON("DisplayWords.json")
+    @Environment(\.presentationMode) var keyStatsListPresentation
+    
+    var body: some View {
+        NavigationView {
+            Form {
+                let mirror = Mirror(reflecting: keyStats)
+                ForEach(Array(mirror.children), id: \.label) { child in  /// Iterate over each variable within the class
+                    if let unwrappedValue = unwrapAnyOptional(value: child.value) {
+                        let label = String(child.label!)
+                        HStack {
+                            Text("\(displayWords.keyStats[label]!):")
+                                .font(.callout)
+                                .fontWeight(.semibold)
+                                .lineLimit(1)
+                            
+                            Spacer()
+                            Text(unwrappedValue)
+                                .font(.callout)
+                                .lineLimit(1)
+                        }
+                    }
+                }
+            }
+            .navigationTitle("Key Stats")
+            .navigationBarTitleDisplayMode(.inline)
+            .toolbar {
+                ToolbarItem(placement: .navigationBarLeading) {
+                    Button(action: { keyStatsListPresentation.wrappedValue.dismiss() }) {
+                        Image(systemName: "multiply")
+                    }
+                        
+                }
+            }
+        }
+    }
+    
+    /*
+     Unwrap optional Int, Double, String into String
+     */
+    private func unwrapAnyOptional(value: Any) -> String? {
+        if let value = value as? Int {
+            return "\(value)"
+        } else if let value = value as? Double {
+            return String(format: "%.3f", value)
+        } else {
+            return value as? String
+        }
+    }
+}
+
+struct KeyStatsList_Previews: PreviewProvider {
+    static var previews: some View {
+        KeyStatsList(keyStats:
+                        KeyStatsModel(
+                            companyName: "Apple inc",
+                            employees: 123,
+                            marketcap: 123,
+                            float: 123,
+                            sharesOutstanding: 123,
+                            beta: 123.12,
+                            peRatio: 123.4,
+                            dividendYield: 123.4,
+                            ttmDividendRate: 123.4,
+                            ttmEPS: 123.4,
+                            avg10Volume: 123,
+                            avg30Volume: 123,
+                            day50MovingAvg: 123.4,
+                            day200MovingAvg: 123.4,
+                            week52Change: 123.4,
+                            week52High: 123.4,
+                            week52Low: 123.4,
+                            week52HighSplitAdjustOnly: 123.4,
+                            week52LowSplitAdjustOnly: 123.4,
+                            maxChangePercent: 123.4,
+                            ytdChangePercent: 123.4,
+                            day5ChangePercent: 123.4,
+                            day30ChangePercent: 123.4,
+                            month1ChangePercent: 123.4,
+                            month3ChangePercent: 123.4,
+                            month6ChangePercent: 123.4,
+                            year1ChangePercent: 123.4,
+                            year2ChangePercent: 123.4,
+                            year5ChangePercent: 123.4,
+                            exDividendDate: "2020-01-01",
+                            nextDividendDate: "2020-01-01",
+                            nextEarningsDate: "2020-01-01"
+                    )
+                )
+    }
+}
--- a/LazyBear/Views/Company/Networking/Company.swift	Sun Jun 20 14:31:39 2021 +0200
+++ b/LazyBear/Views/Company/Networking/Company.swift	Sun Jun 20 16:58:36 2021 +0200
@@ -10,9 +10,11 @@
 
 class Company: ObservableObject {
     @Published var showView = false
+    @Published var showChart = true  /// To show a ProgressView when the chart is refreshed (Date range selected)
     @Published var data = CompanyResponse()
     
     func request(_ url: String, _ requestType: RequestType) {
+        if requestType == .refresh { self.showChart = false }
         let bazooka = Bazooka()
         bazooka.request(url: url, model: CompanyResponse.self) { response in
             switch requestType {
@@ -25,6 +27,7 @@
             }
             
             self.showView = true
+            self.showChart = true
         }
     }
 }