// // 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.forDate, ascending: false)], animation: .spring()) private var items: FetchedResults init(){ } var body: some View { TabView { mainView .tabItem { Label("Main", systemImage: "list.dash") } FilterView() .tabItem { Label("Filter", systemImage: "calendar.circle") } GraphView() .tabItem { Label("Stats", 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 func weekdayName(fromDate date: Date) -> String { let weekday = Calendar.current.component(.weekday, from: date) let calendar = Calendar.current let dayIndex = ((weekday - 1) + (calendar.firstWeekday - 1)) % 7 return calendar.shortWeekdaySymbols[dayIndex] } private var listView: some View { List { ForEach(items) { item in HStack { item.mood.icon .resizable() .aspectRatio(contentMode: .fit) .frame(width: 40, height: 40, alignment: .center) .foregroundColor(item.mood.color) VStack { HStack { Text(weekdayName(fromDate:item.forDate!)) .font(.title3) .foregroundColor(Color(UIColor.label)) .frame(maxWidth: 40, alignment: .leading) Text(" - ") .padding([.leading, .trailing], -10) Text(item.forDate ?? Date(), style: .date) .font(.title3) .foregroundColor(Color(UIColor.label)) .frame(maxWidth: .infinity, alignment: .leading) } Text("\(item.moodString)") .font(.body) .foregroundColor(Color(UIColor.systemGray)) .frame(maxWidth: .infinity, alignment: .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(fakeData: false, backDays: 30) .frame(minHeight: 85, maxHeight: 180) // should match backDays above Text("Past \(30) days") .font(.body) .foregroundColor(Color(UIColor.systemGray)) .frame(maxWidth: .infinity, alignment: .center) } 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.forDate)) let toPredicate = NSPredicate(format: "%K < %@", #keyPath(MoodEntry.forDate), 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) } }