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