Mercurial > public > lazybear
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 } } }