changeset 127:5110adf17b22

Clean code, add ViewSelector
author Dennis Concepción Martín <66180929+denniscm190@users.noreply.github.com>
date Sun, 07 Feb 2021 17:05:18 +0100
parents 0bc8ee5c457a
children 57d22236ccbd
files LazyBear.xcodeproj/project.pbxproj LazyBear.xcodeproj/project.xcworkspace/xcuserdata/dennis.xcuserdatad/UserInterfaceState.xcuserstate lazybear/ApiAccess.swift lazybear/Views/Company.swift lazybear/Views/CompanyList.swift lazybear/Views/CompanyRow.swift lazybear/Views/DateSelection.swift lazybear/Views/HistoryList.swift lazybear/Views/LogoModifier.swift lazybear/Views/News.swift lazybear/Views/NewsDetail.swift lazybear/Views/Price.swift lazybear/Views/Search.swift lazybear/Views/Selection.swift lazybear/Views/Stock.swift lazybear/Views/StockAndNews.swift lazybear/Views/Transactions.swift lazybear/Views/ViewSelector.swift lazybear/Views/WatchlistRow.swift
diffstat 19 files changed, 253 insertions(+), 141 deletions(-) [+]
line wrap: on
line diff
--- a/LazyBear.xcodeproj/project.pbxproj	Sun Feb 07 13:11:53 2021 +0100
+++ b/LazyBear.xcodeproj/project.pbxproj	Sun Feb 07 17:05:18 2021 +0100
@@ -47,8 +47,12 @@
 		95E411BE25BEEA6C00A9C23F /* WatchlistRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95E411BD25BEEA6C00A9C23F /* WatchlistRow.swift */; };
 		95ED176B25CEFE1B00AE34B3 /* RecentSearch+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95ED176925CEFE1B00AE34B3 /* RecentSearch+CoreDataClass.swift */; };
 		95ED176C25CEFE1B00AE34B3 /* RecentSearch+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95ED176A25CEFE1B00AE34B3 /* RecentSearch+CoreDataProperties.swift */; };
+		95ED8CD425D0242200B6B605 /* CompanyList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95ED8CD325D0242200B6B605 /* CompanyList.swift */; };
+		95ED8CD725D0242900B6B605 /* HistoryList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95ED8CD625D0242900B6B605 /* HistoryList.swift */; };
+		95ED8CDB25D02DF300B6B605 /* LogoModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95ED8CDA25D02DF300B6B605 /* LogoModifier.swift */; };
+		95ED8CE025D03D8900B6B605 /* StockAndNews.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95ED8CDF25D03D8900B6B605 /* StockAndNews.swift */; };
 		95F6C2F025BAE2ED003CF389 /* Company.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95F6C2EF25BAE2ED003CF389 /* Company.swift */; };
-		95F6C30925BAF7C2003CF389 /* DateSelection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95F6C30825BAF7C2003CF389 /* DateSelection.swift */; };
+		95F6C30925BAF7C2003CF389 /* Selection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95F6C30825BAF7C2003CF389 /* Selection.swift */; };
 		95F6CA0525CF2A4E0064E4E9 /* ViewSelector.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95F6CA0425CF2A4E0064E4E9 /* ViewSelector.swift */; };
 		95F6F45C25C20D8D002AC66A /* Price.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95F6F45B25C20D8D002AC66A /* Price.swift */; };
 		95F7CAF625ADC7B7009E0E7C /* LazyBear.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 95F7CAF425ADC7B7009E0E7C /* LazyBear.xcdatamodeld */; };
@@ -100,8 +104,12 @@
 		95E411BD25BEEA6C00A9C23F /* WatchlistRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchlistRow.swift; sourceTree = "<group>"; };
 		95ED176925CEFE1B00AE34B3 /* RecentSearch+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RecentSearch+CoreDataClass.swift"; sourceTree = "<group>"; };
 		95ED176A25CEFE1B00AE34B3 /* RecentSearch+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RecentSearch+CoreDataProperties.swift"; sourceTree = "<group>"; };
+		95ED8CD325D0242200B6B605 /* CompanyList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = CompanyList.swift; path = lazybear/Views/CompanyList.swift; sourceTree = SOURCE_ROOT; };
+		95ED8CD625D0242900B6B605 /* HistoryList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = HistoryList.swift; path = lazybear/Views/HistoryList.swift; sourceTree = SOURCE_ROOT; };
+		95ED8CDA25D02DF300B6B605 /* LogoModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = LogoModifier.swift; path = lazybear/Views/LogoModifier.swift; sourceTree = SOURCE_ROOT; };
+		95ED8CDF25D03D8900B6B605 /* StockAndNews.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = StockAndNews.swift; path = lazybear/Views/StockAndNews.swift; sourceTree = SOURCE_ROOT; };
 		95F6C2EF25BAE2ED003CF389 /* Company.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Company.swift; sourceTree = "<group>"; };
-		95F6C30825BAF7C2003CF389 /* DateSelection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateSelection.swift; sourceTree = "<group>"; };
+		95F6C30825BAF7C2003CF389 /* Selection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Selection.swift; sourceTree = "<group>"; };
 		95F6CA0425CF2A4E0064E4E9 /* ViewSelector.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ViewSelector.swift; path = LazyBear/Views/ViewSelector.swift; sourceTree = SOURCE_ROOT; };
 		95F6F45B25C20D8D002AC66A /* Price.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Price.swift; sourceTree = "<group>"; };
 		95F7CAF525ADC7B7009E0E7C /* LazyBear.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = LazyBear.xcdatamodel; sourceTree = "<group>"; };
@@ -159,16 +167,19 @@
 			children = (
 				95E07B6D25CE95A1001718AB /* Search.swift */,
 				95612C4F2598D48200F7698F /* SearchBar.swift */,
+				95ED8CD325D0242200B6B605 /* CompanyList.swift */,
+				95ED8CD625D0242900B6B605 /* HistoryList.swift */,
 				95AB4A8F259DD66D0064C9C1 /* CompanyRow.swift */,
 				95E411A625BEE03000A9C23F /* Watchlist.swift */,
 				95E411BD25BEEA6C00A9C23F /* WatchlistRow.swift */,
+				95ED8CDA25D02DF300B6B605 /* LogoModifier.swift */,
+				9597CE0325C1DFE7004DDFED /* LogoPlaceholder.swift */,
 				95F6F45B25C20D8D002AC66A /* Price.swift */,
-				9597CE0325C1DFE7004DDFED /* LogoPlaceholder.swift */,
 				95E07B7125CE95D9001718AB /* Settings.swift */,
 				95F6C2EF25BAE2ED003CF389 /* Company.swift */,
 				95F6CA0425CF2A4E0064E4E9 /* ViewSelector.swift */,
 				95E411B525BEE84E00A9C23F /* Stock.swift */,
-				95F6C30825BAF7C2003CF389 /* DateSelection.swift */,
+				95F6C30825BAF7C2003CF389 /* Selection.swift */,
 				9520F0B125C712D000692610 /* LineChartShape.swift */,
 				9520F0B425C7131300692610 /* LineChart.swift */,
 				9589C94C25CE0B4C0045DFF3 /* AddWatchlist.swift */,
@@ -178,6 +189,7 @@
 				95E07BA225CEAC7D001718AB /* Transactions.swift */,
 				95E07B9C25CEAC46001718AB /* TransactionDetail.swift */,
 				95E07B9F25CEAC61001718AB /* TransactionRow.swift */,
+				95ED8CDF25D03D8900B6B605 /* StockAndNews.swift */,
 			);
 			path = Views;
 			sourceTree = "<group>";
@@ -336,6 +348,7 @@
 				95E07BA025CEAC61001718AB /* TransactionRow.swift in Sources */,
 				9589C94D25CE0B4C0045DFF3 /* AddWatchlist.swift in Sources */,
 				954DDF0425C456E800848A4B /* QuoteModel.swift in Sources */,
+				95ED8CD725D0242900B6B605 /* HistoryList.swift in Sources */,
 				959D28E225CC9B370029F689 /* NewsRow.swift in Sources */,
 				9520F0B525C7131300692610 /* LineChart.swift in Sources */,
 				9597CE0425C1DFE7004DDFED /* LogoPlaceholder.swift in Sources */,
@@ -350,8 +363,9 @@
 				95AB4A90259DD66D0064C9C1 /* CompanyRow.swift in Sources */,
 				95E07B7225CE95D9001718AB /* Settings.swift in Sources */,
 				959D28DC25CC99710029F689 /* NewsModel.swift in Sources */,
-				95F6C30925BAF7C2003CF389 /* DateSelection.swift in Sources */,
+				95F6C30925BAF7C2003CF389 /* Selection.swift in Sources */,
 				95F6C2F025BAE2ED003CF389 /* Company.swift in Sources */,
+				95ED8CE025D03D8900B6B605 /* StockAndNews.swift in Sources */,
 				95D1BF4925ADCF7700E5D063 /* Persistence.swift in Sources */,
 				958B678525C42B2400BF9F89 /* ApiAccess.swift in Sources */,
 				95B04EB325212369000AD27F /* LazyBearApp.swift in Sources */,
@@ -360,6 +374,8 @@
 				95ED176B25CEFE1B00AE34B3 /* RecentSearch+CoreDataClass.swift in Sources */,
 				95AB4A7D259DCC0C0064C9C1 /* CompanyModel.swift in Sources */,
 				95E411B625BEE84E00A9C23F /* Stock.swift in Sources */,
+				95ED8CD425D0242200B6B605 /* CompanyList.swift in Sources */,
+				95ED8CDB25D02DF300B6B605 /* LogoModifier.swift in Sources */,
 				9520F0B225C712D000692610 /* LineChartShape.swift in Sources */,
 				95F6CA0525CF2A4E0064E4E9 /* ViewSelector.swift in Sources */,
 				95E07BA325CEAC7D001718AB /* Transactions.swift in Sources */,
Binary file LazyBear.xcodeproj/project.xcworkspace/xcuserdata/dennis.xcuserdatad/UserInterfaceState.xcuserstate has changed
--- a/lazybear/ApiAccess.swift	Sun Feb 07 13:11:53 2021 +0100
+++ b/lazybear/ApiAccess.swift	Sun Feb 07 17:05:18 2021 +0100
@@ -11,4 +11,5 @@
 class ApiAccess: ObservableObject {
     @Published var results = [ApiModel]()
     @Published var showingView = false
+    @Published var option = 2  // 1 -> Sandbox / 2 -> Production
 }
--- a/lazybear/Views/Company.swift	Sun Feb 07 13:11:53 2021 +0100
+++ b/lazybear/Views/Company.swift	Sun Feb 07 17:05:18 2021 +0100
@@ -10,24 +10,29 @@
 struct Company: View {
     var name: String
     var symbol: String
+    @State var viewSelected = 0
     
     @Environment(\.presentationMode) var presentationMode
     @Environment(\.managedObjectContext) private var viewContext  // Core data
     
     var body: some View {
-        GeometryReader { geo in
-            ScrollView {
-                VStack(alignment: .leading) {
-                    Stock(name: name, symbol: symbol, lineChartHeight: geo.size.height*0.2)
-                        .padding(.bottom)
-                    
-                    News(symbol: symbol)
-                }
-                .onAppear { saveSearch(name: name, symbol: symbol) }
+        VStack {
+            if viewSelected == 0 {
+                StockAndNews(name: name, symbol: symbol)
+            } else if viewSelected == 1 {
+                Transactions(symbol: symbol)
             }
-        }
+        } .onAppear { saveSearch(name: name, symbol: symbol) }
+        
         .navigationBarTitle(symbol, displayMode: .inline)
-        .navigationBarItems(trailing: AddWatchlist(symbol: symbol, name: name))
+        .navigationBarItems(trailing:
+            HStack {
+                AddWatchlist(symbol: symbol, name: name)
+                    .padding(.trailing)
+                
+                ViewSelector(viewSelected: $viewSelected)
+            }
+        )
     }
     
     private func saveSearch(name: String, symbol: String) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lazybear/Views/CompanyList.swift	Sun Feb 07 17:05:18 2021 +0100
@@ -0,0 +1,29 @@
+//
+//  CompanyList.swift
+//  LazyBear
+//
+//  Created by Dennis Concepción Martín on 7/2/21.
+//
+
+import SwiftUI
+
+struct CompanyList: View {
+    @State var searchedCompany: String
+    
+    var body: some View {
+        ForEach(companiesData.filter({ searchedCompany.isEmpty ? true : $0.name.localizedStandardContains(searchedCompany) })
+                , id: \.symbol) { company in
+                CompanyRow(company: company)
+            
+        }
+    }
+}
+
+struct CompanyList_Previews: PreviewProvider {
+    static var previews: some View {
+        //NavigationView {
+            CompanyList(searchedCompany: "apple inc")
+                .environmentObject(ApiAccess())
+        //}
+    }
+}
--- a/lazybear/Views/CompanyRow.swift	Sun Feb 07 13:11:53 2021 +0100
+++ b/lazybear/Views/CompanyRow.swift	Sun Feb 07 17:05:18 2021 +0100
@@ -12,17 +12,11 @@
     var history: RecentSearch?
     @State var showingCompany = false
     
-    @EnvironmentObject var apiAccess: ApiAccess  // Env apis info
-    let persistenceController = PersistenceController.shared // Core Data
-    
     var body: some View {
         let name = company?.name ?? history?.name ?? ""
         let symbol = company?.symbol ?? history?.symbol ?? ""
         
-        NavigationLink(destination: Company(name: name, symbol: symbol)
-                        .environment(\.managedObjectContext, persistenceController.container.viewContext)
-                        .environmentObject(apiAccess)  // Api info (url and token)
-        ) {
+        NavigationLink(destination: Company(name: name, symbol: symbol)) {
             VStack(alignment: .leading) {
                 Text(symbol.uppercased())
                     .fontWeight(.semibold)
--- a/lazybear/Views/DateSelection.swift	Sun Feb 07 13:11:53 2021 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-//
-//  DateSelection.swift
-//  LazyBear
-//
-//  Created by Dennis Concepción Martín on 22/1/21.
-//
-
-import SwiftUI
-
-struct DateSelection: View {
-    var period = ["1W", "1M", "3M", "6M", "1Y", "2Y", "5Y"]
-    @Binding var selectedperiod: Int
-    
-    var body: some View {
-        Picker(selection: $selectedperiod, label: Text("Please choose a period")) {
-            ForEach(0 ..< period.count) {
-                Text(self.period[$0])
-            }
-        }
-         .pickerStyle(SegmentedPickerStyle())
-    }
-}
-
-struct DateSelection_Previews: PreviewProvider {
-    static var previews: some View {
-        DateSelection(selectedperiod: .constant(0))
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lazybear/Views/HistoryList.swift	Sun Feb 07 17:05:18 2021 +0100
@@ -0,0 +1,61 @@
+//
+//  HistoryList.swift
+//  LazyBear
+//
+//  Created by Dennis Concepción Martín on 7/2/21.
+//
+
+import SwiftUI
+
+struct HistoryList: View {
+    @State private var showingActionSheet = false
+    
+    // <--------- Core Data --------->
+    @Environment(\.managedObjectContext) private var viewContext
+    @FetchRequest(entity: RecentSearch.entity(), sortDescriptors: [])
+    var history: FetchedResults<RecentSearch>
+    // <--------- Core Data --------->
+    
+    var body: some View {
+        if history.count > 0 {
+            Section(header: Text("History"),
+                    footer: Button(action: { self.showingActionSheet = true }
+                    ) {
+                        Text("Clear history").foregroundColor(.blue)
+                            .actionSheet(isPresented: $showingActionSheet) { alert() }
+                    }
+            ) {
+                ForEach(history) { company in
+                    CompanyRow(history: company)
+                }
+            }
+        }
+    }
+    
+    private func delete() {
+        for company in history {
+            viewContext.delete(company)
+        }
+        do {
+            try viewContext.save()
+            print("History deleted")
+        } catch {
+            print(error.localizedDescription)
+        }
+    }
+    
+    private func alert() -> ActionSheet {
+        let action = ActionSheet(
+            title: Text("Clear history"),
+            message: Text("History will be claered from your device"),
+            buttons: [.cancel(Text("Cancel")), .destructive(Text("Clear history")) { delete() }])
+        
+        return action
+    }
+}
+
+struct HistoryList_Previews: PreviewProvider {
+    static var previews: some View {
+        HistoryList()
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lazybear/Views/LogoModifier.swift	Sun Feb 07 17:05:18 2021 +0100
@@ -0,0 +1,17 @@
+//
+//  LogoModifier.swift
+//  LazyBear
+//
+//  Created by Dennis Concepción Martín on 7/2/21.
+//
+
+import SwiftUI
+
+struct LogoModifier: ViewModifier {
+    func body(content: Content) -> some View {
+        content
+            .aspectRatio(contentMode: .fit)
+            .frame(maxWidth: 40, maxHeight: 40)
+            .clipShape(RoundedRectangle(cornerRadius: 3))
+    }
+}
--- a/lazybear/Views/News.swift	Sun Feb 07 13:11:53 2021 +0100
+++ b/lazybear/Views/News.swift	Sun Feb 07 17:05:18 2021 +0100
@@ -19,7 +19,7 @@
     // <--------- API Job --------->
     
     var body: some View {
-        VStack {
+        VStack(alignment: .leading) {
             Text("Business news")
                 .font(.title)
                 .fontWeight(.semibold)
@@ -35,9 +35,8 @@
     
     
     private func getUrl() {
-        // 1 -> Sandbox / 2 -> Production
-        let baseUrl = apiAccess.results[1].url ?? ""
-        let token = apiAccess.results[1].key ?? ""
+        let baseUrl = apiAccess.results[apiAccess.option].url ?? ""
+        let token = apiAccess.results[apiAccess.option].key ?? ""
         let path = "/stable/stock/\(symbol)/news/last/10?token="
         
         self.url = baseUrl + path + token
--- a/lazybear/Views/NewsDetail.swift	Sun Feb 07 13:11:53 2021 +0100
+++ b/lazybear/Views/NewsDetail.swift	Sun Feb 07 17:05:18 2021 +0100
@@ -10,7 +10,6 @@
 
 struct NewsDetail: View {
     @State var new: NewsModel
-    @Environment(\.presentationMode) var newsDetailMode
     
     var body: some View {
         NavigationView {
@@ -38,11 +37,6 @@
             }
             .padding()
             .navigationBarTitle(new.source ?? "-", displayMode: .inline)
-            .toolbar {
-                Button(action: { self.newsDetailMode.wrappedValue.dismiss() }) {
-                    Image(systemName: "multiply")
-                }
-            }
         }
     }
 }
--- a/lazybear/Views/Price.swift	Sun Feb 07 13:11:53 2021 +0100
+++ b/lazybear/Views/Price.swift	Sun Feb 07 17:05:18 2021 +0100
@@ -45,9 +45,8 @@
     }
     
      private func getUrl() {
-        // 1 -> Sandbox / 2 -> Production
-        let baseUrl = apiAccess.results[1].url ?? ""
-        let token = apiAccess.results[1].key ?? ""
+        let baseUrl = apiAccess.results[apiAccess.option].url ?? ""
+        let token = apiAccess.results[apiAccess.option].key ?? ""
         let path = "/stable/stock/\(symbol)/quote?token="
         
         self.url = baseUrl + path + token
--- a/lazybear/Views/Search.swift	Sun Feb 07 13:11:53 2021 +0100
+++ b/lazybear/Views/Search.swift	Sun Feb 07 17:05:18 2021 +0100
@@ -9,38 +9,16 @@
 
 struct Search: View {
     @State var searchedCompany = String()
-    @EnvironmentObject var apiAccess: ApiAccess  // Env apis info
-    
-    // <--------- Core Data --------->
-    let persistenceController = PersistenceController.shared // Core Data
-    @Environment(\.managedObjectContext) private var viewContext
-    @FetchRequest(entity: RecentSearch.entity(), sortDescriptors: [])
-    var searches: FetchedResults<RecentSearch>
-    // <--------- Core Data --------->
     
     var body: some View {
         NavigationView {
             VStack {
                 SearchBar(searchedText: $searchedCompany)
-                // Searched companies
                 List {
                     if searchedCompany.count > 2 {
-                    ForEach(companiesData.filter({ searchedCompany.isEmpty ? true : $0.name.localizedStandardContains(searchedCompany) }), id: \.symbol) { company in
-                            CompanyRow(company: company)
-                                .environment(\.managedObjectContext, persistenceController.container.viewContext)
-                                .environmentObject(apiAccess)  // Api info (url and token)
-                        }
+                        CompanyList(searchedCompany: searchedCompany)
                     } else {
-                        // Historial
-                        if searches.count > 0 {
-                            Section(header: Text("History"),
-                                    footer: Button(action: { delete() }) { Text("Clear history").foregroundColor(.blue)}
-                            ) {
-                                ForEach(searches) { search in
-                                    CompanyRow(history: search)
-                                }
-                            }
-                        }
+                        HistoryList()
                     }
                 }
                 .id(UUID())  // Increase speed in search the list
@@ -48,18 +26,6 @@
             }
         } .navigationViewStyle(StackNavigationViewStyle())
     }
-    
-    private func delete() {
-        for value in searches {
-            viewContext.delete(value)
-        }
-        do {
-            try viewContext.save()
-            print("History deleted")
-        } catch {
-            print(error.localizedDescription)
-        }
-    }
 }
 
 struct Search_Previews: PreviewProvider {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lazybear/Views/Selection.swift	Sun Feb 07 17:05:18 2021 +0100
@@ -0,0 +1,28 @@
+//
+//  DateSelection.swift
+//  LazyBear
+//
+//  Created by Dennis Concepción Martín on 22/1/21.
+//
+
+import SwiftUI
+
+struct Selection: View {
+    var items: [String]
+    @Binding var selected: Int
+    
+    var body: some View {
+        Picker(selection: $selected, label: Text("Please choose a period")) {
+            ForEach(0 ..< items.count) {
+                Text(self.items[$0])
+            }
+        }
+         .pickerStyle(SegmentedPickerStyle())
+    }
+}
+
+struct Selection_Previews: PreviewProvider {
+    static var previews: some View {
+        Selection(items: ["1", "2", "3", "4", "5", "6", "7"], selected: .constant(2))
+    }
+}
--- a/lazybear/Views/Stock.swift	Sun Feb 07 13:11:53 2021 +0100
+++ b/lazybear/Views/Stock.swift	Sun Feb 07 17:05:18 2021 +0100
@@ -14,7 +14,7 @@
     @EnvironmentObject var apiAccess: ApiAccess
 
     // <--------- Picker --------->
-    var period = ["1W", "1M", "3M", "6M", "1Y", "2Y", "5Y"]
+    @State var periods = ["1W", "1M", "3M", "6M", "1Y", "2Y", "5Y"]
     @State var selectedPeriod = 2
     // <--------- Picker --------->
     
@@ -35,9 +35,9 @@
             }
             
             Divider()
-            DateSelection(selectedperiod: $selectedPeriod)
+            Selection(items: periods, selected: $selectedPeriod)
                 .onChange(of: selectedPeriod, perform: { (value) in
-                    getUrl(range: period[selectedPeriod])
+                    getUrl(range: periods[selectedPeriod])
                 })
             
             let prices = data.map { $0.close ?? 0 }
@@ -48,17 +48,15 @@
             }
         }
         .padding([.leading, .trailing])
-        .onAppear { getUrl(range: period[selectedPeriod]) }
+        .onAppear { getUrl(range: periods[selectedPeriod]) }
     }
     
     private func getUrl(range: String) {
         var range = range
-        
-        // 1 -> Sandbox / 2 -> Production
-        let baseUrl = apiAccess.results[1].url ?? ""
-        let token = apiAccess.results[1].key ?? ""
-        if period[selectedPeriod] == "1W" { range = "5dm" }
-        if period[selectedPeriod] == "1M" { range = "1mm" }
+        let baseUrl = apiAccess.results[apiAccess.option].url ?? ""
+        let token = apiAccess.results[apiAccess.option].key ?? ""
+        if periods[selectedPeriod] == "1W" { range = "5dm" }
+        if periods[selectedPeriod] == "1M" { range = "1mm" }
         let path = "/stable/stock/\(symbol)/chart/\(range)?chartCloseOnly=true&includeToday=false&token="
         
         self.url = baseUrl + path + token
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lazybear/Views/StockAndNews.swift	Sun Feb 07 17:05:18 2021 +0100
@@ -0,0 +1,32 @@
+//
+//  StockAndNews.swift
+//  LazyBear
+//
+//  Created by Dennis Concepción Martín on 7/2/21.
+//
+
+import SwiftUI
+
+struct StockAndNews: View {
+    var name: String
+    var symbol: String
+    
+    var body: some View {
+        GeometryReader { geo in
+            ScrollView {
+                VStack(alignment: .leading) {
+                    Stock(name: name, symbol: symbol, lineChartHeight: geo.size.height*0.2)
+                        .padding(.bottom)
+                    
+                    News(symbol: symbol)
+                }
+            }
+        }
+    }
+}
+
+struct StockAndNews_Previews: PreviewProvider {
+    static var previews: some View {
+        StockAndNews(name: "apple inc", symbol: "aapl")
+    }
+}
--- a/lazybear/Views/Transactions.swift	Sun Feb 07 13:11:53 2021 +0100
+++ b/lazybear/Views/Transactions.swift	Sun Feb 07 17:05:18 2021 +0100
@@ -19,28 +19,23 @@
     // <--------- API Job --------->
     
     var body: some View {
-        VStack {
-            HStack {
-                Text("Insider transactions")
-                    .font(.title)
-                    .fontWeight(.semibold)
-                    .padding([.leading, .bottom])
-                Spacer()
-            }
-            .onAppear { getUrl() }
+        VStack(alignment: .leading) {
+            Text("Insider transactions")
+                .font(.title)
+                .fontWeight(.semibold)
+                .padding([.leading, .bottom])
             
             List {
                 ForEach(data, id: \.self) { data in
                     TransactionRow(data: data)
                 }
             }
-        }
+        } .onAppear { getUrl() }
     }
     
     private func getUrl() {
-        // 1 -> Sandbox / 2 -> Production
-        let baseUrl = apiAccess.results[2].url ?? ""
-        let token = apiAccess.results[2].key ?? ""
+        let baseUrl = apiAccess.results[apiAccess.option].url ?? ""
+        let token = apiAccess.results[apiAccess.option].key ?? ""
         let path = "/stable/stock/\(symbol)/insider-transactions?token="
         
         self.url = baseUrl + path + token
--- a/lazybear/Views/ViewSelector.swift	Sun Feb 07 13:11:53 2021 +0100
+++ b/lazybear/Views/ViewSelector.swift	Sun Feb 07 17:05:18 2021 +0100
@@ -8,13 +8,33 @@
 import SwiftUI
 
 struct ViewSelector: View {
+    @State private var showingActionSheet = false
+    @Binding var viewSelected: Int
+    
     var body: some View {
-        Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/)
+        Button(action: { self.showingActionSheet = true; print(self.showingActionSheet) }) {
+            Image(systemName: "ellipsis")
+                .imageScale(.large)
+                .actionSheet(isPresented: $showingActionSheet) { alert() }
+                
+        }
+    }
+    
+    private func alert() -> ActionSheet {
+        let action = ActionSheet(
+            title: Text("Views"),
+            //message: Text("History will be claered from your device"),
+            buttons: [.cancel(Text("Cancel")) { self.showingActionSheet = false },
+                      .default(Text("Chart & news")) { self.viewSelected = 0 },
+                      .default(Text("Insider transactions")) { self.viewSelected = 1 }
+            ])
+        
+        return action
     }
 }
 
 struct ViewSelector_Previews: PreviewProvider {
     static var previews: some View {
-        ViewSelector()
+        ViewSelector(viewSelected: .constant(1))
     }
 }
--- a/lazybear/Views/WatchlistRow.swift	Sun Feb 07 13:11:53 2021 +0100
+++ b/lazybear/Views/WatchlistRow.swift	Sun Feb 07 17:05:18 2021 +0100
@@ -11,16 +11,11 @@
 
 struct WatchlistRow: View {
     var company: WatchlistCompany
-    
+    @Environment(\.editMode) var editMode  // EditButton list
     @EnvironmentObject var apiAccess: ApiAccess
-    @Environment(\.editMode) var editMode  // EditButton list
-    let persistenceController = PersistenceController.shared
     
     var body: some View {
-        NavigationLink(destination: Company(name: company.name ?? "", symbol: company.symbol ?? "")
-                        .environment(\.managedObjectContext, persistenceController.container.viewContext)
-                        .environmentObject(apiAccess)  // Api info (url and token)
-        ) {
+        NavigationLink(destination: Company(name: company.name ?? "", symbol: company.symbol ?? "")) {
             HStack {
                 WebImage(url: URL(string: endpoint()))
                     .resizable()
@@ -54,15 +49,6 @@
     }
 }
 
-struct LogoModifier: ViewModifier {
-    func body(content: Content) -> some View {
-        content
-            .aspectRatio(contentMode: .fit)
-            .frame(maxWidth: 40, maxHeight: 40)
-            .clipShape(RoundedRectangle(cornerRadius: 3))
-    }
-}
-
 
 struct WatchlistRow_Previews: PreviewProvider {
     // Avoid preview crashing