// // ContentView.swift // Shared // // Created by Trey Tartt on 1/5/22. // import SwiftUI import CoreData import Charts struct ContentView: View { @Environment(\.managedObjectContext) private var viewContext @State private var showingSheet = false @State private var showTodayInput = true @FetchRequest( sortDescriptors: [NSSortDescriptor(keyPath: \MoodEntry.date, ascending: false)], animation: .spring()) private var items: FetchedResults var body: some View { TabView { mainView .tabItem { Label("Main", systemImage: "list.dash") } GraphView() .tabItem { Label("Graph", systemImage: "chart.line.uptrend.xyaxis") } } } private var settingsButtonView: some View { HStack { Spacer() Button(action: { showingSheet.toggle() }, label: { Image(systemName: "gear") .foregroundColor(Color(UIColor.systemGray)) .font(.system(size: 20)) }).sheet(isPresented: $showingSheet) { SettingsView() }.padding(.trailing) } } private var listView: some View { List { ForEach(items) { item in HStack { item.mood.icon .font(.system(size: 50)) VStack { Text("\(item.moodString)") .font(.title) .foregroundColor(Color(UIColor.systemGray)) .frame(maxWidth: .infinity, alignment: .leading) Text(item.date!, style: .date) .font(.body) .foregroundColor(Color(UIColor.label)) .frame(maxWidth: .infinity, alignment: .leading) } .padding(.leading) } } .onDelete(perform: deleteItems) } } private var mainView: some View { VStack{ settingsButtonView if shouldShowTodayInput() { AddMoodHeaderView() .frame(minHeight: 85, maxHeight: 180) .frame(minWidth: 0, maxWidth: .infinity) } else { HeaderStatsView(entries: [ //x - position of a bar, y - height of a bar BarChartDataEntry(x: 1, y: 1), BarChartDataEntry(x: 2, y: 5), BarChartDataEntry(x: 3, y: 2), BarChartDataEntry(x: 4, y: 4), BarChartDataEntry(x: 5, y: 1) ]) .frame(minHeight: 85, maxHeight: 180) } listView } } private func deleteItems(offsets: IndexSet) { withAnimation { offsets.map { items[$0] }.forEach(viewContext.delete) do { try viewContext.save() } catch { // Replace this implementation with code to handle the error appropriately. // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. let nsError = error as NSError fatalError("Unresolved error \(nsError), \(nsError.userInfo)") } } } private func shouldShowTodayInput() -> Bool { let fetchRequest = NSFetchRequest(entityName: "MoodEntry") var calendar = Calendar.current calendar.timeZone = NSTimeZone.local // Get today's beginning & end let dateFrom = calendar.startOfDay(for: Date()) // eg. 2016-10-10 00:00:00 let dateTo = calendar.date(byAdding: .day, value: 1, to: dateFrom)! // Note: Times are printed in UTC. Depending on where you live it won't print 00:00:00 but it will work with UTC times which can be converted to local time // Set predicate as date being today's date let fromPredicate = NSPredicate(format: "%@ <= %K", dateFrom as NSDate, #keyPath(MoodEntry.date)) let toPredicate = NSPredicate(format: "%K < %@", #keyPath(MoodEntry.date), dateTo as NSDate) let datePredicate = NSCompoundPredicate(andPredicateWithSubpredicates: [fromPredicate, toPredicate]) fetchRequest.predicate = datePredicate let entries = try! self.viewContext.count(for: fetchRequest) return entries == 0 } } private let itemFormatter: DateFormatter = { let formatter = DateFormatter() formatter.dateStyle = .short formatter.timeStyle = .medium return formatter }() struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView().environment(\.managedObjectContext, PersistenceController.shared.container.viewContext) .onAppear(perform: { PersistenceController.shared.populateMemory() }) ContentView() .preferredColorScheme(.dark) .environment(\.managedObjectContext, PersistenceController.shared.container.viewContext) } }