# HG changeset patch # User Dennis Concepción Martín <66180929+denniscm190@users.noreply.github.com> # Date 1609864989 0 # Node ID 668fd7e0d1213855dbe2a208f1fe0e72e08fb81f first commit diff -r 000000000000 -r 668fd7e0d121 .gitignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.gitignore Tue Jan 05 16:43:09 2021 +0000 @@ -0,0 +1,9 @@ +.DS_Store +Tests +Config.swift +Assets.xcassets +Configuration.storekit +Info.plist +Preview Content +Data +Config.xcconfig diff -r 000000000000 -r 668fd7e0d121 About.swift --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/About.swift Tue Jan 05 16:43:09 2021 +0000 @@ -0,0 +1,80 @@ +// +// Settings.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 27/12/20. +// + +import SwiftUI + +struct About: View { + @Environment(\.presentationMode) var aboutPresentation + + var body: some View { + NavigationView { + VStack(alignment:.leading) { + AppInfo() + + List { + NavigationLink(destination: WhatsNew() + .navigationBarTitle("What's new") + ) { + AboutButton(image: "sparkles", name: "What's new") + } + Button(action: openUrl(url: "https://apps.apple.com/es/app/lazybear-insider-trading/id1534612943?l=en")) { + AboutButton(image: "checkmark.circle.fill", name: "Rate Lazybear") + } + NavigationLink(destination: TipJar()) { + AboutButton(image: "gift.fill", name: "Tip jar") + } + Button(action: openUrl(url: "https://twitter.com/LazybearApp")) { + AboutButton(image: "at.circle.fill", name: "@Lazybear") + } + Button(action: openUrl(url: "https://twitter.com/dennisconcep")) { + AboutButton(image: "at.circle.fill", name: "@DennisConcep") + } + Button(action: openUrl(url: "https://lazybear.app")) { + AboutButton(image: "link.circle.fill", name: "Website") + } + Button(action: openUrl(url: "https://github.com/denniscm190/lazybear-iOS")) { + AboutButton(image: "star.fill", name: "Github") + } + Button(action: { }) { + AboutButton(image: "filemenu.and.selection", name: "Terms & Privacy policy") + } + Button(action: { }) { + AboutButton(image: "envelope.circle.fill", name: "Contact") + } + } + } + .padding() + .navigationTitle("About") + .navigationBarItems(leading: + Button(action: {self.aboutPresentation.wrappedValue.dismiss()}) { + Image(systemName: "multiply") + .resizable() + .frame(width: 25, height: 25) + } + ) + + } + .navigationViewStyle(StackNavigationViewStyle()) + } + + func openUrl(url: String) -> () -> () { + return { + if let url = URL(string: url) { + UIApplication.shared.open(url) + } + } + } +} + +struct About_Previews: PreviewProvider { + static var previews: some View { + NavigationView { + About() + } + .navigationViewStyle(StackNavigationViewStyle()) + } +} diff -r 000000000000 -r 668fd7e0d121 Company.swift --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Company.swift Tue Jan 05 16:43:09 2021 +0000 @@ -0,0 +1,46 @@ +// +// Company.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 29/12/20. +// + +import SwiftUI + +struct Company: View { + @State public var showingInsiders: Bool = false + @State public var showingMain: Bool = true + + // Company + @State var cik: Int + @State var symbol: String + @State var name: String + + var body: some View { + GeometryReader { geo in + VStack { + if showingMain { + Stock(cik: cik, symbol: symbol, name: name) + } else { + Insiders(cik: cik, symbol: symbol, name: name) + } + + // Start bottom selection + Rectangle() + .foregroundColor(.white) + .edgesIgnoringSafeArea(.bottom) + .frame(height: geo.size.height * 0.1) + .overlay( + Selection(showingInsiders: $showingInsiders, showingMain: $showingMain) + ) + } + .background(Color(.systemGray6).edgesIgnoringSafeArea(.all)) + } + } +} + +struct Company_Previews: PreviewProvider { + static var previews: some View { + Company(cik: 123, symbol: "Symbol", name: "Name") + } +} diff -r 000000000000 -r 668fd7e0d121 ContentView.swift --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ContentView.swift Tue Jan 05 16:43:09 2021 +0000 @@ -0,0 +1,87 @@ +// +// ContentView.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 27/09/2020. +// + +import SwiftUI + +struct ContentView: View { + @State var searchedCompany: String = "" + @State var showingSettings = false + @State var showingUser = false + @State public var showingSearch: Bool = false // Search Bar + + var body: some View { + VStack { + if showingSearch == false { + // Setting and user + HStack { + Button(action: {self.showingSettings.toggle()} + ) { + Image(systemName: "gear") + .imageIconModifier() + }.sheet(isPresented: $showingSettings) { + About() + } + + Spacer() + + Button(action: {self.showingUser.toggle() + }) { + Image(systemName: "person") + .imageIconModifier() + }.sheet(isPresented: $showingUser) { + User() + } + } + .transition(.move(edge: .top)) + .animation(.default) + .padding() + } + + SearchBar(searchedText: $searchedCompany, placeholder: "Search ...", showingSearch: $showingSearch) + + if showingSearch == false { + Companies() + .transition(.move(edge: .bottom)) + .animation(.default) + + + } else { + if searchedCompany.count > 2 { + Spacer() + List { + ForEach(companiesData.filter({ searchedCompany.isEmpty ? true : $0.name.localizedStandardContains(searchedCompany) }), id: \.cik) { company in + CompanyRow(company: company) + } + } + .edgesIgnoringSafeArea(.bottom) + .cornerRadius(20) + .id(UUID()) // Increase speed in search the list + } + Spacer() + } + } + .navigationBarHidden(true) + } +} +extension Image { + func imageIconModifier() -> some View { + self + .resizable() + .aspectRatio(contentMode: .fit) + .frame(maxWidth: 30) + } +} + + +struct ContentView_Previews: PreviewProvider { + static var previews: some View { + NavigationView { + ContentView() + } + .navigationViewStyle(StackNavigationViewStyle()) + } +} diff -r 000000000000 -r 668fd7e0d121 Functions/Price.swift --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Functions/Price.swift Tue Jan 05 16:43:09 2021 +0000 @@ -0,0 +1,51 @@ +// +// RequestPrices.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 3/1/21. +// + +import SwiftUI + +class Price: ObservableObject { + @Published var result = [PriceModel]() + @Published var showingView = false + @Published var showingAlert = false + + func request(symbol: String) { + guard let url = URL(string: priceUrl(symbol: symbol, sandbox: true)) else { // Change sandbox when production + print("Invalid URL") + return + } + let request = URLRequest(url: url) + URLSession.shared.dataTask(with: request) { data, response, error in + if let data = data { + if let decodedResponse = try? JSONDecoder().decode([PriceModel].self, from: data) { + // we have good data – go back to the main thread + DispatchQueue.main.async { + // update our UI + self.result = decodedResponse + print("API request ok") + + // Check if data is empty + if self.result.isEmpty || self.result.count <= 1 { + print("Data is empty") + self.showingView = false + self.showingAlert = true + } else { + print("Showing view...") + self.showingView = true + } + + } + + // everything is good, so we can exit + return + } + } + + // if we're still here it means there was a problem + print("Fetch failed: \(error?.localizedDescription ?? "Unknown error")") + }.resume() + } +} diff -r 000000000000 -r 668fd7e0d121 Functions/ReadJson.swift --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Functions/ReadJson.swift Tue Jan 05 16:43:09 2021 +0000 @@ -0,0 +1,35 @@ +// +// ReadJson.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 31/12/20. +// + +import SwiftUI + +import SwiftUI + +// With this function I parse the local JSON file to read it and create a list with its items. +let companiesData: [CompanyData] = load("companies.json") + +func load(_ filename: String) -> T { + let data: Data + + guard let file = Bundle.main.url(forResource: filename, withExtension: nil) + else { + fatalError("Couldn't find \(filename) in main bundle.") + } + + do { + data = try Data(contentsOf: file) + } catch { + fatalError("Couldn't load \(filename) from main bundle:\n\(error)") + } + + do { + let decoder = JSONDecoder() + return try decoder.decode(T.self, from: data) + } catch { + fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)") + } +} diff -r 000000000000 -r 668fd7e0d121 Functions/Transaction.swift --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Functions/Transaction.swift Tue Jan 05 16:43:09 2021 +0000 @@ -0,0 +1,51 @@ +// +// Insiders.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 4/1/21. +// + +import SwiftUI + +class Transaction: ObservableObject { + @Published var result = [TransactionModel]() + @Published var showingView = false + @Published var showingAlert = false + + func request(cik: String, date: String) { + guard let url = URL(string: transactionUrl(cik: cik, date: date)) else { // Change sandbox when production + print("Invalid URL") + return + } + let request = URLRequest(url: url) + URLSession.shared.dataTask(with: request) { data, response, error in + if let data = data { + if let decodedResponse = try? JSONDecoder().decode([TransactionModel].self, from: data) { + // we have good data – go back to the main thread + DispatchQueue.main.async { + // update our UI + self.result = decodedResponse + print("API request ok") + + // Check if data is empty + if self.result.isEmpty || self.result.count <= 1 { + print("Data is empty") + self.showingView = false + self.showingAlert = true + } else { + print("Showing view...") + self.showingView = true + } + + } + + // everything is good, so we can exit + return + } + } + + // if we're still here it means there was a problem + print("Fetch failed: \(error?.localizedDescription ?? "Unknown error")") + }.resume() + } +} diff -r 000000000000 -r 668fd7e0d121 Insiders.swift --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Insiders.swift Tue Jan 05 16:43:09 2021 +0000 @@ -0,0 +1,102 @@ +// +// Insiders.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 2/1/21. +// + +import SwiftUI +import SwiftUICharts + +struct Insiders: View { + @ObservedObject var transaction = Transaction() + + // Company + @State var cik: Int + @State var symbol: String + @State var name: String + + // Picker + var dateFormatter: DateFormatter { + let formatter = DateFormatter() + formatter.dateFormat = "yyyy-MM-dd" + return formatter + } + + @State private var selectedDate = Date().addingTimeInterval(-6*30*24*60*60) // month*days*hours*minutes*seconds + + var body: some View { + VStack { + if transaction.showingView { + // Graph + let cumBuys = cumSum(array: getTransactions(acquisitionOrDisposition: "A")) + let cumSells = cumSum(array: getTransactions(acquisitionOrDisposition: "D")) + let green = GradientColor(start: .green, end: .green) + let red = GradientColor(start: .red, end: .red) + + MultiLineChartView(data: [(cumBuys, green), (cumSells, red)], title: "Buys and sells", form: ChartForm.extraLarge, rateValue: pct(buy: cumBuys.last!, sell: cumSells.last!)) + .padding() + + DatePicker(selection: $selectedDate, in: ...Date(), displayedComponents: .date) { Text("Transactions since").font(.headline) } + .padding([.leading, .top, .trailing]) + .onChange(of: self.selectedDate, perform: { date in + transaction.request(cik: String(cik), date: dateFormatter.string(from: selectedDate)) + }) + + List { + ForEach(transaction.result, id:\.self) { trans in + TransactionRow(trans: trans) + } + } + .offset(y: 10) + } + else { + Spacer() + ProgressView() + Spacer() + } + } + .onAppear { + transaction.request(cik: String(cik), date: dateFormatter.string(from: selectedDate)) + } + .alert(isPresented: $transaction.showingAlert) { + Alert(title: Text("There is no data available"), message: Text("We have no data about this company. Try another one."), dismissButton: .default(Text("Got it!"))) + } + } + // Function to sum an array and return a cumulative sum array + func cumSum(array: [Double]) -> [Double] { + var iterateArray = [Double]() + var cumSumArray = [Double]() + for value in array { + iterateArray.append(value) + cumSumArray.append(iterateArray.reduce(0, +)) + } + return cumSumArray + } + // Return two arrays with buys and sells + func getTransactions(acquisitionOrDisposition: String) -> [Double] { + var result = [Double]() + + for trans in transaction.result { + if trans.acquisition_disposition == acquisitionOrDisposition { + result.append(Double(trans.number_securities_transacted)) + } + } + + return result + } + // Get pct of net buys over sells + func pct(buy: Double, sell: Double) -> Int { + let pctOfBuys = buy / (buy+sell) + let pctOfSells = sell / (buy+sell) + let pct = pctOfBuys - pctOfSells + + return Int(pct*100) + } +} + +struct Insiders_Previews: PreviewProvider { + static var previews: some View { + Insiders(cik: 123, symbol: "Symbol", name: "Name") + } +} diff -r 000000000000 -r 668fd7e0d121 LazyBearApp.swift --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LazyBearApp.swift Tue Jan 05 16:43:09 2021 +0000 @@ -0,0 +1,21 @@ +// +// LazyBearApp.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 27/09/2020. +// + +import SwiftUI +import StoreKit + +@main +struct LazyBearApp: App { + var body: some Scene { + WindowGroup { + NavigationView { + ContentView() + } + .navigationViewStyle(StackNavigationViewStyle()) + } + } +} diff -r 000000000000 -r 668fd7e0d121 Models/CompanyData.swift --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Models/CompanyData.swift Tue Jan 05 16:43:09 2021 +0000 @@ -0,0 +1,14 @@ +// +// CompanyData.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 31/12/20. +// + +import SwiftUI + +struct CompanyData: Hashable, Codable { + var cik: Int + var symbol: String + var name: String +} diff -r 000000000000 -r 668fd7e0d121 Models/PriceModel.swift --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Models/PriceModel.swift Tue Jan 05 16:43:09 2021 +0000 @@ -0,0 +1,16 @@ +// +// Prices.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 3/1/21. +// + +import SwiftUI + +struct PriceModel: Codable { + var close: Double + var date: String + var symbol: String + var volume: Float + var changePercent: Double +} diff -r 000000000000 -r 668fd7e0d121 Models/TransactionModel.swift --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Models/TransactionModel.swift Tue Jan 05 16:43:09 2021 +0000 @@ -0,0 +1,16 @@ +// +// Insiders.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 4/1/21. +// + +import SwiftUI + +struct TransactionModel: Codable, Hashable { + var acquisition_disposition: String + var transaction_date: String + var reporting_owner: String + var transaction_type: String + var number_securities_transacted: Int +} diff -r 000000000000 -r 668fd7e0d121 README.md --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/README.md Tue Jan 05 16:43:09 2021 +0000 @@ -0,0 +1,2 @@ +# Lazybear iOS App +This is the source code of my app Lazybear. You can download it from here https://apps.apple.com/es/app/lazybear-datos-financieros/id1534612943 diff -r 000000000000 -r 668fd7e0d121 Stock.swift --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Stock.swift Tue Jan 05 16:43:09 2021 +0000 @@ -0,0 +1,85 @@ +// +// Stock.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 2/1/21. +// + +import SwiftUI +import SwiftUICharts + +struct Stock: View { + @ObservedObject var price = Price() + + // Company + @State var cik: Int + @State var symbol: String + @State var name: String + + var body: some View { + VStack { + if price.showingView { + HStack { + Text("$ " + String(price.result.last!.close)) + .font(.title) + .fontWeight(.bold) + + let pct = price.result.last!.changePercent * 100 + Text(String(format: "%.2f", pct) + " %") + .font(.headline) + .foregroundColor(whichColor()) + + Spacer() + } + .padding([.leading, .top]) + + HStack { + Text(String(price.result.last!.date) + " last price") + .font(.caption) + .padding([.leading]) + .opacity(0.5) + Spacer() + } + + // Stock Price + let prices = price.result.map { $0.close } // Get an array of a variable in the struct + LineChartView(data: prices, title: "Stock price", legend: "Last 20 days", form: ChartForm.extraLarge, rateValue: nil) + .padding() + + Spacer() + + // Volume + let volume = price.result.map { $0.volume } + BarChartView(data: ChartData(points: volume), title: "Volume", form: ChartForm.extraLarge) + .padding() + + } + else { + Spacer() + ProgressView() + Spacer() + } + } + .onAppear { + price.request(symbol: symbol) + } + .alert(isPresented: $price.showingAlert) { + Alert(title: Text("There is no data available"), message: Text("We have no data about this company. Try another one."), dismissButton: .default(Text("Got it!"))) + } + } + + func whichColor() -> Color { + if price.result.last!.changePercent < 0 { + return Color(.red) + } + else { + return Color(.green) + } + } +} + +struct Stock_Previews: PreviewProvider { + static var previews: some View { + Stock(cik: 123, symbol: "Symbol", name: "Name") + } +} diff -r 000000000000 -r 668fd7e0d121 Supply/AboutButton.swift --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Supply/AboutButton.swift Tue Jan 05 16:43:09 2021 +0000 @@ -0,0 +1,30 @@ +// +// AboutButton.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 31/12/20. +// + +import SwiftUI + +struct AboutButton: View { + @State var image: String + @State var name: String + + var body: some View { + HStack { + Image(systemName: image) + .renderingMode(.original) + .resizable() + .frame(width: 25, height: 25) + + Text(name) + } + } +} + +struct AboutButton_Previews: PreviewProvider { + static var previews: some View { + AboutButton(image: "sparkles", name: "What's new") + } +} diff -r 000000000000 -r 668fd7e0d121 Supply/AppInfo.swift --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Supply/AppInfo.swift Tue Jan 05 16:43:09 2021 +0000 @@ -0,0 +1,41 @@ +// +// AppInfo.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 31/12/20. +// + +import SwiftUI + +struct AppInfo: View { + var body: some View { + HStack { + Spacer() + Image("launchLogo") + .resizable() + .frame(width: /*@START_MENU_TOKEN@*/100/*@END_MENU_TOKEN@*/, height: /*@START_MENU_TOKEN@*/100/*@END_MENU_TOKEN@*/, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/) + + VStack { + Text("Lazybear " + getVersion()) + .fontWeight(/*@START_MENU_TOKEN@*/.bold/*@END_MENU_TOKEN@*/) + + Text("By Dennis Concepción") + } + Spacer() + } + .padding() + } + + // Get app version + func getVersion() -> String { + let dictionary = Bundle.main.infoDictionary! + let version = dictionary["CFBundleShortVersionString"] as! String + return version + } +} + +struct AppInfo_Previews: PreviewProvider { + static var previews: some View { + AppInfo() + } +} diff -r 000000000000 -r 668fd7e0d121 Supply/Companies.swift --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Supply/Companies.swift Tue Jan 05 16:43:09 2021 +0000 @@ -0,0 +1,52 @@ +// +// Companies.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 27/12/20. +// + +import SwiftUI + +struct Companies: View { + var colours = [Color(.systemBlue), Color(.systemYellow), Color(.systemRed), Color(.systemGreen), Color(.systemIndigo), Color(.systemOrange), Color(.systemPink), Color(.systemPurple), Color(.systemTeal), Color(.systemRed)] + + var names = ["adobe", "amazon", "apple", "facebook", "google", "jp", "netflix", "paypal", "salesforce", "tesla"] + var ciks = [796343, 1018724, 320193, 1326801, 1652044, 19617, 1065280, 1633917, 1108524, 1318605] + var symbols = ["adbe", "amzn", "aapl", "fb", "googl", "amj", "nflx", "pypl", "crm", "tsla"] + + let columns = [ + GridItem(.flexible()), + GridItem(.flexible()) + ] + + var body: some View { + ScrollView { + LazyVGrid(columns: columns, spacing: 20) { // Create ScrollView with two columns per row + ForEach((0...9), id: \.self) { index in + NavigationLink(destination: Company(cik: ciks[index], symbol: symbols[index], name: names[index]) + .navigationBarTitle(names[index].capitalized) + ) { + VStack { + Image(names[index]) + .resizable() + .aspectRatio(contentMode: .fit) + + Text(names[index].capitalized) + .foregroundColor(.white) + .fontWeight(.bold) + } + .padding(40) + .background(colours[index].cornerRadius(20)) + } + } + } + .padding() + } + } +} + +struct Companies_Previews: PreviewProvider { + static var previews: some View { + Companies() + } +} diff -r 000000000000 -r 668fd7e0d121 Supply/CompanyRow.swift --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Supply/CompanyRow.swift Tue Jan 05 16:43:09 2021 +0000 @@ -0,0 +1,28 @@ +// +// CompanyRown.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 31/12/20. +// + +import SwiftUI + +struct CompanyRow: View { + var company: CompanyData + + var body: some View { + HStack { + NavigationLink(destination: Company(cik: company.cik, symbol: company.symbol, name: company.name) + .navigationBarTitle(company.name.capitalized) + ) { + Text(company.name.capitalized) + } + } + } +} + +struct CompanyRown_Previews: PreviewProvider { + static var previews: some View { + CompanyRow(company: companiesData[0]) + } +} diff -r 000000000000 -r 668fd7e0d121 Supply/SearchBar.swift --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Supply/SearchBar.swift Tue Jan 05 16:43:09 2021 +0000 @@ -0,0 +1,74 @@ +// +// SearchBar.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 27/12/20. +// + +import SwiftUI + +struct SearchBar: View { + + // Text field + @Binding var searchedText: String + @State var searchBarIsEditing = false + @State var placeholder: String + @Binding var showingSearch: Bool // Content View + + var body: some View { + HStack { + TextField(placeholder, text: $searchedText) + .padding(10) + .padding(.horizontal, 45) + .overlay( + HStack { + Image(systemName: "globe") + .frame(minWidth: 0, maxWidth: .infinity, alignment: .leading) + .padding(.leading) + .foregroundColor(Color("placeholder")) + + if searchBarIsEditing { + Button(action: { + self.searchedText = "" + }) { + Image(systemName: "multiply.circle.fill") + .foregroundColor(Color("placeholder")) + .padding(.trailing) + } + } + } + ) + .background(Color(.systemGray6)) + .cornerRadius(10) + .onTapGesture { + self.searchBarIsEditing = true + withAnimation { + self.showingSearch = true // Content View + } + + } + + if searchBarIsEditing { + Button(action: { + self.searchedText = "" + self.searchBarIsEditing = false + withAnimation { + self.showingSearch = false // Content View + } + // Force hide keyboard + UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil) + + }) { + Text("Cancel") + } + } + } + .padding() + } +} + +struct SearchBar_Previews: PreviewProvider { + static var previews: some View { + SearchBar(searchedText: .constant(""), placeholder: "Placeholder", showingSearch: .constant(true)) + } +} diff -r 000000000000 -r 668fd7e0d121 Supply/Selection.swift --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Supply/Selection.swift Tue Jan 05 16:43:09 2021 +0000 @@ -0,0 +1,74 @@ +// +// Selection.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 30/12/20. +// + +import SwiftUI + +struct Selection: View { + @Binding var showingInsiders: Bool + @Binding var showingMain: Bool + + var body: some View { + // Buttons + HStack { + Group { + // Insiders + Button(action: {toggle(type: "insider")}) { + if showingInsiders { + Image(systemName: "person.fill") + .resizable() + .frame(width: 35, height: 35) + } else { + Image(systemName: "person") + .resizable() + .frame(width: 35, height: 35) + } + } + + // Stock + Button(action: {toggle(type: "stock")}) { + if showingMain { + Image(systemName: "dollarsign.square.fill") + .resizable() + .frame(width: 35, height: 35) + + } else { + Image(systemName: "dollarsign.square") + .resizable() + .frame(width: 35, height: 35) + } + } + }.padding().padding().padding() + } + } + + func toggle(type: String) { + if type == "insider" { + self.showingMain = false + self.showingInsiders = true + } + + if type == "stock" { + self.showingMain = true + self.showingInsiders = false + } + + if type == "description" { + self.showingMain = false + self.showingInsiders = false + } + } +} + +struct Selection_Previews: PreviewProvider { + static var previews: some View { + Selection(showingInsiders: .constant(false), showingMain: .constant(true)) + } +} + +/* + + */ diff -r 000000000000 -r 668fd7e0d121 Supply/TipJar.swift --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Supply/TipJar.swift Tue Jan 05 16:43:09 2021 +0000 @@ -0,0 +1,20 @@ +// +// TipJar.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 31/12/20. +// + +import SwiftUI + +struct TipJar: View { + var body: some View { + Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/) + } +} + +struct TipJar_Previews: PreviewProvider { + static var previews: some View { + TipJar() + } +} diff -r 000000000000 -r 668fd7e0d121 Supply/TransactionRow.swift --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Supply/TransactionRow.swift Tue Jan 05 16:43:09 2021 +0000 @@ -0,0 +1,44 @@ +// +// TransactionRow.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 4/1/21. +// + +import SwiftUI + +struct TransactionRow: View { + var trans: TransactionModel + + var body: some View { + VStack(alignment: .leading) { + HStack { + Image(systemName: "person.fill") + Text(trans.reporting_owner.capitalized) + Spacer() + Text(String(trans.number_securities_transacted)) + .foregroundColor(colourShares(type: trans.acquisition_disposition)) + } + HStack { + Image(systemName: "calendar") + Text(trans.transaction_date) + } + } + .padding() + } + + func colourShares(type: String) -> Color { + if type == "A" { // If aquisition_disposition == A, means "Acquisition" -> buy + return Color(.green) + } + else { + return Color(.red) + } + } +} + +struct TransactionRow_Previews: PreviewProvider { + static var previews: some View { + TransactionRow(trans: TransactionModel(acquisition_disposition: "A", transaction_date: "2020-01-01", reporting_owner: "steve jobs", transaction_type: "F-SomeStuff", number_securities_transacted: 12345)) + } +} diff -r 000000000000 -r 668fd7e0d121 Supply/WhatsNew.swift --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Supply/WhatsNew.swift Tue Jan 05 16:43:09 2021 +0000 @@ -0,0 +1,60 @@ +// +// WhatsNew.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 31/12/20. +// + +import SwiftUI +import SwiftUICharts + +struct WhatsNew: View { + var body: some View { + ScrollView { + VStack(alignment: .leading, spacing: 20) { + let intro = "This new version comes with lots of changes and many cool stuff. I've been working hard to improve the backend efficiency, deploy a new API and other boring stuff that you probably are not interested in. So let's talk about the cool stuff." + Text(intro) + + let title1 = "New design" + let text1 = "As you can see, there is a completely new design, more clean, colourful, and simple. Now you can check the date for the company you want in three clicks. Less is more." + Text(title1 + " 😎") + .title() + + Text(text1) + + let title2 = "Charts! A bunch!" + let text2 = "Look how cool they are" + Text(title2) + .title() + + Text(text2 + " 😁") + HStack { + Spacer() + LineChartView(data: [8,23,54,32,12,37,7,23,43], title: "Some cool title", form: ChartForm.large, rateValue: 14) + Spacer() + } + + let title3 = "Stock prices" + let text3 = "Finally I found a not-so-expensive method to show stock prices. In this version you can see the latest stock price from the previous day, but I promise you in future versions I am going to add real-time stock prices." + Text(title3) + .title() + + Text(text3) + } + .padding() + } + } +} +extension Text { + func title() -> some View { + self + .font(/*@START_MENU_TOKEN@*/.title/*@END_MENU_TOKEN@*/) + .fontWeight(.semibold) + } +} + +struct WhatsNew_Previews: PreviewProvider { + static var previews: some View { + WhatsNew() + } +} diff -r 000000000000 -r 668fd7e0d121 User.swift --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/User.swift Tue Jan 05 16:43:09 2021 +0000 @@ -0,0 +1,49 @@ +// +// User.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 27/12/20. +// + +import SwiftUI + +struct User: View { + @Environment(\.presentationMode) var userPresentation + + var body: some View { + VStack(alignment:.leading) { + HStack { + Button(action: {self.userPresentation.wrappedValue.dismiss() + }) { + Image(systemName: "multiply") + .resizable() + .frame(width: 25, height: 25) + + Spacer() + } + } + + Text("My favourites") + .font(.largeTitle) + .fontWeight(/*@START_MENU_TOKEN@*/.bold/*@END_MENU_TOKEN@*/) + + List { + HStack { + Image(systemName: "star") + .renderingMode(.original) + .resizable() + .frame(width: 25, height: 25) + + Text("Company 1") + } + } + } + .padding() + } +} + +struct User_Previews: PreviewProvider { + static var previews: some View { + User() + } +}