init commit - bring project over from Mood

This commit is contained in:
Trey t
2022-01-10 09:04:38 -06:00
parent ff5d9bea18
commit 58697bf965
30 changed files with 1840 additions and 121 deletions

View File

@@ -0,0 +1,79 @@
//
// AddMoodHeaderView.swift
// Feels
//
// Created by Trey Tartt on 1/5/22.
//
import Foundation
import SwiftUI
import CoreData
struct AddMoodHeaderView: View {
@Environment(\.managedObjectContext) private var viewContext
var body: some View {
ZStack {
Color(UIColor.secondarySystemBackground)
VStack {
Text("How are you feeling today?")
.font(.title)
.foregroundColor(Color(UIColor.label))
.padding()
HStack{
ForEach(Mood.allValues) { mood in
VStack {
Button(action: {
addItem(withMoodValue: mood.rawValue)
}, label: {
mood.icon
.font(.system(size: 50))
})
//Text(mood.strValue)
}.frame(minWidth: 0, maxWidth: .infinity)
}
}
.padding([.leading, .trailing, .bottom])
}
}
.clipShape(RoundedRectangle(cornerRadius: 25, style: .continuous))
.frame(minHeight: 85, maxHeight: 140)
.frame(minWidth: 0, maxWidth: .infinity)
.padding()
}
private func addItem(withMoodValue moodValue: Int) {
withAnimation {
let newItem = MoodEntry(context: viewContext)
newItem.timestamp = Date()
newItem.moodValue = Int16(moodValue)
newItem.date = Date()
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)")
}
}
}
}
struct AddMoodHeaderView_Previews: PreviewProvider {
static var previews: some View {
Group {
AddMoodHeaderView().environment(\.managedObjectContext, PersistenceController.shared.container.viewContext)
AddMoodHeaderView().preferredColorScheme(.dark).environment(\.managedObjectContext, PersistenceController.shared.container.viewContext)
AddMoodHeaderView().environment(\.managedObjectContext, PersistenceController.shared.container.viewContext)
AddMoodHeaderView().preferredColorScheme(.dark).environment(\.managedObjectContext, PersistenceController.shared.container.viewContext)
}
}
}

View File

@@ -0,0 +1,152 @@
//
// 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<MoodEntry>
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<MoodEntry>(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)
}
}

View File

@@ -0,0 +1,16 @@
//
// GraphView.swift
// Feels
//
// Created by Trey Tartt on 1/8/22.
//
import Foundation
import SwiftUI
import CoreData
struct GraphView: View {
var body: some View {
Text("this is a graph")
}
}

View File

@@ -0,0 +1,82 @@
//
// HeaderStatsView.swift
// Feels
//
// Created by Trey Tartt on 1/8/22.
//
import SwiftUI
import Charts
struct HeaderStatsView : UIViewRepresentable {
//Bar chart accepts data as array of BarChartDataEntry objects
var entries : [BarChartDataEntry]
// this func is required to conform to UIViewRepresentable protocol
func makeUIView(context: Context) -> BarChartView {
//crate new chart
let chart = BarChartView()
chart.drawGridBackgroundEnabled = false
chart.drawValueAboveBarEnabled = false
chart.xAxis.drawAxisLineEnabled = false
chart.xAxis.labelTextColor = .clear
chart.rightAxis.drawAxisLineEnabled = false
chart.rightAxis.labelTextColor = .clear
chart.leftAxis.drawAxisLineEnabled = false
chart.leftAxis.labelTextColor = .clear
chart.xAxis.drawGridLinesEnabled = false
chart.leftAxis.drawGridLinesEnabled = false
chart.leftAxis.axisLineColor = .clear
chart.rightAxis.axisLineColor = .clear
chart.legend.textColor = .clear
chart.legend.enabled = false
chart.drawBordersEnabled = false
chart.drawMarkers = false
// chart.yAxis.drawGridLinesEnabled = false
chart.rightAxis.drawGridLinesEnabled = false
chart.borderColor = .clear
//it is convenient to form chart data in a separate func
chart.data = addData()
return chart
}
// this func is required to conform to UIViewRepresentable protocol
func updateUIView(_ uiView: BarChartView, context: Context) {
//when data changes chartd.data update is required
uiView.data = addData()
}
func addData() -> BarChartData{
let data = BarChartData()
//BarChartDataSet is an object that contains information about your data, styling and more
let dataSet = BarChartDataSet(entries: entries)
// change bars color to green
dataSet.colors = [NSUIColor.green]
//change data label
data.addDataSet(dataSet)
return data
}
typealias UIViewType = BarChartView
}
struct HeaderStatsView_Previews: PreviewProvider {
static var previews: some View {
HeaderStatsView(entries: [
//x - position of a bar, y - height of a bar
BarChartDataEntry(x: 1, y: 1),
BarChartDataEntry(x: 2, y: 4),
BarChartDataEntry(x: 3, y: 3),
BarChartDataEntry(x: 4, y: 2),
BarChartDataEntry(x: 5, y: 1)
]).frame(minHeight: 85, maxHeight: 90)
}
}

View File

@@ -0,0 +1,142 @@
//
// SettingsView.swift
// Feels
//
// Created by Trey Tartt on 1/8/22.
//
import SwiftUI
struct SettingsView: View {
@Environment(\.dismiss) var dismiss
@State private var currentDate = Date() {
didSet {
if self.showReminder {
LocalNotification.scheduleReminder(atTime: self.currentDate)
}
}
}
@State private var showReminder: Bool = false {
didSet {
if self.showReminder {
LocalNotification.testIfEnabled(completion: { result in
switch result{
case .success(_):
LocalNotification.scheduleReminder(atTime: self.currentDate)
case .failure(_):
// show error
break
}
})
} else {
LocalNotification.removeNotificaiton()
}
}
}
var body: some View { ZStack {
Color(UIColor.secondarySystemBackground)
VStack {
closeButtonView
.padding()
notificationCell
randomShitCell
addTestDataCell
clearDB
whyBackgroundMode
Spacer()
}
.padding()
}
}
private var closeButtonView: some View {
HStack{
Spacer()
Button(action: {
dismiss()
}, label: {
Text("Exit")
.font(.body)
.foregroundColor(Color(UIColor.systemBlue))
})
}
}
private var notificationCell: some View {
ZStack {
Color(UIColor.systemBackground)
VStack {
Toggle("Would you like to be reminded?", isOn: $showReminder)
.padding()
DatePicker("", selection: $currentDate, displayedComponents: .hourAndMinute)
.disabled(showReminder == false)
.padding()
}
}
.fixedSize(horizontal: false, vertical: true)
.clipShape(RoundedRectangle(cornerRadius: 25, style: .continuous))
}
private var randomShitCell: some View {
ZStack {
Color(UIColor.systemBackground)
VStack {
Text("random shit")
.padding()
}
}
.fixedSize(horizontal: false, vertical: true)
.clipShape(RoundedRectangle(cornerRadius: 25, style: .continuous))
}
private var addTestDataCell: some View {
ZStack {
Color(UIColor.systemBackground)
Button(action: {
PersistenceController.shared.populateTestData()
}, label: {
Text("Add test data")
})
.padding()
}
.fixedSize(horizontal: false, vertical: true)
.clipShape(RoundedRectangle(cornerRadius: 25, style: .continuous))
}
private var clearDB: some View {
ZStack {
Color(UIColor.systemBackground)
Button(action: {
PersistenceController.shared.clearDB()
}, label: {
Text("Clear DB")
})
.padding()
}
.fixedSize(horizontal: false, vertical: true)
.clipShape(RoundedRectangle(cornerRadius: 25, style: .continuous))
}
private var whyBackgroundMode: some View {
ZStack {
Color(UIColor.systemBackground)
Text("we do bg mode b/c we can")
.padding()
}
.fixedSize(horizontal: false, vertical: true)
.clipShape(RoundedRectangle(cornerRadius: 25, style: .continuous))
}
}
struct SettingsView_Previews: PreviewProvider {
static var previews: some View {
SettingsView()
SettingsView()
.preferredColorScheme(.dark)
}
}