changeset 116:4e920489a57e

Implement BusinessNews module
author Dennis Concepción Martín <66180929+denniscm190@users.noreply.github.com>
date Thu, 04 Feb 2021 23:29:00 +0100
parents 33e03e2863f6
children 82ac1ea65269
files LazyBear.xcodeproj/project.pbxproj LazyBear.xcodeproj/project.xcworkspace/xcuserdata/dennis.xcuserdatad/UserInterfaceState.xcuserstate lazybear/Models/NewsModel.swift lazybear/Views/Company.swift lazybear/Views/News.swift lazybear/Views/NewsRow.swift lazybear/Views/Price.swift
diffstat 7 files changed, 141 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/LazyBear.xcodeproj/project.pbxproj	Thu Feb 04 20:36:33 2021 +0100
+++ b/LazyBear.xcodeproj/project.pbxproj	Thu Feb 04 23:29:00 2021 +0100
@@ -24,6 +24,9 @@
 		958B678525C42B2400BF9F89 /* ApiAccess.swift in Sources */ = {isa = PBXBuildFile; fileRef = 958B678425C42B2400BF9F89 /* ApiAccess.swift */; };
 		9597CE0125C1DC0A004DDFED /* LogoModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9597CE0025C1DC0A004DDFED /* LogoModifier.swift */; };
 		9597CE0425C1DFE7004DDFED /* LogoPlaceholder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9597CE0325C1DFE7004DDFED /* LogoPlaceholder.swift */; };
+		959D28DC25CC99710029F689 /* NewsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 959D28DB25CC99710029F689 /* NewsModel.swift */; };
+		959D28DF25CC9A1A0029F689 /* News.swift in Sources */ = {isa = PBXBuildFile; fileRef = 959D28DE25CC9A1A0029F689 /* News.swift */; };
+		959D28E225CC9B370029F689 /* NewsRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 959D28E125CC9B370029F689 /* NewsRow.swift */; };
 		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 */; };
@@ -70,6 +73,9 @@
 		958B678425C42B2400BF9F89 /* ApiAccess.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ApiAccess.swift; path = lazybear/ApiAccess.swift; sourceTree = SOURCE_ROOT; };
 		9597CE0025C1DC0A004DDFED /* LogoModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogoModifier.swift; sourceTree = "<group>"; };
 		9597CE0325C1DFE7004DDFED /* LogoPlaceholder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogoPlaceholder.swift; sourceTree = "<group>"; };
+		959D28DB25CC99710029F689 /* NewsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = NewsModel.swift; path = lazybear/Models/NewsModel.swift; sourceTree = SOURCE_ROOT; };
+		959D28DE25CC9A1A0029F689 /* News.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = News.swift; path = lazybear/Views/News.swift; sourceTree = SOURCE_ROOT; };
+		959D28E125CC9B370029F689 /* NewsRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = NewsRow.swift; path = lazybear/Views/NewsRow.swift; sourceTree = SOURCE_ROOT; };
 		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>"; };
@@ -135,6 +141,7 @@
 				95FE646A25C30B880052832E /* ApiModel.swift */,
 				954DDF0325C456E800848A4B /* QuoteModel.swift */,
 				95363CE125C87CF000B74131 /* InsiderTransactionModel.swift */,
+				959D28DB25CC99710029F689 /* NewsModel.swift */,
 			);
 			path = Models;
 			sourceTree = "<group>";
@@ -162,6 +169,8 @@
 				9520F0B425C7131300692610 /* LineChart.swift */,
 				95363CE525C87FEC00B74131 /* InsiderTransactions.swift */,
 				95363CE925C8858800B74131 /* TransactionRow.swift */,
+				959D28DE25CC9A1A0029F689 /* News.swift */,
+				959D28E125CC9B370029F689 /* NewsRow.swift */,
 			);
 			path = Views;
 			sourceTree = "<group>";
@@ -312,8 +321,10 @@
 				95F6F45C25C20D8D002AC66A /* Price.swift in Sources */,
 				9597CE0125C1DC0A004DDFED /* LogoModifier.swift in Sources */,
 				954DDF0425C456E800848A4B /* QuoteModel.swift in Sources */,
+				959D28E225CC9B370029F689 /* NewsRow.swift in Sources */,
 				9520F0B525C7131300692610 /* LineChart.swift in Sources */,
 				9597CE0425C1DFE7004DDFED /* LogoPlaceholder.swift in Sources */,
+				959D28DF25CC9A1A0029F689 /* News.swift in Sources */,
 				95FE646B25C30B880052832E /* ApiModel.swift in Sources */,
 				95363CE625C87FEC00B74131 /* InsiderTransactions.swift in Sources */,
 				95F6C30525BAF599003CF389 /* CompanyHeader.swift in Sources */,
@@ -326,6 +337,7 @@
 				95B04EB525212369000AD27F /* ContentView.swift in Sources */,
 				95AB4A90259DD66D0064C9C1 /* CompanyRow.swift in Sources */,
 				95F6C30125BAEC8B003CF389 /* CompanyView.swift in Sources */,
+				959D28DC25CC99710029F689 /* NewsModel.swift in Sources */,
 				95F6C30925BAF7C2003CF389 /* DateSelection.swift in Sources */,
 				95F6C2F025BAE2ED003CF389 /* Company.swift in Sources */,
 				95F6F46125C20E63002AC66A /* ListHeader.swift in Sources */,
Binary file LazyBear.xcodeproj/project.xcworkspace/xcuserdata/dennis.xcuserdatad/UserInterfaceState.xcuserstate has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lazybear/Models/NewsModel.swift	Thu Feb 04 23:29:00 2021 +0100
@@ -0,0 +1,17 @@
+//
+//  NewsModel.swift
+//  LazyBear
+//
+//  Created by Dennis Concepción Martín on 4/2/21.
+//
+
+import SwiftUI
+
+struct NewsModel: Codable, Hashable {
+    var datetime: Int?
+    var headline: String?
+    var source: String?
+    var url: String?
+    var summary: String?
+    var image: String?
+}
--- a/lazybear/Views/Company.swift	Thu Feb 04 20:36:33 2021 +0100
+++ b/lazybear/Views/Company.swift	Thu Feb 04 23:29:00 2021 +0100
@@ -13,9 +13,6 @@
     
     let persistenceController = PersistenceController.shared
     
-    var views = ["Stock", "Insiders"]
-    @State private var selectedView = 0
-    
     var body: some View {
         VStack {
             CompanyHeader(name: self.name, symbol: self.symbol)
@@ -27,14 +24,14 @@
                             Stock(name: name, symbol: symbol, lineChartHeight: geo.size.height*0.2)
                                 .padding(.bottom)
                             
-                            
+                            News(symbol: symbol)
                         }
                         .environment(\.managedObjectContext, persistenceController.container.viewContext)
                     }
                 }
                 .tabItem {
-                    Image(systemName: "1.circle")
-                    Text("First")
+                    Image(systemName: "chart.bar.fill")
+                    Text("Stock")
                 }.tag(0)
                 
                 // Second view
@@ -42,8 +39,8 @@
                     InsiderTransactions(symbol: symbol)
                 }
                 .tabItem {
-                    Image(systemName: "2.circle")
-                    Text("Second")
+                    Image(systemName: "chart.pie.fill")
+                    Text("Insiders")
                 }.tag(1)
             }
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lazybear/Views/News.swift	Thu Feb 04 23:29:00 2021 +0100
@@ -0,0 +1,52 @@
+//
+//  News.swift
+//  LazyBear
+//
+//  Created by Dennis Concepción Martín on 4/2/21.
+//
+
+import SwiftUI
+
+struct News: View {
+    var symbol: String
+    @EnvironmentObject var apiAccess: ApiAccess
+    
+    // <--------- API Job --------->
+    @State private var url = String() {
+        didSet { request(url: url, model: [NewsModel].self) { self.news = $0 } }}
+    
+    @State private var news = [NewsModel]()
+    // <--------- API Job --------->
+    
+    var body: some View {
+        Text("Business news")
+            .font(.title)
+            .fontWeight(.semibold)
+            .padding([.leading, .top])
+        
+        Divider()
+        
+        VStack {
+            ForEach(news, id: \.self) { new in
+                NewsRow(new: new)
+            }
+        }
+        .onAppear { getUrl() }
+    }
+    
+    
+    private func getUrl() {
+        // 1 -> Sandbox / 2 -> Production
+        let baseUrl = apiAccess.results[2].url ?? ""
+        let token = apiAccess.results[2].key ?? ""
+        let path = "/stable/stock/\(symbol)/news/last/10?token="
+        
+        self.url = baseUrl + path + token
+    }
+}
+
+struct News_Previews: PreviewProvider {
+    static var previews: some View {
+        News(symbol: "aapl")
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lazybear/Views/NewsRow.swift	Thu Feb 04 23:29:00 2021 +0100
@@ -0,0 +1,54 @@
+//
+//  NewsRow.swift
+//  LazyBear
+//
+//  Created by Dennis Concepción Martín on 4/2/21.
+//
+
+import SwiftUI
+
+struct NewsRow: View {
+    @State var new: NewsModel
+    
+    var body: some View {
+        VStack(alignment: .leading) {
+            Text(new.source ?? "-")
+                .font(.caption2)
+            
+            Text(new.headline ?? "-")
+                .font(.headline)
+                .fontWeight(.semibold)
+                .lineLimit(4)
+            
+            Text(new.summary ?? "-")
+                .lineLimit(3)
+                .font(.caption)
+                .padding(.top, 3)
+            
+            let (hours, minutes) = convertEpoch()
+            Text("\(hours) hours and \(minutes) minutes ago")
+                .font(.caption)
+                .fontWeight(.semibold)
+                .padding(.top, 3)
+            
+            Divider()
+        }
+        .padding([.leading, .trailing])
+    }
+    
+    private func convertEpoch() -> (String, String) {
+        let now = Date() // Current date
+        let articlePublished = Date(timeIntervalSince1970: TimeInterval(new.datetime ?? 0)/1000)
+        
+        let calendar = Calendar.current
+        let components = calendar.dateComponents([.hour, .minute], from: articlePublished, to: now)
+        
+        return (String(components.hour ?? 0), String(components.minute ?? 0))
+    }
+}
+
+struct NewsRow_Previews: PreviewProvider {
+    static var previews: some View {
+        NewsRow(new: NewsModel(datetime: 248375623, headline: "Leak says Apple’s first mixed-reality headset will cost $3,000", source: "BGR", url: "", summary: "A new report lists the purported price and release date of Apple’s upcoming high-end mixed-reality (MR) glasses. The headset will supposedly retail for around $3,000 in 2022. The device will reportedly use cameras to track the wearer's hands, while internal sensors track eye movements. The headset is said to feature two 8K displays that will follow the eyes' movement, displaying the images that are in focus at high resolution, with objects in peripheral vision being shown at a lower resolution. Apple has been rumored more than once to be developing its own smart headgear that would work in tandem with other devices, like the iPhone or a Mac. The so-called Apple Glasses project has been the subject.", image: ""))
+    }
+}
--- a/lazybear/Views/Price.swift	Thu Feb 04 20:36:33 2021 +0100
+++ b/lazybear/Views/Price.swift	Thu Feb 04 23:29:00 2021 +0100
@@ -14,8 +14,8 @@
     @EnvironmentObject var apiAccess: ApiAccess
     
     // <--------- API Job --------->
+    @State private var showingView = false
     @State private var url = String() { didSet { requestPrice() }}
-    @State private var showingView = false
     @State private var data = [QuoteModel]() { didSet { self.showingView = true }}
     // <--------- API Job --------->