changeset 97:bd35f88e65cd

Update Stock View
author Dennis Concepción Martín <66180929+denniscm190@users.noreply.github.com>
date Sat, 30 Jan 2021 19:34:25 +0100
parents 7f395c0c8d6e
children b49877856a71
files LazyBear.xcodeproj/project.pbxproj LazyBear.xcodeproj/project.xcworkspace/xcuserdata/dennis.xcuserdatad/UserInterfaceState.xcuserstate README.md lazybear/Views/AddWatchlist.swift lazybear/Views/Company.swift lazybear/Views/Price.swift lazybear/Views/Stock.swift lazybear/Views/WatchlistRow.swift
diffstat 8 files changed, 106 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/LazyBear.xcodeproj/project.pbxproj	Fri Jan 29 23:03:32 2021 +0100
+++ b/LazyBear.xcodeproj/project.pbxproj	Sat Jan 30 19:34:25 2021 +0100
@@ -22,6 +22,7 @@
 		95AB4A7A259DCBAE0064C9C1 /* ReadJson.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95AB4A79259DCBAE0064C9C1 /* ReadJson.swift */; };
 		95AB4A7D259DCC0C0064C9C1 /* CompanyModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95AB4A7C259DCC0C0064C9C1 /* CompanyModel.swift */; };
 		95AB4A90259DD66D0064C9C1 /* CompanyRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95AB4A8F259DD66D0064C9C1 /* CompanyRow.swift */; };
+		95AD892425C5D8A200BCE8E4 /* AddWatchlist.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95AD892325C5D8A200BCE8E4 /* AddWatchlist.swift */; };
 		95B04EB325212369000AD27F /* LazyBearApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95B04EB225212369000AD27F /* LazyBearApp.swift */; };
 		95B04EB525212369000AD27F /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95B04EB425212369000AD27F /* ContentView.swift */; };
 		95B04EB72521236A000AD27F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 95B04EB62521236A000AD27F /* Assets.xcassets */; };
@@ -63,6 +64,7 @@
 		95AB4A79259DCBAE0064C9C1 /* ReadJson.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ReadJson.swift; path = LazyBear/Jobs/ReadJson.swift; sourceTree = SOURCE_ROOT; };
 		95AB4A7C259DCC0C0064C9C1 /* CompanyModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = CompanyModel.swift; path = lazybear/Models/CompanyModel.swift; sourceTree = SOURCE_ROOT; };
 		95AB4A8F259DD66D0064C9C1 /* CompanyRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompanyRow.swift; sourceTree = "<group>"; };
+		95AD892325C5D8A200BCE8E4 /* AddWatchlist.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AddWatchlist.swift; path = lazybear/Views/AddWatchlist.swift; sourceTree = SOURCE_ROOT; };
 		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 = "<group>"; };
 		95B04EB425212369000AD27F /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
@@ -144,6 +146,7 @@
 				95F6C30025BAEC8B003CF389 /* CompanyView.swift */,
 				95F6C2EF25BAE2ED003CF389 /* Company.swift */,
 				95E411B525BEE84E00A9C23F /* Stock.swift */,
+				95AD892325C5D8A200BCE8E4 /* AddWatchlist.swift */,
 				95F6C30425BAF599003CF389 /* CompanyHeader.swift */,
 				95F6C30825BAF7C2003CF389 /* DateSelection.swift */,
 			);
@@ -302,6 +305,7 @@
 				95F6C30525BAF599003CF389 /* CompanyHeader.swift in Sources */,
 				95612C512598D48200F7698F /* SearchBar.swift in Sources */,
 				95E411BE25BEEA6C00A9C23F /* WatchlistRow.swift in Sources */,
+				95AD892425C5D8A200BCE8E4 /* AddWatchlist.swift in Sources */,
 				950B79F625B1CB7A00E5DB5B /* CompanyList.swift in Sources */,
 				95078FD125BF4E640004FA75 /* CloudKitManager.swift in Sources */,
 				95B04EB525212369000AD27F /* ContentView.swift in Sources */,
Binary file LazyBear.xcodeproj/project.xcworkspace/xcuserdata/dennis.xcuserdatad/UserInterfaceState.xcuserstate has changed
--- a/README.md	Fri Jan 29 23:03:32 2021 +0100
+++ b/README.md	Sat Jan 30 19:34:25 2021 +0100
@@ -18,7 +18,7 @@
 Check our [website](https://lazybear.app)
 
 ## Open source frameworks used 
-- [swiftui-charts](https://github.com/spacenation/swiftui-charts)   
+- [SDWebImageSwiftUI](https://github.com/SDWebImage/SDWebImageSwiftUI)   
 
 ## License
 Repository under [GPLv3](https://www.gnu.org/licenses/gpl-3.0.html). Check [LICENSE](LICENSE.md) for more details
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lazybear/Views/AddWatchlist.swift	Sat Jan 30 19:34:25 2021 +0100
@@ -0,0 +1,44 @@
+//
+//  AddWatchlist.swift
+//  LazyBear
+//
+//  Created by Dennis Concepción Martín on 30/1/21.
+//
+
+import SwiftUI
+
+struct AddWatchlist: View {
+    var name: String
+    var symbol: String
+    
+    @Environment(\.managedObjectContext) private var viewContext
+    
+    var body: some View {
+        Button(action: { addWatchlist(name: name, symbol: symbol) }) {
+            ZStack {
+                RoundedRectangle(cornerRadius: 10)
+                Text("Add to watchlist")
+                    .foregroundColor(.white)
+            }
+            .frame(width: 150)
+        }
+    }
+    
+    func addWatchlist(name: String, symbol: String) {
+        let watchlistCompany = WatchlistCompany(context: viewContext)
+        watchlistCompany.name = name
+        watchlistCompany.symbol = symbol
+        do {
+            try viewContext.save()
+            print("Company saved.")
+        } catch {
+            print(error.localizedDescription)
+        }
+    }
+}
+
+struct AddWatchlist_Previews: PreviewProvider {
+    static var previews: some View {
+        AddWatchlist(name: "apple inc", symbol: "aapl")
+    }
+}
--- a/lazybear/Views/Company.swift	Fri Jan 29 23:03:32 2021 +0100
+++ b/lazybear/Views/Company.swift	Sat Jan 30 19:34:25 2021 +0100
@@ -11,11 +11,14 @@
     var name: String
     var symbol: String
     
+    let persistenceController = PersistenceController.shared
+    
     var body: some View {
         CompanyHeader(name: self.name, symbol: self.symbol)
         ScrollView {
             VStack(alignment: .leading) {
                 Stock(name: name, symbol: symbol)
+                    .environment(\.managedObjectContext, persistenceController.container.viewContext)
             }
         }
     }
--- a/lazybear/Views/Price.swift	Fri Jan 29 23:03:32 2021 +0100
+++ b/lazybear/Views/Price.swift	Sat Jan 30 19:34:25 2021 +0100
@@ -10,26 +10,40 @@
 
 struct Price: View {
     @State var symbol: String
+    @State var showVertical: Bool
     
     @State var url = String() { didSet { giveMePrices() }}
     @State var showingView = false
     
     @State var latestPrice = Float()
     @State var changePercent = Double() { didSet { self.showingView = true }}
+    @State var negativeChange = false
     
     let iexApi = IexApi()  // Request api function
-    let timer = Timer.publish(every: 10, on: .main, in: .common).autoconnect()  // Set recurrent price request
+    let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()  // Set recurrent price request
     
     @EnvironmentObject var apiAccess: ApiAccess
     
     var body: some View {
-        VStack {
+        VStack(alignment: .trailing) {
             if self.showingView {
-                Text("\(latestPrice, specifier: "%.2f")")
-                    //.onReceive(timer) { _ in giveMePrices() }
+                Group {
+                    Text("\(latestPrice, specifier: "%.2f")")
+                        .fontWeight(.semibold)
+
+                    Text("\(changePercent*100, specifier: "%.2f")%")
+                        .font(.subheadline)
+                        .foregroundColor(.white)
+                        .background(Color(negativeChange ? .red : .green).cornerRadius(5))
+                }
+                .if(showVertical) { content in
+                        HStack { content }
+                    }
             }
         }
         .onAppear { getUrl() }
+        //.onReceive(timer) { _ in giveMePrices() }
+        .onDisappear { self.timer.upstream.connect().cancel() }  // Stop timer
     }
     
     private func getUrl() {
@@ -42,13 +56,25 @@
     private func giveMePrices() {
         iexApi.request(url: url, model: QuoteModel.self) { result in
             self.latestPrice = result.latestPrice
+            if self.changePercent >= 0 { self.negativeChange = true }
             self.changePercent = result.changePercent
         }
     }
 }
+// Wrap content if some condition is satisfied
+extension View {
+   @ViewBuilder
+   func `if`<Content: View>(_ conditional: Bool, content: (Self) -> Content) -> some View {
+        if conditional {
+            content(self)
+        } else {
+            self
+        }
+    }
+}
 
 struct Price_Previews: PreviewProvider {
     static var previews: some View {
-        Price(symbol: "AAPL")
+        Price(symbol: "AAPL", showVertical: false)
     }
 }
--- a/lazybear/Views/Stock.swift	Fri Jan 29 23:03:32 2021 +0100
+++ b/lazybear/Views/Stock.swift	Sat Jan 30 19:34:25 2021 +0100
@@ -8,27 +8,32 @@
 import SwiftUI
 
 struct Stock: View {
-    @Environment(\.managedObjectContext) private var viewContext
     var name: String
     var symbol: String
     
-    var body: some View {
-        Button(action: { addWatchlist(name: name, symbol: symbol) }) {
-            Text("Add to watchlist")
-        }
-
-    }
+    @State var selectedPeriod = 2
+    
+    @Environment(\.managedObjectContext) private var viewContext
+    @FetchRequest(entity: WatchlistCompany.entity(), sortDescriptors: [])
+    var companies: FetchedResults<WatchlistCompany>  // Fetch core data
     
-    func addWatchlist(name: String, symbol: String) {
-        let watchlistCompany = WatchlistCompany(context: viewContext)
-        watchlistCompany.name = name
-        watchlistCompany.symbol = symbol
-        do {
-            try viewContext.save()
-            print("Company saved.")
-        } catch {
-            print(error.localizedDescription)
+    var body: some View {
+        VStack {
+            Divider()
+            HStack {
+                let watchSymbols = companies.map { $0.symbol }
+                if !watchSymbols.contains(symbol) {
+                    AddWatchlist(name: name, symbol: symbol)
+                }
+                
+                Spacer()
+                Price(symbol: symbol, showVertical: true)
+            }
+            
+            Divider()
+            DateSelection(selectedperiod: $selectedPeriod)
         }
+        .padding([.leading, .trailing])
     }
 }
 
--- a/lazybear/Views/WatchlistRow.swift	Fri Jan 29 23:03:32 2021 +0100
+++ b/lazybear/Views/WatchlistRow.swift	Sat Jan 30 19:34:25 2021 +0100
@@ -32,12 +32,12 @@
                         .fontWeight(.semibold)
                     
                     Text(company.name ?? "".capitalized)
-                        .font(.caption)
+                        .font(.subheadline)
                 }
                 
                 Spacer()
                 if self.editMode?.wrappedValue.isEditing ?? true { } else { // If is not editing -> show prices
-                    Price(symbol: company.symbol ?? "")
+                    Price(symbol: company.symbol ?? "", showVertical: false)
                 }
             }
         }