# HG changeset patch # User Dennis Concepción Martín <66180929+denniscm190@users.noreply.github.com> # Date 1610727789 0 # Node ID 387abbfa0a580a465ac6b9a51b0b25596053c5e9 # Parent 3dd331a54bc79288fdae24cacc6b22344a4f7f50 Working on insiders charts diff -r 3dd331a54bc7 -r 387abbfa0a58 LazyBear.xcodeproj/project.pbxproj --- a/LazyBear.xcodeproj/project.pbxproj Thu Jan 14 19:15:22 2021 +0000 +++ b/LazyBear.xcodeproj/project.pbxproj Fri Jan 15 16:23:09 2021 +0000 @@ -8,12 +8,17 @@ /* Begin PBXBuildFile section */ 95002580256D17D9008FFD28 /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9500257F256D17D9008FFD28 /* StoreKit.framework */; }; + 950B79F625B1CB7A00E5DB5B /* CompanyList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 950B79F525B1CB7A00E5DB5B /* CompanyList.swift */; }; + 950B79F925B1CEA100E5DB5B /* PriceOverview.swift in Sources */ = {isa = PBXBuildFile; fileRef = 950B79F825B1CEA100E5DB5B /* PriceOverview.swift */; }; + 950B79FC25B1CFD400E5DB5B /* StockCharts.swift in Sources */ = {isa = PBXBuildFile; fileRef = 950B79FB25B1CFD400E5DB5B /* StockCharts.swift */; }; + 950B79FF25B1E68D00E5DB5B /* InsiderCharts.swift in Sources */ = {isa = PBXBuildFile; fileRef = 950B79FE25B1E68D00E5DB5B /* InsiderCharts.swift */; }; + 950B7A0425B1E7E100E5DB5B /* TransactionList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 950B7A0325B1E7E100E5DB5B /* TransactionList.swift */; }; 9521A8BD259B93200000D417 /* Company.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9521A8BC259B93200000D417 /* Company.swift */; }; 954D992225A2105F001F7F60 /* companies.json in Resources */ = {isa = PBXBuildFile; fileRef = 954D992125A2105F001F7F60 /* companies.json */; }; - 954D992525A2123B001F7F60 /* PriceModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 954D992425A2123B001F7F60 /* PriceModel.swift */; }; + 954D992525A2123B001F7F60 /* HistoricalPricesModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 954D992425A2123B001F7F60 /* HistoricalPricesModel.swift */; }; 954D996D25A2461B001F7F60 /* SwiftUICharts in Frameworks */ = {isa = PBXBuildFile; productRef = 954D996C25A2461B001F7F60 /* SwiftUICharts */; }; 954D997125A253A9001F7F60 /* Config.swift in Sources */ = {isa = PBXBuildFile; fileRef = 954D997025A253A9001F7F60 /* Config.swift */; }; - 954D998325A27571001F7F60 /* Price.swift in Sources */ = {isa = PBXBuildFile; fileRef = 954D998225A27571001F7F60 /* Price.swift */; }; + 954D998325A27571001F7F60 /* HistoricalPrices.swift in Sources */ = {isa = PBXBuildFile; fileRef = 954D998225A27571001F7F60 /* HistoricalPrices.swift */; }; 9552A61F25B06580001CD0C8 /* SampleConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9552A61E25B0657F001CD0C8 /* SampleConfig.swift */; }; 95612C472598D17F00F7698F /* User.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95612C462598D17F00F7698F /* User.swift */; }; 95612C4A2598D1F800F7698F /* About.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95612C492598D1F800F7698F /* About.swift */; }; @@ -24,12 +29,13 @@ 956FAF7C25AF421E0002B2C1 /* FavCompany+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 956FAF7A25AF421E0002B2C1 /* FavCompany+CoreDataProperties.swift */; }; 958DF3D825A08F4E00D10D22 /* Stock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 958DF3D725A08F4E00D10D22 /* Stock.swift */; }; 958DF3DB25A08F8600D10D22 /* Insiders.swift in Sources */ = {isa = PBXBuildFile; fileRef = 958DF3DA25A08F8600D10D22 /* Insiders.swift */; }; - 95A1ECAF25A36127001D4A21 /* Transaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95A1ECAE25A36127001D4A21 /* Transaction.swift */; }; - 95A1ECB225A36230001D4A21 /* TransactionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95A1ECB125A36230001D4A21 /* TransactionModel.swift */; }; + 958E472B25B1CA8B0048E770 /* FavCompanies.swift in Sources */ = {isa = PBXBuildFile; fileRef = 958E472A25B1CA8B0048E770 /* FavCompanies.swift */; }; + 95A1ECAF25A36127001D4A21 /* InsiderTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95A1ECAE25A36127001D4A21 /* InsiderTransaction.swift */; }; + 95A1ECB225A36230001D4A21 /* InsiderTransactionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95A1ECB125A36230001D4A21 /* InsiderTransactionModel.swift */; }; 95A1ECC525A37541001D4A21 /* TransactionRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95A1ECC425A37541001D4A21 /* TransactionRow.swift */; }; 95A8103825AF476F000FD1D6 /* FavCompanyRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95A8103725AF476F000FD1D6 /* FavCompanyRow.swift */; }; 95AB4A7A259DCBAE0064C9C1 /* ReadJson.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95AB4A79259DCBAE0064C9C1 /* ReadJson.swift */; }; - 95AB4A7D259DCC0C0064C9C1 /* CompanyData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95AB4A7C259DCC0C0064C9C1 /* CompanyData.swift */; }; + 95AB4A7D259DCC0C0064C9C1 /* CompanyDataModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95AB4A7C259DCC0C0064C9C1 /* CompanyDataModel.swift */; }; 95AB4A90259DD66D0064C9C1 /* CompanyRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95AB4A8F259DD66D0064C9C1 /* CompanyRow.swift */; }; 95B04EB325212369000AD27F /* LazyBearApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95B04EB225212369000AD27F /* LazyBearApp.swift */; }; 95B04EB525212369000AD27F /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95B04EB425212369000AD27F /* ContentView.swift */; }; @@ -48,11 +54,16 @@ /* Begin PBXFileReference section */ 95002578256D1564008FFD28 /* Configuration.storekit */ = {isa = PBXFileReference; lastKnownFileType = text; path = Configuration.storekit; sourceTree = ""; }; 9500257F256D17D9008FFD28 /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = System/Library/Frameworks/StoreKit.framework; sourceTree = SDKROOT; }; + 950B79F525B1CB7A00E5DB5B /* CompanyList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompanyList.swift; sourceTree = ""; }; + 950B79F825B1CEA100E5DB5B /* PriceOverview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PriceOverview.swift; sourceTree = ""; }; + 950B79FB25B1CFD400E5DB5B /* StockCharts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StockCharts.swift; sourceTree = ""; }; + 950B79FE25B1E68D00E5DB5B /* InsiderCharts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InsiderCharts.swift; sourceTree = ""; }; + 950B7A0325B1E7E100E5DB5B /* TransactionList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionList.swift; sourceTree = ""; }; 9521A8BC259B93200000D417 /* Company.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = Company.swift; path = lazybear/Company.swift; sourceTree = SOURCE_ROOT; }; 954D992125A2105F001F7F60 /* companies.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = companies.json; path = lazybear/Data/companies.json; sourceTree = SOURCE_ROOT; }; - 954D992425A2123B001F7F60 /* PriceModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = PriceModel.swift; path = lazybear/Models/PriceModel.swift; sourceTree = SOURCE_ROOT; }; + 954D992425A2123B001F7F60 /* HistoricalPricesModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = HistoricalPricesModel.swift; path = lazybear/Models/HistoricalPricesModel.swift; sourceTree = SOURCE_ROOT; }; 954D997025A253A9001F7F60 /* Config.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = Config.swift; path = lazybear/Config.swift; sourceTree = SOURCE_ROOT; }; - 954D998225A27571001F7F60 /* Price.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = Price.swift; path = lazybear/Functions/Price.swift; sourceTree = SOURCE_ROOT; }; + 954D998225A27571001F7F60 /* HistoricalPrices.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = HistoricalPrices.swift; path = lazybear/Functions/HistoricalPrices.swift; sourceTree = SOURCE_ROOT; }; 9552A61E25B0657F001CD0C8 /* SampleConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = SampleConfig.swift; path = lazybear/SampleConfig.swift; sourceTree = SOURCE_ROOT; }; 95612C462598D17F00F7698F /* User.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = User.swift; path = lazybear/User.swift; sourceTree = SOURCE_ROOT; }; 95612C492598D1F800F7698F /* About.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = About.swift; path = lazybear/About.swift; sourceTree = SOURCE_ROOT; }; @@ -63,12 +74,13 @@ 956FAF7A25AF421E0002B2C1 /* FavCompany+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FavCompany+CoreDataProperties.swift"; sourceTree = ""; }; 958DF3D725A08F4E00D10D22 /* Stock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = Stock.swift; path = lazybear/Stock.swift; sourceTree = SOURCE_ROOT; }; 958DF3DA25A08F8600D10D22 /* Insiders.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = Insiders.swift; path = lazybear/Insiders.swift; sourceTree = SOURCE_ROOT; }; - 95A1ECAE25A36127001D4A21 /* Transaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = Transaction.swift; path = lazybear/Functions/Transaction.swift; sourceTree = SOURCE_ROOT; }; - 95A1ECB125A36230001D4A21 /* TransactionModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = TransactionModel.swift; path = lazybear/Models/TransactionModel.swift; sourceTree = SOURCE_ROOT; }; + 958E472A25B1CA8B0048E770 /* FavCompanies.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = FavCompanies.swift; path = "lazybear/Supply views/FavCompanies.swift"; sourceTree = SOURCE_ROOT; }; + 95A1ECAE25A36127001D4A21 /* InsiderTransaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = InsiderTransaction.swift; path = lazybear/Functions/InsiderTransaction.swift; sourceTree = SOURCE_ROOT; }; + 95A1ECB125A36230001D4A21 /* InsiderTransactionModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = InsiderTransactionModel.swift; path = lazybear/Models/InsiderTransactionModel.swift; sourceTree = SOURCE_ROOT; }; 95A1ECC425A37541001D4A21 /* TransactionRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionRow.swift; sourceTree = ""; }; 95A8103725AF476F000FD1D6 /* FavCompanyRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FavCompanyRow.swift; sourceTree = ""; }; 95AB4A79259DCBAE0064C9C1 /* ReadJson.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ReadJson.swift; path = lazybear/Functions/ReadJson.swift; sourceTree = SOURCE_ROOT; }; - 95AB4A7C259DCC0C0064C9C1 /* CompanyData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = CompanyData.swift; path = lazybear/Models/CompanyData.swift; sourceTree = SOURCE_ROOT; }; + 95AB4A7C259DCC0C0064C9C1 /* CompanyDataModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = CompanyDataModel.swift; path = lazybear/Models/CompanyDataModel.swift; sourceTree = SOURCE_ROOT; }; 95AB4A8F259DD66D0064C9C1 /* CompanyRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompanyRow.swift; sourceTree = ""; }; 95B04EAF25212369000AD27F /* LazyBear.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LazyBear.app; sourceTree = BUILT_PRODUCTS_DIR; }; 95B04EB225212369000AD27F /* LazyBearApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LazyBearApp.swift; sourceTree = ""; }; @@ -115,9 +127,10 @@ path = Tests; sourceTree = ""; }; - 95612C4D2598D48200F7698F /* Supply */ = { + 95612C4D2598D48200F7698F /* Supply views */ = { isa = PBXGroup; children = ( + 958E472A25B1CA8B0048E770 /* FavCompanies.swift */, 95612C4E2598D48200F7698F /* Companies.swift */, 95612C4F2598D48200F7698F /* SearchBar.swift */, 956AACC6259CA8EF00CB9F16 /* Selection.swift */, @@ -128,17 +141,22 @@ 95DF519C259DE118003790B2 /* TipJar.swift */, 95A1ECC425A37541001D4A21 /* TransactionRow.swift */, 95A8103725AF476F000FD1D6 /* FavCompanyRow.swift */, + 950B79F525B1CB7A00E5DB5B /* CompanyList.swift */, + 950B79F825B1CEA100E5DB5B /* PriceOverview.swift */, + 950B79FB25B1CFD400E5DB5B /* StockCharts.swift */, + 950B79FE25B1E68D00E5DB5B /* InsiderCharts.swift */, + 950B7A0325B1E7E100E5DB5B /* TransactionList.swift */, ); - name = Supply; - path = lazybear/Supply; + name = "Supply views"; + path = "lazybear/Supply views"; sourceTree = SOURCE_ROOT; }; 95855384259CD9800081CF24 /* Functions */ = { isa = PBXGroup; children = ( 95AB4A79259DCBAE0064C9C1 /* ReadJson.swift */, - 954D998225A27571001F7F60 /* Price.swift */, - 95A1ECAE25A36127001D4A21 /* Transaction.swift */, + 954D998225A27571001F7F60 /* HistoricalPrices.swift */, + 95A1ECAE25A36127001D4A21 /* InsiderTransaction.swift */, ); path = Functions; sourceTree = ""; @@ -146,9 +164,9 @@ 9592F496259D29F1005AB6F1 /* Models */ = { isa = PBXGroup; children = ( - 95AB4A7C259DCC0C0064C9C1 /* CompanyData.swift */, - 954D992425A2123B001F7F60 /* PriceModel.swift */, - 95A1ECB125A36230001D4A21 /* TransactionModel.swift */, + 95AB4A7C259DCC0C0064C9C1 /* CompanyDataModel.swift */, + 954D992425A2123B001F7F60 /* HistoricalPricesModel.swift */, + 95A1ECB125A36230001D4A21 /* InsiderTransactionModel.swift */, ); path = Models; sourceTree = ""; @@ -198,7 +216,7 @@ 9521A8BC259B93200000D417 /* Company.swift */, 958DF3D725A08F4E00D10D22 /* Stock.swift */, 958DF3DA25A08F8600D10D22 /* Insiders.swift */, - 95612C4D2598D48200F7698F /* Supply */, + 95612C4D2598D48200F7698F /* Supply views */, 95855384259CD9800081CF24 /* Functions */, 9592F496259D29F1005AB6F1 /* Models */, 95AB4A71259DCAB20064C9C1 /* Data */, @@ -294,13 +312,19 @@ files = ( 95AB4A7A259DCBAE0064C9C1 /* ReadJson.swift in Sources */, 95DF5194259DDC45003790B2 /* AboutButton.swift in Sources */, + 950B79F925B1CEA100E5DB5B /* PriceOverview.swift in Sources */, 95612C512598D48200F7698F /* SearchBar.swift in Sources */, 95A1ECC525A37541001D4A21 /* TransactionRow.swift in Sources */, + 950B79F625B1CB7A00E5DB5B /* CompanyList.swift in Sources */, 956FAF7C25AF421E0002B2C1 /* FavCompany+CoreDataProperties.swift in Sources */, 95B04EB525212369000AD27F /* ContentView.swift in Sources */, 95AB4A90259DD66D0064C9C1 /* CompanyRow.swift in Sources */, 95D1BF4925ADCF7700E5D063 /* Persistence.swift in Sources */, 95612C472598D17F00F7698F /* User.swift in Sources */, + 950B7A0425B1E7E100E5DB5B /* TransactionList.swift in Sources */, + 950B79FC25B1CFD400E5DB5B /* StockCharts.swift in Sources */, + 958E472B25B1CA8B0048E770 /* FavCompanies.swift in Sources */, + 950B79FF25B1E68D00E5DB5B /* InsiderCharts.swift in Sources */, 956FAF7B25AF421E0002B2C1 /* FavCompany+CoreDataClass.swift in Sources */, 95D1BF4C25ADD08500E5D063 /* Main.swift in Sources */, 95612C4A2598D1F800F7698F /* About.swift in Sources */, @@ -308,19 +332,19 @@ 95A8103825AF476F000FD1D6 /* FavCompanyRow.swift in Sources */, 958DF3D825A08F4E00D10D22 /* Stock.swift in Sources */, 956AACC7259CA8EF00CB9F16 /* Selection.swift in Sources */, - 954D998325A27571001F7F60 /* Price.swift in Sources */, - 95AB4A7D259DCC0C0064C9C1 /* CompanyData.swift in Sources */, - 95A1ECB225A36230001D4A21 /* TransactionModel.swift in Sources */, + 954D998325A27571001F7F60 /* HistoricalPrices.swift in Sources */, + 95AB4A7D259DCC0C0064C9C1 /* CompanyDataModel.swift in Sources */, + 95A1ECB225A36230001D4A21 /* InsiderTransactionModel.swift in Sources */, 95DF519A259DE0E2003790B2 /* WhatsNew.swift in Sources */, 958DF3DB25A08F8600D10D22 /* Insiders.swift in Sources */, 95612C502598D48200F7698F /* Companies.swift in Sources */, 95DF5197259DDD68003790B2 /* AppInfo.swift in Sources */, 954D997125A253A9001F7F60 /* Config.swift in Sources */, - 95A1ECAF25A36127001D4A21 /* Transaction.swift in Sources */, + 95A1ECAF25A36127001D4A21 /* InsiderTransaction.swift in Sources */, 95D0012825B0C3A5007D45FD /* SizeClassView.swift in Sources */, 9521A8BD259B93200000D417 /* Company.swift in Sources */, 9552A61F25B06580001CD0C8 /* SampleConfig.swift in Sources */, - 954D992525A2123B001F7F60 /* PriceModel.swift in Sources */, + 954D992525A2123B001F7F60 /* HistoricalPricesModel.swift in Sources */, 95F7CAF625ADC7B7009E0E7C /* LazyBear.xcdatamodeld in Sources */, 95DF519D259DE118003790B2 /* TipJar.swift in Sources */, ); diff -r 3dd331a54bc7 -r 387abbfa0a58 LazyBear.xcodeproj/project.xcworkspace/xcuserdata/dennis.xcuserdatad/UserInterfaceState.xcuserstate Binary file LazyBear.xcodeproj/project.xcworkspace/xcuserdata/dennis.xcuserdatad/UserInterfaceState.xcuserstate has changed diff -r 3dd331a54bc7 -r 387abbfa0a58 lazybear/ContentView.swift --- a/lazybear/ContentView.swift Thu Jan 14 19:15:22 2021 +0000 +++ b/lazybear/ContentView.swift Fri Jan 15 16:23:09 2021 +0000 @@ -9,9 +9,6 @@ import CoreData struct ContentView: View { - @Environment(\.managedObjectContext) private var viewContext - @FetchRequest(entity: FavCompany.entity(), sortDescriptors: []) - var favourites: FetchedResults var body: some View { Main() diff -r 3dd331a54bc7 -r 387abbfa0a58 lazybear/Functions/HistoricalPrices.swift --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lazybear/Functions/HistoricalPrices.swift Fri Jan 15 16:23:09 2021 +0000 @@ -0,0 +1,51 @@ +// +// RequestPrices.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 3/1/21. +// + +import SwiftUI + +class HistoricalPrices: ObservableObject { + @Published var result = [HistoricalPricesModel]() + @Published var showingView = false + @Published var showingAlert = false + + func request(symbol: String) { + guard let url = URL(string: priceUrl(symbol: symbol, sandbox: true)) else { // Change sandbox when production + print("Invalid URL") + return + } + let request = URLRequest(url: url) + URLSession.shared.dataTask(with: request) { data, response, error in + if let data = data { + if let decodedResponse = try? JSONDecoder().decode([HistoricalPricesModel].self, from: data) { + // we have good data – go back to the main thread + DispatchQueue.main.async { + // update our UI + self.result = decodedResponse + print("API request ok") + + // Check if data is empty + if self.result.isEmpty || self.result.count <= 1 { + print("Data is empty") + self.showingView = false + self.showingAlert = true + } else { + print("Showing view...") + self.showingView = true + } + + } + + // everything is good, so we can exit + return + } + } + + // if we're still here it means there was a problem + print("Fetch failed: \(error?.localizedDescription ?? "Unknown error")") + }.resume() + } +} diff -r 3dd331a54bc7 -r 387abbfa0a58 lazybear/Functions/InsiderTransaction.swift --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lazybear/Functions/InsiderTransaction.swift Fri Jan 15 16:23:09 2021 +0000 @@ -0,0 +1,51 @@ +// +// Insiders.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 4/1/21. +// + +import SwiftUI + +class InsiderTransaction: ObservableObject { + @Published var result = [InsiderTransactionModel]() + @Published var showingView = false + @Published var showingAlert = false + + func request(cik: String, date: String) { + guard let url = URL(string: transactionUrl(cik: cik, date: date)) else { // Change sandbox when production + print("Invalid URL") + return + } + let request = URLRequest(url: url) + URLSession.shared.dataTask(with: request) { data, response, error in + if let data = data { + if let decodedResponse = try? JSONDecoder().decode([InsiderTransactionModel].self, from: data) { + // we have good data – go back to the main thread + DispatchQueue.main.async { + // update our UI + self.result = decodedResponse + print("API request ok") + + // Check if data is empty + if self.result.isEmpty || self.result.count <= 1 { + print("Data is empty") + self.showingView = false + self.showingAlert = true + } else { + print("Showing view...") + self.showingView = true + } + + } + + // everything is good, so we can exit + return + } + } + + // if we're still here it means there was a problem + print("Fetch failed: \(error?.localizedDescription ?? "Unknown error")") + }.resume() + } +} diff -r 3dd331a54bc7 -r 387abbfa0a58 lazybear/Functions/Price.swift --- a/lazybear/Functions/Price.swift Thu Jan 14 19:15:22 2021 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +0,0 @@ -// -// RequestPrices.swift -// LazyBear -// -// Created by Dennis Concepción Martín on 3/1/21. -// - -import SwiftUI - -class Price: ObservableObject { - @Published var result = [PriceModel]() - @Published var showingView = false - @Published var showingAlert = false - - func request(symbol: String) { - guard let url = URL(string: priceUrl(symbol: symbol, sandbox: true)) else { // Change sandbox when production - print("Invalid URL") - return - } - let request = URLRequest(url: url) - URLSession.shared.dataTask(with: request) { data, response, error in - if let data = data { - if let decodedResponse = try? JSONDecoder().decode([PriceModel].self, from: data) { - // we have good data – go back to the main thread - DispatchQueue.main.async { - // update our UI - self.result = decodedResponse - print("API request ok") - - // Check if data is empty - if self.result.isEmpty || self.result.count <= 1 { - print("Data is empty") - self.showingView = false - self.showingAlert = true - } else { - print("Showing view...") - self.showingView = true - } - - } - - // everything is good, so we can exit - return - } - } - - // if we're still here it means there was a problem - print("Fetch failed: \(error?.localizedDescription ?? "Unknown error")") - }.resume() - } -} diff -r 3dd331a54bc7 -r 387abbfa0a58 lazybear/Functions/ReadJson.swift --- a/lazybear/Functions/ReadJson.swift Thu Jan 14 19:15:22 2021 +0000 +++ b/lazybear/Functions/ReadJson.swift Fri Jan 15 16:23:09 2021 +0000 @@ -10,7 +10,7 @@ import SwiftUI // With this function I parse the local JSON file to read it and create a list with its items. -let companiesData: [CompanyData] = load("companies.json") +let companiesData: [CompanyDataModel] = load("companies.json") func load(_ filename: String) -> T { let data: Data diff -r 3dd331a54bc7 -r 387abbfa0a58 lazybear/Functions/Transaction.swift --- a/lazybear/Functions/Transaction.swift Thu Jan 14 19:15:22 2021 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +0,0 @@ -// -// Insiders.swift -// LazyBear -// -// Created by Dennis Concepción Martín on 4/1/21. -// - -import SwiftUI - -class Transaction: ObservableObject { - @Published var result = [TransactionModel]() - @Published var showingView = false - @Published var showingAlert = false - - func request(cik: String, date: String) { - guard let url = URL(string: transactionUrl(cik: cik, date: date)) else { // Change sandbox when production - print("Invalid URL") - return - } - let request = URLRequest(url: url) - URLSession.shared.dataTask(with: request) { data, response, error in - if let data = data { - if let decodedResponse = try? JSONDecoder().decode([TransactionModel].self, from: data) { - // we have good data – go back to the main thread - DispatchQueue.main.async { - // update our UI - self.result = decodedResponse - print("API request ok") - - // Check if data is empty - if self.result.isEmpty || self.result.count <= 1 { - print("Data is empty") - self.showingView = false - self.showingAlert = true - } else { - print("Showing view...") - self.showingView = true - } - - } - - // everything is good, so we can exit - return - } - } - - // if we're still here it means there was a problem - print("Fetch failed: \(error?.localizedDescription ?? "Unknown error")") - }.resume() - } -} diff -r 3dd331a54bc7 -r 387abbfa0a58 lazybear/Insiders.swift --- a/lazybear/Insiders.swift Thu Jan 14 19:15:22 2021 +0000 +++ b/lazybear/Insiders.swift Fri Jan 15 16:23:09 2021 +0000 @@ -9,12 +9,11 @@ import SwiftUICharts struct Insiders: View { - // Company arguments var cik: Int var symbol: String var name: String - @ObservedObject var transaction = Transaction() + @ObservedObject var transaction = InsiderTransaction() // Picker var dateFormatter: DateFormatter { @@ -29,28 +28,17 @@ if transaction.showingView { GeometryReader { geo in VStack { - // Graph - let cumBuys = cumSum(array: getTransactions(acquisitionOrDisposition: "A")) - let cumSells = cumSum(array: getTransactions(acquisitionOrDisposition: "D")) - let green = GradientColor(start: .green, end: .green) - let red = GradientColor(start: .red, end: .red) + let width = geo.size.height*0.6 + InsiderCharts(transaction: transaction, width: width) - let width = geo.size.height*0.6 - MultiLineChartView(data: [(cumBuys, green), (cumSells, red)], title: "Buys and sells", form: CGSize(width: width, height: width/2.3), rateValue: pct(buy: cumBuys.last!, sell: cumSells.last!)) - .padding() - DatePicker(selection: $selectedDate, in: ...Date(), displayedComponents: .date) { Text("Transactions since").font(.headline) } .padding([.leading, .top, .trailing]) .onChange(of: self.selectedDate, perform: { date in transaction.request(cik: String(cik), date: dateFormatter.string(from: selectedDate)) }) - List { - ForEach(transaction.result, id:\.self) { trans in - TransactionRow(trans: trans) - } - } - .offset(y: 10) + TransactionList(transaction: transaction) + .offset(y: 10) } } } @@ -70,36 +58,6 @@ } } } - // Function to sum an array and return a cumulative sum array - func cumSum(array: [Double]) -> [Double] { - var iterateArray = [Double]() - var cumSumArray = [Double]() - for value in array { - iterateArray.append(value) - cumSumArray.append(iterateArray.reduce(0, +)) - } - return cumSumArray - } - // Return two arrays with buys and sells - func getTransactions(acquisitionOrDisposition: String) -> [Double] { - var result = [Double]() - - for trans in transaction.result { - if trans.acquisition_disposition == acquisitionOrDisposition { - result.append(Double(trans.number_securities_transacted)) - } - } - - return result - } - // Get pct of net buys over sells - func pct(buy: Double, sell: Double) -> Int { - let pctOfBuys = buy / (buy+sell) - let pctOfSells = sell / (buy+sell) - let pct = pctOfBuys - pctOfSells - - return Int(pct*100) - } } struct Insiders_Previews: PreviewProvider { diff -r 3dd331a54bc7 -r 387abbfa0a58 lazybear/LazyBearApp.swift --- a/lazybear/LazyBearApp.swift Thu Jan 14 19:15:22 2021 +0000 +++ b/lazybear/LazyBearApp.swift Fri Jan 15 16:23:09 2021 +0000 @@ -14,7 +14,7 @@ var body: some Scene { WindowGroup { NavigationView { - SizeClassView() + ContentView() .environment(\.managedObjectContext, persistenceController.container.viewContext) } .navigationViewStyle(StackNavigationViewStyle()) diff -r 3dd331a54bc7 -r 387abbfa0a58 lazybear/Main.swift --- a/lazybear/Main.swift Thu Jan 14 19:15:22 2021 +0000 +++ b/lazybear/Main.swift Fri Jan 15 16:23:09 2021 +0000 @@ -8,56 +8,50 @@ import SwiftUI struct Main: View { - @State var searchedCompany: String = "" - @State var showingSettings = false - @State var showingUser = false - @State public var showingSearch: Bool = false // Search Bar - @Environment(\.managedObjectContext) private var viewContext + @State var searchedCompany: String = "" // Search bar + @State public var showingSearch: Bool = false // Search bar + @State var showingSettings = false // View sheet + @State var showingUser = false // View sheet + @Environment(\.managedObjectContext) private var viewContext // Core data var body: some View { VStack { if showingSearch == false { - // Setting and user + // Setting and user icons HStack { - Button(action: {self.showingSettings.toggle()} - ) { + Button(action: { self.showingSettings.toggle() }) { Image(systemName: "gear") .imageIconModifier() + }.sheet(isPresented: $showingSettings) { About() + } - + Spacer() - Button(action: {self.showingUser.toggle() - }) { + Button(action: { self.showingUser.toggle() }) { Image(systemName: "person") .imageIconModifier() - }.sheet(isPresented: $showingUser) { + + } + .sheet(isPresented: $showingUser) { User() .environment(\.managedObjectContext, self.viewContext) + } } .padding() } SearchBar(searchedText: $searchedCompany, placeholder: "Search ...", showingSearch: $showingSearch, exitButton: "Cancel") - if showingSearch == false { Companies() .transition(.move(edge: .bottom)) .animation(.default) - - } else { + } + else { if searchedCompany.count > 2 { - Spacer() - List { - ForEach(companiesData.filter({ searchedCompany.isEmpty ? true : $0.name.localizedStandardContains(searchedCompany) }), id: \.cik) { company in - CompanyRow(company: company) - } - } - .edgesIgnoringSafeArea(.bottom) - .cornerRadius(20) - .id(UUID()) // Increase speed in search the list + CompanyList(searchedCompany: $searchedCompany, isCoreData: false) } Spacer() } diff -r 3dd331a54bc7 -r 387abbfa0a58 lazybear/Models/CompanyData.swift --- a/lazybear/Models/CompanyData.swift Thu Jan 14 19:15:22 2021 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -// -// CompanyData.swift -// LazyBear -// -// Created by Dennis Concepción Martín on 31/12/20. -// - -import SwiftUI - -struct CompanyData: Hashable, Codable { - var cik: Int - var symbol: String - var name: String -} diff -r 3dd331a54bc7 -r 387abbfa0a58 lazybear/Models/CompanyDataModel.swift --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lazybear/Models/CompanyDataModel.swift Fri Jan 15 16:23:09 2021 +0000 @@ -0,0 +1,14 @@ +// +// CompanyData.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 31/12/20. +// + +import SwiftUI + +struct CompanyDataModel: Hashable, Codable { + var cik: Int + var symbol: String + var name: String +} diff -r 3dd331a54bc7 -r 387abbfa0a58 lazybear/Models/HistoricalPricesModel.swift --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lazybear/Models/HistoricalPricesModel.swift Fri Jan 15 16:23:09 2021 +0000 @@ -0,0 +1,17 @@ +// +// Prices.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 3/1/21. +// + +import SwiftUI + +struct HistoricalPricesModel: Codable { + var date: String + var close: Double + var volume: Float + var change: Double + var changePercent: Double + var changeOverTime: Double +} diff -r 3dd331a54bc7 -r 387abbfa0a58 lazybear/Models/InsiderTransactionModel.swift --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lazybear/Models/InsiderTransactionModel.swift Fri Jan 15 16:23:09 2021 +0000 @@ -0,0 +1,16 @@ +// +// Insiders.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 4/1/21. +// + +import SwiftUI + +struct InsiderTransactionModel: Codable, Hashable { + var acquisition_disposition: String + var transaction_date: String + var reporting_owner: String + var transaction_type: String + var number_securities_transacted: Int +} diff -r 3dd331a54bc7 -r 387abbfa0a58 lazybear/Models/PriceModel.swift --- a/lazybear/Models/PriceModel.swift Thu Jan 14 19:15:22 2021 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,16 +0,0 @@ -// -// Prices.swift -// LazyBear -// -// Created by Dennis Concepción Martín on 3/1/21. -// - -import SwiftUI - -struct PriceModel: Codable { - var close: Double - var date: String - var symbol: String - var volume: Float - var changePercent: Double -} diff -r 3dd331a54bc7 -r 387abbfa0a58 lazybear/Models/TransactionModel.swift --- a/lazybear/Models/TransactionModel.swift Thu Jan 14 19:15:22 2021 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,16 +0,0 @@ -// -// Insiders.swift -// LazyBear -// -// Created by Dennis Concepción Martín on 4/1/21. -// - -import SwiftUI - -struct TransactionModel: Codable, Hashable { - var acquisition_disposition: String - var transaction_date: String - var reporting_owner: String - var transaction_type: String - var number_securities_transacted: Int -} diff -r 3dd331a54bc7 -r 387abbfa0a58 lazybear/Stock.swift --- a/lazybear/Stock.swift Thu Jan 14 19:15:22 2021 +0000 +++ b/lazybear/Stock.swift Fri Jan 15 16:23:09 2021 +0000 @@ -6,55 +6,20 @@ // import SwiftUI -import SwiftUICharts struct Stock: View { - // Company arguments var cik: Int var symbol: String var name: String - - @ObservedObject var price = Price() + @ObservedObject var historicalPrices = HistoricalPrices() var body: some View { - if price.showingView { - GeometryReader { geo in - VStack { - HStack { - Text("$ " + String(price.result.last!.close)) - .font(.title) - .fontWeight(.bold) - - let pct = price.result.last!.changePercent * 100 - Text(String(format: "%.2f", pct) + " %") - .font(.headline) - .foregroundColor(whichColor()) - - Spacer() - } - .padding([.leading, .top, .trailing]) - - HStack { - Text(String(price.result.last!.date) + " last price") - .font(.caption) - .padding([.leading]) - .opacity(0.5) - - Spacer() - } - - // Stock Price - let width = geo.size.width*0.9 - let prices = price.result.map { $0.close } // Get an array of a variable in the struct - ScrollView { - LineChartView(data: prices, title: "Stock price", legend: "Last 20 days", form: CGSize(width: width, height: width/2), rateValue: nil) // It has a minimum height - .padding() - - // Volume - let volume = price.result.map { $0.volume } - BarChartView(data: ChartData(points: volume), title: "Volume", form: CGSize(width: width, height: width/1.5)) - .padding() - } + if historicalPrices.showingView { + GeometryReader { geo in + VStack { + PriceOverview(historicalPrices: historicalPrices) + let width = geo.size.width*0.9 + StockCharts(historicalPrices: historicalPrices, width: width) } } } @@ -66,24 +31,15 @@ } .onAppear { print(symbol) - price.request(symbol: symbol) + historicalPrices.request(symbol: symbol) } - .alert(isPresented: $price.showingAlert) { + .alert(isPresented: $historicalPrices.showingAlert) { Alert(title: Text("There is no data available"), message: Text("We have no data about this company. Try another one."), dismissButton: .default(Text("Got it!"))) } } } - - func whichColor() -> Color { - if price.result.last!.changePercent < 0 { - return Color(.red) - } - else { - return Color(.green) - } - } } extension Image { func favouriteIcon() -> some View { diff -r 3dd331a54bc7 -r 387abbfa0a58 lazybear/Supply views/AboutButton.swift --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lazybear/Supply views/AboutButton.swift Fri Jan 15 16:23:09 2021 +0000 @@ -0,0 +1,30 @@ +// +// AboutButton.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 31/12/20. +// + +import SwiftUI + +struct AboutButton: View { + @State var image: String + @State var name: String + + var body: some View { + HStack { + Image(systemName: image) + .renderingMode(.original) + .resizable() + .frame(width: 25, height: 25) + + Text(name) + } + } +} + +struct AboutButton_Previews: PreviewProvider { + static var previews: some View { + AboutButton(image: "sparkles", name: "What's new") + } +} diff -r 3dd331a54bc7 -r 387abbfa0a58 lazybear/Supply views/AppInfo.swift --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lazybear/Supply views/AppInfo.swift Fri Jan 15 16:23:09 2021 +0000 @@ -0,0 +1,41 @@ +// +// AppInfo.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 31/12/20. +// + +import SwiftUI + +struct AppInfo: View { + var body: some View { + HStack { + Spacer() + Image("launchLogo") + .resizable() + .frame(width: /*@START_MENU_TOKEN@*/100/*@END_MENU_TOKEN@*/, height: /*@START_MENU_TOKEN@*/100/*@END_MENU_TOKEN@*/, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/) + + VStack { + Text("Lazybear " + getVersion()) + .fontWeight(/*@START_MENU_TOKEN@*/.bold/*@END_MENU_TOKEN@*/) + + Text("By Dennis Concepción") + } + Spacer() + } + .padding() + } + + // Get app version + func getVersion() -> String { + let dictionary = Bundle.main.infoDictionary! + let version = dictionary["CFBundleShortVersionString"] as! String + return version + } +} + +struct AppInfo_Previews: PreviewProvider { + static var previews: some View { + AppInfo() + } +} diff -r 3dd331a54bc7 -r 387abbfa0a58 lazybear/Supply views/Companies.swift --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lazybear/Supply views/Companies.swift Fri Jan 15 16:23:09 2021 +0000 @@ -0,0 +1,52 @@ +// +// Companies.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 27/12/20. +// + +import SwiftUI + +struct Companies: View { + var colours = [Color(.systemBlue), Color(.systemYellow), Color(.systemRed), Color(.systemGreen), Color(.systemIndigo), Color(.systemOrange), Color(.systemPink), Color(.systemPurple), Color(.systemTeal), Color(.systemRed)] + + var names = ["adobe", "amazon", "apple", "facebook", "google", "jp", "netflix", "paypal", "salesforce", "tesla"] + var ciks = [796343, 1018724, 320193, 1326801, 1652044, 19617, 1065280, 1633917, 1108524, 1318605] + var symbols = ["adbe", "amzn", "aapl", "fb", "googl", "amj", "nflx", "pypl", "crm", "tsla"] + + let columns = [ + GridItem(.flexible()), + GridItem(.flexible()) + ] + + var body: some View { + ScrollView { + LazyVGrid(columns: columns, spacing: 20) { // Create ScrollView with two columns per row + ForEach((0...9), id: \.self) { index in + NavigationLink(destination: Company(cik: 796343, symbol: symbols[index], name: names[index]) + .navigationBarTitle(names[index].capitalized) + ) { + VStack { + Image(names[index]) + .resizable() + .aspectRatio(contentMode: .fit) + + Text(names[index].capitalized) + .foregroundColor(.white) + .fontWeight(.bold) + } + .padding(40) + .background(colours[index].cornerRadius(20)) + } + } + } + .padding() + } + } +} + +struct Companies_Previews: PreviewProvider { + static var previews: some View { + Companies() + } +} diff -r 3dd331a54bc7 -r 387abbfa0a58 lazybear/Supply views/CompanyList.swift --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lazybear/Supply views/CompanyList.swift Fri Jan 15 16:23:09 2021 +0000 @@ -0,0 +1,36 @@ +// +// CompanyList.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 15/1/21. +// + +import SwiftUI + +struct CompanyList: View { + @Binding var searchedCompany: String + @State var isCoreData: Bool + + var body: some View { + Spacer() + List { + ForEach(companiesData.filter({ searchedCompany.isEmpty ? true : $0.name.localizedStandardContains(searchedCompany) }), id: \.cik) { company in + if isCoreData { + FavCompanyRow(company: company) + } + else { + CompanyRow(company: company) + } + } + } + .edgesIgnoringSafeArea(.bottom) + .cornerRadius(20) + .id(UUID()) // Increase speed in search the list + } +} + +struct CompanyList_Previews: PreviewProvider { + static var previews: some View { + CompanyList(searchedCompany: .constant("Apple"), isCoreData: false) + } +} diff -r 3dd331a54bc7 -r 387abbfa0a58 lazybear/Supply views/CompanyRow.swift --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lazybear/Supply views/CompanyRow.swift Fri Jan 15 16:23:09 2021 +0000 @@ -0,0 +1,28 @@ +// +// CompanyRown.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 31/12/20. +// + +import SwiftUI + +struct CompanyRow: View { + var company: CompanyDataModel + + var body: some View { + HStack { + NavigationLink(destination: Company(cik: company.cik, symbol: company.symbol, name: company.name) + .navigationBarTitle(company.name.capitalized) + ) { + Text(company.name.capitalized) + } + } + } +} + +struct CompanyRown_Previews: PreviewProvider { + static var previews: some View { + CompanyRow(company: companiesData[0]) + } +} diff -r 3dd331a54bc7 -r 387abbfa0a58 lazybear/Supply views/FavCompanies.swift --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lazybear/Supply views/FavCompanies.swift Fri Jan 15 16:23:09 2021 +0000 @@ -0,0 +1,47 @@ +// +// FavCompanies.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 15/1/21. +// + +import SwiftUI + +struct FavCompanies: View { + @Environment(\.managedObjectContext) private var viewContext // Core data + @FetchRequest(entity: FavCompany.entity(), sortDescriptors: []) // Core data + var favCompanies: FetchedResults // Fetch core data + + var body: some View { + List { + ForEach(favCompanies) { favCompany in + HStack { + NavigationLink(destination: Company(cik: Int(favCompany.cik), symbol: favCompany.symbol, name: favCompany.name) + .navigationBarTitle(favCompany.name.capitalized) + ) { + Text(favCompany.name.capitalized) + } + }.padding() + } + // Delete from persistent storage + .onDelete { indexSet in + for index in indexSet { + viewContext.delete(favCompanies[index]) + } + do { + try viewContext.save() + print("Company deleted") + } catch { + print(error.localizedDescription) + } + } + } + } + + } + +struct FavCompanies_Previews: PreviewProvider { + static var previews: some View { + FavCompanies() + } +} diff -r 3dd331a54bc7 -r 387abbfa0a58 lazybear/Supply views/FavCompanyRow.swift --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lazybear/Supply views/FavCompanyRow.swift Fri Jan 15 16:23:09 2021 +0000 @@ -0,0 +1,74 @@ +// +// FavCompanyRow.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 13/1/21. +// + +import SwiftUI + +struct FavCompanyRow: View { + var company: CompanyDataModel + @Environment(\.managedObjectContext) private var viewContext + @FetchRequest(entity: FavCompany.entity(), sortDescriptors: []) + var favCompanies: FetchedResults + + var body: some View { + let names = favCompanies.map { $0.name } + HStack { + if names.contains(company.name) { + Button(action: { deleteFavourite(symbol: company.symbol) }) { + Image(systemName: "minus.circle.fill") + .iconModifier() + } + } + else { + Button(action: { addFavourite(cik: company.cik, symbol: company.symbol, name: company.name) }) { + Image(systemName: "plus.circle.fill") + .iconModifier() + } + } + Text(company.name.capitalized) + } + } + + func addFavourite(cik: Int, symbol: String, name: String) { + let favCompany = FavCompany(context: viewContext) + favCompany.cik = Int32(cik) + favCompany.symbol = symbol + favCompany.name = name + do { + try viewContext.save() + print("Company saved.") + } catch { + print(error.localizedDescription) + } + } + + func deleteFavourite(symbol: String) { + let symbols = favCompanies.map { $0.symbol } // Get array of symbols + let index = symbols.firstIndex(of: symbol) // Find index of the symbol to delete + viewContext.delete(favCompanies[index!]) // Delete it + // Save the deletion + do { + try viewContext.save() + print("Company deleted") + } catch { + print(error.localizedDescription) + } + } +} +extension Image { + func iconModifier() -> some View { + self + .renderingMode(.original) + .resizable() + .frame(width: 25, height: 25) + } +} + +struct FavCompanyRow_Previews: PreviewProvider { + static var previews: some View { + FavCompanyRow(company: companiesData[0]) + } +} diff -r 3dd331a54bc7 -r 387abbfa0a58 lazybear/Supply views/InsiderCharts.swift --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lazybear/Supply views/InsiderCharts.swift Fri Jan 15 16:23:09 2021 +0000 @@ -0,0 +1,32 @@ +// +// TransactionCharts.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 15/1/21. +// + +import SwiftUI +import Charts + +struct InsiderCharts: View { + @State var transaction: InsiderTransaction + @State var width: CGFloat + + var body: some View { + VStack { + + + } + } + + func cumulativeSum() -> [Double] { + + return [Double]() + } +} + +struct TransactionCharts_Previews: PreviewProvider { + static var previews: some View { + InsiderCharts(transaction: InsiderTransaction.init(), width: 100) + } +} diff -r 3dd331a54bc7 -r 387abbfa0a58 lazybear/Supply views/PriceOverview.swift --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lazybear/Supply views/PriceOverview.swift Fri Jan 15 16:23:09 2021 +0000 @@ -0,0 +1,54 @@ +// +// PriceOverview.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 15/1/21. +// + +import SwiftUI + +struct PriceOverview: View { + @State var historicalPrices: HistoricalPrices + + var body: some View { + VStack { + HStack { + Text("$ " + String(historicalPrices.result.last!.close)) + .font(.title) + .fontWeight(.bold) + + let pct = historicalPrices.result.last!.changePercent * 100 + Text(String(format: "%.2f", pct) + " %") + .font(.headline) + .foregroundColor(whichColor()) + + Spacer() + } + .padding([.leading, .top, .trailing]) + + HStack { + Text(String(historicalPrices.result.last!.date) + " last price") + .font(.caption) + .padding([.leading]) + .opacity(0.5) + + Spacer() + } + } + } + + func whichColor() -> Color { + if historicalPrices.result.last!.changePercent < 0 { + return Color(.red) + } + else { + return Color(.green) + } + } +} + +struct PriceOverview_Previews: PreviewProvider { + static var previews: some View { + PriceOverview(historicalPrices: HistoricalPrices.init()) + } +} diff -r 3dd331a54bc7 -r 387abbfa0a58 lazybear/Supply views/SearchBar.swift --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lazybear/Supply views/SearchBar.swift Fri Jan 15 16:23:09 2021 +0000 @@ -0,0 +1,75 @@ +// +// SearchBar.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 27/12/20. +// + +import SwiftUI + +struct SearchBar: View { + + // Text field + @Binding var searchedText: String + @State var searchBarIsEditing = false + @State var placeholder: String + @Binding var showingSearch: Bool // Content View + @State var exitButton: String + + var body: some View { + HStack { + TextField(placeholder, text: $searchedText) + .padding(10) + .padding(.horizontal, 45) + .overlay( + HStack { + Image(systemName: "globe") + .frame(minWidth: 0, maxWidth: .infinity, alignment: .leading) + .padding(.leading) + .foregroundColor(Color("placeholder")) + + if searchBarIsEditing { + Button(action: { + self.searchedText = "" + }) { + Image(systemName: "multiply.circle.fill") + .foregroundColor(Color("placeholder")) + .padding(.trailing) + } + } + } + ) + .background(Color(.systemGray6)) + .cornerRadius(10) + .onTapGesture { + self.searchBarIsEditing = true + withAnimation { + self.showingSearch = true // Content View + } + + } + + if searchBarIsEditing { + Button(action: { + self.searchedText = "" + self.searchBarIsEditing = false + withAnimation { + self.showingSearch = false // Content View + } + // Force hide keyboard + UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil) + + }) { + Text(exitButton) + } + } + } + .padding() + } +} + +struct SearchBar_Previews: PreviewProvider { + static var previews: some View { + SearchBar(searchedText: .constant(""), placeholder: "Placeholder", showingSearch: .constant(true), exitButton: "Cancel") + } +} diff -r 3dd331a54bc7 -r 387abbfa0a58 lazybear/Supply views/Selection.swift --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lazybear/Supply views/Selection.swift Fri Jan 15 16:23:09 2021 +0000 @@ -0,0 +1,75 @@ +// +// Selection.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 30/12/20. +// + +import SwiftUI + +struct Selection: View { + @Binding var showingInsiders: Bool + @Binding var showingStocks: Bool + + var body: some View { + // Buttons + HStack { + Group { + // Insiders + Button(action: {toggle(type: "insider")}) { + if showingInsiders { + Image(systemName: "person.fill") + .resizable() + .frame(width: 35, height: 35) + } else { + Image(systemName: "person") + .resizable() + .frame(width: 35, height: 35) + } + } + + // Stock + Button(action: {toggle(type: "stock")}) { + if showingStocks { + Image(systemName: "dollarsign.square.fill") + .resizable() + .frame(width: 35, height: 35) + + } else { + Image(systemName: "dollarsign.square") + .resizable() + .frame(width: 35, height: 35) + } + } + } + .padding().padding().padding() + } + } + + func toggle(type: String) { + if type == "insider" { + self.showingStocks = false + self.showingInsiders = true + } + + if type == "stock" { + self.showingStocks = true + self.showingInsiders = false + } + + if type == "description" { + self.showingStocks = false + self.showingInsiders = false + } + } +} + +struct Selection_Previews: PreviewProvider { + static var previews: some View { + Selection(showingInsiders: .constant(false), showingStocks: .constant(true)) + } +} + +/* + + */ diff -r 3dd331a54bc7 -r 387abbfa0a58 lazybear/Supply views/StockCharts.swift --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lazybear/Supply views/StockCharts.swift Fri Jan 15 16:23:09 2021 +0000 @@ -0,0 +1,34 @@ +// +// ScrollCharts.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 15/1/21. +// + +import SwiftUI +import SwiftUICharts + +struct StockCharts: View { + @State var historicalPrices: HistoricalPrices + @State var width: CGFloat + + var body: some View { + let prices = historicalPrices.result.map { $0.close } // Get an array of the variable "Close" in the struct + ScrollView { + // Stock price + LineChartView(data: prices, title: "Stock price", legend: "Last 20 days", form: CGSize(width: width, height: width/2), rateValue: nil) + .padding() + + // Volume + let volume = historicalPrices.result.map { $0.volume } + BarChartView(data: ChartData(points: volume), title: "Volume", form: CGSize(width: width, height: width/1.5)) + .padding() + } + } +} + +struct ScrollCharts_Previews: PreviewProvider { + static var previews: some View { + StockCharts(historicalPrices: HistoricalPrices.init(), width: 100) + } +} diff -r 3dd331a54bc7 -r 387abbfa0a58 lazybear/Supply views/TipJar.swift --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lazybear/Supply views/TipJar.swift Fri Jan 15 16:23:09 2021 +0000 @@ -0,0 +1,20 @@ +// +// TipJar.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 31/12/20. +// + +import SwiftUI + +struct TipJar: View { + var body: some View { + Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/) + } +} + +struct TipJar_Previews: PreviewProvider { + static var previews: some View { + TipJar() + } +} diff -r 3dd331a54bc7 -r 387abbfa0a58 lazybear/Supply views/TransactionList.swift --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lazybear/Supply views/TransactionList.swift Fri Jan 15 16:23:09 2021 +0000 @@ -0,0 +1,26 @@ +// +// TransactionList.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 15/1/21. +// + +import SwiftUI + +struct TransactionList: View { + @State var transaction: InsiderTransaction + + var body: some View { + List { + ForEach(transaction.result, id:\.self) { trans in + TransactionRow(trans: trans) + } + } + } +} + +struct TransactionList_Previews: PreviewProvider { + static var previews: some View { + TransactionList(transaction: InsiderTransaction.init()) + } +} diff -r 3dd331a54bc7 -r 387abbfa0a58 lazybear/Supply views/TransactionRow.swift --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lazybear/Supply views/TransactionRow.swift Fri Jan 15 16:23:09 2021 +0000 @@ -0,0 +1,44 @@ +// +// TransactionRow.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 4/1/21. +// + +import SwiftUI + +struct TransactionRow: View { + var trans: InsiderTransactionModel + + var body: some View { + VStack(alignment: .leading) { + HStack { + Image(systemName: "person.fill") + Text(trans.reporting_owner.capitalized) + Spacer() + Text(String(trans.number_securities_transacted)) + .foregroundColor(colourShares(type: trans.acquisition_disposition)) + } + HStack { + Image(systemName: "calendar") + Text(trans.transaction_date) + } + } + .padding() + } + + func colourShares(type: String) -> Color { + if type == "A" { // If aquisition_disposition == A, means "Acquisition" -> buy + return Color(.green) + } + else { + return Color(.red) + } + } +} + +struct TransactionRow_Previews: PreviewProvider { + static var previews: some View { + TransactionRow(trans: InsiderTransactionModel(acquisition_disposition: "A", transaction_date: "2020-01-01", reporting_owner: "steve jobs", transaction_type: "F-SomeStuff", number_securities_transacted: 12345)) + } +} diff -r 3dd331a54bc7 -r 387abbfa0a58 lazybear/Supply views/WhatsNew.swift --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lazybear/Supply views/WhatsNew.swift Fri Jan 15 16:23:09 2021 +0000 @@ -0,0 +1,101 @@ +// +// WhatsNew.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 31/12/20. +// + +import SwiftUI +import SwiftUICharts + +struct WhatsNew: View { + var body: some View { + GeometryReader { geo in + ScrollView { + VStack(alignment: .leading, spacing: 20) { + Group { + let intro = "This new version comes with lots of changes and many cool stuff. I've been working hard to improve the backend efficiency, deploy a new API and other boring stuff that you probably are not interested in. So let's talk about the cool stuff." + Text(intro) + } + + Group { + let title1 = "New design" + let text1 = "As you can see, there is a completely new design, more clean, colourful, and simple. Less is more." + Text(title1 + " 😎") + .title() + + Text(text1) + } + + Group { + let title2 = "Charts! A bunch!" + let text2 = "Look how cool they are" + Text(title2) + .title() + + Text(text2 + " 😁") + } + + Group { + HStack { + Spacer() + let width = geo.size.height*0.4 + LineChartView(data: [8,23,54,32,12,37,7,23,43], title: "Some cool title", form: CGSize(width: width, height: width/2), rateValue: 14) + Spacer() + } + } + + Group { + let title3 = "Stock prices" + let text3 = "Finally I found a not-so-expensive method to show stock prices. In this version you can see the latest stock price from the previous day, but I promise you in future versions I am going to add real-time stock prices." + Text(title3) + .title() + + Text(text3) + } + + Group { + let title4 = "Watchlist 👀" + let text4 = "Now, you can save your favourite companies to have a quick access whenever you want." + Text(title4) + .title() + + Text(text4) + + Text("Favourites") + .font(.headline) + + ExampleFavourite(companyName: "Apple Inc") + ExampleFavourite(companyName: "Netflix") + ExampleFavourite(companyName: "Goldman Sachs") + } + } + .padding() + } + } + } +} +extension Text { + func title() -> some View { + self + .font(/*@START_MENU_TOKEN@*/.title/*@END_MENU_TOKEN@*/) + .fontWeight(.semibold) + } +} + +struct ExampleFavourite: View { + @State var companyName: String + var body: some View { + HStack { + Image(systemName: "star.fill") + .renderingMode(.original) + Text(companyName) + } + } +} + +struct WhatsNew_Previews: PreviewProvider { + static var previews: some View { + WhatsNew() + } +} diff -r 3dd331a54bc7 -r 387abbfa0a58 lazybear/Supply/AboutButton.swift --- a/lazybear/Supply/AboutButton.swift Thu Jan 14 19:15:22 2021 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,30 +0,0 @@ -// -// AboutButton.swift -// LazyBear -// -// Created by Dennis Concepción Martín on 31/12/20. -// - -import SwiftUI - -struct AboutButton: View { - @State var image: String - @State var name: String - - var body: some View { - HStack { - Image(systemName: image) - .renderingMode(.original) - .resizable() - .frame(width: 25, height: 25) - - Text(name) - } - } -} - -struct AboutButton_Previews: PreviewProvider { - static var previews: some View { - AboutButton(image: "sparkles", name: "What's new") - } -} diff -r 3dd331a54bc7 -r 387abbfa0a58 lazybear/Supply/AppInfo.swift --- a/lazybear/Supply/AppInfo.swift Thu Jan 14 19:15:22 2021 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -// -// AppInfo.swift -// LazyBear -// -// Created by Dennis Concepción Martín on 31/12/20. -// - -import SwiftUI - -struct AppInfo: View { - var body: some View { - HStack { - Spacer() - Image("launchLogo") - .resizable() - .frame(width: /*@START_MENU_TOKEN@*/100/*@END_MENU_TOKEN@*/, height: /*@START_MENU_TOKEN@*/100/*@END_MENU_TOKEN@*/, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/) - - VStack { - Text("Lazybear " + getVersion()) - .fontWeight(/*@START_MENU_TOKEN@*/.bold/*@END_MENU_TOKEN@*/) - - Text("By Dennis Concepción") - } - Spacer() - } - .padding() - } - - // Get app version - func getVersion() -> String { - let dictionary = Bundle.main.infoDictionary! - let version = dictionary["CFBundleShortVersionString"] as! String - return version - } -} - -struct AppInfo_Previews: PreviewProvider { - static var previews: some View { - AppInfo() - } -} diff -r 3dd331a54bc7 -r 387abbfa0a58 lazybear/Supply/Companies.swift --- a/lazybear/Supply/Companies.swift Thu Jan 14 19:15:22 2021 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +0,0 @@ -// -// Companies.swift -// LazyBear -// -// Created by Dennis Concepción Martín on 27/12/20. -// - -import SwiftUI - -struct Companies: View { - var colours = [Color(.systemBlue), Color(.systemYellow), Color(.systemRed), Color(.systemGreen), Color(.systemIndigo), Color(.systemOrange), Color(.systemPink), Color(.systemPurple), Color(.systemTeal), Color(.systemRed)] - - var names = ["adobe", "amazon", "apple", "facebook", "google", "jp", "netflix", "paypal", "salesforce", "tesla"] - var ciks = [796343, 1018724, 320193, 1326801, 1652044, 19617, 1065280, 1633917, 1108524, 1318605] - var symbols = ["adbe", "amzn", "aapl", "fb", "googl", "amj", "nflx", "pypl", "crm", "tsla"] - - let columns = [ - GridItem(.flexible()), - GridItem(.flexible()) - ] - - var body: some View { - ScrollView { - LazyVGrid(columns: columns, spacing: 20) { // Create ScrollView with two columns per row - ForEach((0...9), id: \.self) { index in - NavigationLink(destination: Company(cik: 796343, symbol: symbols[index], name: names[index]) - .navigationBarTitle(names[index].capitalized) - ) { - VStack { - Image(names[index]) - .resizable() - .aspectRatio(contentMode: .fit) - - Text(names[index].capitalized) - .foregroundColor(.white) - .fontWeight(.bold) - } - .padding(40) - .background(colours[index].cornerRadius(20)) - } - } - } - .padding() - } - } -} - -struct Companies_Previews: PreviewProvider { - static var previews: some View { - Companies() - } -} diff -r 3dd331a54bc7 -r 387abbfa0a58 lazybear/Supply/CompanyRow.swift --- a/lazybear/Supply/CompanyRow.swift Thu Jan 14 19:15:22 2021 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,28 +0,0 @@ -// -// CompanyRown.swift -// LazyBear -// -// Created by Dennis Concepción Martín on 31/12/20. -// - -import SwiftUI - -struct CompanyRow: View { - var company: CompanyData - - var body: some View { - HStack { - NavigationLink(destination: Company(cik: company.cik, symbol: company.symbol, name: company.name) - .navigationBarTitle(company.name.capitalized) - ) { - Text(company.name.capitalized) - } - } - } -} - -struct CompanyRown_Previews: PreviewProvider { - static var previews: some View { - CompanyRow(company: companiesData[0]) - } -} diff -r 3dd331a54bc7 -r 387abbfa0a58 lazybear/Supply/FavCompanyRow.swift --- a/lazybear/Supply/FavCompanyRow.swift Thu Jan 14 19:15:22 2021 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,74 +0,0 @@ -// -// FavCompanyRow.swift -// LazyBear -// -// Created by Dennis Concepción Martín on 13/1/21. -// - -import SwiftUI - -struct FavCompanyRow: View { - var company: CompanyData - @Environment(\.managedObjectContext) private var viewContext - @FetchRequest(entity: FavCompany.entity(), sortDescriptors: []) - var favCompanies: FetchedResults - - var body: some View { - let names = favCompanies.map { $0.name } - HStack { - if names.contains(company.name) { - Button(action: { deleteFavourite(symbol: company.symbol) }) { - Image(systemName: "minus.circle.fill") - .iconModifier() - } - } - else { - Button(action: { addFavourite(cik: company.cik, symbol: company.symbol, name: company.name) }) { - Image(systemName: "plus.circle.fill") - .iconModifier() - } - } - Text(company.name.capitalized) - } - } - - func addFavourite(cik: Int, symbol: String, name: String) { - let favCompany = FavCompany(context: viewContext) - favCompany.cik = Int32(cik) - favCompany.symbol = symbol - favCompany.name = name - do { - try viewContext.save() - print("Company saved.") - } catch { - print(error.localizedDescription) - } - } - - func deleteFavourite(symbol: String) { - let symbols = favCompanies.map { $0.symbol } // Get array of symbols - let index = symbols.firstIndex(of: symbol) // Find index of the symbol to delete - viewContext.delete(favCompanies[index!]) // Delete it - // Save the deletion - do { - try viewContext.save() - print("Company deleted") - } catch { - print(error.localizedDescription) - } - } -} -extension Image { - func iconModifier() -> some View { - self - .renderingMode(.original) - .resizable() - .frame(width: 25, height: 25) - } -} - -struct FavCompanyRow_Previews: PreviewProvider { - static var previews: some View { - FavCompanyRow(company: companiesData[0]) - } -} diff -r 3dd331a54bc7 -r 387abbfa0a58 lazybear/Supply/SearchBar.swift --- a/lazybear/Supply/SearchBar.swift Thu Jan 14 19:15:22 2021 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,75 +0,0 @@ -// -// SearchBar.swift -// LazyBear -// -// Created by Dennis Concepción Martín on 27/12/20. -// - -import SwiftUI - -struct SearchBar: View { - - // Text field - @Binding var searchedText: String - @State var searchBarIsEditing = false - @State var placeholder: String - @Binding var showingSearch: Bool // Content View - @State var exitButton: String - - var body: some View { - HStack { - TextField(placeholder, text: $searchedText) - .padding(10) - .padding(.horizontal, 45) - .overlay( - HStack { - Image(systemName: "globe") - .frame(minWidth: 0, maxWidth: .infinity, alignment: .leading) - .padding(.leading) - .foregroundColor(Color("placeholder")) - - if searchBarIsEditing { - Button(action: { - self.searchedText = "" - }) { - Image(systemName: "multiply.circle.fill") - .foregroundColor(Color("placeholder")) - .padding(.trailing) - } - } - } - ) - .background(Color(.systemGray6)) - .cornerRadius(10) - .onTapGesture { - self.searchBarIsEditing = true - withAnimation { - self.showingSearch = true // Content View - } - - } - - if searchBarIsEditing { - Button(action: { - self.searchedText = "" - self.searchBarIsEditing = false - withAnimation { - self.showingSearch = false // Content View - } - // Force hide keyboard - UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil) - - }) { - Text(exitButton) - } - } - } - .padding() - } -} - -struct SearchBar_Previews: PreviewProvider { - static var previews: some View { - SearchBar(searchedText: .constant(""), placeholder: "Placeholder", showingSearch: .constant(true), exitButton: "Cancel") - } -} diff -r 3dd331a54bc7 -r 387abbfa0a58 lazybear/Supply/Selection.swift --- a/lazybear/Supply/Selection.swift Thu Jan 14 19:15:22 2021 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,75 +0,0 @@ -// -// Selection.swift -// LazyBear -// -// Created by Dennis Concepción Martín on 30/12/20. -// - -import SwiftUI - -struct Selection: View { - @Binding var showingInsiders: Bool - @Binding var showingStocks: Bool - - var body: some View { - // Buttons - HStack { - Group { - // Insiders - Button(action: {toggle(type: "insider")}) { - if showingInsiders { - Image(systemName: "person.fill") - .resizable() - .frame(width: 35, height: 35) - } else { - Image(systemName: "person") - .resizable() - .frame(width: 35, height: 35) - } - } - - // Stock - Button(action: {toggle(type: "stock")}) { - if showingStocks { - Image(systemName: "dollarsign.square.fill") - .resizable() - .frame(width: 35, height: 35) - - } else { - Image(systemName: "dollarsign.square") - .resizable() - .frame(width: 35, height: 35) - } - } - } - .padding().padding().padding() - } - } - - func toggle(type: String) { - if type == "insider" { - self.showingStocks = false - self.showingInsiders = true - } - - if type == "stock" { - self.showingStocks = true - self.showingInsiders = false - } - - if type == "description" { - self.showingStocks = false - self.showingInsiders = false - } - } -} - -struct Selection_Previews: PreviewProvider { - static var previews: some View { - Selection(showingInsiders: .constant(false), showingStocks: .constant(true)) - } -} - -/* - - */ diff -r 3dd331a54bc7 -r 387abbfa0a58 lazybear/Supply/TipJar.swift --- a/lazybear/Supply/TipJar.swift Thu Jan 14 19:15:22 2021 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,20 +0,0 @@ -// -// TipJar.swift -// LazyBear -// -// Created by Dennis Concepción Martín on 31/12/20. -// - -import SwiftUI - -struct TipJar: View { - var body: some View { - Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/) - } -} - -struct TipJar_Previews: PreviewProvider { - static var previews: some View { - TipJar() - } -} diff -r 3dd331a54bc7 -r 387abbfa0a58 lazybear/Supply/TransactionRow.swift --- a/lazybear/Supply/TransactionRow.swift Thu Jan 14 19:15:22 2021 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,44 +0,0 @@ -// -// TransactionRow.swift -// LazyBear -// -// Created by Dennis Concepción Martín on 4/1/21. -// - -import SwiftUI - -struct TransactionRow: View { - var trans: TransactionModel - - var body: some View { - VStack(alignment: .leading) { - HStack { - Image(systemName: "person.fill") - Text(trans.reporting_owner.capitalized) - Spacer() - Text(String(trans.number_securities_transacted)) - .foregroundColor(colourShares(type: trans.acquisition_disposition)) - } - HStack { - Image(systemName: "calendar") - Text(trans.transaction_date) - } - } - .padding() - } - - func colourShares(type: String) -> Color { - if type == "A" { // If aquisition_disposition == A, means "Acquisition" -> buy - return Color(.green) - } - else { - return Color(.red) - } - } -} - -struct TransactionRow_Previews: PreviewProvider { - static var previews: some View { - TransactionRow(trans: TransactionModel(acquisition_disposition: "A", transaction_date: "2020-01-01", reporting_owner: "steve jobs", transaction_type: "F-SomeStuff", number_securities_transacted: 12345)) - } -} diff -r 3dd331a54bc7 -r 387abbfa0a58 lazybear/Supply/WhatsNew.swift --- a/lazybear/Supply/WhatsNew.swift Thu Jan 14 19:15:22 2021 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,101 +0,0 @@ -// -// WhatsNew.swift -// LazyBear -// -// Created by Dennis Concepción Martín on 31/12/20. -// - -import SwiftUI -import SwiftUICharts - -struct WhatsNew: View { - var body: some View { - GeometryReader { geo in - ScrollView { - VStack(alignment: .leading, spacing: 20) { - Group { - let intro = "This new version comes with lots of changes and many cool stuff. I've been working hard to improve the backend efficiency, deploy a new API and other boring stuff that you probably are not interested in. So let's talk about the cool stuff." - Text(intro) - } - - Group { - let title1 = "New design" - let text1 = "As you can see, there is a completely new design, more clean, colourful, and simple. Less is more." - Text(title1 + " 😎") - .title() - - Text(text1) - } - - Group { - let title2 = "Charts! A bunch!" - let text2 = "Look how cool they are" - Text(title2) - .title() - - Text(text2 + " 😁") - } - - Group { - HStack { - Spacer() - let width = geo.size.height*0.4 - LineChartView(data: [8,23,54,32,12,37,7,23,43], title: "Some cool title", form: CGSize(width: width, height: width/2), rateValue: 14) - Spacer() - } - } - - Group { - let title3 = "Stock prices" - let text3 = "Finally I found a not-so-expensive method to show stock prices. In this version you can see the latest stock price from the previous day, but I promise you in future versions I am going to add real-time stock prices." - Text(title3) - .title() - - Text(text3) - } - - Group { - let title4 = "Watchlist 👀" - let text4 = "Now, you can save your favourite companies to have a quick access whenever you want." - Text(title4) - .title() - - Text(text4) - - Text("Favourites") - .font(.headline) - - ExampleFavourite(companyName: "Apple Inc") - ExampleFavourite(companyName: "Netflix") - ExampleFavourite(companyName: "Goldman Sachs") - } - } - .padding() - } - } - } -} -extension Text { - func title() -> some View { - self - .font(/*@START_MENU_TOKEN@*/.title/*@END_MENU_TOKEN@*/) - .fontWeight(.semibold) - } -} - -struct ExampleFavourite: View { - @State var companyName: String - var body: some View { - HStack { - Image(systemName: "star.fill") - .renderingMode(.original) - Text(companyName) - } - } -} - -struct WhatsNew_Previews: PreviewProvider { - static var previews: some View { - WhatsNew() - } -} diff -r 3dd331a54bc7 -r 387abbfa0a58 lazybear/User.swift --- a/lazybear/User.swift Thu Jan 14 19:15:22 2021 +0000 +++ b/lazybear/User.swift Fri Jan 15 16:23:09 2021 +0000 @@ -8,55 +8,20 @@ import SwiftUI struct User: View { - @Environment(\.presentationMode) var userPresentation - @State var searchedCompany: String = "" + @Environment(\.presentationMode) var userPresentation // Dismiss sheet + @State var searchedCompany: String = "" // Search bar @State public var showingSearch: Bool = false // Search Bar - @Environment(\.managedObjectContext) private var viewContext - @FetchRequest(entity: FavCompany.entity(), sortDescriptors: []) - var favCompanies: FetchedResults - var body: some View { NavigationView { VStack(alignment:.leading) { SearchBar(searchedText: $searchedCompany, placeholder: "Add a company ...", showingSearch: $showingSearch, exitButton: "Done") if showingSearch == false { - // Display favourites - List { - ForEach(favCompanies) { favCompany in - HStack { - NavigationLink(destination: Company(cik: Int(favCompany.cik), symbol: favCompany.symbol, name: favCompany.name) - .navigationBarTitle(favCompany.name.capitalized) - ) { - Text(favCompany.name.capitalized) - } - }.padding() - } - // Delete from persistent storage - .onDelete { indexSet in - for index in indexSet { - viewContext.delete(favCompanies[index]) - } - do { - try viewContext.save() - print("Company deleted") - } catch { - print(error.localizedDescription) - } - } + FavCompanies() } - } else { if searchedCompany.count > 2 { - Spacer() - List { - ForEach(companiesData.filter({ searchedCompany.isEmpty ? true : $0.name.localizedStandardContains(searchedCompany) }), id: \.cik) { company in - FavCompanyRow(company: company) - } - } - .edgesIgnoringSafeArea(.bottom) - .cornerRadius(20) - .id(UUID()) // Increase speed in search the list + CompanyList(searchedCompany: $searchedCompany, isCoreData: true) } Spacer() } @@ -64,7 +29,7 @@ .padding() .navigationTitle("My watchlist") .navigationBarItems(leading: - Button(action: {self.userPresentation.wrappedValue.dismiss()}) { + Button(action: { self.userPresentation.wrappedValue.dismiss() }) { Image(systemName: "multiply") .resizable() .frame(width: 25, height: 25)