changeset 427:e707dbfc3115

Fixing weird animation .onDelete
author Dennis Concepción Martín <66180929+denniscm190@users.noreply.github.com>
date Wed, 16 Jun 2021 13:46:40 +0200
parents 4ec307505b3a
children 8c58ce834d95
files LazyBear/Views/Profile/Helpers/WatchlistSheet.swift LazyBear/Views/Profile/ProfileView.swift
diffstat 2 files changed, 108 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LazyBear/Views/Profile/Helpers/WatchlistSheet.swift	Wed Jun 16 13:46:40 2021 +0200
@@ -0,0 +1,70 @@
+//
+//  WatchlistSheet.swift
+//  LazyBear
+//
+//  Created by Dennis Concepción Martín on 16/6/21.
+//
+
+import SwiftUI
+
+struct WatchlistSheet: View {
+    var listName: String
+    var companies: [CompanyModel]
+    
+    @Environment(\.presentationMode) private var watchlistSheetPresentation
+    @Environment(\.managedObjectContext) private var moc
+    @FetchRequest(entity: WatchlistCompany.entity(), sortDescriptors: [NSSortDescriptor(key:"symbol", ascending:true)])
+    var watchlistCompanies: FetchedResults<WatchlistCompany>
+    
+    /*
+     NSSortDescriptor and .sorted(by: {} in ForEach must coincide. If not .onDelete is not working well.
+     */
+    var body: some View {
+        NavigationView {
+            VStack {
+                List {
+                    ForEach(companies.sorted(by: { $0.companyName < $1.companyName }), id: \.self) { company in
+                        StockSheetRow(company: company)
+                    }
+                    .onDelete(perform: deleteCompany)
+                }
+            }
+            .navigationTitle(listName)
+            .navigationBarTitleDisplayMode(.inline)
+            .toolbar {
+                ToolbarItem(placement: .navigationBarLeading) {
+                    Button(action: {watchlistSheetPresentation.wrappedValue.dismiss()}) {
+                        Image(systemName: "multiply")
+                    }
+                }
+            }
+        }
+    }
+    
+    /*
+     Delete company from watchlist
+     */
+    private func deleteCompany(at offsets: IndexSet) {
+        print(watchlistCompanies)
+        for index in offsets {
+            print(index)
+            let company = watchlistCompanies[index]
+            moc.delete(company)
+        }
+        do {
+            try moc.save()
+            print("Company deleted")
+        } catch {
+            print(error.localizedDescription)
+        }
+    }
+}
+
+struct WatchlistSheet_Previews: PreviewProvider {
+    static var previews: some View {
+        WatchlistSheet(
+            listName: "Most active",
+            companies: [CompanyModel(symbol: "aapl", companyName: "Apple Inc", latestPrice: 120.3, changePercent: 0.03, intradayPrices: [120.3])]
+        )
+    }
+}
--- a/LazyBear/Views/Profile/ProfileView.swift	Wed Jun 16 13:46:24 2021 +0200
+++ b/LazyBear/Views/Profile/ProfileView.swift	Wed Jun 16 13:46:40 2021 +0200
@@ -21,22 +21,16 @@
         if profile.showView {
             NavigationView {
                 List {
-                    /*
-                     Get Watchlist names -> Create rows for each watchlist -> in each row, show companies
-                     */
-                    let watchlists = Set(watchlistCompanies.map { $0.watchlist })  /// Set -> avoid duplicates names
-                    
-                    ForEach(Array(watchlists).sorted(), id: \.self) { listName in
-                        let symbols = watchlistCompanies.filter({ $0.watchlist == listName }).map { $0.symbol }  /// Get symbols contained in specified watchlist (Core Data)
-                        
-                        if let companies = profile.data.quotes {
-                            let list = companies.filter({ symbols.contains($0.key) })  /// From API response select the companies within the specified watchlist
-                            StockRow(list: [listName: list], intradayPrices: profile.data.intradayPrices)
+                    if let apiCompanies = profile.data.quotes {
+                        let watchlistsNames = Array(Set(watchlistCompanies.map { $0.watchlistName })).sorted()  /// Get watchlistsNames in Core Data
+                        ForEach(watchlistsNames, id: \.self) { watchlistName in
+                            let companies = createWatchlistRow(apiCompanies, watchlistCompanies, watchlistName)
+                            StockRow(listName: watchlistName, companies: companies, showWatchlistSheet: true)
                         }
-                    }
-                    .listRowInsets(EdgeInsets())
-                    .onAppear {  /// Request API again when Core Data changes to update the list
-                        refreshList()
+                        .listRowInsets(EdgeInsets())
+                        .onAppear {  /// Request API again when Core Data changes to update the list
+                            refreshList()
+                        }
                     }
                 }
                 .onAppear { self.timer = Timer.publish(every: 10, on: .main, in: .common).autoconnect() }  /// Start timer
@@ -67,6 +61,35 @@
     }
     
     /*
+     At this point, we have the API response with the watchlist companies data requested and received. Now, we have to extract from the API response
+     the companies within the selected watchlist. To do that, we should do the following:
+     1) Get an array of all the symbols within the specified watchlist.
+     2) Iterate over watchlistSymbols and return the company (QuoteModel object) from apiCompanies that matches.
+     3) Append this symbol to a new array.
+     */
+    private func createWatchlistRow(_ apiCompanies: [CompanyModel], _ watchlistCompanies: FetchedResults<WatchlistCompany>, _ watchlistName: String) -> [CompanyModel] {
+        let watchlistSymbols = watchlistCompanies.filter({ $0.watchlistName == watchlistName }).map { $0.symbol }  /// Get symbols contained in watchlistsName (Core Data)
+        
+        var companies = [CompanyModel]()
+        for watchlistSymbol in watchlistSymbols {
+            let company = apiCompanies.first(where: { $0.symbol == watchlistSymbol })
+            companies.append(company!)
+        }
+        
+        return companies
+    }
+    
+    /*
+     When a company is added to a watchlist or a new watchlist is created -> call function
+     to make the API request and refresh correctly the list
+     */
+    private func refreshList() {
+        if profile.data.quotes!.count < watchlistCompanies.count {
+            prepareUrl(.initial)
+        }
+    }
+    
+    /*
      Get symbols in watchlists (Core Data) -> Prepare url -> Request
      */
     private func prepareUrl(_ requestType: RequestType) {
@@ -91,20 +114,6 @@
             profile.request(url, .streaming)
         }
     }
-        
-    
-    /*
-     When a company is added to a watchlist or a new watchlist is created -> call function
-     to make the API request and refresh correctly the list
-     */
-    private func refreshList() {
-//        print("Companies in watchlist -> \(watchlistCompanies.count)")
-//        print("Companies requested -> \(profile.data.quotes!.count)")
-        
-        if profile.data.quotes!.count < watchlistCompanies.count {
-            prepareUrl(.initial)
-        }
-    }
 }
 
 struct ProfileView_Previews: PreviewProvider {